Compare commits
4 Commits
1.0.0
...
ZeroFiveEi
Author | SHA1 | Date | |
---|---|---|---|
35904f5421 | |||
868310c687 | |||
57a9ad89e9 | |||
6d2b06ac0c |
@ -1,12 +1,12 @@
|
|||||||
Derek Foreman <derek@signalmarketing.com> and Ben Jansens <xor@orodu.net>
|
Derek Foreman <derek@signalmarketing.com> and Ben Jansens <xor@orodu.net>
|
||||||
Copyright (C) 2002-2006 Derek Foreman and Ben Jansens
|
Copyright (C) 2002-2006 Derek Foreman and Ben Jansens
|
||||||
Mario Danic <mario.danic@gmail.com>, Thomas Schmitt <scdbackup@gmx.net>
|
Mario Danic <mario.danic@gmail.com>, Thomas Schmitt <scdbackup@gmx.net>
|
||||||
Copyright (C) 2006-2010 Mario Danic, Thomas Schmitt
|
Copyright (C) 2006-2008 Mario Danic, Thomas Schmitt
|
||||||
|
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License version 2 or later
|
it under the terms of the GNU General Public License version 2 as
|
||||||
as published by the Free Software Foundation.
|
published by the Free Software Foundation.
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
This program is distributed in the hope that it will be useful,
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
279
ChangeLog
279
ChangeLog
@ -1,278 +1 @@
|
|||||||
SVN trunk (to become libburn-1.0.2.pl00.tar.gz)
|
nothing here now
|
||||||
===============================================================================
|
|
||||||
- no novelties yet
|
|
||||||
|
|
||||||
libburn-1.0.0.pl00.tar.gz Sun Jan 16 2011
|
|
||||||
===============================================================================
|
|
||||||
* Allowed umask to create stdio-drive files with rw-permissions for all
|
|
||||||
* cdrskin now refuses to burn if the foreseeable size exceeds media capacity
|
|
||||||
|
|
||||||
libburn-0.9.0.pl00.tar.gz Wed Dec 08 2010
|
|
||||||
===============================================================================
|
|
||||||
* Regression fix: SCSI reply data logging was disabled in release 0.8.6
|
|
||||||
|
|
||||||
libburn-0.8.8.pl00.tar.gz Wed Oct 20 2010
|
|
||||||
===============================================================================
|
|
||||||
* New API call burn_offst_source_new()
|
|
||||||
* New API call burn_disc_get_bd_spare_info()
|
|
||||||
|
|
||||||
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.
|
|
||||||
|
52
Makefile.am
52
Makefile.am
@ -1,8 +1,4 @@
|
|||||||
|
pkgconfigdir=$(libdir)/pkgconfig
|
||||||
# ts A90315 : LIBBURNIA_PKGCONFDIR is defined OS specific in acinclude.m4
|
|
||||||
# was: pkgconfigdir=$(libdir)/pkgconfig
|
|
||||||
pkgconfigdir=$(LIBBURNIA_PKGCONFDIR)
|
|
||||||
|
|
||||||
libincludedir=$(includedir)/libburn
|
libincludedir=$(includedir)/libburn
|
||||||
|
|
||||||
lib_LTLIBRARIES = libburn/libburn.la
|
lib_LTLIBRARIES = libburn/libburn.la
|
||||||
@ -12,9 +8,6 @@ lib_LTLIBRARIES = libburn/libburn.la
|
|||||||
# Build libraries
|
# Build libraries
|
||||||
libburn_libburn_la_LDFLAGS = \
|
libburn_libburn_la_LDFLAGS = \
|
||||||
-version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE)
|
-version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE)
|
||||||
# This causes undesired .o names
|
|
||||||
# configure.ac appends -D options to variable CFLAG
|
|
||||||
### libburn_libburn_la_CFLAGS = $(LIBBURN_DVD_OBS_64K)
|
|
||||||
libburn_libburn_la_LIBADD = $(LIBBURN_ARCH_LIBS) $(THREAD_LIBS)
|
libburn_libburn_la_LIBADD = $(LIBBURN_ARCH_LIBS) $(THREAD_LIBS)
|
||||||
libburn_libburn_la_SOURCES = \
|
libburn_libburn_la_SOURCES = \
|
||||||
libburn/async.c \
|
libburn/async.c \
|
||||||
@ -28,13 +21,13 @@ libburn_libburn_la_SOURCES = \
|
|||||||
libburn/debug.h \
|
libburn/debug.h \
|
||||||
libburn/drive.c \
|
libburn/drive.c \
|
||||||
libburn/drive.h \
|
libburn/drive.h \
|
||||||
libburn/ecma130ab.c \
|
|
||||||
libburn/ecma130ab.h \
|
|
||||||
libburn/error.h \
|
libburn/error.h \
|
||||||
libburn/file.c \
|
libburn/file.c \
|
||||||
libburn/file.h \
|
libburn/file.h \
|
||||||
libburn/init.c \
|
libburn/init.c \
|
||||||
libburn/init.h \
|
libburn/init.h \
|
||||||
|
libburn/lec.c \
|
||||||
|
libburn/lec.h \
|
||||||
libburn/libburn.h \
|
libburn/libburn.h \
|
||||||
libburn/libdax_audioxtr.h \
|
libburn/libdax_audioxtr.h \
|
||||||
libburn/libdax_audioxtr.c \
|
libburn/libdax_audioxtr.c \
|
||||||
@ -75,15 +68,11 @@ libburn_libburn_la_SOURCES = \
|
|||||||
libinclude_HEADERS = \
|
libinclude_HEADERS = \
|
||||||
libburn/libburn.h
|
libburn/libburn.h
|
||||||
|
|
||||||
install-exec-hook:
|
|
||||||
$(LIBBURNIA_LDCONFIG_CMD) "$(DESTDIR)$(libdir)" || echo 'NOTE: Explicite dynamic library configuration failed. If needed, configure manually for:' "$(DESTDIR)$(libdir)"
|
|
||||||
|
|
||||||
## ========================================================================= ##
|
## ========================================================================= ##
|
||||||
|
|
||||||
## Build test applications
|
## Build test applications
|
||||||
noinst_PROGRAMS = \
|
noinst_PROGRAMS = \
|
||||||
test/libburner \
|
test/libburner \
|
||||||
test/offst_source \
|
|
||||||
test/telltoc \
|
test/telltoc \
|
||||||
test/dewav \
|
test/dewav \
|
||||||
test/fake_au \
|
test/fake_au \
|
||||||
@ -93,37 +82,32 @@ noinst_PROGRAMS = \
|
|||||||
bin_PROGRAMS = \
|
bin_PROGRAMS = \
|
||||||
cdrskin/cdrskin
|
cdrskin/cdrskin
|
||||||
|
|
||||||
LIBBURN_EXTRALIBS = $(LIBBURN_ARCH_LIBS) $(THREAD_LIBS)
|
|
||||||
|
|
||||||
test_libburner_CPPFLAGS = -Ilibburn
|
test_libburner_CPPFLAGS = -Ilibburn
|
||||||
test_libburner_LDADD = $(libburn_libburn_la_OBJECTS) $(LIBBURN_EXTRALIBS)
|
test_libburner_LDADD = $(libburn_libburn_la_OBJECTS) $(THREAD_LIBS)
|
||||||
test_libburner_SOURCES = test/libburner.c
|
test_libburner_SOURCES = test/libburner.c
|
||||||
test_offst_source_CPPFLAGS = -Ilibburn
|
|
||||||
test_offst_source_LDADD = $(libburn_libburn_la_OBJECTS) $(LIBBURN_EXTRALIBS)
|
|
||||||
test_offst_source_SOURCES = test/offst_source.c
|
|
||||||
test_telltoc_CPPFLAGS = -Ilibburn
|
test_telltoc_CPPFLAGS = -Ilibburn
|
||||||
test_telltoc_LDADD = $(libburn_libburn_la_OBJECTS) $(LIBBURN_EXTRALIBS)
|
test_telltoc_LDADD = $(libburn_libburn_la_OBJECTS) $(THREAD_LIBS)
|
||||||
test_telltoc_SOURCES = test/telltoc.c
|
test_telltoc_SOURCES = test/telltoc.c
|
||||||
test_dewav_CPPFLAGS = -Ilibburn
|
test_dewav_CPPFLAGS = -Ilibburn
|
||||||
test_dewav_LDADD = $(libburn_libburn_la_OBJECTS) $(LIBBURN_EXTRALIBS)
|
test_dewav_LDADD = $(libburn_libburn_la_OBJECTS) $(THREAD_LIBS)
|
||||||
test_dewav_SOURCES = test/dewav.c
|
test_dewav_SOURCES = test/dewav.c
|
||||||
test_fake_au_CPPFLAGS =
|
test_fake_au_CPPFLAGS =
|
||||||
test_fake_au_LDADD =
|
test_fake_au_LDADD =
|
||||||
test_fake_au_SOURCES = test/fake_au.c
|
test_fake_au_SOURCES = test/fake_au.c
|
||||||
test_poll_CPPFLAGS = -Ilibburn
|
test_poll_CPPFLAGS = -Ilibburn
|
||||||
test_poll_LDADD = $(libburn_libburn_la_OBJECTS) $(LIBBURN_EXTRALIBS)
|
test_poll_LDADD = $(libburn_libburn_la_OBJECTS) $(THREAD_LIBS)
|
||||||
test_poll_SOURCES = test/poll.c
|
test_poll_SOURCES = test/poll.c
|
||||||
test_structest_CPPFLAGS = -Ilibburn
|
test_structest_CPPFLAGS = -Ilibburn
|
||||||
test_structest_LDADD = $(libburn_libburn_la_OBJECTS) $(LIBBURN_EXTRALIBS)
|
test_structest_LDADD = $(libburn_libburn_la_OBJECTS) $(THREAD_LIBS)
|
||||||
test_structest_SOURCES = test/structest.c
|
test_structest_SOURCES = test/structest.c
|
||||||
|
|
||||||
## cdrskin construction site - ts A60816 - B10116
|
## cdrskin construction site - ts A60816 - A81207
|
||||||
cdrskin_cdrskin_CPPFLAGS = -Ilibburn
|
cdrskin_cdrskin_CPPFLAGS = -Ilibburn
|
||||||
cdrskin_cdrskin_CFLAGS = -DCdrskin_libburn_1_0_0
|
cdrskin_cdrskin_CFLAGS = -DCdrskin_libburn_0_5_8
|
||||||
|
|
||||||
# cdrskin_cdrskin_LDADD = $(libburn_libburn_la_OBJECTS) $(LIBBURN_EXTRALIBS)
|
# cdrskin_cdrskin_LDADD = $(libburn_libburn_la_OBJECTS) $(THREAD_LIBS)
|
||||||
# ts A80123, change proposed by Simon Huggins to cause dynamic libburn linking
|
# ts A80123, change proposed by Simon Huggins to cause dynamic libburn linking
|
||||||
cdrskin_cdrskin_LDADD = libburn/libburn.la $(LIBBURN_EXTRALIBS)
|
cdrskin_cdrskin_LDADD = libburn/libburn.la $(THREAD_LIBS)
|
||||||
|
|
||||||
cdrskin_cdrskin_SOURCES = cdrskin/cdrskin.c cdrskin/cdrfifo.c cdrskin/cdrfifo.h cdrskin/cdrskin_timestamp.h
|
cdrskin_cdrskin_SOURCES = cdrskin/cdrskin.c cdrskin/cdrfifo.c cdrskin/cdrfifo.h cdrskin/cdrskin_timestamp.h
|
||||||
##
|
##
|
||||||
@ -150,10 +134,7 @@ doc/html: doc/doxygen.conf
|
|||||||
doc-upload: doc/html
|
doc-upload: doc/html
|
||||||
scp -r $</* $(webhost):$(webpath)
|
scp -r $</* $(webhost):$(webpath)
|
||||||
|
|
||||||
## ts B00729
|
all: doc
|
||||||
## 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 \
|
||||||
@ -209,17 +190,10 @@ 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-freebsd.h \
|
libburn/os-freebsd.h \
|
||||||
libburn/os-linux.h \
|
libburn/os-linux.h \
|
||||||
libburn/os-libcdio.h \
|
|
||||||
libburn/os-solaris.h \
|
|
||||||
libburn/sg-dummy.c \
|
|
||||||
libburn/sg-freebsd.c \
|
libburn/sg-freebsd.c \
|
||||||
libburn/sg-linux.c \
|
libburn/sg-linux.c \
|
||||||
libburn/sg-libcdio.c \
|
|
||||||
libburn/sg-solaris.c \
|
|
||||||
COPYING \
|
COPYING \
|
||||||
NEWS \
|
NEWS \
|
||||||
ChangeLog \
|
ChangeLog \
|
||||||
|
359
README
359
README
@ -4,95 +4,43 @@
|
|||||||
This all is under GPL.
|
This all is under GPL.
|
||||||
(See GPL reference, our clarification and commitment at the end of this text)
|
(See GPL reference, our clarification and commitment at the end of this text)
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
libburn-project.org
|
libburnia-project.org
|
||||||
By Mario Danic <mario.danic@gmail.com> and Thomas Schmitt <scdbackup@gmx.net>
|
By Mario Danic <mario.danic@gmail.com> and Thomas Schmitt <scdbackup@gmx.net>
|
||||||
Copyright (C) 2006-2011 Mario Danic, Thomas Schmitt
|
Copyright (C) 2006-2008 Mario Danic, Thomas Schmitt
|
||||||
Still containing parts of Libburn. By Derek Foreman <derek@signalmarketing.com>
|
|
||||||
and Ben Jansens <xor@orodu.net>
|
Still containing parts of
|
||||||
|
Libburn. By Derek Foreman <derek@signalmarketing.com> and
|
||||||
|
Ben Jansens <xor@orodu.net>
|
||||||
Copyright (C) 2002-2006 Derek Foreman and Ben Jansens
|
Copyright (C) 2002-2006 Derek Foreman and Ben Jansens
|
||||||
|
|
||||||
http://files.libburnia-project.org/releases/libburn-1.0.0.pl00.tar.gz
|
This libburnia-project.org toplevel README (C) 2006-2008 Thomas Schmitt
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
Build and Installation
|
Build and Installation
|
||||||
|
|
||||||
From tarball
|
Our build system is based on autotools. For preparing the build of a SVN
|
||||||
|
snapshot you will need autotools of at least version 1.7.
|
||||||
|
Check out from SVN by
|
||||||
|
svn co http://svn.libburnia-project.org/libburn/trunk libburn
|
||||||
|
go into directory libburn and apply autotools by
|
||||||
|
./bootstrap
|
||||||
|
|
||||||
Obtain libburn-1.0.0.pl00.tar.gz, take it to a directory of your choice and do:
|
Alternatively you may unpack a release tarball for which you do not need
|
||||||
|
autotools installed.
|
||||||
|
|
||||||
tar xzf libburn-1.0.0.pl00.tar.gz
|
To build a libburnia-project.org subproject it should be sufficient to go
|
||||||
cd libburn-1.0.0
|
into its toplevel directory (here: "libburn") and execute
|
||||||
./configure --prefix=/usr
|
./configure --prefix=/usr
|
||||||
make
|
make
|
||||||
|
|
||||||
To make libburn accessible for running resp. application development,
|
To make libburn accessible for running resp. application development,
|
||||||
and to install the cdrecord compatibility binary cdrskin, do
|
and to install the cdrecord compatibility binary cdrskin, do:
|
||||||
(as Superuser):
|
|
||||||
|
|
||||||
make install
|
make install
|
||||||
|
|
||||||
This procedure installs libburn.so.4 and cdrskin depending on it.
|
|
||||||
|
Above procedure installs cdrskin depending on libburn.so.4 .
|
||||||
For a standalone cdrskin binary, see cdrskin/README.
|
For a standalone cdrskin binary, see cdrskin/README.
|
||||||
|
|
||||||
A behavioral conflict is known between any burn software and demons like hald
|
|
||||||
which probe CD drives. This can spoil burn runs for CD-R or CD-RW.
|
|
||||||
You may have to keep your hald away from the drive. See for example
|
|
||||||
http://www.freebsd.org/gnome/docs/halfaq.html
|
|
||||||
|
|
||||||
|
|
||||||
From SVN
|
|
||||||
|
|
||||||
Our build system is based on autotools. For preparing the build of a SVN
|
|
||||||
snapshot you will need autotools of at least version 1.7.
|
|
||||||
Do in a directory of your choice:
|
|
||||||
|
|
||||||
svn co http://svn.libburnia-project.org/libburn/trunk libburn-svn
|
|
||||||
cd libburn-svn
|
|
||||||
./bootstrap
|
|
||||||
./configure --prefix=/usr
|
|
||||||
make
|
|
||||||
make install
|
|
||||||
|
|
||||||
Warning: The trunk might contain experimental features which might not
|
|
||||||
persist until next release.
|
|
||||||
|
|
||||||
|
|
||||||
Special ./configure options
|
|
||||||
|
|
||||||
make install on GNU/Linux will try to run program ldconfig with the library
|
|
||||||
installation directory as only argument. Failure to do so will not abort
|
|
||||||
installation. One may disable ldconfig by ./configure option:
|
|
||||||
--disable-ldconfig-at-install
|
|
||||||
|
|
||||||
In some situations Linux may deliver a better write performance to drives if
|
|
||||||
the track input is read with O_DIRECT (see man 2 open). The API call
|
|
||||||
burn_os_open_track_src() and the input readers of cdrskin and libburn fifo
|
|
||||||
can be told to use this peculiar read mode by:
|
|
||||||
--enable-track-src-odirect
|
|
||||||
|
|
||||||
But often libburn call burn_write_opts_set_dvd_obs(opts, 64*1024) will yield
|
|
||||||
even better performance in such a situation. 64k can be made default at
|
|
||||||
configure time by:
|
|
||||||
--enable-dvd-obs-64k
|
|
||||||
This may be combined with above --enable-track-src-odirect .
|
|
||||||
|
|
||||||
Alternatively the transport of SCSI commands can be done via libcdio-0.83.
|
|
||||||
You may install it and re-run libburn's ./configure with option
|
|
||||||
--enable-libcdio
|
|
||||||
|
|
||||||
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 clean ; make
|
|
||||||
make install
|
|
||||||
|
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
An important part of the project, libisofs, is hosted in a bzr repository at
|
An important part of the project, libisofs, is hosted in a bzr repository at
|
||||||
launchpad.net :
|
launchpad.net :
|
||||||
@ -103,6 +51,7 @@ Another part the project, libisoburn, is hosted in the libburnia SVN, too:
|
|||||||
|
|
||||||
See README files there.
|
See README files there.
|
||||||
|
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
@ -110,28 +59,27 @@ See README files there.
|
|||||||
|
|
||||||
libburnia-project.org is an open-source software project for reading, mastering
|
libburnia-project.org is an open-source software project for reading, mastering
|
||||||
and writing optical discs.
|
and writing optical discs.
|
||||||
For now this means CD media, all DVD media except DVD-R DL, all BD media.
|
For now this means only CD media and all single layer DVD media except DVD+R.
|
||||||
|
|
||||||
The project comprises of several more or less interdependent parts which
|
The project comprises of several more or less interdependent parts which
|
||||||
together strive to be a usable foundation for application development.
|
together strive to be a usable foundation for application development.
|
||||||
These are libraries, language bindings, and middleware binaries which emulate
|
These are libraries, language bindings, and middleware binaries which emulate
|
||||||
classical (and valuable) Linux tools.
|
classical (and valuable) Linux tools.
|
||||||
Currently it is supported on GNU/Linux with kernels >= 2.4,
|
Currently it is supported on Linux with kernels >= 2.4 and on FreeBSD versions
|
||||||
on FreeBSD with ATAPI/CAM enabled in the kernel (see man atapicam),
|
with ATAPI/CAM support enabled in the kernel, see atapicam(4).
|
||||||
and on OpenSolaris (tested with kernel 5.11).
|
|
||||||
On other X/Open compliant systems there will only be pseudo drives, but no
|
|
||||||
direct MMC operation on real CD/DVD/BD drives.
|
|
||||||
|
|
||||||
For full ports to other systems we would need : login on a development machine
|
Our scope is currently Linux 2.4 or 2.6 and FreeBSD versions with ATAPI/CAM
|
||||||
resp. a live OS on CD or DVD, advise from a system person about the equivalent
|
support enabled in the kernel, see atapicam(4). For ports to other systems
|
||||||
of Linux sg or FreeBSD CAM, volunteers for testing of realistic use cases.
|
we would need : login on a development machine resp. a live OS on CD or DVD,
|
||||||
|
advise from a system person about the equivalent of Linux sg or FreeBSD CAM,
|
||||||
|
volunteers for testing of realistic use cases.
|
||||||
|
|
||||||
We have a well tested code base for burning data and audio CDs, DVDs and BDs.
|
We have a well tested code base for burning data and audio CDs and many DVD
|
||||||
The burn API is quite comprehensively documented and can be used to build a
|
types. The burn API is quite comprehensively documented and can be used to
|
||||||
presentable application.
|
build a presentable application.
|
||||||
We have a functional application which emulates the core use cases of cdrecord
|
We have a functional binary which emulates the core use cases of cdrecord in
|
||||||
in order to prove that usability, and in order to allow you to explore
|
order to prove that usability, and in order to allow you to explore libburn's
|
||||||
libburn's scope by help of existing cdrecord frontends.
|
scope by help of existing cdrecord frontends.
|
||||||
|
|
||||||
ISO 9660 filesystems with Rock Ridge and Joliet extensions can be created
|
ISO 9660 filesystems with Rock Ridge and Joliet extensions can be created
|
||||||
and manipulated quite freely. This capability together with our burn capability
|
and manipulated quite freely. This capability together with our burn capability
|
||||||
@ -150,15 +98,12 @@ 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.
|
||||||
An own ISO 9660 extension stores ACLs, xattr, and MD5 of file
|
libisofs is to be the foundation of our upcoming mkisofs emulation.
|
||||||
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
|
||||||
@ -174,12 +119,8 @@ The project components (list subject to growth, hopefully):
|
|||||||
- xorriso is an application of all three libraries which creates, loads,
|
- xorriso is an application of all three libraries which creates, loads,
|
||||||
manipulates and writes ISO 9660 filesystem images with
|
manipulates and writes ISO 9660 filesystem images with
|
||||||
Rock Ridge extensions. Manipulation is not only adding or
|
Rock Ridge extensions. Manipulation is not only adding or
|
||||||
overwriting of files but also deleting, renaming, attribute
|
overwriting of files but also deletion, renaming, and attribute
|
||||||
changing, incremental backups, activating boot images, and
|
changing.
|
||||||
extracting of files from ISO images to disk. There is also a
|
|
||||||
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
|
||||||
@ -202,13 +143,6 @@ libburn.so.4 (since 0.3.4, March 2007),
|
|||||||
libisofs.so.6 (since 0.6.2, February 2008),
|
libisofs.so.6 (since 0.6.2, February 2008),
|
||||||
libisoburn.so.1 (since 0.1.0, February 2008).
|
libisoburn.so.1 (since 0.1.0, February 2008).
|
||||||
|
|
||||||
Applications must use 64 bit off_t. E.g. by defining
|
|
||||||
#define _LARGEFILE_SOURCE
|
|
||||||
#define _FILE_OFFSET_BITS 64
|
|
||||||
or take special precautions to interface with the libraries by 64 bit integers
|
|
||||||
where the .h files prescribe off_t. To reduce libburn's off_t size to 32 bit
|
|
||||||
will keep it from processing tracks of more than 2 GB size.
|
|
||||||
|
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
Project history as far as known to me:
|
Project history as far as known to me:
|
||||||
@ -402,206 +336,12 @@ Project history as far as known to me:
|
|||||||
- 7th Dec 2008 libburn-0.5.8 prevents a SIGSEGV with wierd CD table-of-content
|
- 7th Dec 2008 libburn-0.5.8 prevents a SIGSEGV with wierd CD table-of-content
|
||||||
and improves BD-RE formatting.
|
and improves BD-RE formatting.
|
||||||
|
|
||||||
- 9th Dec 2008 Our project received a donation from Thomas Weber.
|
|
||||||
|
|
||||||
- 2nd Jan 2009 libburn-0.6.0 allows to format BD-R and to write to either
|
|
||||||
formatted or unformatted BD-R.
|
|
||||||
|
|
||||||
- 6th Jan 2009 libisoburn-0.3.2. xorriso can produce and execute commands for
|
|
||||||
mounting older sessions from all kinds of media. Pseudo-drives outside the
|
|
||||||
/dev/ tree can be addressed without prefix "stdio:".
|
|
||||||
|
|
||||||
- 20th Feb 2009 libburn-0.6.2 source release now compiles out of the box
|
|
||||||
on FreeBSD.
|
|
||||||
|
|
||||||
- 28 Feb 2009 libisofs-0.6.14 can record ACLs and Extended Attributes xattr
|
|
||||||
in its ISO images.
|
|
||||||
|
|
||||||
- 01 Mar 2009 libisoburn-0.3.4. xorriso makes use of the ACL and xattr
|
|
||||||
capabilities provided by libisofs for xorriso backup features.
|
|
||||||
|
|
||||||
- 11 Mar 2009 libisofs-0.6.16 of libisofs fixes two bugs which on Solaris
|
|
||||||
prevented to navigate the ISO images by ".." and to recognize the Rock Ridge
|
|
||||||
extensions of ISO images. The ban to build libisofs on operating systems
|
|
||||||
other than Linux and FreeBSD has been lifted.
|
|
||||||
|
|
||||||
- 13 Mar 2009 libburn-0.6.4 got a dummy adapter for SCSI/MMC command transport.
|
|
||||||
It will show no drives and thus libburn will only be able to perform
|
|
||||||
operations on "stdio:" pseudo drives. Nevertheless this allowed to lift the
|
|
||||||
ban to build libburn on operating systems other than Linux and FreeBSD.
|
|
||||||
|
|
||||||
- 16 Mar 2009 libisoburn-0.3.6: xorriso uses RRIP version 1.10 as default
|
|
||||||
in order to be mountable where mkisofs images are mountable.
|
|
||||||
|
|
||||||
- 17 Apr 2009 libisofs-0.6.18 introduces content filtering of data files.
|
|
||||||
Built-in filters allow compression to formats gzip and zisofs. External
|
|
||||||
filter processes allow arbitrary data conversions like encryption.
|
|
||||||
|
|
||||||
- 19 Apr 2009 libisoburn-0.3.8 makes use of the new libisofs capability to
|
|
||||||
perform content filtering of data files.
|
|
||||||
|
|
||||||
- 08 May 2009 libburn-0.6.6 fixes a bug with aborting on broken output pipe
|
|
||||||
and a bug with device scan on FreeBSD.
|
|
||||||
|
|
||||||
- 31 May 2009 libisofs-0.6.20 can record hard link relations in ISO images
|
|
||||||
and offers support with restoring them to disk. Current Linux kernels will
|
|
||||||
mount images with such hard links but will attribute a unique inode number
|
|
||||||
to each file.
|
|
||||||
|
|
||||||
- 28 Jun 2009 libisoburn-0.4.0: xorriso can record and restore hard link
|
|
||||||
relations of files. Performance of data reading has been improved. Option
|
|
||||||
-find now supports logical operators with its tests.
|
|
||||||
|
|
||||||
- 14 Jul 2009 libburn-0.6.8 fixes bugs and shortcommings with old MMC-1 drives
|
|
||||||
and with large SCSI bus numbers as handed out by Linux for USB drives.
|
|
||||||
|
|
||||||
- 20 Jul 2009 libisoburn-0.4.0.pl01 fixes a regression in xorriso which caused
|
|
||||||
data loss in older sessions if xorriso was used underneath growisofs.
|
|
||||||
Affected are releases since libisoburn-0.3.2 in january 2009.
|
|
||||||
|
|
||||||
- 25 Aug 2009 libisofs-0.6.22 can record MD5 checksums for the whole session
|
|
||||||
and for each single data file. Checksum tags allow to verify superblock and
|
|
||||||
directory tree before importing them.
|
|
||||||
|
|
||||||
- 27 Aug 2009 libburn-0.7.0 allows to calm down a drive and to inquire its
|
|
||||||
supported profiles. It works around some pitfalls with U3 enhanced memory
|
|
||||||
sticks which emulate a CD-ROM.
|
|
||||||
|
|
||||||
- 27 Aug 2009 libisoburn-0.4.0.pl00 can record MD5 checksums by which one may
|
|
||||||
verify the session or single data files in the image. When comparing image
|
|
||||||
files with files in the local filesystem, the MD5 sums avoid the need for
|
|
||||||
reading file content from the image.
|
|
||||||
|
|
||||||
- 22 Sep 2009 libisoburn-0.4.0.pl01 fixes a bug in xorriso option -cut_out.
|
|
||||||
|
|
||||||
- 08 Oct 2009 libisofs-0.6.24 fixes a bug which could cause the loss of blanks
|
|
||||||
in file names when a new session got added to an ISO image. With names
|
|
||||||
shorter than 251 characters this happened only to trailing blanks.
|
|
||||||
|
|
||||||
- 08 Oct 2009 libisoburn-0.4.0.pl02 fixes bugs with xorriso option -for_backup,
|
|
||||||
with xorrisofs -help, and with xorrecord -help.
|
|
||||||
|
|
||||||
- 12 Oct 2009 libburn-0.7.2 fixes a bug with CD TAO multi-track dummy sessions.
|
|
||||||
It can retrieve media product info and can process track input which was
|
|
||||||
prepared for CD-ROM XA Mode 2 Form 1. cdrskin now performs option -minfo.
|
|
||||||
|
|
||||||
- 28 Oct 2009 libisoburn-0.4.4 fixes a bug with cdrecord emulation and
|
|
||||||
introduces new information options about media type and ISO image id strings.
|
|
||||||
On Linux it helps with mounting two sessions of the same media
|
|
||||||
simultaneously.
|
|
||||||
|
|
||||||
- 12 Nov 2009 libburn-0.7.2.pl01 works around problems with Pioneer DVR-216D.
|
|
||||||
DVD-R runs made the drive stuck. Ejecting the tray did not work properly.
|
|
||||||
|
|
||||||
- 06 Dec 2009 libburn-0.7.4 works around problems with newer DVD burners,
|
|
||||||
provides throughput enhancements with hampered busses on Linux, and new
|
|
||||||
API calls to log SCSI commands and to control the libburn fifo.
|
|
||||||
|
|
||||||
- 09 Dec 2009 libisoburn-0.4.6 allows performance tuning of output to DVD
|
|
||||||
drives or disk files.
|
|
||||||
|
|
||||||
- 26 Dec 2009 libburn-0.7.4.pl01 fixes the release tarball which was lacking
|
|
||||||
the files of the generic system adapter for X/Open.
|
|
||||||
|
|
||||||
- 29 Dec 2009 Our project received a donation for purchasing a fine small
|
|
||||||
computer which shall serve as OS farm for development and support.
|
|
||||||
|
|
||||||
- 20 Jan 2010 Version 0.6.26 of libisofs fixes minor bugs and shall enhance
|
|
||||||
portability.
|
|
||||||
|
|
||||||
- 22 Jan 2010 libburn-0.7.6 has an improved system adapter for FreeBSD,
|
|
||||||
fixes bugs about the generic X/Open system adapter, and allows to use
|
|
||||||
libcdio >= 0.83 as SCSI transport facility.
|
|
||||||
|
|
||||||
- 10 Feb 2010 libisofs-0.6.28 fixes a regression about bootable images which
|
|
||||||
was introduced by version 0.6.22 in August 2009.
|
|
||||||
|
|
||||||
- 23 Feb 2010 libisoburn-0.5.0 marks the transition of the xorriso standalone
|
|
||||||
version to an official GNU project. The name changed to "GNU xorriso" and its
|
|
||||||
license is now GPLv3+.
|
|
||||||
The licenses of libburnia libraries and applications are not affected by
|
|
||||||
this change.
|
|
||||||
|
|
||||||
- 10 Mar 2010 libburn-0.7.8 fixes bugs and improves the built-in abort handler
|
|
||||||
on FreeBSD.
|
|
||||||
|
|
||||||
- 30 Mar 2010 Release 0.5.2 of libisoburn provides xorriso documentation in
|
|
||||||
GNU Texinfo format with embedded extra data to derive a full man page.
|
|
||||||
|
|
||||||
- 09 Apr 2010 libburn-0.8.0 now works with ahci driver on FreeBSD 8-STABLE.
|
|
||||||
|
|
||||||
- 03 May 2010 Version 0.6.32 of libisofs is able to create ISO images with
|
|
||||||
multiple boot images. All boot catalog parameters described in El-Torito
|
|
||||||
specs can be set and inquired. This allows to use GRUB boot images for EFI.
|
|
||||||
|
|
||||||
- 04 May 2010 Release 0.5.6.pl00 of libisoburn makes use of the new libisofs
|
|
||||||
capabilities about boot images.
|
|
||||||
|
|
||||||
- 11 Jun 2010 libburn-0.8.2 now works on Solaris.
|
|
||||||
|
|
||||||
- 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.
|
|
||||||
|
|
||||||
- Sat Sep 18 2010 Release 0.6.2.pl00 of libisoburn introduces a partition
|
|
||||||
with non-zero offset for ISO 9660 images on USB sticks, improves mkisofs
|
|
||||||
emulation, and fixes a regression which existed since version 0.4.2.
|
|
||||||
|
|
||||||
- Wed Oct 20 2010 libburn-0.8.8 can report the used amount of BD spare blocks.
|
|
||||||
|
|
||||||
- Sat Oct 23 2010 Version 0.6.38 of libisofs can use libjte to produce jigdo
|
|
||||||
files along with the ISO image. Further filesystem images may be appended
|
|
||||||
as MBR partitions 1 to 4. The capability was added to produce boot blocks
|
|
||||||
for computers with MIPS CPU.
|
|
||||||
|
|
||||||
- Tue Oct 26 2010 Release 0.6.4.pl00 of libisoburn and xorriso makes use of
|
|
||||||
the new libisofs capabilities.
|
|
||||||
|
|
||||||
- Wed Dec 08 2010 libburn-0.9.0 fixes a regression with SCSI command logging.
|
|
||||||
|
|
||||||
- Fri Dec 10 2010 Version 0.6.40 of libisofs makes the prediction of the
|
|
||||||
emerging image size less expensive and is able to make images bootable
|
|
||||||
for SUN SPARC systems.
|
|
||||||
|
|
||||||
- Sun Dec 12 2010 Release 0.6.6.pl00 of libisoburn and xorriso can read ISO
|
|
||||||
images which were copied to a different start address than they were prepared
|
|
||||||
for.
|
|
||||||
|
|
||||||
- Mon Jan 17 2011 we go for release 1.0.0. This does not indicate a
|
|
||||||
technological overhaul but shall emphasize the maturity of the software.
|
|
||||||
libisofs-1.0.0 fixes a bug about the length of ECMA-119 directory names and
|
|
||||||
is ready to allow untranslated ECMA-119 names (violating the specs).
|
|
||||||
libburn-1.0.0.pl00 allows umask to create stdio-drive files with
|
|
||||||
rw-permissions for all. cdrskin now refuses to burn if the foreseeable size
|
|
||||||
exceeds media capacity
|
|
||||||
libisoburn-1.0.0.pl00 allows to create an ISO 9660:1999 directory tree,
|
|
||||||
improved the emulation fidelity of command -as mkisofs, lowered the default
|
|
||||||
abort threshold for xorriso batch mode, and increased that threshold for
|
|
||||||
xorriso dialog mode.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License version 2 or later
|
it under the terms of the GNU General Public License as published by
|
||||||
as published by the Free Software Foundation.
|
the Free Software Foundation. To be exact: version 2 of that License.
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
This program is distributed in the hope that it will be useful,
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
@ -619,16 +359,16 @@ other copyrighted code has been replaced by ours and by copyright-free
|
|||||||
contributions of our friends:
|
contributions of our friends:
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
We, the copyright holders, agree on the interpretation that dynamical linking
|
We, the copyright holders, agree on the interpretation that
|
||||||
of our libraries constitutes "use of" and not "derivation from" our work in
|
dynamical linking of our libraries constitutes "use of" and
|
||||||
the sense of GPL, provided those libraries are compiled from our unaltered
|
not "derivation from" our work in the sense of GPL, provided
|
||||||
code or from altered code published under GPL.
|
those libraries are compiled from our unaltered code.
|
||||||
|
|
||||||
So we will not raise legal protest if you link our libraries dynamically with
|
Thus you may link our libraries dynamically with applications
|
||||||
applications which are not under GPL, or if you distribute our libraries
|
which are not under GPL. You may distribute our libraries and
|
||||||
and application tools in binary form, as long as you fulfill the usual
|
application tools in binary form, if you fulfill the usual
|
||||||
condition of GPL to offer a copy of their source code -altered or unaltered-
|
condition of GPL to offer a copy of the source code -altered
|
||||||
under GPL.
|
or unaltered- under GPL.
|
||||||
|
|
||||||
We ask you politely to use our work in open source spirit
|
We ask you politely to use our work in open source spirit
|
||||||
and with the due reference to the entire open source community.
|
and with the due reference to the entire open source community.
|
||||||
@ -645,5 +385,4 @@ means to qualify for GPL.
|
|||||||
For now we are firmly committed to maintain one single license: GPL.
|
For now we are firmly committed to maintain one single license: GPL.
|
||||||
|
|
||||||
signed: Mario Danic, Thomas Schmitt
|
signed: Mario Danic, Thomas Schmitt
|
||||||
Agreement joined later by: Vreixo Formoso
|
|
||||||
|
|
||||||
|
97
acinclude.m4
97
acinclude.m4
@ -1,111 +1,22 @@
|
|||||||
AC_DEFUN([LIBBURNIA_SET_FLAGS],
|
|
||||||
[
|
|
||||||
case $target_os in
|
|
||||||
freebsd*)
|
|
||||||
LDFLAGS="$LDFLAGS -L/usr/local/lib"
|
|
||||||
CPPFLAGS="$CPPFLAGS -I/usr/local/include"
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
])
|
|
||||||
|
|
||||||
|
|
||||||
AC_DEFUN([TARGET_SHIZZLE],
|
AC_DEFUN([TARGET_SHIZZLE],
|
||||||
[
|
[
|
||||||
ARCH=""
|
ARCH=""
|
||||||
LIBBURNIA_PKGCONFDIR="$libdir"/pkgconfig
|
|
||||||
|
|
||||||
AC_MSG_CHECKING([target operating system])
|
AC_MSG_CHECKING([target operating system])
|
||||||
|
|
||||||
LIBBURNIA_LDCONFIG_CMD="echo 'No ldconfig run performed. If needed, configure manually for:'"
|
case $target in
|
||||||
|
*-*-linux*)
|
||||||
case $target_os in
|
|
||||||
linux*)
|
|
||||||
ARCH=linux
|
ARCH=linux
|
||||||
LIBBURN_ARCH_LIBS=
|
LIBBURN_ARCH_LIBS=
|
||||||
LIBBURNIA_LDCONFIG_CMD=ldconfig
|
|
||||||
;;
|
;;
|
||||||
freebsd*)
|
*-*-freebsd*)
|
||||||
ARCH=freebsd
|
|
||||||
LIBBURN_ARCH_LIBS=-lcam
|
|
||||||
LIBBURNIA_PKGCONFDIR=$(echo "$libdir" | sed 's/\/lib$/\/libdata/')/pkgconfig
|
|
||||||
;;
|
|
||||||
kfreebsd*-gnu)
|
|
||||||
ARCH=freebsd
|
ARCH=freebsd
|
||||||
LIBBURN_ARCH_LIBS=-lcam
|
LIBBURN_ARCH_LIBS=-lcam
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
ARCH=
|
AC_ERROR([You are attempting to compile for an unsupported platform])
|
||||||
LIBBURN_ARCH_LIBS=
|
|
||||||
# AC_ERROR([You are attempting to compile for an unsupported platform])
|
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
AC_MSG_RESULT([$ARCH])
|
AC_MSG_RESULT([$ARCH])
|
||||||
])
|
])
|
||||||
|
|
||||||
|
|
||||||
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 Important: Must be performed _after_ TARGET_SHIZZLE
|
|
||||||
dnl
|
|
||||||
AC_DEFUN([LIBBURNIA_SET_PKGCONFIG],
|
|
||||||
[
|
|
||||||
### for testing --enable-libdir-pkgconfig on Linux
|
|
||||||
### LIBBURNIA_PKGCONFDIR="$libdir"data/pkgconfig
|
|
||||||
|
|
||||||
if test "x$LIBBURNIA_PKGCONFDIR" = "x$libdir"/pkgconfig
|
|
||||||
then
|
|
||||||
dummy=dummy
|
|
||||||
else
|
|
||||||
AC_ARG_ENABLE(libdir-pkgconfig,
|
|
||||||
[ --enable-libdir-pkgconfig Install to $libdir/pkgconfig on any OS, default=no],
|
|
||||||
, enable_libdir_pkgconfig="no")
|
|
||||||
AC_MSG_CHECKING([for --enable-libdir-pkgconfig])
|
|
||||||
if test "x$enable_libdir_pkgconfig" = xyes
|
|
||||||
then
|
|
||||||
LIBBURNIA_PKGCONFDIR="$libdir"/pkgconfig
|
|
||||||
fi
|
|
||||||
AC_MSG_RESULT([$enable_libdir_pkgconfig])
|
|
||||||
fi
|
|
||||||
|
|
||||||
libburnia_pkgconfig_override="no"
|
|
||||||
AC_ARG_ENABLE(pkgconfig-path,
|
|
||||||
[ --enable-pkgconfig-path=DIR Absolute path of directory for libisofs-*.pc],
|
|
||||||
libburnia_pkgconfig_override="yes" , enable_pkgconfig_path="none")
|
|
||||||
AC_MSG_CHECKING([for overridden pkgconfig directory path])
|
|
||||||
if test "x$enable_pkgconfig_path" = xno
|
|
||||||
then
|
|
||||||
libburnia_pkgconfig_override="no"
|
|
||||||
fi
|
|
||||||
if test "x$enable_pkgconfig_path" = x -o "x$enable_pkgconfig_path" = xyes
|
|
||||||
then
|
|
||||||
libburnia_pkgconfig_override="invalid argument"
|
|
||||||
fi
|
|
||||||
if test "x$libburnia_pkgconfig_override" = xyes
|
|
||||||
then
|
|
||||||
LIBBURNIA_PKGCONFDIR="$enable_pkgconfig_path"
|
|
||||||
AC_MSG_RESULT([$LIBBURNIA_PKGCONFDIR])
|
|
||||||
else
|
|
||||||
AC_MSG_RESULT([$libburnia_pkgconfig_override])
|
|
||||||
fi
|
|
||||||
AC_SUBST(LIBBURNIA_PKGCONFDIR)
|
|
||||||
|
|
||||||
dnl For debugging only
|
|
||||||
### AC_MSG_RESULT([LIBBURNIA_PKGCONFDIR = $LIBBURNIA_PKGCONFDIR])
|
|
||||||
|
|
||||||
])
|
|
||||||
|
|
||||||
|
205
cdrskin/README
205
cdrskin/README
@ -4,21 +4,16 @@
|
|||||||
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-1.0.0.pl00.tar.gz
|
http://scdbackup.sourceforge.net/cdrskin-0.5.8.pl00.tar.gz
|
||||||
|
Copyright (C) 2006-2008 Thomas Schmitt, provided under GPL version 2.
|
||||||
Copyright (C) 2006-2011 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 GNU/Linux with kernels >= 2.4,
|
Currently it is supported on Linux with kernels >= 2.4 and on FreeBSD versions
|
||||||
on FreeBSD and on OpenSolaris.
|
with ATAPI/CAM support enabled in the kernel, see atapicam(4).
|
||||||
IDE drives under Linux 2.4. need kernel module ide-scsi.
|
|
||||||
ATA and SATA drives under FreeBSD need kernel module atapicam.
|
|
||||||
On other X/Open compliant systems there will only be emulated drives, but no
|
|
||||||
direct MMC operation on real CD/DVD/BD drives.
|
|
||||||
|
|
||||||
By using this software you agree to the disclaimer at the end of this text
|
By using this software you agree to the disclaimer at the end of this text
|
||||||
"This software is provided as is. There is no warranty implied and ..."
|
"This software is provided as is. There is no warranty implied and ..."
|
||||||
@ -26,10 +21,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-1.0.0.pl00.tar.gz, take it to a directory of your choice and do:
|
Obtain cdrskin-0.5.8.pl00.tar.gz, take it to a directory of your choice and do:
|
||||||
|
|
||||||
tar xzf cdrskin-1.0.0.pl00.tar.gz
|
tar xzf cdrskin-0.5.8.pl00.tar.gz
|
||||||
cd cdrskin-1.0.0
|
cd cdrskin-0.5.8
|
||||||
|
|
||||||
Within that directory execute:
|
Within that directory execute:
|
||||||
|
|
||||||
@ -37,7 +32,8 @@ Within that directory execute:
|
|||||||
make
|
make
|
||||||
|
|
||||||
This will already produce a cdrskin binary. But it will be necessary to
|
This will already produce a cdrskin binary. But it will be necessary to
|
||||||
install libburn in order to use this binary.
|
install libburn in order to use this binary. Installation of libburn is
|
||||||
|
beyond the scope of cdrskin. For this, see included libburn docs.
|
||||||
|
|
||||||
In order to surely get a standalone binary, execute
|
In order to surely get a standalone binary, execute
|
||||||
|
|
||||||
@ -74,7 +70,7 @@ It is not necessary for the standalone cdrskin binary to have libburn
|
|||||||
installed, since it incorporates the necessary libburn parts at compile time.
|
installed, since it incorporates the necessary libburn parts at compile time.
|
||||||
It will not collide with an installed version of libburn either.
|
It will not collide with an installed version of libburn either.
|
||||||
But libpthread must be installed on the system and glibc has to match. (See
|
But libpthread must be installed on the system and glibc has to match. (See
|
||||||
below for a way to create a totally static linked binary.)
|
below for a way to create a statically linked binary.)
|
||||||
|
|
||||||
To install the man page, you may do: echo $MANPATH and choose one of the
|
To install the man page, you may do: echo $MANPATH and choose one of the
|
||||||
listed directories to copy the man-page under its ./man1 directory. Like:
|
listed directories to copy the man-page under its ./man1 directory. Like:
|
||||||
@ -104,25 +100,17 @@ 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'
|
||||||
|
|
||||||
On Linux, full and insecure enabling of both for everybody would look like
|
So full and insecure enabling of both for everybody would look like
|
||||||
chmod a+rw /dev/sr0 /dev/hda
|
|
||||||
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.
|
chmod a+rw /dev/sr0 /dev/sr1
|
||||||
On Solaris, pfexec privileges may be restricted to "basic,sys_devices".
|
|
||||||
See below "System Dependend Drive Permission Examples".
|
This is equivalent to the traditional setup chmod a+x,u+s cdrecord.
|
||||||
|
|
||||||
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
|
||||||
@ -150,7 +138,7 @@ Obtain some info about the drive
|
|||||||
cdrskin dev=0,1,0 -checkdrive
|
cdrskin dev=0,1,0 -checkdrive
|
||||||
|
|
||||||
Obtain some info about the drive and the inserted media
|
Obtain some info about the drive and the inserted media
|
||||||
cdrskin dev=0,1,0 -atip -v -minfo
|
cdrskin dev=0,1,0 -atip -v
|
||||||
|
|
||||||
Prepare CD-RW or DVD-RW for re-use, DVD-RAM or BD-RE for first use
|
Prepare CD-RW or DVD-RW for re-use, DVD-RAM or BD-RE for first use
|
||||||
cdrskin -v dev=/dev/sg1 blank=as_needed -eject
|
cdrskin -v dev=/dev/sg1 blank=as_needed -eject
|
||||||
@ -286,16 +274,13 @@ behavior.
|
|||||||
BD-RE media need formatting before first use. cdrskin option "blank=as_needed"
|
BD-RE media need formatting before first use. cdrskin option "blank=as_needed"
|
||||||
recognizes unformatted BD-RE and applies a lengthy formatting run.
|
recognizes unformatted BD-RE and applies a lengthy formatting run.
|
||||||
|
|
||||||
During write operations DVD-RAM and BD-RE automatically apply Defect
|
During write operations DVD-RAM and BD-RE automatically apply defect
|
||||||
Management. This usually slows them down to half nominal speed. If drive
|
management. This usually slows them down to half nominal speed. If drive
|
||||||
and media produce flawless results anyway, then one can try to reach full
|
and media produce flawless results anyway, then one can try to reach full
|
||||||
nominal speed by option "stream_recording=on".
|
nominal speed by option "stream_recording=on".
|
||||||
In this case bad blocks are not detected during write and not even previously
|
In this case bad blocks are not detected during write and not even previously
|
||||||
known bad blocks are avoided. So you have to make your own readability tests
|
known bad blocks are avoided. So you have to make your own readability tests
|
||||||
and go back to half speed as soon as the first read errors show up.
|
and go back to half speed as soon as the first read errors show up.
|
||||||
Instead of "on" one may also set a start address for stream recording.
|
|
||||||
Like "stream_recording=100m". This will write slowly to the first 100 MB of
|
|
||||||
the media and accelerate when writing to higher addresses.
|
|
||||||
|
|
||||||
Option --grow_overwriteable_iso allows -multi (although unneeded), enables
|
Option --grow_overwriteable_iso allows -multi (although unneeded), enables
|
||||||
-msinfo and -toc, and makes blank=fast an invalidator for ISO filesystems
|
-msinfo and -toc, and makes blank=fast an invalidator for ISO filesystems
|
||||||
@ -310,11 +295,10 @@ Add-on session (equivalent to growisofs -M):
|
|||||||
cdrskin dev=/dev/sr0 --grow_overwriteable_iso ... -
|
cdrskin dev=/dev/sr0 --grow_overwriteable_iso ... -
|
||||||
|
|
||||||
|
|
||||||
DVD-RW , DVD-R , DVD-R DL
|
DVD-RW and DVD-R
|
||||||
|
|
||||||
DVD-RW are usable if formatted to state "Restricted Overwrite" or if in state
|
DVD-RW are usable if formatted to state "Restricted Overwrite" or if in state
|
||||||
"Sequential Recording". DVD-R are always in sequential state. DVD-R DL are
|
"Sequential Recording". DVD-R are always in sequential state.
|
||||||
always sequential and incapable of multi-session.
|
|
||||||
|
|
||||||
"Sequential" is the state of unused media and of media previously blanked
|
"Sequential" is the state of unused media and of media previously blanked
|
||||||
or written by cdrecord. dvd+rw-format -blank can also achieve this state.
|
or written by cdrecord. dvd+rw-format -blank can also achieve this state.
|
||||||
@ -366,24 +350,14 @@ Incremental Streaming afterwards. So blank=fast will do full blanking.
|
|||||||
blank=deformat_sequential_quickest is faster but might yield DAO-only media.
|
blank=deformat_sequential_quickest is faster but might yield DAO-only media.
|
||||||
|
|
||||||
|
|
||||||
DVD+R , DVD+R DL , BD-R
|
DVD+R and DVD+R DL
|
||||||
|
|
||||||
From the view of cdrskin they behave much like DVD-R. Each track gets wrapped
|
From the view of cdrskin they behave much like DVD-R. Each track gets wrapped
|
||||||
into an own session, though.
|
into an own session, though.
|
||||||
|
|
||||||
DVD+R DL appear as extra large DVD+R. cdrskin does not allow to set the address
|
DVD+R DL appear as extra large DVD+R. cdrskin does not allow to set the address
|
||||||
of the layer break where a reading drive might show some delay while switching
|
of the layer break where a reading drive might show some delay while switching
|
||||||
between both media layers.
|
between both media layers.
|
||||||
|
|
||||||
BD-R are sold unformatted blank. If used without initial formatting then the
|
|
||||||
drive is supposed to format them to maximum payload size with no Defect
|
|
||||||
Management (see also above with BD-RE).
|
|
||||||
If Defect Management is desired then BD-R need to be formatted before the
|
|
||||||
first attempt to write a session to them.
|
|
||||||
blank=format_if_needed will detect the situation and eventually apply
|
|
||||||
default sized Defect Management formatting.
|
|
||||||
blank=format_defectmgt_* will apply non-default parameters to formatting.
|
|
||||||
|
|
||||||
|
|
||||||
Emulated Drives
|
Emulated Drives
|
||||||
|
|
||||||
@ -403,26 +377,6 @@ drive. See man page section FILES for a way to lift that ban.
|
|||||||
|
|
||||||
Special compilation variations
|
Special compilation variations
|
||||||
|
|
||||||
All following options of ./configure and cdrskin/compile_cdrskin.sh are
|
|
||||||
combinable. After runs of ./configure do as next:
|
|
||||||
make clean ; make
|
|
||||||
|
|
||||||
In some situations Linux may deliver a better write performance to drives if
|
|
||||||
the track input is read with O_DIRECT (see man 2 open). The API call
|
|
||||||
burn_os_open_track_src() and the input readers of cdrskin and libburn fifo
|
|
||||||
can be told to use this peculiar read mode by:
|
|
||||||
--enable-track-src-odirect
|
|
||||||
|
|
||||||
But often cdrskin option dvd_obs=64k will yield even better performance in
|
|
||||||
such a situation. 64k can be made default at compile time by
|
|
||||||
cdrskin/compile_cdrskin.sh -dvd_obs_64k
|
|
||||||
It can also be enabled at configure time by
|
|
||||||
./configure ... --enable-dvd-obs-64k ...
|
|
||||||
|
|
||||||
Alternatively the transport of SCSI commands can be done via libcdio-0.83.
|
|
||||||
You may install it and re-run libburn's ./configure with option
|
|
||||||
--enable-libcdio
|
|
||||||
|
|
||||||
You may get a (super fat) statically linked binary by :
|
You may get a (super fat) statically linked binary by :
|
||||||
cdrskin/compile_cdrskin.sh -static
|
cdrskin/compile_cdrskin.sh -static
|
||||||
if your system supports static linking, at all. This will not help with kernels
|
if your system supports static linking, at all. This will not help with kernels
|
||||||
@ -438,84 +392,6 @@ 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
|
||||||
@ -532,7 +408,7 @@ are the cause. Any mistake of the burn program is supposed to be caught
|
|||||||
by the drive's firmware and to lead to mere misburns.
|
by the drive's firmware and to lead to mere misburns.
|
||||||
The worst mishaps which hit the author imposed the need to reboot the
|
The worst mishaps which hit the author imposed the need to reboot the
|
||||||
system because of drives gnawing endlessly on ill media. Permanent hardware
|
system because of drives gnawing endlessly on ill media. Permanent hardware
|
||||||
damage did not occur in 3.5 years of development. But one never knows ...
|
damage did not occur in 2.5 years of development. But one never knows ...
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
@ -544,7 +420,7 @@ contributions in a due way.
|
|||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License version 2 or later
|
it under the terms of the GNU General Public License version 2
|
||||||
as published by the Free Software Foundation.
|
as published by the Free Software Foundation.
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
This program is distributed in the hope that it will be useful,
|
||||||
@ -560,7 +436,7 @@ contributions in a due way.
|
|||||||
Based on and sub project of:
|
Based on and sub project of:
|
||||||
libburnia-project.org
|
libburnia-project.org
|
||||||
By Mario Danic <mario.danic@gmail.com> and Thomas Schmitt <scdbackup@gmx.net>
|
By Mario Danic <mario.danic@gmail.com> and Thomas Schmitt <scdbackup@gmx.net>
|
||||||
Copyright (C) 2006-2010 Mario Danic, Thomas Schmitt
|
Copyright (C) 2006-2008 Mario Danic, Thomas Schmitt
|
||||||
|
|
||||||
libburnia-project.org is inspired by and in other components still containing
|
libburnia-project.org is inspired by and in other components still containing
|
||||||
parts of
|
parts of
|
||||||
@ -571,3 +447,34 @@ See toplevel README for an overview of the current copyright situation in
|
|||||||
libburnia-project.org.
|
libburnia-project.org.
|
||||||
|
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
cdrskin is currently copyright Thomas Schmitt only.
|
||||||
|
It adopts the following commitment by the toplevel copyright holders:
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
We, the copyright holders, agree on the interpretation that
|
||||||
|
dynamical linking of our libraries constitutes "use of" and
|
||||||
|
not "derivation from" our work in the sense of GPL, provided
|
||||||
|
those libraries are compiled from our unaltered code.
|
||||||
|
|
||||||
|
Thus you may link our libraries dynamically with applications
|
||||||
|
which are not under GPL. You may distribute our libraries and
|
||||||
|
application tools in binary form, if you fulfill the usual
|
||||||
|
condition of GPL to offer a copy of the source code -altered
|
||||||
|
or unaltered- under GPL.
|
||||||
|
|
||||||
|
We ask you politely to use our work in open source spirit
|
||||||
|
and with the due reference to the entire open source community.
|
||||||
|
|
||||||
|
If there should really arise the case where above clarification
|
||||||
|
does not suffice to fulfill a clear and neat request in open source
|
||||||
|
spirit that would otherwise be declined for mere formal reasons,
|
||||||
|
only in that case we will duely consider to issue a special license
|
||||||
|
covering only that special case.
|
||||||
|
It is the open source idea of responsible freedom which will be
|
||||||
|
decisive and you will have to prove that you exhausted all own
|
||||||
|
means to qualify for GPL.
|
||||||
|
|
||||||
|
For now we are firmly committed to maintain one single license: GPL.
|
||||||
|
|
||||||
|
signed for cdrskin: Thomas Schmitt
|
||||||
|
@ -38,7 +38,7 @@ original="./libburn_svn_release.tgz"
|
|||||||
# My changes are in $changes , mainly in $changes/cdrskin
|
# My changes are in $changes , mainly in $changes/cdrskin
|
||||||
changes="./libburn-release"
|
changes="./libburn-release"
|
||||||
|
|
||||||
skin_release="1.0.0"
|
skin_release="0.5.8"
|
||||||
patch_level=".pl00"
|
patch_level=".pl00"
|
||||||
skin_rev="$skin_release""$patch_level"
|
skin_rev="$skin_release""$patch_level"
|
||||||
|
|
||||||
@ -117,7 +117,6 @@ cp -a "$cdrskin_dir" "$cdrskin_target"
|
|||||||
|
|
||||||
# Remove copied vim.swp and binaries
|
# Remove copied vim.swp and binaries
|
||||||
rm "$cdrskin_target"/.*.swp
|
rm "$cdrskin_target"/.*.swp
|
||||||
rm "$cdrskin_target"/.*.swo
|
|
||||||
rm "$cdrskin_target"/*.o
|
rm "$cdrskin_target"/*.o
|
||||||
rm "$cdrskin_target"/cdrfifo
|
rm "$cdrskin_target"/cdrfifo
|
||||||
rm "$cdrskin_target"/cdrskin
|
rm "$cdrskin_target"/cdrskin
|
@ -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="1.0.1"
|
skin_release="0.5.9"
|
||||||
patch_level=""
|
patch_level=""
|
||||||
skin_rev="$skin_release""$patch_level"
|
skin_rev="$skin_release""$patch_level"
|
||||||
|
|
||||||
@ -116,7 +116,6 @@ cp -a "$cdrskin_dir" "$cdrskin_target"
|
|||||||
|
|
||||||
# Remove copied vim.swp and binaries
|
# Remove copied vim.swp and binaries
|
||||||
rm "$cdrskin_target"/.*.swp
|
rm "$cdrskin_target"/.*.swp
|
||||||
rm "$cdrskin_target"/.*.swo
|
|
||||||
rm "$cdrskin_target"/*.o
|
rm "$cdrskin_target"/*.o
|
||||||
rm "$cdrskin_target"/cdrfifo
|
rm "$cdrskin_target"/cdrfifo
|
||||||
rm "$cdrskin_target"/cdrskin
|
rm "$cdrskin_target"/cdrskin
|
@ -25,16 +25,11 @@
|
|||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#include <sys/select.h>
|
#include <sys/select.h>
|
||||||
|
|
||||||
#ifndef Cdrfifo_standalonE
|
|
||||||
/* <<< until release of 0.7.4 : for Libburn_has_open_trac_srC */
|
|
||||||
#include "../libburn/libburn.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "cdrfifo.h"
|
#include "cdrfifo.h"
|
||||||
|
|
||||||
|
|
||||||
/* 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 *) calloc(anz, sizeof(typ));
|
#define TSOB_FELD(typ,anz) (typ *) malloc((anz)*sizeof(typ));
|
||||||
|
|
||||||
|
|
||||||
#define Cdrfifo_buffer_chunK 2048
|
#define Cdrfifo_buffer_chunK 2048
|
||||||
@ -125,7 +120,7 @@ struct CdrfifO {
|
|||||||
struct burn_source object.
|
struct burn_source object.
|
||||||
@param chunk_size Size of buffer block for a single transaction (0=default)
|
@param chunk_size Size of buffer block for a single transaction (0=default)
|
||||||
@param buffer_size Size of fifo buffer
|
@param buffer_size Size of fifo buffer
|
||||||
@param flag bit0= Debugging verbosity
|
@param flag Unused yet
|
||||||
@return 1 on success, <=0 on failure
|
@return 1 on success, <=0 on failure
|
||||||
*/
|
*/
|
||||||
int Cdrfifo_new(struct CdrfifO **ff, int source_fd, int dest_fd,
|
int Cdrfifo_new(struct CdrfifO **ff, int source_fd, int dest_fd,
|
||||||
@ -179,13 +174,7 @@ int Cdrfifo_new(struct CdrfifO **ff, int source_fd, int dest_fd,
|
|||||||
o->follow_up_fd_idx= -1;
|
o->follow_up_fd_idx= -1;
|
||||||
o->next= o->prev= NULL;
|
o->next= o->prev= NULL;
|
||||||
o->chain_idx= 0;
|
o->chain_idx= 0;
|
||||||
|
|
||||||
#ifdef Libburn_has_open_trac_srC
|
|
||||||
o->buffer= burn_os_alloc_buffer((size_t) buffer_size, 0);
|
|
||||||
#else
|
|
||||||
o->buffer= TSOB_FELD(char,buffer_size);
|
o->buffer= TSOB_FELD(char,buffer_size);
|
||||||
#endif /* ! Libburn_has_open_trac_srC */
|
|
||||||
|
|
||||||
if(o->buffer==NULL)
|
if(o->buffer==NULL)
|
||||||
goto failed;
|
goto failed;
|
||||||
return(1);
|
return(1);
|
||||||
@ -203,11 +192,10 @@ int Cdrfifo_close(struct CdrfifO *o, int flag)
|
|||||||
if(o->dest_fd!=-1)
|
if(o->dest_fd!=-1)
|
||||||
close(o->dest_fd);
|
close(o->dest_fd);
|
||||||
o->dest_fd= -1;
|
o->dest_fd= -1;
|
||||||
for(i=0; i<o->follow_up_fd_counter; i++) {
|
for(i=0; i<o->follow_up_fd_counter; i++)
|
||||||
if(o->follow_up_fds[i][1]!=-1)
|
if(o->follow_up_fds[i][1]!=-1)
|
||||||
close(o->follow_up_fds[i][1]);
|
close(o->follow_up_fds[i][1]);
|
||||||
o->follow_up_fds[i][1]= -1;
|
o->follow_up_fds[i][1]= -1;
|
||||||
}
|
|
||||||
return(1);
|
return(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -238,14 +226,8 @@ int Cdrfifo_destroy(struct CdrfifO **ff, int flag)
|
|||||||
|
|
||||||
if(o->iso_fs_descr!=NULL)
|
if(o->iso_fs_descr!=NULL)
|
||||||
free((char *) o->iso_fs_descr);
|
free((char *) o->iso_fs_descr);
|
||||||
|
|
||||||
if(o->buffer!=NULL)
|
if(o->buffer!=NULL)
|
||||||
#ifdef Libburn_has_open_trac_srC
|
|
||||||
burn_os_free_buffer(o->buffer, o->buffer_size, 0);
|
|
||||||
#else
|
|
||||||
free((char *) o->buffer);
|
free((char *) o->buffer);
|
||||||
#endif /* Libburn_has_open_trac_srC */
|
|
||||||
|
|
||||||
free((char *) o);
|
free((char *) o);
|
||||||
(*ff)= NULL;
|
(*ff)= NULL;
|
||||||
return(1);
|
return(1);
|
||||||
@ -634,7 +616,7 @@ return: <0 = error , 0 = idle , 1 = did some work
|
|||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
double buffer_space;
|
double buffer_space;
|
||||||
int can_read,can_write= 0,ret,did_work= 0,idx,sod,eop_is_near,eop_idx;
|
int can_read,can_write,ret,did_work= 0,idx,sod,eop_is_near,eop_idx;
|
||||||
|
|
||||||
buffer_space= Cdrfifo_tell_buffer_space(o,0);
|
buffer_space= Cdrfifo_tell_buffer_space(o,0);
|
||||||
if(o->dest_fd>=0) if(FD_ISSET((o->dest_fd),wts)) {
|
if(o->dest_fd>=0) if(FD_ISSET((o->dest_fd),wts)) {
|
||||||
@ -677,46 +659,6 @@ return: <0 = error , 0 = idle , 1 = did some work
|
|||||||
after_write:;
|
after_write:;
|
||||||
if(o->source_fd>=0) if(FD_ISSET((o->source_fd),rds)) {
|
if(o->source_fd>=0) if(FD_ISSET((o->source_fd),rds)) {
|
||||||
can_read= o->buffer_size - o->write_idx;
|
can_read= o->buffer_size - o->write_idx;
|
||||||
|
|
||||||
#ifdef Libburn_has_open_trac_srC
|
|
||||||
|
|
||||||
/* ts A91115
|
|
||||||
This chunksize must be aligned to filesystem blocksize.
|
|
||||||
*/
|
|
||||||
#define Cdrfifo_o_direct_chunK 32768
|
|
||||||
|
|
||||||
if(o->write_idx < o->read_idx && o->write_idx + can_read > o->read_idx)
|
|
||||||
can_read= o->read_idx - o->write_idx;
|
|
||||||
if(o->fd_in_limit>=0.0)
|
|
||||||
if(can_read > o->fd_in_limit - o->fd_in_counter)
|
|
||||||
can_read= o->fd_in_limit - o->fd_in_counter;
|
|
||||||
/* Make sure to read with properly aligned size */
|
|
||||||
if(can_read > Cdrfifo_o_direct_chunK)
|
|
||||||
can_read= Cdrfifo_o_direct_chunK;
|
|
||||||
else if(can_read < Cdrfifo_o_direct_chunK)
|
|
||||||
can_read= -1;
|
|
||||||
ret= 0;
|
|
||||||
if(can_read>0)
|
|
||||||
ret= read(o->source_fd,o->buffer+o->write_idx,can_read);
|
|
||||||
if(can_read < 0) {
|
|
||||||
/* waiting for a full Cdrfifo_o_direct_chunK to fit */
|
|
||||||
if(can_write <= 0 && o->dest_fd >= 0) {
|
|
||||||
fd_set rds,wts,exs;
|
|
||||||
struct timeval wt;
|
|
||||||
|
|
||||||
FD_ZERO(&rds);
|
|
||||||
FD_ZERO(&wts);
|
|
||||||
FD_ZERO(&exs);
|
|
||||||
FD_SET((o->dest_fd),&wts);
|
|
||||||
wt.tv_sec= 0;
|
|
||||||
wt.tv_usec= 10000;
|
|
||||||
select(o->dest_fd + 1,&rds, &wts, &exs, &wt);
|
|
||||||
|
|
||||||
}
|
|
||||||
} else
|
|
||||||
|
|
||||||
#else /* Libburn_has_open_trac_srC */
|
|
||||||
|
|
||||||
if(can_read>o->chunk_size)
|
if(can_read>o->chunk_size)
|
||||||
can_read= o->chunk_size;
|
can_read= o->chunk_size;
|
||||||
if(o->write_idx<o->read_idx && o->write_idx+can_read > o->read_idx)
|
if(o->write_idx<o->read_idx && o->write_idx+can_read > o->read_idx)
|
||||||
@ -727,9 +669,6 @@ after_write:;
|
|||||||
ret= 0;
|
ret= 0;
|
||||||
if(can_read>0)
|
if(can_read>0)
|
||||||
ret= read(o->source_fd,o->buffer+o->write_idx,can_read);
|
ret= read(o->source_fd,o->buffer+o->write_idx,can_read);
|
||||||
|
|
||||||
#endif /* ! Libburn_has_open_trac_srC */
|
|
||||||
|
|
||||||
if(ret==-1) {
|
if(ret==-1) {
|
||||||
|
|
||||||
/* >>> handle input error */;
|
/* >>> handle input error */;
|
||||||
|
@ -33,7 +33,7 @@ struct CdrfifO;
|
|||||||
struct burn_source object.
|
struct burn_source object.
|
||||||
@param chunk_size Size of buffer block for a single transaction (0=default)
|
@param chunk_size Size of buffer block for a single transaction (0=default)
|
||||||
@param buffer_size Size of fifo buffer
|
@param buffer_size Size of fifo buffer
|
||||||
@param flag bit0= Debugging verbosity
|
@param flag unused yet
|
||||||
@return 1 on success, <=0 on failure
|
@return 1 on success, <=0 on failure
|
||||||
*/
|
*/
|
||||||
int Cdrfifo_new(struct CdrfifO **ff, int source_fd, int dest_fd,
|
int Cdrfifo_new(struct CdrfifO **ff, int source_fd, int dest_fd,
|
||||||
|
@ -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 "Jan 09, 2011"
|
.TH CDRSKIN 1 "Oct 15, 2008"
|
||||||
.\" Please adjust this date whenever revising the manpage.
|
.\" Please adjust this date whenever revising the manpage.
|
||||||
.\"
|
.\"
|
||||||
.\" Some roff macros, for reference:
|
.\" Some roff macros, for reference:
|
||||||
@ -16,7 +16,7 @@
|
|||||||
.\" .sp <n> insert n+1 empty lines
|
.\" .sp <n> insert n+1 empty lines
|
||||||
.\" for manpage-specific macros, see man(7)
|
.\" for manpage-specific macros, see man(7)
|
||||||
.SH NAME
|
.SH NAME
|
||||||
cdrskin \- burns preformatted data to CD, DVD, and BD via libburn.
|
cdrskin \- burns preformatted data to CD, DVD, and BD-RE via libburn.
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
.B cdrskin
|
.B cdrskin
|
||||||
.RI [ options | track_source_addresses ]
|
.RI [ options | track_source_addresses ]
|
||||||
@ -28,14 +28,14 @@ cdrskin \- burns preformatted data to CD, DVD, and BD via libburn.
|
|||||||
.\" respectively.
|
.\" respectively.
|
||||||
.PP
|
.PP
|
||||||
\fBcdrskin\fP is a program that provides some of cdrecord's options
|
\fBcdrskin\fP is a program that provides some of cdrecord's options
|
||||||
in a compatible way for CD media. With DVD and BD it has its own ways.
|
in a compatible way for CD media. With DVD and BD-RE it has its own ways.
|
||||||
You do not need to be superuser for its daily usage.
|
You do not need to be superuser for its daily usage.
|
||||||
.SS
|
.SS
|
||||||
.B Overview of features:
|
.B Overview of features:
|
||||||
.br
|
.br
|
||||||
Blanking of CD-RW and DVD-RW.
|
Blanking of CD-RW and DVD-RW.
|
||||||
.br
|
.br
|
||||||
Formatting of DVD-RW, DVD+RW, DVD-RAM, BD.
|
Formatting of DVD-RW, DVD+RW, DVD-RAM, BD-RE.
|
||||||
.br
|
.br
|
||||||
Burning of data or audio tracks to CD,
|
Burning of data or audio tracks to CD,
|
||||||
.br
|
.br
|
||||||
@ -45,9 +45,9 @@ or in Session at Once mode for seamless tracks.
|
|||||||
.br
|
.br
|
||||||
Multi session on CD (follow-up sessions in TAO only)
|
Multi session on CD (follow-up sessions in TAO only)
|
||||||
.br
|
.br
|
||||||
or on DVD-R[W] (in Incremental mode) or DVD+R[/DL] or BD-R.
|
or on DVD-R[W] (in Incremental mode) or on DVD+R[/DL].
|
||||||
.br
|
.br
|
||||||
Single session Disk-at-once on DVD-RW, DVD-R, DVD-R DL.
|
Single session on DVD-RW or DVD-R (Disk-at-once).
|
||||||
.br
|
.br
|
||||||
Single session or emulated ISO-9660 multi-session
|
Single session or emulated ISO-9660 multi-session
|
||||||
.br
|
.br
|
||||||
@ -67,7 +67,7 @@ Write mode selection
|
|||||||
.br
|
.br
|
||||||
Recordable CD Media
|
Recordable CD Media
|
||||||
.br
|
.br
|
||||||
Sequentially Recordable DVD or BD Media
|
Sequentially Recordable DVD Media
|
||||||
.br
|
.br
|
||||||
Overwriteable DVD or BD Media
|
Overwriteable DVD or BD Media
|
||||||
.br
|
.br
|
||||||
@ -82,7 +82,7 @@ A \fBtrack\fP stores a stream of bytes.
|
|||||||
.br
|
.br
|
||||||
Each track is initiated by one track source address argument, which may either
|
Each track is initiated by one track source address argument, which may either
|
||||||
be "-" for standard input or the address of a readable file. If no write mode
|
be "-" for standard input or the address of a readable file. If no write mode
|
||||||
is given explicitly then one will be chosen which matches the peculiarities
|
is given explicitely then one will be chosen which matches the peculiarities
|
||||||
of track sources and the state of the output media.
|
of track sources and the state of the output media.
|
||||||
.PP
|
.PP
|
||||||
More than one track can be burned by a single run of cdrskin.
|
More than one track can be burned by a single run of cdrskin.
|
||||||
@ -93,13 +93,13 @@ Some media types can be kept appendable so that further tracks can
|
|||||||
be written to them in subsequent runs of cdrskin (see option -multi).
|
be written to them in subsequent runs of cdrskin (see option -multi).
|
||||||
Info about the addresses of burned tracks is kept in a table of
|
Info about the addresses of burned tracks is kept in a table of
|
||||||
content (TOC) on media and can be retrieved via cdrskin option -toc.
|
content (TOC) on media and can be retrieved via cdrskin option -toc.
|
||||||
This information is also used by the operating systems' CD-ROM read drivers.
|
These informations are also used by the operating systems' CD-ROM read drivers.
|
||||||
.PP
|
.PP
|
||||||
In general there are two types of tracks: data and audio. They differ in
|
In general there are two types of tracks: data and audio. They differ in
|
||||||
sector size, throughput and readability via the systems' CD-ROM drivers
|
sector size, throughput and readability via the systems' CD-ROM drivers
|
||||||
resp. by music CD players. With DVD and BD there is only type data.
|
resp. by music CD players. With DVD and BD there is only type data.
|
||||||
.br
|
.br
|
||||||
If not explicitly option -audio is given, then any track is burned as type
|
If not explicitely option -audio is given, then any track is burned as type
|
||||||
data, unless the track source is a file with suffix ".wav" or ".au" and has a
|
data, unless the track source is a file with suffix ".wav" or ".au" and has a
|
||||||
header part which identifies it as MS-WAVE resp. SUN Audio with suitable
|
header part which identifies it as MS-WAVE resp. SUN Audio with suitable
|
||||||
parameters. Such files are burned as audio tracks by default.
|
parameters. Such files are burned as audio tracks by default.
|
||||||
@ -138,7 +138,7 @@ try to choose a write mode which matches the defined recording job,
|
|||||||
the capabilities of the drive and the state of the present media.
|
the capabilities of the drive and the state of the present media.
|
||||||
.br
|
.br
|
||||||
So the mentioning of write modes in the following paragraphs and in the
|
So the mentioning of write modes in the following paragraphs and in the
|
||||||
examples is not so much a demand that the user shall choose one explicitly,
|
examples is not so much a demand that the user shall choose one explicitely,
|
||||||
but rather an illustration of what to expect with particular media types.
|
but rather an illustration of what to expect with particular media types.
|
||||||
.SS
|
.SS
|
||||||
.B Recordable CD Media:
|
.B Recordable CD Media:
|
||||||
@ -164,13 +164,12 @@ make it completely unreadable. It is no effective privacy precaution.
|
|||||||
Multiple cycles of blanking and overwriting with random numbers might be
|
Multiple cycles of blanking and overwriting with random numbers might be
|
||||||
needed.
|
needed.
|
||||||
.SS
|
.SS
|
||||||
.B Sequentially Recordable DVD or BD Media:
|
.B Sequentially Recordable DVD Media:
|
||||||
.br
|
.br
|
||||||
Currently DVD-RW, DVD-R[DL], DVD+R[DL], and BD-R can be used for the Sequential
|
Currently DVD-RW, DVD-R and DVD+R[/DL] can be used for the Sequential recording
|
||||||
recording model. It resembles the model of CD media. Only DVD-RW can be
|
model.
|
||||||
blanked and re-used from scratch.
|
|
||||||
.br
|
.br
|
||||||
DVD-RW are sequential media if they are in state "Sequential Recording".
|
This applies to DVD-RW only if they are in state "Sequential Recording".
|
||||||
The media must be either blank or appendable.
|
The media must be either blank or appendable.
|
||||||
Newly purchased DVD-RW and DVD-R media are in this state.
|
Newly purchased DVD-RW and DVD-R media are in this state.
|
||||||
Used DVD-RW get into blank sequential state by option
|
Used DVD-RW get into blank sequential state by option
|
||||||
@ -181,39 +180,35 @@ With DVD-R[W] two write modes may be available:
|
|||||||
Mode DAO has many restrictions. It does not work with
|
Mode DAO has many restrictions. It does not work with
|
||||||
appendable media, allows no -multi and only a single track. The size of the
|
appendable media, allows no -multi and only a single track. The size of the
|
||||||
track needs to be known in advance. So either its source has to be a disk file
|
track needs to be known in advance. So either its source has to be a disk file
|
||||||
of recognizable size or the size has to be announced explicitly by options
|
of recognizable size or the size has to be announced explicitely by options
|
||||||
.B tsize=
|
.B tsize=
|
||||||
or
|
or
|
||||||
.B tao_to_sao_tsize= .
|
.B tao_to_sao_tsize= .
|
||||||
.br
|
.br
|
||||||
DAO is the only mode for DVD-R media which do not offer feature 21h Incremental
|
DAO is the only mode for media which do not offer feature 21h Incremental
|
||||||
Streaming (e.g. DVD-R DL). DAO may also be selected explicitly by option
|
Streaming. DAO may also be selected explicitely by option
|
||||||
.B -sao .
|
.B -sao .
|
||||||
Program growisofs uses DAO on sequential DVD-R[W] media for maximum
|
Program growisofs uses DAO on sequential DVD-R[W] media for maximum
|
||||||
DVD-ROM/-Video compatibility.
|
DVD-ROM/-Video compatibility.
|
||||||
.br
|
.br
|
||||||
The other mode, Incremental Streaming, is the default write mode if
|
The other mode, Incremental Streaming, is the default write mode if
|
||||||
it is available and if the restrictions of DAO would prevent the job.
|
it is available and if the restrictions of DAO would prevent the job.
|
||||||
Incremental Streaming may be selected explicitly by option
|
Incremental Streaming may be selected explicitely 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 . It does not work with DVD-R DL and minimally blanked DVD-RW.
|
.B -multi .
|
||||||
The only restriction towards CD-R[W] is the lack of support for -audio tracks.
|
The only restriction towards CD-R[W] is the lack of support for -audio tracks.
|
||||||
Multiple tracks per session are permissible.
|
Multiple tracks per session are permissible.
|
||||||
.br
|
.br
|
||||||
The write modes for DVD+R[/DL] and BD-R resemble those with DVD-R except that
|
The write modes for DVD+R[/DL] resemble those with DVD-R except that with +R
|
||||||
each track gets wrapped in an own session. There is no -dummy writing
|
each track gets wrapped in an own session. There is no -dummy writing with
|
||||||
with DVD+R[/DL] or BD-R.
|
DVD+R[/DL].
|
||||||
.br
|
.br
|
||||||
Quite deliberately write mode -sao insists in the tradition of a predicted
|
Quite deliberately write mode -sao insists in the tradition of a predicted
|
||||||
track size and blank media, whereas -tao writes the tracks open ended and
|
track size and blank media, whereas -tao writes the tracks open ended and
|
||||||
allows appendable media.
|
allows appendable media.
|
||||||
.br
|
.br
|
||||||
BD-R may be formatted before first use to enable the Defect Management which
|
|
||||||
might catch and repair some bad spots at the expense of slow speed
|
|
||||||
even with flawless media.
|
|
||||||
.br
|
|
||||||
.B Note:
|
.B Note:
|
||||||
Option -multi might make DVD media unreadable in some DVD-ROM drives.
|
Option -multi might make DVD media unreadable in some DVD-ROM drives.
|
||||||
Best reader compatibility is achieved without it
|
Best reader compatibility is achieved without it
|
||||||
@ -225,7 +220,7 @@ Currently types DVD+RW, DVD-RW, DVD-RAM and BD-RE can be overwritten via
|
|||||||
cdrskin.
|
cdrskin.
|
||||||
.br
|
.br
|
||||||
Option -audio is not allowed. Only one track is allowed.
|
Option -audio is not allowed. Only one track is allowed.
|
||||||
Option -multi cannot mark a recognizable end of overwriteable media.
|
Option -multi cannot mark a recognizeable end of overwriteable media.
|
||||||
Therefore -multi is banned unless ISO-9660 images shall be expandable by help
|
Therefore -multi is banned unless ISO-9660 images shall be expandable by help
|
||||||
of option
|
of option
|
||||||
.B --grow_overwriteable_iso .
|
.B --grow_overwriteable_iso .
|
||||||
@ -254,7 +249,7 @@ that it has to be formatted again. If in doubt, just give it a try.
|
|||||||
.SS
|
.SS
|
||||||
.B Drive preparation and addressing:
|
.B Drive preparation and addressing:
|
||||||
.br
|
.br
|
||||||
The drives, CD, DVD, or BD burners, are accessed via addresses which
|
The drives, either CD burners or DVD burners, are accessed via addresses which
|
||||||
are specific to libburn and the operating system. Those addresses get listed
|
are specific to libburn and the operating system. Those addresses get listed
|
||||||
by a run of \fBcdrskin --devices\fP.
|
by a run of \fBcdrskin --devices\fP.
|
||||||
.br
|
.br
|
||||||
@ -271,22 +266,19 @@ 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 consist of three numbers:
|
traditional cdrecord SCSI addresses which on Linux consist of three
|
||||||
Bus,Target,Lun. On Linux there is also a related address family "ATA" which
|
numbers: Bus,Target,Lun. 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: links to libburn-suitable device files,
|
Further are accepted on Linux: 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
|
||||||
@ -353,7 +345,7 @@ print "Mounted Media:" and media type text.
|
|||||||
Announces that the subsequent tracks are to be burned as audio.
|
Announces that the subsequent tracks are to be burned as audio.
|
||||||
The source is supposed to be uncompressed headerless PCM, 44100 Hz, 16 bit,
|
The source is supposed to be uncompressed headerless PCM, 44100 Hz, 16 bit,
|
||||||
stereo. For little-endian byte order (which is usual on PCs) use option
|
stereo. For little-endian byte order (which is usual on PCs) use option
|
||||||
-swab. Unless marked explicitly by option -data, input files with suffix
|
-swab. Unless marked explicitely by option -data, input files with suffix
|
||||||
".wav" are examined wether they have a header in MS-WAVE format confirming
|
".wav" are examined wether they have a header in MS-WAVE format confirming
|
||||||
those parameters and eventually raw audio data get extracted and burned as
|
those parameters and eventually raw audio data get extracted and burned as
|
||||||
audio track. Same is done for suffix ".au" and SUN Audio.
|
audio track. Same is done for suffix ".au" and SUN Audio.
|
||||||
@ -361,7 +353,7 @@ audio track. Same is done for suffix ".au" and SUN Audio.
|
|||||||
Option -audio may be used only with CD media and not with DVD or BD.
|
Option -audio may be used only with CD media and not with DVD or BD.
|
||||||
.TP
|
.TP
|
||||||
.BI blank= type
|
.BI blank= type
|
||||||
Blank a CD-RW, DVD-RW, or format a DVD-RW, DVD+RW, DVD-RAM, BD.
|
Blank a CD-RW, DVD-RW, or format a DVD-RW, DVD+RW, DVD-RAM, BD-RE.
|
||||||
This is combinable with burning in the same run of cdrskin.
|
This is combinable with burning in the same run of cdrskin.
|
||||||
The type given with blank= selects the particular behavior:
|
The type given with blank= selects the particular behavior:
|
||||||
.RS
|
.RS
|
||||||
@ -373,7 +365,7 @@ It is a reason to abort if the media cannot assume thoroughly writeable state,
|
|||||||
e.g. if it is non-blank write-once.
|
e.g. if it is non-blank write-once.
|
||||||
.br
|
.br
|
||||||
This leaves unformatted DVD-RW in unformatted blank state. To format DVD-RW use
|
This leaves unformatted DVD-RW in unformatted blank state. To format DVD-RW use
|
||||||
blank=format_overwriteable. Blank unformatted BD-R stay unformatted.
|
blank=format_overwriteable.
|
||||||
.br
|
.br
|
||||||
(Note: blank=as_needed is not an original cdrecord option.)
|
(Note: blank=as_needed is not an original cdrecord option.)
|
||||||
.TP
|
.TP
|
||||||
@ -402,11 +394,10 @@ This is faster than full blanking but may yield media incapable of
|
|||||||
Incremental Streaming (-tao).
|
Incremental Streaming (-tao).
|
||||||
.TP
|
.TP
|
||||||
format_if_needed
|
format_if_needed
|
||||||
Format a media if it is not formatted yet,
|
Format a media if it is not overwriteably formatted yet,
|
||||||
and if cdrskin supports formatting for the media type,
|
and if cdrskin supports formatting for the media type,
|
||||||
and if formatting will not happen automatically during write.
|
and if formatting will not happen automatically during write.
|
||||||
This currently applies to unformatted DVD-RW, DVD-RAM, BD-RE,
|
This currently applies to unformatted DVD-RW, DVD-RAM and BD-RE.
|
||||||
and blank unformatted BD-R.
|
|
||||||
Eventually the appropriate default formatting is chosen.
|
Eventually the appropriate default formatting is chosen.
|
||||||
If other media or states are encountered then nothing happens.
|
If other media or states are encountered then nothing happens.
|
||||||
.br
|
.br
|
||||||
@ -436,7 +427,7 @@ For DVD+RW this is the only supported explicit formatting type. It provides
|
|||||||
complete "de-icing" so no reader slips on unwritten data areas.
|
complete "de-icing" so no reader slips on unwritten data areas.
|
||||||
.TP
|
.TP
|
||||||
format_defectmgt
|
format_defectmgt
|
||||||
Format DVD-RAM or BD to reserve the default amount of spare blocks for
|
Format DVD-RAM or BD-RE to reserve the default amount of spare blocks for
|
||||||
defect management.
|
defect management.
|
||||||
.br
|
.br
|
||||||
The following format_defectmgt_* allow to submit user wishes which
|
The following format_defectmgt_* allow to submit user wishes which
|
||||||
@ -460,25 +451,25 @@ Whether there happens certification at all depends much on the media state
|
|||||||
and the actually selected format descriptor.
|
and the actually selected format descriptor.
|
||||||
.TP
|
.TP
|
||||||
format_defectmgt_max
|
format_defectmgt_max
|
||||||
Format DVD-RAM or BD to reserve a maximum number of spare blocks.
|
Format DVD-RAM or BD-RE to reserve a maximum number of spare blocks.
|
||||||
.TP
|
.TP
|
||||||
format_defectmgt_min
|
format_defectmgt_min
|
||||||
Format DVD-RAM or BD to reserve a minimum number of spare blocks.
|
Format DVD-RAM or BD-RE to reserve a minimum number of spare blocks.
|
||||||
It might be necessary to format format_defectmgt_none first in order to get
|
It might be necessary to format format_defectmgt_none first in order to get
|
||||||
offered the most minmal spare blocks sizes for format_defectmgt_min.
|
offered the most minmal spare blocks sizes for format_defectmgt_min.
|
||||||
.TP
|
.TP
|
||||||
format_defectmgt_none
|
format_defectmgt_none
|
||||||
Format DVD-RAM or BD-RE to the largest available payload in the hope to disable
|
Format DVD-RAM or BD-RE to the largest available payload in the hope to disable
|
||||||
defect management at all. This may or may not have a speed increasing effect.
|
defect management at all. This seems not to have a speed increasing effect,
|
||||||
Unformatted blank BD-R will be left unformatted.
|
though.
|
||||||
.TP
|
.TP
|
||||||
format_defectmgt_payload_<size>
|
format_defectmgt_payload_<size>
|
||||||
Format DVD-RAM or BD. The text after "format_defectmgt_payload_" gives a
|
Format DVD-RAM or BD-RE. The text after "format_defectmgt_payload_" gives a
|
||||||
number of bytes, eventually with suffixes "s", "k", "m". The largest number
|
number of bytes, eventually with suffixes "s", "k", "m". The largest number
|
||||||
of spare blocks will be chosen which allows at least the given payload size.
|
of spare blocks will be chosen which allows at least the given payload size.
|
||||||
.TP
|
.TP
|
||||||
format_by_index_<number>
|
format_by_index_<number>
|
||||||
Format DVD-RW, DVD+RW, DVD-RAM or BD.
|
Format DVD-RW, DVD+RW, DVD-RAM or BD-RE.
|
||||||
The number after "format_by_index_" is used as index to the list of available
|
The number after "format_by_index_" is used as index to the list of available
|
||||||
format descriptors. This list can be obtained by option --list_formats.
|
format descriptors. This list can be obtained by option --list_formats.
|
||||||
The numbers after text "Format idx" are the ones to be used with
|
The numbers after text "Format idx" are the ones to be used with
|
||||||
@ -500,15 +491,7 @@ or DVD-R[W] in Disc-at-once mode.
|
|||||||
.TP
|
.TP
|
||||||
.BI \-data
|
.BI \-data
|
||||||
Subsequent tracks are data tracks. This option is default and only needed
|
Subsequent tracks are data tracks. This option is default and only needed
|
||||||
to mark the end of the range of an eventual option -audio or -xa1.
|
to mark the end of the range of an eventual option -audio.
|
||||||
.br
|
|
||||||
Options -mode2, -xa, and -xa2 get mapped to -data, not using the desired CD
|
|
||||||
sector formats and thus not taking advantage of eventual higher payload.
|
|
||||||
.BI \-xa1
|
|
||||||
Subsequent tracks are data tracks with input suitable for CD-ROM XA mode 2
|
|
||||||
form 1. This differs from -data input by 8 additional header bytes per block.
|
|
||||||
cdrskin will not write CD-ROM XA but rather strip the header bytes and write as
|
|
||||||
-data tracks.
|
|
||||||
.TP
|
.TP
|
||||||
.BI dev= target
|
.BI dev= target
|
||||||
Set the address of the drive to use. Valid are at least the
|
Set the address of the drive to use. Valid are at least the
|
||||||
@ -530,7 +513,7 @@ of Bus,Target,Lun addresses.
|
|||||||
Set "driveropts=noburnfree" to disable the drive's eventual protection
|
Set "driveropts=noburnfree" to disable the drive's eventual protection
|
||||||
mechanism against temporary lack of source data (i.e. buffer underrun).
|
mechanism against temporary lack of source data (i.e. buffer underrun).
|
||||||
A drive that announces no such capabilities will not get them enabled anyway,
|
A drive that announces no such capabilities will not get them enabled anyway,
|
||||||
even if attempted explicitly via "driveropts=burnfree".
|
even if attempted explicitely via "driveropts=burnfree".
|
||||||
.TP
|
.TP
|
||||||
.BI \-dummy
|
.BI \-dummy
|
||||||
Try to perform the drive operations without actually affecting the inserted
|
Try to perform the drive operations without actually affecting the inserted
|
||||||
@ -554,9 +537,6 @@ which appear to be in the desired blank or format state already.
|
|||||||
This option enables a burn run with option -dummy even if libburn believes
|
This option enables a burn run with option -dummy even if libburn believes
|
||||||
that drive and media will not simulate the write mode but will write for real.
|
that drive and media will not simulate the write mode but will write for real.
|
||||||
.br
|
.br
|
||||||
It enables a burn run where cdrskin expects to exceed the available media
|
|
||||||
capacity.
|
|
||||||
.br
|
|
||||||
.B Caution:
|
.B Caution:
|
||||||
Use this only when in urgent need.
|
Use this only when in urgent need.
|
||||||
.TP
|
.TP
|
||||||
@ -603,7 +583,7 @@ will be used under the assumption that it is a single session filesystem.
|
|||||||
.br
|
.br
|
||||||
If not, then the burn run will be aborted.
|
If not, then the burn run will be aborted.
|
||||||
.br
|
.br
|
||||||
The range of -isosize is exactly one track. Further tracks may be preceded
|
The range of -isosize is exactly one track. Further tracks may be preceeded
|
||||||
by further -isosize options, though. At least 15 blocks of padding will be
|
by further -isosize options, though. At least 15 blocks of padding will be
|
||||||
added to each -isosize track. But be advised to rather use padsize=300k.
|
added to each -isosize track. But be advised to rather use padsize=300k.
|
||||||
.br
|
.br
|
||||||
@ -630,10 +610,6 @@ modesty_on_drive=1:min_percent=<percentage>:max_percent=95
|
|||||||
.br
|
.br
|
||||||
Percentage is permissible between 25 and 95.
|
Percentage is permissible between 25 and 95.
|
||||||
.TP
|
.TP
|
||||||
.BI -minfo
|
|
||||||
Print information about the loaded media. This includes media type, writability
|
|
||||||
state, and a quite readable table of content.
|
|
||||||
.TP
|
|
||||||
.BI msifile= path
|
.BI msifile= path
|
||||||
Run option -msinfo and copy the result line into the file given by path.
|
Run option -msinfo and copy the result line into the file given by path.
|
||||||
Unlike -msinfo this option does not redirect all normal output away from
|
Unlike -msinfo this option does not redirect all normal output away from
|
||||||
@ -656,14 +632,13 @@ To have a chance for working on overwriteable media, this option has to be
|
|||||||
accompanied by option --grow_overwriteable_iso.
|
accompanied by option --grow_overwriteable_iso.
|
||||||
.TP
|
.TP
|
||||||
.BI \-multi
|
.BI \-multi
|
||||||
This option keeps CD, unformatted DVD-R[W], DVD+R, or BD-R appendable
|
This option keeps the CD or unformatted DVD-R[W] appendable after the current
|
||||||
after the current session has been written.
|
session has been written.
|
||||||
Without it the disc gets closed and may not be written any more - unless it
|
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 and on DVD-R DL media.
|
with DVD-R[W] DAO write mode. Option --prodvd_cli_compatible eventually makes
|
||||||
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
|
||||||
@ -698,9 +673,16 @@ Add the given amount of trailing zeros to the next data track. This option
|
|||||||
gets reset to padsize=0 after that next track is written. It may be set
|
gets reset to padsize=0 after that next track is written. It may be set
|
||||||
again before the next track argument. About size specifiers, see option fs=.
|
again before the next track argument. About size specifiers, see option fs=.
|
||||||
.TP
|
.TP
|
||||||
|
.BI \-raw96r
|
||||||
|
Write CD in RAW/RAW96R mode. This mode allows to put more payload bytes
|
||||||
|
into a CD sector but obviously at the cost of error correction. It can only
|
||||||
|
be used for tracks of fixely predicted size. Some drives allow this mode but
|
||||||
|
then behave strange or even go bad for the next few attempts to burn a CD.
|
||||||
|
One should use it only if inavoidable.
|
||||||
|
.TP
|
||||||
.BI \-sao
|
.BI \-sao
|
||||||
Write CD in Session At Once mode or sequential DVD-R[W] in Disc-at-once
|
Write CD in Session At Once mode, a sequential DVD-R[W] in Disc-at-once
|
||||||
(DAO) mode.
|
(DAO) mode, or a DVD+R[/DL].
|
||||||
.br
|
.br
|
||||||
With CD this mode is able to put several audio tracks on media without
|
With CD this mode is able to put several audio tracks on media without
|
||||||
producing audible gaps between them.
|
producing audible gaps between them.
|
||||||
@ -708,11 +690,11 @@ producing audible gaps between them.
|
|||||||
With DVD-R[W] this mode can only write a single track.
|
With DVD-R[W] this mode can only write a single track.
|
||||||
No -multi is allowed with DVD-R[W] -sao.
|
No -multi is allowed with DVD-R[W] -sao.
|
||||||
.br
|
.br
|
||||||
-sao is permissible with overwriteable DVD, or DVD+R[/DL], or BD but actually
|
-sao is permissible with overwriteable DVD, BD or DVD+R[/DL] but actually
|
||||||
only imposes restrictions without providing known advantages.
|
only imposes restrictions without providing known advantages.
|
||||||
.br
|
.br
|
||||||
-sao can only be used for tracks of fixely predicted size. This implies that
|
-sao can only be used for tracks of fixely predicted size. This implies that
|
||||||
track arguments which depict stdin or named pipes need to be preceded by
|
track arguments which depict stdin or named pipes need to be preceeded by
|
||||||
option tsize= or by option tao_to_sao_tsize=.
|
option tsize= or by option tao_to_sao_tsize=.
|
||||||
.br
|
.br
|
||||||
-sao cannot be used on appendable media.
|
-sao cannot be used on appendable media.
|
||||||
@ -757,8 +739,6 @@ 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.
|
||||||
@ -805,11 +785,6 @@ Level 2 additionally reports about option settings derived from arguments or
|
|||||||
startup files. Level 3 is for debugging and useful mainly in conjunction with
|
startup files. Level 3 is for debugging and useful mainly in conjunction with
|
||||||
somebody who had a look into the program sourcecode.
|
somebody who had a look into the program sourcecode.
|
||||||
.TP
|
.TP
|
||||||
.BI \-V
|
|
||||||
Enable logging of SCSI commands to stderr. This allows expert examination
|
|
||||||
of the interaction between libburn and the drive. The commands are specified
|
|
||||||
in SCSI-3 standards SPC, SBC, MMC.
|
|
||||||
.TP
|
|
||||||
.BI \-waiti
|
.BI \-waiti
|
||||||
Wait until input data is available at stdin or EOF occurs at stdin.
|
Wait until input data is available at stdin or EOF occurs at stdin.
|
||||||
Only then begin to access any drives.
|
Only then begin to access any drives.
|
||||||
@ -831,7 +806,7 @@ Alphabetical list of options which are genuine to cdrskin and intended for
|
|||||||
normal use:
|
normal use:
|
||||||
.TP
|
.TP
|
||||||
.BI \--adjust_speed_to_drive
|
.BI \--adjust_speed_to_drive
|
||||||
Curb explicitly given speed= values to the maximum which is announced by the
|
Curb explicitely given speed= values to the maximum which is announced by the
|
||||||
drive for the loaded media. By default, such an adjustment is only made with
|
drive for the loaded media. By default, such an adjustment is only made with
|
||||||
pseudo-speeds 0 and -1 whereas speed settings > 0 are sent unchanged to the
|
pseudo-speeds 0 and -1 whereas speed settings > 0 are sent unchanged to the
|
||||||
drive which will then choose an appropriate speed on its own.
|
drive which will then choose an appropriate speed on its own.
|
||||||
@ -908,14 +883,6 @@ Both, write_start_address and direct_write_amount size must be aligned to a
|
|||||||
media dependend transaction size. With DVD-RAM, BD-RE, DVD+RW this is 2k, with
|
media dependend transaction size. With DVD-RAM, BD-RE, DVD+RW this is 2k, with
|
||||||
overwriteable DVD-RW it is 32k.
|
overwriteable DVD-RW it is 32k.
|
||||||
.TP
|
.TP
|
||||||
.BI dvd_obs= default|32k|64k
|
|
||||||
Linux specific:
|
|
||||||
Set the number of bytes to be transmitted with each write operation to DVD
|
|
||||||
or BD media. Tracks get padded up to the next multiple of this write
|
|
||||||
size. A number of 64 KB may improve throughput with bus systems which
|
|
||||||
show latency problems. The default depends on media type, option
|
|
||||||
stream_recording=, and on compile time options.
|
|
||||||
.TP
|
|
||||||
.BI fallback_program= command
|
.BI fallback_program= command
|
||||||
Set a command name to be executed if cdrskin encounters a known cdrecord
|
Set a command name to be executed if cdrskin encounters a known cdrecord
|
||||||
option which it does not yet support. If a non-empty command is given with
|
option which it does not yet support. If a non-empty command is given with
|
||||||
@ -925,7 +892,7 @@ to cdrskin, then cdrskin will delegate the job to said command.
|
|||||||
The natural commands to be given are cdrecord or wodim but one may well submit
|
The natural commands to be given are cdrecord or wodim but one may well submit
|
||||||
the address of an own program.
|
the address of an own program.
|
||||||
.br
|
.br
|
||||||
The fallback program will get all arguments of cdrskin which do not match
|
The fallback programm will get all arguments of cdrskin which do not match
|
||||||
the shell patterns --?* or *_*=* . This eventually suppresses path names of
|
the shell patterns --?* or *_*=* . This eventually suppresses path names of
|
||||||
track sources which happen to match those patterns. The options from the
|
track sources which happen to match those patterns. The options from the
|
||||||
startup files are not handed to the fallback program.
|
startup files are not handed to the fallback program.
|
||||||
@ -971,12 +938,12 @@ source is a ISO-9660 filesystem image.
|
|||||||
With overwriteable media and no option blank=fast|all present it expands an
|
With overwriteable media and no option blank=fast|all present it expands an
|
||||||
eventual ISO-9660 filesystem on media. It is assumed that this image's inner
|
eventual ISO-9660 filesystem on media. It is assumed that this image's inner
|
||||||
size description points to the end of the valuable data.
|
size description points to the end of the valuable data.
|
||||||
Overwriteable media with a recognizable ISO-9660 size will be regarded as
|
Overwriteable media with a recognizeable ISO-9660 size will be regarded as
|
||||||
appendable rather than as blank. I.e. options -msinfo and -toc will work.
|
appendable rather than as blank. I.e. options -msinfo and -toc will work.
|
||||||
-toc will always show a single session with its size increasing with
|
-toc will always show a single session with its size increasing with
|
||||||
every added mkisofs image.
|
every added mkisofs image.
|
||||||
.br
|
.br
|
||||||
If not overridden by option write_start_address=, the track with the new image
|
If not overriden by option write_start_address=, the track with the new image
|
||||||
will be placed behind the end of the old one. One may use option
|
will be placed behind the end of the old one. One may use option
|
||||||
assert_write_lba= to make sure that media state and mkisofs job do match.
|
assert_write_lba= to make sure that media state and mkisofs job do match.
|
||||||
.br
|
.br
|
||||||
@ -1008,10 +975,6 @@ List all ignored cdrecord options. The "-" options cannot be used as addresses
|
|||||||
of track sources. No track source address may begin with a text equal to an
|
of track sources. No track source address may begin with a text equal to an
|
||||||
option which ends by "=". The list is ended by an empty line.
|
option which ends by "=". The list is ended by an empty line.
|
||||||
.TP
|
.TP
|
||||||
.BI \--long_toc
|
|
||||||
Like option -toc but marking each session start by a line "first: X last: Y"
|
|
||||||
and each session end by "track:lout ...".
|
|
||||||
.TP
|
|
||||||
.BI \--no_rc
|
.BI \--no_rc
|
||||||
Only if used as first command line argument this option prevents reading and
|
Only if used as first command line argument this option prevents reading and
|
||||||
interpretation of eventual startup files. See section FILES below.
|
interpretation of eventual startup files. See section FILES below.
|
||||||
@ -1030,22 +993,6 @@ which can only do DAO but not Incremental Streaming.
|
|||||||
.BI \--single_track
|
.BI \--single_track
|
||||||
Accept only the last argument of the command line as track source address.
|
Accept only the last argument of the command line as track source address.
|
||||||
.TP
|
.TP
|
||||||
.BI stdio_sync= on|off|number
|
|
||||||
Set the number of bytes after which to force output to drives with prefix
|
|
||||||
"stdio:". This forcing keeps the memory from being clogged with lots of
|
|
||||||
pending data for slow devices. Default "on" is the same as "16m".
|
|
||||||
Forced output can be disabled by "off".
|
|
||||||
.TP
|
|
||||||
.BI stream_recording= on|off|number
|
|
||||||
By setting "on" request that compliance to the desired speed setting is
|
|
||||||
preferred over management of write errors. With DVD-RAM and BD this can
|
|
||||||
bring effective write speed near to the nominal write speed of the media.
|
|
||||||
But it will also disable the automatic use of replacement blocks
|
|
||||||
if write errors occur. It might as well be disliked or ignored by the drive.
|
|
||||||
.br
|
|
||||||
If a number is given, then error management stays enabled for all byte
|
|
||||||
addresses below that number. Any number below 16s is the same as "off".
|
|
||||||
.TP
|
|
||||||
.BI tao_to_sao_tsize= size
|
.BI tao_to_sao_tsize= size
|
||||||
Set an exact fixed size for the next track to be in effect only if the track
|
Set an exact fixed size for the next track to be in effect only if the track
|
||||||
source cannot deliver a size prediction and no tsize= was specified and an
|
source cannot deliver a size prediction and no tsize= was specified and an
|
||||||
@ -1071,7 +1018,7 @@ the available capacity. So for most realistic results one may set up
|
|||||||
the full burn session and add --tell_media_space. But if one has to expect
|
the full burn session and add --tell_media_space. But if one has to expect
|
||||||
a cdrskin version prior to 0.3.3 no track source should be given in order
|
a cdrskin version prior to 0.3.3 no track source should be given in order
|
||||||
not to start an involuntary burn session.
|
not to start an involuntary burn session.
|
||||||
In this case set at least -sao or -tao explicitly.
|
In this case set at least -sao or -tao explicitely.
|
||||||
.br
|
.br
|
||||||
The result gets printed to standard output. It is 0 or empty if no writing
|
The result gets printed to standard output. It is 0 or empty if no writing
|
||||||
is possible with the given options.
|
is possible with the given options.
|
||||||
@ -1096,11 +1043,12 @@ 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 option is without effect because no media types are
|
tested. Currently this applies to :
|
||||||
under test reservation.
|
|
||||||
.br
|
.br
|
||||||
(If you really test experimental media, then please report the outcome on
|
Profile 0015h , DVD-R/DL Sequential (will not allow -multi).
|
||||||
libburn-hackers@pykix.org)
|
.br
|
||||||
|
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
|
||||||
@ -1138,7 +1086,7 @@ Wether this leads to senseful behavior depends on operating system and kernel.
|
|||||||
Linux specific: Select a SCSI device file family to be scanned for by
|
Linux specific: Select a SCSI device file family to be scanned for by
|
||||||
options --devices and -scanbus.
|
options --devices and -scanbus.
|
||||||
Normally this is /dev/sgN on kernel versions < 2.6 and /dev/srN
|
Normally this is /dev/sgN on kernel versions < 2.6 and /dev/srN
|
||||||
on kernels >= 2.6 . This option allows to explicitly override that default
|
on kernels >= 2.6 . This option allows to explicitely override that default
|
||||||
in order to meet other programs at a common device file for each drive.
|
in order to meet other programs at a common device file for each drive.
|
||||||
On kernel 2.4 families sr and scd will find no drives.
|
On kernel 2.4 families sr and scd will find no drives.
|
||||||
.br
|
.br
|
||||||
@ -1231,9 +1179,14 @@ Linux specific:
|
|||||||
Use and report literal Bus,Target,Lun addresses rather than real SCSI and
|
Use and report literal Bus,Target,Lun addresses rather than real SCSI and
|
||||||
pseudo ATA addresses. This method is outdated and was never compatible with
|
pseudo ATA addresses. This method is outdated and was never compatible with
|
||||||
original cdrecord.
|
original cdrecord.
|
||||||
.BI --xa1-ignore
|
.TP
|
||||||
Silently interpret option -xa1 as -data. This may be necessary if a frontent
|
.BI stream_recording="on"|"off"
|
||||||
does not prepare -xa1 block headers but insists in using option -xa1.
|
By setting "on" request that compliance to the desired speed setting is
|
||||||
|
preferred over management of write errors. With DVD-RAM and BD-RE this can
|
||||||
|
bring effective write speed near to the nominal write speed of the media.
|
||||||
|
But it will also disable the automatic use of replacement blocks
|
||||||
|
if write errors occur. It might as well be disliked or ignored by the drive.
|
||||||
|
.br
|
||||||
.SH EXAMPLES
|
.SH EXAMPLES
|
||||||
.SS
|
.SS
|
||||||
.B Get an overview of drives and their addresses:
|
.B Get an overview of drives and their addresses:
|
||||||
@ -1250,7 +1203,7 @@ cdrskin dev=0,1,0 -checkdrive
|
|||||||
.br
|
.br
|
||||||
cdrskin dev=ATA:1,0,0 -v -atip
|
cdrskin dev=ATA:1,0,0 -v -atip
|
||||||
.br
|
.br
|
||||||
cdrskin dev=/dev/hdc -minfo
|
cdrskin dev=/dev/hdc -toc
|
||||||
.SS
|
.SS
|
||||||
.B Prepare CD-RW or DVD-RW for re-use, DVD-RAM or BD-RE for first use:
|
.B Prepare CD-RW or DVD-RW for re-use, DVD-RAM or BD-RE for first use:
|
||||||
.br
|
.br
|
||||||
@ -1270,7 +1223,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 or DVD-R DL):
|
.B Write compressed afio archive on-the-fly (not possible with minimally blanked DVD-RW):
|
||||||
.br
|
.br
|
||||||
find . | afio -oZ - | \\
|
find . | afio -oZ - | \\
|
||||||
.br
|
.br
|
||||||
@ -1278,15 +1231,15 @@ cdrskin -v dev=0,1,0 fs=32m speed=8 \\
|
|||||||
.br
|
.br
|
||||||
blank=as_needed padsize=300k -
|
blank=as_needed padsize=300k -
|
||||||
.SS
|
.SS
|
||||||
.B Write multi-session to the same CD, DVD-R[W], DVD+R[/DL], or BD-R:
|
.B Write multi-session to the same CD, DVD-R[W] or DVD+R[/DL]:
|
||||||
.br
|
.br
|
||||||
cdrskin dev=/dev/sr0 -v padsize=300k -multi 1.iso
|
cdrskin dev=/dev/hdc -v padsize=300k -multi 1.iso
|
||||||
.br
|
.br
|
||||||
cdrskin dev=/dev/sr0 -v padsize=300k -multi 2.iso
|
cdrskin dev=/dev/hdc -v padsize=300k -multi 2.iso
|
||||||
.br
|
.br
|
||||||
cdrskin dev=/dev/sr0 -v padsize=300k -multi 3.iso
|
cdrskin dev=/dev/hdc -v padsize=300k -multi 3.iso
|
||||||
.br
|
.br
|
||||||
cdrskin dev=/dev/sr0 -v padsize=300k 4.iso
|
cdrskin dev=/dev/hdc -v padsize=300k 4.iso
|
||||||
.SS
|
.SS
|
||||||
.B Get multi-session info for option -C of program mkisofs:
|
.B Get multi-session info for option -C of program mkisofs:
|
||||||
.br
|
.br
|
||||||
|
1325
cdrskin/cdrskin.c
1325
cdrskin/cdrskin.c
File diff suppressed because it is too large
Load Diff
@ -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-R DL, 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-RW, DVD+RW, DVD+R, DVD+R/DL, DVD-RAM, BD-RE, 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,8 +24,7 @@
|
|||||||
<P>
|
<P>
|
||||||
<H2>Purpose:</H2>
|
<H2>Purpose:</H2>
|
||||||
Burns preformatted data to CD, DVD, and BD media:<BR>
|
Burns preformatted data to CD, DVD, and BD media:<BR>
|
||||||
CD-R, DVD-R, DVD-R DL, DVD+R, DVD+R DL, BD-R, CD-RW,
|
CD-R, DVD-R, DVD+R, DVD+R/DL, CD-RW, DVD-RW, DVD-RAM, DVD+RW, BD-RE
|
||||||
DVD-RW, DVD-RAM, DVD+RW, BD-RE
|
|
||||||
</P>
|
</P>
|
||||||
<P>
|
<P>
|
||||||
|
|
||||||
@ -35,12 +34,10 @@ DVD-RW, DVD-RAM, DVD+RW, BD-RE
|
|||||||
|
|
||||||
<P>
|
<P>
|
||||||
<H2>Hardware requirements:</H2>
|
<H2>Hardware requirements:</H2>
|
||||||
About any CD, DVD, or BD recorder produced in the recent ten years.
|
A CD/DVD/BD recorder suitable for
|
||||||
<BR>
|
<A HREF="http://libburnia-project.org">http://libburnia-project.org</A> <BR>
|
||||||
<A HREF="http://libburnia-project.org">libburn</A>
|
(SCSI , ATA , USB , or SATA writers compliant to standard MMC-3 for CD
|
||||||
supports recorders which are compliant to standards MMC-1 for CD and
|
and to MMC-5 for DVD or BD).
|
||||||
MMC-5 for DVD or BD. Linux, FreeBSD, and Solaris allow to access drives
|
|
||||||
connected via SCSI, PATA (aka IDE, ATA), USB, or SATA.
|
|
||||||
<BR>
|
<BR>
|
||||||
</P>
|
</P>
|
||||||
|
|
||||||
@ -51,10 +48,7 @@ connected via SCSI, PATA (aka IDE, ATA), USB, or SATA.
|
|||||||
<DD>With kernel 2.4 an ATA drive has to be under ide-scsi emulation.</DD>
|
<DD>With kernel 2.4 an ATA drive has to be under ide-scsi emulation.</DD>
|
||||||
<DD>With kernel 2.6 the drive should not be under ide-scsi.</DD>
|
<DD>With kernel 2.6 the drive should not be under ide-scsi.</DD>
|
||||||
<DT>or FreeBSD (with libc, of course) :</DT>
|
<DT>or FreeBSD (with libc, of course) :</DT>
|
||||||
<DD>ATA and SATA drives need atapicam running.</DD>
|
<DD>ATAPI/CAM support has to be enabled in the kernel, see atapicam(4).</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>
|
||||||
@ -65,18 +59,18 @@ connected via SCSI, PATA (aka IDE, ATA), USB, or SATA.
|
|||||||
GPL software included:<BR>
|
GPL software included:<BR>
|
||||||
</H2>
|
</H2>
|
||||||
<DL>
|
<DL>
|
||||||
<DT>libburn-1.0.0</DT>
|
<DT>libburn-0.5.8</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)
|
||||||
</DD>
|
</DD>
|
||||||
<DD>transfers data to CD, DVD, BD</DD>
|
<DD>transfers data to CD, DVD, BD-RE</DD>
|
||||||
</DL>
|
</DL>
|
||||||
</P>
|
</P>
|
||||||
|
|
||||||
<P>
|
<P>
|
||||||
This program system has been tested on Intel/AMD with Linux, FreeBSD,
|
This program system has been tested on Intel/AMD Linux and FreeBSD systems
|
||||||
and OpenSolaris based operating systems.<BR>
|
only.<BR>
|
||||||
Ports to other usable systems are appreciated. Reports are welcome.
|
Ports to other usable systems are appreciated. Reports are welcome.
|
||||||
</P>
|
</P>
|
||||||
|
|
||||||
@ -96,11 +90,10 @@ 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, cdrskin is able to perform any recording job
|
On all DVD media except DVD-R DL, cdrskin is able to perform any recording job
|
||||||
which is possible with cdrecord.
|
which is possible with cdrecord.
|
||||||
Other than with cdrecord, 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 and
|
write mode -tao works with anything but quickly blanked DVD-RW.
|
||||||
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>
|
||||||
@ -109,15 +102,14 @@ DVD-R DL, which both support no -multi.
|
|||||||
<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 access to the /dev files
|
<DT>Ordinary users should then get granted rw access to the /dev files
|
||||||
as listed by option --devices. Linux and FreeBSD demand rw-permission.
|
as listed by option --devices.</DT>
|
||||||
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>
|
||||||
<DD>$<KBD> cdrskin dev=0,1,0 -checkdrive</KBD></DD>
|
<DD>$<KBD> cdrskin dev=0,1,0 -checkdrive</KBD></DD>
|
||||||
<DD>$<KBD> cdrskin dev=ATA:1,0,0 -v -atip</KBD></DD>
|
<DD>$<KBD> cdrskin dev=ATA:1,0,0 -v -atip</KBD></DD>
|
||||||
<DD>$<KBD> cdrskin dev=/dev/hdc -minfo</KBD></DD>
|
<DD>$<KBD> cdrskin dev=/dev/hdc -toc</KBD></DD>
|
||||||
|
|
||||||
<DT>Prepare CD-RW or DVD-RW for re-use, DVD-RAM or BD-RE for first use:</DT>
|
<DT>Prepare CD-RW or DVD-RW for re-use, DVD-RAM or BD-RE for first use:</DT>
|
||||||
<DD>$<KBD> cdrskin -v dev=/dev/sg1 blank=as_needed -eject</KBD></DD>
|
<DD>$<KBD> cdrskin -v dev=/dev/sg1 blank=as_needed -eject</KBD></DD>
|
||||||
@ -133,8 +125,7 @@ On Solaris it is r-permission and privileges "basic,sys_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>Write compressed afio archive on-the-fly:</DT>
|
||||||
(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>
|
||||||
@ -157,9 +148,6 @@ On Solaris it is r-permission and privileges "basic,sys_devices".</DT>
|
|||||||
<DD><KBD> --tell_media_space 2>/dev/null)</KBD></DD>
|
<DD><KBD> --tell_media_space 2>/dev/null)</KBD></DD>
|
||||||
<DD>$<KBD> echo "Available: $x blocks of 2048 data bytes"</KBD></DD>
|
<DD>$<KBD> echo "Available: $x blocks of 2048 data bytes"</KBD></DD>
|
||||||
|
|
||||||
<DT>Accelerate BD-RE writing to full nominal speed after the first 250 MB</DT>
|
|
||||||
<DD>$<KBD> cdrskin ... stream_recording=250m ...</KBD>
|
|
||||||
|
|
||||||
<DT>Write audio tracks to CD:</DT>
|
<DT>Write audio tracks to CD:</DT>
|
||||||
<DD>$<KBD> cdrskin -v dev=ATA:1,0,0 speed=48 -sao \</KBD></DD>
|
<DD>$<KBD> cdrskin -v dev=ATA:1,0,0 speed=48 -sao \</KBD></DD>
|
||||||
<DD><KBD> track1.wav track2.au -audio -swab track3.raw</KBD></DD>
|
<DD><KBD> track1.wav track2.au -audio -swab track3.raw</KBD></DD>
|
||||||
@ -186,11 +174,14 @@ man cdrecord</A></KBD></DD>
|
|||||||
<DL>
|
<DL>
|
||||||
<DT>Learn to know a more versatile way to burn ISO 9660 formatted data</DT>
|
<DT>Learn to know a more versatile way to burn ISO 9660 formatted data</DT>
|
||||||
<DD>
|
<DD>
|
||||||
Standalone ISO 9660 multi-session CD/DVD/BD tool
|
Standalone ISO 9660 multi-session CD/DVD tool
|
||||||
<A HREF="http://scdbackup.sourceforge.net/xorriso_eng.html">xorriso</A>.
|
<A HREF="http://scdbackup.sourceforge.net/xorriso_eng.html">xorriso</A>.
|
||||||
</DD>
|
</DD>
|
||||||
</DL>
|
</DL>
|
||||||
|
|
||||||
|
Testers wanted who are willing to risk some DVD-R DL media
|
||||||
|
or to do experiments on BD-R media.
|
||||||
|
|
||||||
</P>
|
</P>
|
||||||
|
|
||||||
<HR>
|
<HR>
|
||||||
@ -200,8 +191,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-1.0.0.pl00.tar.gz">cdrskin-1.0.0.pl00.tar.gz</A>
|
<DD><A HREF="cdrskin-0.5.8.pl00.tar.gz">cdrskin-0.5.8.pl00.tar.gz</A>
|
||||||
(870 KB).
|
(740 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
|
||||||
@ -250,54 +241,44 @@ 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.9.0.pl00:
|
Enhancements towards previous stable version cdrskin-0.5.6.pl00:
|
||||||
|
<UL>
|
||||||
|
<LI>Improvements about BD-RE formatting</LI>
|
||||||
|
<!--
|
||||||
|
<LI>none</LI>
|
||||||
|
-->
|
||||||
|
</UL>
|
||||||
|
|
||||||
|
Bug fixes towards cdrskin-0.5.6.pl00:
|
||||||
<UL>
|
<UL>
|
||||||
<LI>
|
<LI>
|
||||||
<LI>Allowed umask to create stdio-drive files with rw-permissions for all</LI>
|
A session without leadout entry on CD caused a SIGSEGV by NULL
|
||||||
<LI>cdrskin now refuses to burn if the foreseeable size exceeds media capacity
|
|
||||||
</LI>
|
</LI>
|
||||||
<!--
|
<!--
|
||||||
<LI>none</LI>
|
<LI>none</LI>
|
||||||
-->
|
-->
|
||||||
</UL>
|
</UL>
|
||||||
|
|
||||||
Bug fixes towards cdrskin-0.9.0.pl00:
|
</P>
|
||||||
<UL>
|
|
||||||
<LI>none</LI>
|
|
||||||
<!--
|
|
||||||
<LI>none</LI>
|
|
||||||
-->
|
|
||||||
</UL>
|
|
||||||
|
|
||||||
<HR>
|
<HR>
|
||||||
|
|
||||||
<P>
|
<P>
|
||||||
<DL>
|
<DL>
|
||||||
<DT><H3>Development snapshot, version 1.0.1 :</H3></DT>
|
<DT><H3>Development snapshot, version 0.5.9 :</H3></DT>
|
||||||
<DD>Enhancements towards current stable version 1.0.0.pl00:
|
<DD>Enhancements towards current stable version 0.5.8.pl00:
|
||||||
<UL>
|
<UL>
|
||||||
<LI>none yet</LI>
|
|
||||||
<!--
|
<!--
|
||||||
<LI>none yet</LI>
|
|
||||||
-->
|
-->
|
||||||
|
<LI>none yet</LI>
|
||||||
|
|
||||||
</UL>
|
</UL>
|
||||||
</DD>
|
</DD>
|
||||||
|
|
||||||
<DD>Bug fixes towards cdrskin-1.0.0.pl00:
|
|
||||||
<UL>
|
|
||||||
<LI>none yet</LI>
|
|
||||||
<!--
|
|
||||||
<LI>none yet</LI>
|
|
||||||
-->
|
|
||||||
</UL>
|
|
||||||
</DD>
|
|
||||||
|
|
||||||
<DD> </DD>
|
<DD> </DD>
|
||||||
<DD><A HREF="README_cdrskin_devel">README 1.0.1</A>
|
<DD><A HREF="README_cdrskin_devel">README 0.5.9</A>
|
||||||
<DD><A HREF="cdrskin__help_devel">cdrskin-1.0.1 --help</A></DD>
|
<DD><A HREF="cdrskin__help_devel">cdrskin_0.5.9 --help</A></DD>
|
||||||
<DD><A HREF="cdrskin_help_devel">cdrskin-1.0.1 -help</A></DD>
|
<DD><A HREF="cdrskin_help_devel">cdrskin_0.5.9 -help</A></DD>
|
||||||
<DD><A HREF="man_1_cdrskin_devel.html">man cdrskin (as of 1.0.1)</A></DD>
|
<DD><A HREF="man_1_cdrskin_devel.html">man cdrskin (as of 0.5.9)</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>
|
||||||
@ -317,8 +298,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-1.0.1.tar.gz">cdrskin-1.0.1.tar.gz</A>
|
<A HREF="cdrskin-0.5.9.tar.gz">cdrskin-0.5.9.tar.gz</A>
|
||||||
(870 KB).
|
(740 KB).
|
||||||
</DD>
|
</DD>
|
||||||
|
|
||||||
<!-- This is not offered any more since spring 2008
|
<!-- This is not offered any more since spring 2008
|
||||||
@ -351,7 +332,7 @@ Historic versions based on Derek's and Ben's
|
|||||||
<BR>
|
<BR>
|
||||||
Very special thanks to Andy Polyakov whose
|
Very special thanks to Andy Polyakov whose
|
||||||
<A HREF="http://fy.chalmers.se/~appro/linux/DVD+RW/tools">dvd+rw-tools</A>
|
<A HREF="http://fy.chalmers.se/~appro/linux/DVD+RW/tools">dvd+rw-tools</A>
|
||||||
provide libburn with invaluable examples on how to deal with DVD and BD media.
|
provide libburn with invaluable examples on how to deal with DVD media.
|
||||||
</P>
|
</P>
|
||||||
|
|
||||||
<HR>
|
<HR>
|
||||||
@ -513,17 +494,12 @@ and by <A HREF="http://sourceforge.net">sourceforge.net</A><BR>
|
|||||||
<A href="http://sourceforge.net">
|
<A href="http://sourceforge.net">
|
||||||
<IMG src="sflogo-88-1.png" BORDER="0" ALT="SourceForge Logo"></A>
|
<IMG src="sflogo-88-1.png" BORDER="0" ALT="SourceForge Logo"></A>
|
||||||
<!-- on sourceforge use : <IMG src="http://sourceforge.net/sflogo.php?group_id=16010" width="88" height="31" border="0" alt="SourceForge Logo"></A> -->
|
<!-- on sourceforge use : <IMG src="http://sourceforge.net/sflogo.php?group_id=16010" width="88" height="31" border="0" alt="SourceForge Logo"></A> -->
|
||||||
<P>
|
|
||||||
Enjoying a FreeBSD shell account with the opportunity to
|
|
||||||
build and install cdrskin at<BR>
|
|
||||||
<A HREF="http://www.en.free-shells.com.ar">free-shells.com.ar</A>
|
|
||||||
</P>
|
|
||||||
</FONT></CENTER>
|
</FONT></CENTER>
|
||||||
<HR>
|
<HR>
|
||||||
<DL>
|
<DL>
|
||||||
<DT>Links to my other published software projects :
|
<DT>Links to my other published software projects :
|
||||||
<DD><A HREF="http://scdbackup.webframe.org/xorriso_eng.html">
|
<DD><A HREF="http://scdbackup.webframe.org/xorriso_eng.html">
|
||||||
xorriso, a standalone ISO 9660 multi-session CD/DVD/BD burn tool.
|
xorriso, a standalone ISO 9660 multi-session CD/DVD burn tool.
|
||||||
No mkisofs needed.
|
No mkisofs needed.
|
||||||
<DL>
|
<DL>
|
||||||
<DD>
|
<DD>
|
||||||
|
@ -1 +1 @@
|
|||||||
#define Cdrskin_timestamP "2011.01.16.123001"
|
#define Cdrskin_timestamP "2008.12.07.140001"
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -1,38 +1,24 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
# compile_cdrskin.sh
|
# compile_cdrskin.sh
|
||||||
# Copyright 2005 - 2011 Thomas Schmitt, scdbackup@gmx.net, GPL
|
# Copyright 2005 - 2008 Thomas Schmitt, scdbackup@gmx.net, GPL version 2
|
||||||
# to be executed within ./libburn-* resp ./cdrskin-*
|
# to be executed within ./libburn-* resp ./cdrskin-*
|
||||||
|
|
||||||
debug_opts="-O2"
|
debug_opts="-O2"
|
||||||
def_opts=
|
def_opts=
|
||||||
largefile_opts="-D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE=1"
|
largefile_opts="-D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE=1"
|
||||||
fifo_opts=""
|
libvers="-DCdrskin_libburn_0_5_8"
|
||||||
libvers="-DCdrskin_libburn_1_0_0"
|
cleanup_src_or_obj="libburn/cleanup.o"
|
||||||
|
libdax_msgs_o="libburn/libdax_msgs.o"
|
||||||
# To be used if Makefile.am uses libburn_libburn_la_CFLAGS
|
libdax_audioxtr_o="libburn/libdax_audioxtr.o"
|
||||||
# burn="libburn/libburn_libburn_la-"
|
|
||||||
burn="libburn/"
|
|
||||||
|
|
||||||
cleanup_src_or_obj="$burn"cleanup.o
|
|
||||||
libdax_msgs_o="$burn"libdax_msgs.o
|
|
||||||
libdax_audioxtr_o="$burn"libdax_audioxtr.o
|
|
||||||
do_strip=0
|
do_strip=0
|
||||||
static_opts=
|
static_opts=
|
||||||
warn_opts="-Wall"
|
warn_opts="-Wall"
|
||||||
libcdio=
|
|
||||||
fifo_source="cdrskin/cdrfifo.c"
|
fifo_source="cdrskin/cdrfifo.c"
|
||||||
compile_cdrskin=1
|
compile_cdrskin=1
|
||||||
compile_cdrfifo=0
|
compile_cdrfifo=0
|
||||||
compile_dewav=0
|
compile_dewav=0
|
||||||
|
|
||||||
libcam=
|
|
||||||
os=$(uname -s)
|
|
||||||
case $os in
|
|
||||||
*FreeBSD)
|
|
||||||
libcam="-lcam"
|
|
||||||
esac
|
|
||||||
|
|
||||||
for i in "$@"
|
for i in "$@"
|
||||||
do
|
do
|
||||||
if test "$i" = "-compile_cdrfifo"
|
if test "$i" = "-compile_cdrfifo"
|
||||||
@ -45,20 +31,20 @@ do
|
|||||||
then
|
then
|
||||||
libvers="-DCdrskin_libburn_cvs_A60220_tS"
|
libvers="-DCdrskin_libburn_cvs_A60220_tS"
|
||||||
libdax_audioxtr_o=
|
libdax_audioxtr_o=
|
||||||
libdax_msgs_o="$burn"message.o
|
libdax_msgs_o="libburn/message.o"
|
||||||
cleanup_src_or_obj="-DCleanup_has_no_libburn_os_H cdrskin/cleanup.c"
|
cleanup_src_or_obj="-DCleanup_has_no_libburn_os_H cdrskin/cleanup.c"
|
||||||
elif test "$i" = "-libburn_1_0_0"
|
elif test "$i" = "-libburn_0_5_8"
|
||||||
then
|
then
|
||||||
libvers="-DCdrskin_libburn_1_0_0"
|
libvers="-DCdrskin_libburn_0_5_8"
|
||||||
libdax_audioxtr_o="$burn"libdax_audioxtr.o
|
libdax_audioxtr_o="libburn/libdax_audioxtr.o"
|
||||||
libdax_msgs_o="$burn"libdax_msgs.o
|
libdax_msgs_o="libburn/libdax_msgs.o"
|
||||||
cleanup_src_or_obj="$burn"cleanup.o
|
cleanup_src_or_obj="libburn/cleanup.o"
|
||||||
elif test "$i" = "-libburn_svn"
|
elif test "$i" = "-libburn_svn"
|
||||||
then
|
then
|
||||||
libvers="-DCdrskin_libburn_1_0_1"
|
libvers="-DCdrskin_libburn_0_5_9"
|
||||||
libdax_audioxtr_o="$burn"libdax_audioxtr.o
|
libdax_audioxtr_o="libburn/libdax_audioxtr.o"
|
||||||
libdax_msgs_o="$burn"libdax_msgs.o
|
libdax_msgs_o="libburn/libdax_msgs.o"
|
||||||
cleanup_src_or_obj="$burn"cleanup.o
|
cleanup_src_or_obj="libburn/cleanup.o"
|
||||||
elif test "$i" = "-newapi" -o "$i" = "-experimental"
|
elif test "$i" = "-newapi" -o "$i" = "-experimental"
|
||||||
then
|
then
|
||||||
def_opts="$def_opts -DCdrskin_new_api_tesT"
|
def_opts="$def_opts -DCdrskin_new_api_tesT"
|
||||||
@ -69,9 +55,6 @@ do
|
|||||||
elif test "$i" = "-no_largefile"
|
elif test "$i" = "-no_largefile"
|
||||||
then
|
then
|
||||||
largefile_opts=
|
largefile_opts=
|
||||||
elif test "$i" = "-dvd_obs_64k"
|
|
||||||
then
|
|
||||||
def_opts="$def_opts -DCdrskin_dvd_obs_default_64K"
|
|
||||||
elif test "$i" = "-do_not_compile_cdrskin"
|
elif test "$i" = "-do_not_compile_cdrskin"
|
||||||
then
|
then
|
||||||
compile_cdrskin=0
|
compile_cdrskin=0
|
||||||
@ -83,23 +66,6 @@ do
|
|||||||
elif test "$i" = "-do_strip"
|
elif test "$i" = "-do_strip"
|
||||||
then
|
then
|
||||||
do_strip=1
|
do_strip=1
|
||||||
elif test "$i" = "-use_libburn_fifo"
|
|
||||||
then
|
|
||||||
fifo_opts="-DCdrskin_use_libburn_fifO"
|
|
||||||
elif test "$i" = "-use_no_libburn_fifo"
|
|
||||||
then
|
|
||||||
fifo_opts=""
|
|
||||||
elif test "$i" = "-use_no_cdrfifo"
|
|
||||||
then
|
|
||||||
fifo_source=
|
|
||||||
fifo_opts="-DCdrskin_use_libburn_fifO -DCdrskin_no_cdrfifO"
|
|
||||||
elif test "$i" = "-use_libburn_cleanup"
|
|
||||||
then
|
|
||||||
fifo_source=
|
|
||||||
fifo_opts="-DCdrskin_use_libburn_cleanuP -DCdrskin_use_libburn_fifO -DCdrskin_no_cdrfifO"
|
|
||||||
elif test "$i" = "-use_libcdio"
|
|
||||||
then
|
|
||||||
libcdio="-lcdio"
|
|
||||||
elif test "$i" = "-g"
|
elif test "$i" = "-g"
|
||||||
then
|
then
|
||||||
debug_opts="-g"
|
debug_opts="-g"
|
||||||
@ -109,13 +75,11 @@ 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_1_0_0 set macro to match libburn-1.0.0"
|
echo " -cvs_A60220 set macro to match libburn-CVS of 20 Feb 2006."
|
||||||
|
echo " -libburn_0_5_8 set macro to match libburn-0.5.8"
|
||||||
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 " -no_largefile do not use 64 bit off_t (must match libburn)."
|
||||||
echo " -use_libcdio link with -lcdio because libburn uses it."
|
|
||||||
echo " -do_not_compile_cdrskin omit compilation of cdrskin/cdrskin."
|
echo " -do_not_compile_cdrskin omit compilation of cdrskin/cdrskin."
|
||||||
echo " -use_no_libburn_fifo use cdrfifo even for single track non-CD"
|
|
||||||
echo " -use_no_cdrfifo always use fifo of libburn and never cdrfifo"
|
|
||||||
echo " -experimental use newly introduced libburn features."
|
echo " -experimental use newly introduced libburn features."
|
||||||
echo " -oldfashioned use pre-0.2.2 libburn features only."
|
echo " -oldfashioned use pre-0.2.2 libburn features only."
|
||||||
echo " -do_diet produce capability reduced lean version."
|
echo " -do_diet produce capability reduced lean version."
|
||||||
@ -136,14 +100,13 @@ echo "Build timestamp : $timestamp"
|
|||||||
|
|
||||||
if test "$compile_cdrskin"
|
if test "$compile_cdrskin"
|
||||||
then
|
then
|
||||||
echo "compiling program cdrskin/cdrskin.c $fifo_source $static_opts $debug_opts $libvers $fifo_opts $def_opts $cleanup_src_or_obj $libcdio $libcam"
|
echo "compiling program cdrskin/cdrskin.c $static_opts $debug_opts $libvers $def_opts $cleanup_src_or_obj"
|
||||||
cc -I. \
|
cc -I. \
|
||||||
$warn_opts \
|
$warn_opts \
|
||||||
$static_opts \
|
$static_opts \
|
||||||
$debug_opts \
|
$debug_opts \
|
||||||
$libvers \
|
$libvers \
|
||||||
$largefile_opts \
|
$largefile_opts \
|
||||||
$fifo_opts \
|
|
||||||
$def_opts \
|
$def_opts \
|
||||||
\
|
\
|
||||||
-DCdrskin_build_timestamP='"'"$timestamp"'"' \
|
-DCdrskin_build_timestamP='"'"$timestamp"'"' \
|
||||||
@ -155,34 +118,32 @@ then
|
|||||||
\
|
\
|
||||||
$cleanup_src_or_obj \
|
$cleanup_src_or_obj \
|
||||||
\
|
\
|
||||||
"$burn"async.o \
|
libburn/async.o \
|
||||||
"$burn"debug.o \
|
libburn/debug.o \
|
||||||
"$burn"drive.o \
|
libburn/drive.o \
|
||||||
"$burn"file.o \
|
libburn/file.o \
|
||||||
"$burn"init.o \
|
libburn/init.o \
|
||||||
"$burn"options.o \
|
libburn/options.o \
|
||||||
"$burn"source.o \
|
libburn/source.o \
|
||||||
"$burn"structure.o \
|
libburn/structure.o \
|
||||||
\
|
\
|
||||||
"$burn"sg.o \
|
libburn/sg.o \
|
||||||
"$burn"write.o \
|
libburn/write.o \
|
||||||
"$burn"read.o \
|
libburn/read.o \
|
||||||
$libdax_audioxtr_o \
|
$libdax_audioxtr_o \
|
||||||
$libdax_msgs_o \
|
$libdax_msgs_o \
|
||||||
\
|
\
|
||||||
"$burn"mmc.o \
|
libburn/mmc.o \
|
||||||
"$burn"sbc.o \
|
libburn/sbc.o \
|
||||||
"$burn"spc.o \
|
libburn/spc.o \
|
||||||
"$burn"util.o \
|
libburn/util.o \
|
||||||
\
|
\
|
||||||
"$burn"sector.o \
|
libburn/sector.o \
|
||||||
"$burn"toc.o \
|
libburn/toc.o \
|
||||||
\
|
\
|
||||||
"$burn"crc.o \
|
libburn/crc.o \
|
||||||
"$burn"ecma130ab.o \
|
libburn/lec.o \
|
||||||
\
|
\
|
||||||
$libcdio \
|
|
||||||
$libcam \
|
|
||||||
-lpthread
|
-lpthread
|
||||||
|
|
||||||
ret=$?
|
ret=$?
|
||||||
@ -224,8 +185,8 @@ then
|
|||||||
-DDewav_without_libburN \
|
-DDewav_without_libburN \
|
||||||
-o test/dewav \
|
-o test/dewav \
|
||||||
test/dewav.c \
|
test/dewav.c \
|
||||||
"$burn"libdax_audioxtr.o \
|
libburn/libdax_audioxtr.o \
|
||||||
"$burn"libdax_msgs.o \
|
libburn/libdax_msgs.o \
|
||||||
\
|
\
|
||||||
-lpthread
|
-lpthread
|
||||||
|
|
||||||
|
@ -10,8 +10,8 @@ Schilling's cdrtools. cdrskin strives to be a second source for the services
|
|||||||
traditionally provided by cdrecord. Currently it does CD-R and CD-RW this way.
|
traditionally provided by cdrecord. Currently it does CD-R and CD-RW this way.
|
||||||
Overwriteable media DVD-RAM, DVD+RW, DVD-RW, and BD-RE are handled differently
|
Overwriteable media DVD-RAM, DVD+RW, DVD-RW, and BD-RE are handled differently
|
||||||
than with cdrecord-ProDVD in order to offer TAO-like single track recording.
|
than with cdrecord-ProDVD in order to offer TAO-like single track recording.
|
||||||
Sequential DVD-R[W], DVD+R, DVD+R DL, BD-R are handled like CD-R[W] with TAO
|
Sequential DVD-R[W], DVD+R, DVD+R DL are handled like CD-R[W] with TAO and
|
||||||
and multi-session. Additionally cdrskin offers cdrecord-ProDVD-like mode DAO
|
multi-session. Additionally cdrskin offers cdrecord-ProDVD-like mode DAO
|
||||||
with DVD-R[W].
|
with DVD-R[W].
|
||||||
|
|
||||||
cdrskin does not contain any bytes copied from cdrecord's sources.
|
cdrskin does not contain any bytes copied from cdrecord's sources.
|
||||||
|
159
configure.ac
159
configure.ac
@ -1,15 +1,13 @@
|
|||||||
AC_INIT([libburn], [1.0.0], [http://libburnia-project.org])
|
AC_INIT([libburn], [0.5.8], [http://libburnia-project.org])
|
||||||
AC_PREREQ([2.50])
|
AC_PREREQ([2.50])
|
||||||
dnl AC_CONFIG_HEADER([config.h])
|
dnl AC_CONFIG_HEADER([config.h])
|
||||||
|
|
||||||
AC_CANONICAL_HOST
|
AC_CANONICAL_HOST
|
||||||
AC_CANONICAL_TARGET
|
AC_CANONICAL_TARGET
|
||||||
|
|
||||||
LIBBURNIA_SET_FLAGS
|
|
||||||
|
|
||||||
AM_INIT_AUTOMAKE([subdir-objects])
|
AM_INIT_AUTOMAKE([subdir-objects])
|
||||||
|
|
||||||
dnl Notes by ts A71207 - B10116 :
|
dnl Notes by ts A71207 - A81111 :
|
||||||
dnl
|
dnl
|
||||||
dnl Regrettably the meaning of the various version types was misunderstood
|
dnl Regrettably the meaning of the various version types was misunderstood
|
||||||
dnl before version 0.4.1.
|
dnl before version 0.4.1.
|
||||||
@ -44,8 +42,7 @@ dnl So this is a superspace of the SONAME version space. To avoid
|
|||||||
dnl ill SONAME, the value of CURRENT must be larger than AGE.
|
dnl ill SONAME, the value of CURRENT must be larger than AGE.
|
||||||
dnl See also http://www.gnu.org/software/libtool/manual.html#Interfaces
|
dnl See also http://www.gnu.org/software/libtool/manual.html#Interfaces
|
||||||
dnl
|
dnl
|
||||||
dnl On Linux the name of the dynamic library will be
|
dnl The name of the dynamic library will be libburn.so.$SONAME.$AGE.$REV .
|
||||||
dnl libburn.so.$SONAME.$AGE.$REV
|
|
||||||
dnl In the terminology of this file:
|
dnl In the terminology of this file:
|
||||||
dnl CURRENT = LT_CURRENT
|
dnl CURRENT = LT_CURRENT
|
||||||
dnl AGE = LT_AGE
|
dnl AGE = LT_AGE
|
||||||
@ -70,23 +67,6 @@ dnl 0.5.2 = libburn.so.4.17.0
|
|||||||
dnl 0.5.4 = libburn.so.4.19.0
|
dnl 0.5.4 = libburn.so.4.19.0
|
||||||
dnl 0.5.6 = libburn.so.4.21.0
|
dnl 0.5.6 = libburn.so.4.21.0
|
||||||
dnl 0.5.8 = libburn.so.4.23.0
|
dnl 0.5.8 = libburn.so.4.23.0
|
||||||
dnl 0.6.0 = libburn.so.4.25.0
|
|
||||||
dnl 0.6.2 = libburn.so.4.27.0
|
|
||||||
dnl 0.6.4 = libburn.so.4.29.0
|
|
||||||
dnl 0.6.6 = libburn.so.4.31.0
|
|
||||||
dnl 0.6.8 = libburn.so.4.33.0
|
|
||||||
dnl 0.7.0 = libburn.so.4.35.0
|
|
||||||
dnl 0.7.2 = libburn.so.4.37.0
|
|
||||||
dnl 0.7.4 = libburn.so.4.39.0
|
|
||||||
dnl 0.7.6 = libburn.so.4.41.0
|
|
||||||
dnl 0.7.8 = libburn.so.4.43.0
|
|
||||||
dnl 0.8.0 = libburn.so.4.45.0
|
|
||||||
dnl 0.8.2 = libburn.so.4.47.0
|
|
||||||
dnl 0.8.4 = libburn.so.4.49.0
|
|
||||||
dnl 0.8.6 = libburn.so.4.51.0
|
|
||||||
dnl 0.8.8 = libburn.so.4.53.0
|
|
||||||
dnl 0.9.0 = libburn.so.4.55.0
|
|
||||||
dnl 1.0.0 = libburn.so.4.57.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.
|
||||||
@ -110,9 +90,9 @@ dnl
|
|||||||
dnl If BURN_*_VERSION changes, be sure to change AC_INIT above to match.
|
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=1
|
BURN_MAJOR_VERSION=0
|
||||||
BURN_MINOR_VERSION=0
|
BURN_MINOR_VERSION=5
|
||||||
BURN_MICRO_VERSION=0
|
BURN_MICRO_VERSION=8
|
||||||
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)
|
||||||
@ -123,14 +103,15 @@ AC_SUBST(BURN_VERSION)
|
|||||||
dnl Libtool versioning
|
dnl Libtool versioning
|
||||||
LT_RELEASE=$BURN_MAJOR_VERSION.$BURN_MINOR_VERSION.$BURN_MICRO_VERSION
|
LT_RELEASE=$BURN_MAJOR_VERSION.$BURN_MINOR_VERSION.$BURN_MICRO_VERSION
|
||||||
dnl
|
dnl
|
||||||
dnl ### This is the release version libburn-1.0.0
|
dnl ts A81207
|
||||||
dnl This is the development version after above release version
|
dnl This is the release version libburn-0.5.8 = libburn.so.4.23.0
|
||||||
|
dnl ### This is the development version after above release version
|
||||||
dnl LT_CURRENT++, LT_AGE++ has not yet happened.
|
dnl LT_CURRENT++, LT_AGE++ has not yet happened.
|
||||||
dnl ### LT_CURRENT++, LT_AGE++ has happened meanwhile.
|
dnl ### LT_CURRENT++, LT_AGE++ has happened meanwhile.
|
||||||
dnl
|
dnl
|
||||||
dnl SONAME = 61 - 57 = 4 . Linux library name = libburn.so.4.57.0
|
dnl SONAME = 27 - 23 = 4 . Library name = libburn.so.4.23.0
|
||||||
LT_CURRENT=61
|
LT_CURRENT=27
|
||||||
LT_AGE=57
|
LT_AGE=23
|
||||||
LT_REVISION=0
|
LT_REVISION=0
|
||||||
LT_CURRENT_MINUS_AGE=`expr $LT_CURRENT - $LT_AGE`
|
LT_CURRENT_MINUS_AGE=`expr $LT_CURRENT - $LT_AGE`
|
||||||
|
|
||||||
@ -177,108 +158,8 @@ AC_SUBST(THREAD_LIBS)
|
|||||||
|
|
||||||
TARGET_SHIZZLE
|
TARGET_SHIZZLE
|
||||||
AC_SUBST(ARCH)
|
AC_SUBST(ARCH)
|
||||||
AC_SUBST(LIBBURNIA_PKGCONFDIR)
|
|
||||||
AC_SUBST(LIBBURN_ARCH_LIBS)
|
AC_SUBST(LIBBURN_ARCH_LIBS)
|
||||||
|
|
||||||
dnl ts A90303
|
|
||||||
dnl Check the preconditions for using statvfs() in sg-dummy
|
|
||||||
dnl (sg-linux and sg-freebsd use statvfs() unconditionally)
|
|
||||||
STATVFS_DEF=-DLibburn_os_has_statvfS
|
|
||||||
AC_CHECK_HEADER(sys/statvfs.h, X=, STATVFS_DEF=)
|
|
||||||
AC_CHECK_FUNC([statvfs], X=, STATVFS_DEF=)
|
|
||||||
dnl If this would be done more specifically in Makefile.am
|
|
||||||
dnl via libburn_libburn_la_CFLAGS then undesired .o file names would emerge
|
|
||||||
CFLAGS="$STATVFS_DEF $CFLAGS"
|
|
||||||
|
|
||||||
dnl ts A91122
|
|
||||||
AC_ARG_ENABLE(track-src-odirect,
|
|
||||||
[ --enable-track-src-odirect Enable use of O_DIRECT with track input, default=no],
|
|
||||||
, enable_track_src_odirect=no)
|
|
||||||
if test x$enable_track_src_odirect = xyes; then
|
|
||||||
LIBBURN_O_DIRECT_DEF="-DLibburn_read_o_direcT"
|
|
||||||
echo "enabled use of O_DIRECT with track input"
|
|
||||||
else
|
|
||||||
LIBBURN_O_DIRECT_DEF=
|
|
||||||
echo "disabled use of O_DIRECT with track input"
|
|
||||||
fi
|
|
||||||
dnl Avoid the need for libburn_libburn_la_CFLAGS in Makefile.am (ugly .o names)
|
|
||||||
dnl ### AC_SUBST(LIBBURN_O_DIRECT_DEF)
|
|
||||||
CFLAGS="$LIBBURN_O_DIRECT_DEF $CFLAGS"
|
|
||||||
|
|
||||||
dnl ts A91116
|
|
||||||
AC_ARG_ENABLE(dvd-obs-64k,
|
|
||||||
[ --enable-dvd-obs-64k 64 KB default size for DVD/BD writing, default=no],
|
|
||||||
, enable_dvd_obs_64k=no)
|
|
||||||
if test x$enable_dvd_obs_64k = xyes; then
|
|
||||||
LIBBURN_DVD_OBS_64K="-DLibburn_dvd_obs_default_64K"
|
|
||||||
echo "enabled write size default 64 KB on DVD and BD"
|
|
||||||
else
|
|
||||||
LIBBURN_DVD_OBS_64K=
|
|
||||||
echo "disabled write size default 64 KB on DVD and BD"
|
|
||||||
fi
|
|
||||||
CFLAGS="$LIBBURN_DVD_OBS_64K $CFLAGS"
|
|
||||||
|
|
||||||
dnl ts A91218
|
|
||||||
AC_ARG_ENABLE(libcdio,
|
|
||||||
[ --enable-libcdio Enable EXPERIMENTAL use of libcdio as system adapter, default=no],
|
|
||||||
, enable_libcdio=no)
|
|
||||||
if test x$enable_libcdio = xyes; then
|
|
||||||
dnl Check whether there is libcdio-devel and libcdio-runtime.
|
|
||||||
dnl If not, erase this macro
|
|
||||||
LIBCDIO_DEF="-DLibburn_use_libcdiO"
|
|
||||||
dnl The empty yes case obviously causes -lcdio to be linked
|
|
||||||
AC_CHECK_HEADER(cdio/cdio.h, AC_CHECK_LIB(cdio, mmc_last_cmd_sense, , LIBCDIO_DEF= ), LIBCDIO_DEF= )
|
|
||||||
else
|
|
||||||
LIBCDIO_DEF=
|
|
||||||
fi
|
|
||||||
if test x$LIBCDIO_DEF = x
|
|
||||||
then
|
|
||||||
if test x$enable_libcdio = xyes
|
|
||||||
then
|
|
||||||
echo "WARNING: could not enable use of libcdio as system adapter"
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
echo "enabled EXPERIMENTAL use of libcdio as system adapter"
|
|
||||||
CFLAGS="$LIBCDIO_DEF $CFLAGS"
|
|
||||||
|
|
||||||
LIBCDIO_REQUIRED=0.83
|
|
||||||
PKG_CHECK_MODULES(LIBCDIO, libcdio >= $LIBCDIO_REQUIRED)
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
AC_ARG_ENABLE(ldconfig-at-install,
|
|
||||||
[ --enable-ldconfig-at-install On GNU/Linux run ldconfig, default=yes],
|
|
||||||
, ldconfig_at_install=yes)
|
|
||||||
if test x$ldconfig_at_install = xyes; then
|
|
||||||
dummy=dummy
|
|
||||||
else
|
|
||||||
LIBBURNIA_LDCONFIG_CMD="echo 'NOTE: ldconfig is disabled. If needed, configure manually for:'"
|
|
||||||
echo "disabled run of ldconfig during installation on GNU/Linux"
|
|
||||||
fi
|
|
||||||
AC_SUBST(LIBBURNIA_LDCONFIG_CMD)
|
|
||||||
|
|
||||||
|
|
||||||
dnl Add compiler-specific flags
|
dnl Add compiler-specific flags
|
||||||
|
|
||||||
dnl See if the user wants aggressive optimizations of the code
|
dnl See if the user wants aggressive optimizations of the code
|
||||||
@ -287,23 +168,17 @@ AC_ARG_ENABLE(debug,
|
|||||||
, enable_debug=yes)
|
, enable_debug=yes)
|
||||||
if test x$enable_debug != xyes; then
|
if test x$enable_debug != xyes; then
|
||||||
if test x$GCC = xyes; then
|
if test x$GCC = xyes; then
|
||||||
CFLAGS="-O3 $CFLAGS"
|
CFLAGS="$CFLAGS -O3"
|
||||||
CFLAGS="-fexpensive-optimizations $CFLAGS"
|
CFLAGS="$CFLAGS -fexpensive-optimizations"
|
||||||
fi
|
fi
|
||||||
CFLAGS="-DNDEBUG $CFLAGS"
|
CFLAGS="$CFLAGS -DNDEBUG"
|
||||||
else
|
else
|
||||||
if test x$GCC = xyes; then
|
if test x$GCC = xyes; then
|
||||||
CFLAGS="-g -pedantic -Wall $CFLAGS"
|
CFLAGS="$CFLAGS -g -pedantic -Wall"
|
||||||
fi
|
fi
|
||||||
CFLAGS="-DDEBUG $CFLAGS"
|
CFLAGS="$CFLAGS -DDEBUG"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
dnl Determine target directory for libburn-*.pc
|
|
||||||
dnl Important: Must be performed _after_ TARGET_SHIZZLE
|
|
||||||
dnl
|
|
||||||
LIBBURNIA_SET_PKGCONFIG
|
|
||||||
|
|
||||||
|
|
||||||
AC_CONFIG_FILES([
|
AC_CONFIG_FILES([
|
||||||
Makefile
|
Makefile
|
||||||
doc/doxygen.conf
|
doc/doxygen.conf
|
||||||
|
133
doc/comments
133
doc/comments
@ -1,50 +1,106 @@
|
|||||||
/**
|
/**
|
||||||
@author Mario Danic, Thomas Schmitt
|
@author Mario Danic, Thomas Schmitt
|
||||||
|
|
||||||
@mainpage Libburn Documentation Index
|
@mainpage Libburnia Documentation Index
|
||||||
|
|
||||||
@section intro Introduction
|
@section intro Introduction
|
||||||
|
|
||||||
Libburnia is an open-source project for reading, mastering and writing
|
Libburnia is an open-source project for reading, mastering and writing
|
||||||
optical discs. This page is about its capability to handle optical media.
|
optical discs.
|
||||||
For now this means CD-R, CD-RW, DVD-RAM, DVD+RW, DVD+R, DVD+R/DL, DVD-RW,
|
For now this means CD-R, CD-RW, DVD-RAM, DVD+RW, DVD+R, DVD+R/DL, DVD-RW,
|
||||||
DVD-R, DVD-R/DL, BD-R, BD-RE.
|
DVD-R, BD-RE.
|
||||||
|
|
||||||
Our scope is currently Linux 2.4 and 2.6, or FreeBSD, or Solaris . For ports
|
Not supported yet are DVD-R/DL, HD-DVD, BD-R (blue ray). Testers for
|
||||||
to other systems we would need : login on a development machine resp.
|
DVD-R/DL are wanted, though. BD-R programming efforts would be made
|
||||||
an OS ithat is installable on an AMD 64-bit PC, advise from a system person
|
if an interested tester contacts us.
|
||||||
about the equivalent of Linux sg or FreeBSD CAM, volunteers for testing of
|
|
||||||
realistic use cases.
|
|
||||||
|
|
||||||
libburn is the library by which preformatted data get onto optical media.
|
The project comprises of several more or less interdependent parts which
|
||||||
Its code is independent of cdrecord. Its DVD capabilities are learned from
|
together strive to be a usable foundation for application development.
|
||||||
studying the code of dvd+rw-tools and MMC-5 specs. No code but only the pure
|
These are libraries, language bindings, and middleware binaries which emulate
|
||||||
SCSI knowledge has been taken from dvd+rw-tools, though.
|
classical (and valuable) Linux tools.
|
||||||
|
|
||||||
cdrskin is a limited cdrecord compatibility wrapper for libburn.
|
Our scope is currently Linux 2.4 and 2.6 only. For ports to other systems
|
||||||
cdrecord is a powerful GPL'ed burn program included in Joerg Schilling's
|
we would need : login on a development machine resp. a live OS on CD or DVD,
|
||||||
cdrtools. cdrskin strives to be a second source for the services traditionally
|
advise from a system person about the equivalent of Linux sg or FreeBSD CAM,
|
||||||
provided by cdrecord. Additionally it provides libburn's DVD/BD capabilities,
|
volunteers for testing of realistic use cases.
|
||||||
where only -sao is compatible with cdrecord.
|
|
||||||
cdrskin does not contain any bytes copied from cdrecord's sources.
|
|
||||||
Many bytes have been copied from the message output of cdrecord runs, though.
|
|
||||||
See cdrskin/README for more.
|
|
||||||
|
|
||||||
The burn API example of libburn is named test/libburner.c . The API for media
|
We have a well tested code base for burning data and audio CDs and many DVD
|
||||||
information inquiry is demonstrated in test/telltoc.c .
|
types. The burn API is quite comprehensively documented and can be used to
|
||||||
Explore these examples if you look for inspiration.
|
build a presentable application.
|
||||||
|
We have a functional binary which emulates the core use cases of cdrecord in
|
||||||
|
order to prove that usability, and in order to allow you to explore libburn's
|
||||||
|
scope by help of existing cdrecord frontends.
|
||||||
|
|
||||||
SONAME:
|
ISO 9660 filesystems with Rock Ridge and Joliet extensions can be created
|
||||||
|
and manipulated quite freely. This capability together with our burn capability
|
||||||
|
makes possible a single binary application which covers all steps of image
|
||||||
|
composition, updating and writing. Quite unique in the Linux world.
|
||||||
|
|
||||||
|
@subsection components The project components (list subject to growth, hopefully):
|
||||||
|
|
||||||
|
- libburn is the library by which preformatted data get onto optical media.
|
||||||
|
It uses either /dev/sgN (e.g. on kernel 2.4 with ide-scsi) or
|
||||||
|
/dev/srM or /dev/hdX (e.g. on kernel 2.6).
|
||||||
|
libburn is the foundation of our cdrecord emulation. Its code is
|
||||||
|
independent of cdrecord. Its DVD capabilities are learned from
|
||||||
|
studying the code of dvd+rw-tools and MMC-5 specs. No code but only
|
||||||
|
the pure SCSI knowledge has been taken from dvd+rw-tools, though.
|
||||||
|
|
||||||
|
- libisofs is the library to pack up hard disk files and directories into a
|
||||||
|
ISO 9660 disk image. This may then be brought to CD via libburn.
|
||||||
|
libisofs is to be the foundation of our upcoming mkisofs emulation.
|
||||||
|
|
||||||
|
- libisoburn is an add-on to libburn and libisofs which coordinates both and
|
||||||
|
also allows to grow ISO-9660 filesystem images on multi-session
|
||||||
|
media as well as on overwriteable media via the same API.
|
||||||
|
All media peculiarities are handled automatically.
|
||||||
|
|
||||||
|
- cdrskin is a limited cdrecord compatibility wrapper for libburn.
|
||||||
|
cdrecord is a powerful GPL'ed burn program included in Joerg
|
||||||
|
Schilling's cdrtools. cdrskin strives to be a second source for
|
||||||
|
the services traditionally provided by cdrecord. Additionally it
|
||||||
|
provides libburn's DVD/BD capabilities, where only -sao is
|
||||||
|
compatible with cdrecord.
|
||||||
|
cdrskin does not contain any bytes copied from cdrecord's sources.
|
||||||
|
Many bytes have been copied from the message output of cdrecord
|
||||||
|
runs, though.
|
||||||
|
See cdrskin/README for more.
|
||||||
|
|
||||||
|
- xorriso is an application of all three libraries which creates, loads,
|
||||||
|
manipulates and writes ISO 9660 filesystem images with
|
||||||
|
Rock Ridge extensions. Manipulation is not only adding or
|
||||||
|
overwriting of files but also deletion, renaming, and attribute
|
||||||
|
changing. An incremental backup feature is provided.
|
||||||
|
See xorriso/README for more
|
||||||
|
|
||||||
|
- "test" is a collection of application gestures and examples given by the
|
||||||
|
authors of the library features. The burn API example of libburn
|
||||||
|
is named test/libburner.c . The API for media information inquiry is
|
||||||
|
demonstrated in test/telltoc.c .
|
||||||
|
Explore these examples if you look for inspiration.
|
||||||
|
|
||||||
|
We strive to be a responsive upstream.
|
||||||
|
|
||||||
|
Our libraries are committed to maintain older feature sets in newer versions.
|
||||||
|
This applies to source code headers (API) as well as to linkable objects (ABI).
|
||||||
|
The only exception from this rule is about non-release versions x.y.*[13579]
|
||||||
|
which are allowed to introduce new features, change those new features in
|
||||||
|
any way and even may revoke such new features before the next release of
|
||||||
|
x.y.*[02468]. As soon as it is released, a feature is promised to persist.
|
||||||
|
|
||||||
|
SONAMES:
|
||||||
libburn.so.4 (since 0.3.4, March 2007),
|
libburn.so.4 (since 0.3.4, March 2007),
|
||||||
|
libisofs.so.6 (since 0.6.2, February 2008),
|
||||||
|
libisoburn.so.1 (since 0.1.0, February 2008).
|
||||||
|
|
||||||
|
|
||||||
@section using Using libburn
|
@section using Using the libraries
|
||||||
|
|
||||||
Our build system is based on autotools.
|
Our build system is based on autotools.
|
||||||
User experience tells us that you will need at least autotools version 1.7.
|
User experience tells us that you will need at least autotools version 1.7.
|
||||||
|
|
||||||
To build libburn and its companion applications go into its toplevel directory
|
To build libburn and its subprojects it should be sufficient to go into
|
||||||
and execute
|
its toplevel directory and execute
|
||||||
|
|
||||||
- ./bootstrap (needed if you downloaded from SVN)
|
- ./bootstrap (needed if you downloaded from SVN)
|
||||||
|
|
||||||
@ -56,25 +112,30 @@ To make the libraries accessible for running resp. developing applications
|
|||||||
|
|
||||||
- make install
|
- make install
|
||||||
|
|
||||||
|
Both libraries are written in C language and get built by autotools.
|
||||||
|
Thus we expect them to be useable by a wide range of Linux-implemented
|
||||||
|
languages and development tools.
|
||||||
|
|
||||||
|
|
||||||
@section libburner Libburner
|
@section libburner Libburner
|
||||||
|
|
||||||
libburner is a minimal demo application for the library libburn
|
libburner is a minimal demo application for the library libburn
|
||||||
(see: libburn/libburn.h) as provided on http://libburnia-project.org .
|
(see: libburn/libburn.h) as provided on http://libburnia-project.org .
|
||||||
It can list the available devices, can burn to recordable CD, DVD, or BD,
|
It can list the available devices, can blank a CD-RW or DVD-RW and
|
||||||
can blank a CD-RW or DVD-RW, and can format unformatted DVD-RW, BD-R, or BD-RE.
|
can burn to recordable CD and recordable single layer DVD.
|
||||||
|
|
||||||
It's main purpose, nevertheless, is to show you how to use libburn and also
|
It's main purpose, nevertheless, is to show you how to use libburn and also
|
||||||
to serve the libburnia team as reference application. libburner does indeed
|
to serve the libburnia team as reference application. libburner does indeed
|
||||||
define the standard way how above gestures can be implemented and stay upward
|
define the standard way how above three gestures can be implemented and
|
||||||
compatible for a good while.
|
stay upward compatible for a good while.
|
||||||
|
|
||||||
@subsection libburner-help Libburner --help
|
@subsection libburner-help Libburner --help
|
||||||
<pre>
|
<pre>
|
||||||
Usage: test/libburner
|
Usage: test/libburner
|
||||||
[--drive address|driveno|"-"] [--audio]
|
[--drive <address>|<driveno>|"-"] [--audio]
|
||||||
[--blank_fast|--blank_full|--format] [--try_to_simulate]
|
[--blank_fast|--blank_full|--format_overwrite]
|
||||||
[--multi] [one or more imagefiles|"-"]
|
[--try_to_simulate]
|
||||||
|
[--multi] [<one or more imagefiles>|"-"]
|
||||||
Examples
|
Examples
|
||||||
A bus scan (needs rw-permissions to see a drive):
|
A bus scan (needs rw-permissions to see a drive):
|
||||||
test/libburner --drive -
|
test/libburner --drive -
|
||||||
@ -86,8 +147,8 @@ Blank a used CD-RW (is combinable with burning in one run):
|
|||||||
test/libburner --drive /dev/hdc --blank_fast
|
test/libburner --drive /dev/hdc --blank_fast
|
||||||
Blank a used DVD-RW (is combinable with burning in one run):
|
Blank a used DVD-RW (is combinable with burning in one run):
|
||||||
test/libburner --drive /dev/hdc --blank_full
|
test/libburner --drive /dev/hdc --blank_full
|
||||||
Format a DVD-RW, BD-RE or BD-R:
|
Format a DVD-RW to avoid need for blanking before re-use:
|
||||||
test/libburner --drive /dev/hdc --format
|
test/libburner --drive /dev/hdc --format_overwrite
|
||||||
Burn two audio tracks (to CD only):
|
Burn two audio tracks (to CD only):
|
||||||
lame --decode -t /path/to/track1.mp3 track1.cd
|
lame --decode -t /path/to/track1.mp3 track1.cd
|
||||||
test/dewav /path/to/track2.wav -o track2.cd
|
test/dewav /path/to/track2.wav -o track2.cd
|
||||||
|
174
doc/cookbook.txt
174
doc/cookbook.txt
@ -1,4 +1,4 @@
|
|||||||
libburnia-project.org Optical Media Rotisserie Recipes as of January 2010
|
libburnia-project.org Optical Media Rotisserie Recipes as of April 2008
|
||||||
|
|
||||||
Content:
|
Content:
|
||||||
- TAO Multi-Session CD Cookbook (CD-R, CD-RW)
|
- TAO Multi-Session CD Cookbook (CD-R, CD-RW)
|
||||||
@ -6,7 +6,6 @@ Content:
|
|||||||
- Overwriteable DVD Cookbook (DVD-RAM, DVD+RW, DVD-RW, BD-RE)
|
- Overwriteable DVD Cookbook (DVD-RAM, DVD+RW, DVD-RW, BD-RE)
|
||||||
- Sequential DVD-R[W] Cookbook
|
- Sequential DVD-R[W] Cookbook
|
||||||
- DVD+R[/DL] Cookbook
|
- DVD+R[/DL] Cookbook
|
||||||
- BD-R Cookbook
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
TAO Multi-Session CD Cookbook
|
TAO Multi-Session CD Cookbook
|
||||||
@ -86,7 +85,7 @@ parameters:
|
|||||||
BUFE Buffer Underrun protection 0=off, 1=on
|
BUFE Buffer Underrun protection 0=off, 1=on
|
||||||
Test Write -dummy mode for writing 0=off, 1=on
|
Test Write -dummy mode for writing 0=off, 1=on
|
||||||
Write Type Packet/TAO/SAO/RAW 01h = TAO
|
Write Type Packet/TAO/SAO/RAW 01h = TAO
|
||||||
Multi-session Whether to keep appendable 00b = finalize
|
Multi-session Wether to keep appendable 00b = finalize
|
||||||
11b = keep appendable
|
11b = keep appendable
|
||||||
Track Mode Describes frame type 4 for data , 0 for audio
|
Track Mode Describes frame type 4 for data , 0 for audio
|
||||||
Data Block Type Layout of payload blocks 8 for 2048 byte data blocks
|
Data Block Type Layout of payload blocks 8 for 2048 byte data blocks
|
||||||
@ -119,22 +118,19 @@ A track must at least contain 300 payload blocks: 4 seconds of audio or
|
|||||||
600 KiB of data.
|
600 KiB of data.
|
||||||
(mmc5r03c.pdf 6.3.3.1.2)
|
(mmc5r03c.pdf 6.3.3.1.2)
|
||||||
|
|
||||||
Up to december 2009 the track was closed by 5Bh CLOSE TRACK SESSION Close
|
The track has to be closed by 5Bh CLOSE TRACK SESSION Close Function 001b.
|
||||||
Function 001b. Older MMC specifies a valid Logical Track Number FFh to depict
|
Older MMC specifies a valid Logical Track Number FFh to depict the open track.
|
||||||
the open track. MMC-5 is quite silent about this. FFh worked for my drives.
|
MMC-5 is quite silent about this. FFh works for my drives.
|
||||||
(mmc5r03c.pdf 6.3.3.1.2)
|
(mmc5r03c.pdf 6.3.3.1.2)
|
||||||
This is omitted since libburn-0.7.4, relying entirely on 35h SYNCHRONIZE CACHE.
|
|
||||||
First appeared a drive where CLOSE TRACK fails in simulation mode, later
|
|
||||||
another one produced error replies even with real burning.
|
|
||||||
|
|
||||||
After that, a new track may be written beginning with sending the mode page 05h
|
After that, a new track may be written beginning with sending the mode page 05h
|
||||||
again. It is not tested whether 05h can be omitted if Track Mode and Data Block
|
again. It is not tested wether 05h can be omitted if Track Mode and Data Block
|
||||||
Type are the same as with the previous track.
|
Type are the same as with the previous track.
|
||||||
The new track will be added to the session which was opened by the first track.
|
The new track will be added to the session which was opened by the first track.
|
||||||
|
|
||||||
After the last track of a session, 5Bh CLOSE TRACK SESSION Close Function 010b
|
After the last track of a session, 5Bh CLOSE TRACK SESSION Close Function 010b
|
||||||
with Logical Track Number 0 closes the session. It depends on the Multi-Session
|
with Logical Track Number 0 closes the session. It depends on the Multi-Session
|
||||||
value in mode page 05h whether the disc is finalized or stays appendable.
|
value in mode page 05h wether the disc is finalized or stays appendable.
|
||||||
(mmc5r03c.pdf 6.3.3.1.3)
|
(mmc5r03c.pdf 6.3.3.1.3)
|
||||||
|
|
||||||
|
|
||||||
@ -205,7 +201,7 @@ for finalized disc.
|
|||||||
In libburn the address of the first track in the last session is obtained from
|
In libburn the address of the first track in the last session is obtained from
|
||||||
the last session's POINT = A0h and from the track descriptor with the POINT
|
the last session's POINT = A0h and from the track descriptor with the POINT
|
||||||
value matching the PMIN value of the A0h descriptor.
|
value matching the PMIN value of the A0h descriptor.
|
||||||
Untested is whether POINT = B0h and 52h READ TRACK INFORMATION are always in
|
Untested is wether POINT = B0h and 52h READ TRACK INFORMATION are always in
|
||||||
sync. libburn uses the info provided by 52h READ TRACK INFORMATION.
|
sync. libburn uses the info provided by 52h READ TRACK INFORMATION.
|
||||||
|
|
||||||
|
|
||||||
@ -311,7 +307,7 @@ A Write Parameters mode page 05h has to be composed and transmitted via
|
|||||||
BUFE Buffer Underrun protection 0=off, 1=on
|
BUFE Buffer Underrun protection 0=off, 1=on
|
||||||
Test Write -dummy mode for writing 0=off, 1=on
|
Test Write -dummy mode for writing 0=off, 1=on
|
||||||
Write Type Packet/TAO/SAO/RAW 02h = SAO
|
Write Type Packet/TAO/SAO/RAW 02h = SAO
|
||||||
Multi-session Whether to keep appendable 00b = finalize
|
Multi-session Wether to keep appendable 00b = finalize
|
||||||
11b = keep appendable
|
11b = keep appendable
|
||||||
Track Mode Describes frame type 0 (is ignored)
|
Track Mode Describes frame type 0 (is ignored)
|
||||||
Data Block Type Layout of payload blocks 0 (is ignored)
|
Data Block Type Layout of payload blocks 0 (is ignored)
|
||||||
@ -352,7 +348,7 @@ There is no separator between the tracks of a pure mode SAO session.
|
|||||||
(If the session was mixed mode, there would be extended Pre-gaps and Post-gaps
|
(If the session was mixed mode, there would be extended Pre-gaps and Post-gaps
|
||||||
between data mode tracks and audio mode tracks.)
|
between data mode tracks and audio mode tracks.)
|
||||||
(libburn sends its own buffer to the drive at the end of each track but does
|
(libburn sends its own buffer to the drive at the end of each track but does
|
||||||
not sync the drive's chache. It is unclear whether this separation of tracks
|
not sync the drive's chache. It is unclear wether this separation of tracks
|
||||||
on the level of 2Ah WRITE is necessary with a pure mode session. It does not
|
on the level of 2Ah WRITE is necessary with a pure mode session. It does not
|
||||||
harm in any case and would probably be unavoidable if audio and data tracks
|
harm in any case and would probably be unavoidable if audio and data tracks
|
||||||
were mixed.)
|
were mixed.)
|
||||||
@ -408,7 +404,7 @@ correctness of Pre-gap and Post-gap would become evident.
|
|||||||
Inspired by Andy Polyakov's http://fy.chalmers.se/~appro/linux/DVD+RW/tools ,
|
Inspired by Andy Polyakov's http://fy.chalmers.se/~appro/linux/DVD+RW/tools ,
|
||||||
backed by reading mmc5r03c.pdf from http://www.t10.org/ftp/t10/drafts/mmc5/
|
backed by reading mmc5r03c.pdf from http://www.t10.org/ftp/t10/drafts/mmc5/
|
||||||
by own experiments with drives NEC ND-4570A, LG GSA-4082B, PHILIPS SPD3300L,
|
by own experiments with drives NEC ND-4570A, LG GSA-4082B, PHILIPS SPD3300L,
|
||||||
LG GGW H20L, and by BD-RE experiments done by Giulio Orsero on LG BE06LU10.
|
and by BD-RE experiments done by Giulio Orsero on LG BE06LU10.
|
||||||
|
|
||||||
For libburnia-project.org by Thomas Schmitt <scdbackup@gmx.net>
|
For libburnia-project.org by Thomas Schmitt <scdbackup@gmx.net>
|
||||||
|
|
||||||
@ -701,14 +697,9 @@ managment. There is no way to increase payload capacity by format 01h.
|
|||||||
(mmc5r03c.pdf 6.5.4.2.2.1)
|
(mmc5r03c.pdf 6.5.4.2.2.1)
|
||||||
|
|
||||||
With BD-RE there are three format types : 00h, 30h and 31h.
|
With BD-RE there are three format types : 00h, 30h and 31h.
|
||||||
00h offers the default size format. This may be the only fast formatting
|
00h offers the default size format.
|
||||||
mode that is offered by the drive.
|
|
||||||
Feature 0023h tells whether format 31h and certain 30h subtypes are available.
|
|
||||||
(mmc5r03c.pdf 5.3.13)
|
|
||||||
30h offers several sizes with defect management. Usually there are three
|
30h offers several sizes with defect management. Usually there are three
|
||||||
sizes given: #1: default size, #2: maximum spare area, #3: minimal spare.
|
size to choose: #1: default size, #2: maximum spare area, #3: minimal spare.
|
||||||
One may demand any spare size between maximum and minimum. There may be quick
|
|
||||||
certification and full certification. See feature 0023h.
|
|
||||||
31h offers a single size and disables defect management. This has the side
|
31h offers a single size and disables defect management. This has the side
|
||||||
effect to speed up writing to nominal speed.
|
effect to speed up writing to nominal speed.
|
||||||
(mmc5r03c.pdf 6.5.4.2.15, 6.24.3.3, Table 472)
|
(mmc5r03c.pdf 6.5.4.2.15, 6.24.3.3, Table 472)
|
||||||
@ -747,7 +738,7 @@ DVD-RAM and BD-RE tuning :
|
|||||||
|
|
||||||
A special aspect of DVD-RAM and BD-RE is their low speed with write operations,
|
A special aspect of DVD-RAM and BD-RE is their low speed with write operations,
|
||||||
which usually is only half than the nominal speed of media and drive.
|
which usually is only half than the nominal speed of media and drive.
|
||||||
This is blamed to the automatic checkreading which happens for managing
|
This is blamed to the automatic checkreading which happens ifor managing
|
||||||
eventual defects.
|
eventual defects.
|
||||||
|
|
||||||
Defect management of BD-RE can be disabled by format type 31h. See above.
|
Defect management of BD-RE can be disabled by format type 31h. See above.
|
||||||
@ -758,8 +749,7 @@ The only known way to get full speed from DVD-RAM or BD-RE with enabled defect
|
|||||||
management is the use of AAh WRITE12 with Streaming Bit set to 1.
|
management is the use of AAh WRITE12 with Streaming Bit set to 1.
|
||||||
(mmc5r03c.pdf 6.45)
|
(mmc5r03c.pdf 6.45)
|
||||||
With some DVD-RAM drives this fails if a write buffer is not full 32 kB.
|
With some DVD-RAM drives this fails if a write buffer is not full 32 kB.
|
||||||
With the tested BD-RE one must write full 64 kB buffers, or else writing
|
With the tested BD-RE ione has to write write full 64 kB buffers.
|
||||||
might not get into effect at all.
|
|
||||||
|
|
||||||
Although it seems not optimal, this is specified not only to disable the
|
Although it seems not optimal, this is specified not only to disable the
|
||||||
cumbersome checkread but also to ignore known defects and to write data
|
cumbersome checkread but also to ignore known defects and to write data
|
||||||
@ -770,11 +760,10 @@ incorrectable errors.
|
|||||||
|
|
||||||
Caveat:
|
Caveat:
|
||||||
MMC-5 does not guarantee AAh WRITE12 to work on DVD-RAM or BD-RE at all.
|
MMC-5 does not guarantee AAh WRITE12 to work on DVD-RAM or BD-RE at all.
|
||||||
None of the features of profiles 0012h and 0043h promises the existence of
|
None of the features of profiles 0012h and 0043 promises the existence of
|
||||||
AAh WRITE12.
|
AAh WRITE12.
|
||||||
|
Nevertheless it worked on all tested drives is proper alignment was observed.
|
||||||
(mmc5r03c.pdf 5.4.13, 6.45)
|
(mmc5r03c.pdf 5.4.13, 6.45)
|
||||||
Nevertheless it worked on all tested drives if proper alignment and block
|
|
||||||
size was observed.
|
|
||||||
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
@ -801,9 +790,9 @@ The bytes 0 to 5 of a PVD block are
|
|||||||
0x01 'C' 'D' '0' '0' '1'
|
0x01 'C' 'D' '0' '0' '1'
|
||||||
The sector count can then be read from byte 80 to 83
|
The sector count can then be read from byte 80 to 83
|
||||||
sectors= pvd[80] | (pvd[81] << 8) | (pvd[82] << 16) | (pvd[83] << 24);
|
sectors= pvd[80] | (pvd[81] << 8) | (pvd[82] << 16) | (pvd[83] << 24);
|
||||||
(Ecma-119.pdf 8.4)
|
|
||||||
To support CD, DVD and BD media alike, it is advisable to round the NWA
|
To support CD, DVD and BD media alike, it is advisable to round the NWA
|
||||||
to the next multiple of 32 (= 64 KiB).
|
to the next multiple of 32 (= 64 KiB).
|
||||||
|
(Ecma-119.pdf 8.4)
|
||||||
|
|
||||||
So one can use 0 as MSC1 and prepare a new ISO session for the computed NWA.
|
So one can use 0 as MSC1 and prepare a new ISO session for the computed NWA.
|
||||||
After writing the session it is necessary to patch the PVD at LBA 16.
|
After writing the session it is necessary to patch the PVD at LBA 16.
|
||||||
@ -812,7 +801,7 @@ It is stored in both notations LSB and MSB:
|
|||||||
for(i= 0; i < 4; i++)
|
for(i= 0; i < 4; i++)
|
||||||
pvd[87 - i]= pvd[80 + i]= (sectors >> (8 * i)) & 0xff;
|
pvd[87 - i]= pvd[80 + i]= (sectors >> (8 * i)) & 0xff;
|
||||||
|
|
||||||
cdrskin --grow_overwriteable_iso not only patches the sector fields of the
|
cdrskin --grow_overwriteable not only patches the sector fields of the
|
||||||
PVD block but also the blocks up to LBA 31 which begin with
|
PVD block but also the blocks up to LBA 31 which begin with
|
||||||
0xff 'C' 'D' '0' '0' '1'
|
0xff 'C' 'D' '0' '0' '1'
|
||||||
libisoburn submits 64 KiB data buffer to libisofs before image generation and
|
libisoburn submits 64 KiB data buffer to libisofs before image generation and
|
||||||
@ -846,8 +835,6 @@ This chain gives the start addresses of sessions. The sector count minus start
|
|||||||
address gives the size of a particular session. ECMA-119 explains how to
|
address gives the size of a particular session. ECMA-119 explains how to
|
||||||
retrieve more info from the PVD (e.g. the volume id).
|
retrieve more info from the PVD (e.g. the volume id).
|
||||||
|
|
||||||
See also the multi-session example in libisofs/doc/checksums.txt.
|
|
||||||
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
|
|
||||||
@ -940,7 +927,7 @@ Multi-Session by the application.
|
|||||||
LS_V Link size valid 1=true
|
LS_V Link size valid 1=true
|
||||||
Test Write -dummy mode for writing 0=off, 1=on
|
Test Write -dummy mode for writing 0=off, 1=on
|
||||||
Write Type Packet/TAO/SAO/RAW 00h = Incremental (Packet)
|
Write Type Packet/TAO/SAO/RAW 00h = Incremental (Packet)
|
||||||
Multi-session Whether to keep appendable 00b = finalize
|
Multi-session Wether to keep appendable 00b = finalize
|
||||||
11b = keep appendable
|
11b = keep appendable
|
||||||
Track Mode Describes frame type 5 [*1]
|
Track Mode Describes frame type 5 [*1]
|
||||||
Data Block Type Layout of payload blocks 8 [*2]
|
Data Block Type Layout of payload blocks 8 [*2]
|
||||||
@ -987,7 +974,7 @@ from the reply of 51h READ DISC INFORMATION requesting Data Type 000b
|
|||||||
Multiple tracks are permissible in a single session. After all of them have
|
Multiple tracks are permissible in a single session. After all of them have
|
||||||
been written, 5Bh CLOSE TRACK SESSION Close Function 010b with Logical Track
|
been written, 5Bh CLOSE TRACK SESSION Close Function 010b with Logical Track
|
||||||
Number 0 closes the session. It depends on the Multi-Session value in mode
|
Number 0 closes the session. It depends on the Multi-Session value in mode
|
||||||
page 05h whether the disc is finalized or stays appendable.
|
page 05h wether the disc is finalized or stays appendable.
|
||||||
(mmc5r03c.pdf 6.3.3.2.3)
|
(mmc5r03c.pdf 6.3.3.2.3)
|
||||||
|
|
||||||
|
|
||||||
@ -1012,7 +999,7 @@ The mode page 05h to be sent :
|
|||||||
LS_V Link size valid 0=false [*3]
|
LS_V Link size valid 0=false [*3]
|
||||||
Test Write -dummy mode for writing 0=off, 1=on
|
Test Write -dummy mode for writing 0=off, 1=on
|
||||||
Write Type Packet/TAO/SAO/RAW 02h = DAO (same code as SAO)
|
Write Type Packet/TAO/SAO/RAW 02h = DAO (same code as SAO)
|
||||||
Multi-session Whether to keep appendable 00b = finalize
|
Multi-session Wether to keep appendable 00b = finalize
|
||||||
Track Mode Describes frame type 5 [*1]
|
Track Mode Describes frame type 5 [*1]
|
||||||
Data Block Type Layout of payload blocks 8 [*2]
|
Data Block Type Layout of payload blocks 8 [*2]
|
||||||
Link Size ??? 0 [*3]
|
Link Size ??? 0 [*3]
|
||||||
@ -1229,7 +1216,7 @@ No mode page 05h is to be sent.
|
|||||||
growisofs sends a page but the specs clearly state that one shall not do.
|
growisofs sends a page but the specs clearly state that one shall not do.
|
||||||
(mmc5r03c.pdf 7.5.3)
|
(mmc5r03c.pdf 7.5.3)
|
||||||
|
|
||||||
It is optional whether a track size is reserved in advance or not. Eventually
|
It is optional wether a track size is reserved in advance or not. Eventually
|
||||||
this is done by 53h RESERVE TRACK, RMZ=ARSV=0. Reservation size should better
|
this is done by 53h RESERVE TRACK, RMZ=ARSV=0. Reservation size should better
|
||||||
already be aligned to 32 KiB.
|
already be aligned to 32 KiB.
|
||||||
(mmc5r03c.pdf 6.31)
|
(mmc5r03c.pdf 6.31)
|
||||||
@ -1286,118 +1273,3 @@ in http://libburnia-project.org/ticket/13 .
|
|||||||
|
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
BD-R Cookbook
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
Inspired by reading mmc5r03c.pdf from http://www.t10.org/ftp/t10/drafts/mmc5/
|
|
||||||
backed by experiments iwith drive LG GGW H20L.
|
|
||||||
|
|
||||||
For libburnia-project.org by Thomas Schmitt <scdbackup@gmx.net>
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
Media type can be recognized by Current Profile from 46h GET CONFIGURATION.
|
|
||||||
(mmc5r03c.pdf 6.6.2.1)
|
|
||||||
BD-R 0042h
|
|
||||||
|
|
||||||
There are two basic recording modes defined: Sequential Recording Mode SRM and
|
|
||||||
Random Recording Mode RRM. The latter is optional and for now not topic of this
|
|
||||||
text.
|
|
||||||
(mmc5r03c.pdf 4.5.3.5)
|
|
||||||
|
|
||||||
|
|
||||||
- SRM Formatting
|
|
||||||
- Writing a session in SRM-POW
|
|
||||||
(- Pseudo-OverWrite SRM+POW)
|
|
||||||
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
SRM Formatting:
|
|
||||||
|
|
||||||
Despite being write-once media BD-R can optionally carry some formatting.
|
|
||||||
|
|
||||||
SRM has a disc structure model with tracks and sessions.
|
|
||||||
Several tracks may be open at the same time, each having its own NWA.
|
|
||||||
(mmc5r03c.pdf 4.5.3.5.2.2)
|
|
||||||
This structure is formatted onto blank media automatically as soon as the
|
|
||||||
first serious write attempt occurs.
|
|
||||||
(mmc5r03c.pdf 4.5.3.5)
|
|
||||||
Before such a write attempt, blank media may be explicitely formatted with
|
|
||||||
spares, which provide defect management.
|
|
||||||
(mmc5r03c.pdf 4.5.3.5.3)
|
|
||||||
Tracks get created from other tracks via RESERVE TRACK splitting.
|
|
||||||
(mmc5r03c.pdf 4.5.3.5.2.5)
|
|
||||||
|
|
||||||
On top of defect management there may be Pseudo-OverWrite SRM+POW, a costly
|
|
||||||
way to write several times to the same LBA. See below.
|
|
||||||
Fully sequential states are called SRM-POW.
|
|
||||||
(mmc5r03c.pdf 4.5.3.5.4)
|
|
||||||
|
|
||||||
Explicite formatting is done by 04h FORMAT UNIT. Its data payload consists
|
|
||||||
of a Format List Header and a Format Descriptor. It is advisable to set
|
|
||||||
the Immed bit and the FOV bit in header byte number 1. The descriptor should
|
|
||||||
be a copy of a descriptor from 23h READ FORMAT CAPACITIES but the size may be
|
|
||||||
adjusted within a certain range.
|
|
||||||
(mmc5r03c.pdf 6.5, 6.5.3.2, 6.5.3.3)
|
|
||||||
|
|
||||||
Format type 00h creates SRM layouts with a default number of spares (or
|
|
||||||
eventually RRM) chosen by the format sub-type:
|
|
||||||
00b = SRM with support for POW
|
|
||||||
01b = SRM without POW (but with some spares for defect management)
|
|
||||||
10b = (RRM)
|
|
||||||
(mmc5r03c.pdf 6.5.4.2.1.6)
|
|
||||||
|
|
||||||
Format type 32h uses the same sub-types but allows to allocate non-default
|
|
||||||
amounts of spares. Similar to BD-RE format 31h, three format descriptors are
|
|
||||||
offered: #1: default size, #2: maximum spare area, #3: minimal spare.
|
|
||||||
The size may be chosen within that range.
|
|
||||||
|
|
||||||
The sense behind the Type Dependent Parameters is obscure
|
|
||||||
to me. Best will be to set ISA_V and TDMA_V to 0.
|
|
||||||
(mmc5r03c.pdf 6.5.4.2.1.17)
|
|
||||||
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
Writing a session in SRM:
|
|
||||||
|
|
||||||
The procedure and constraints for writing BD-R SRM-POW are very similar to
|
|
||||||
DVD+R. libburn flatly re-uses its DVD+R code except the Close Function for
|
|
||||||
finalizing a disc.
|
|
||||||
|
|
||||||
In short:
|
|
||||||
If all written sessions are closed, then there is exactly one NWA.
|
|
||||||
In the beginning there is an empty session and track. A new track can be
|
|
||||||
written either with pre-announced size (by RESERVE TRACK) or open-end by
|
|
||||||
simply starting to write to the NWA. When done the track gets closed by
|
|
||||||
close function 001b. Then either session or disc gets closed depending on
|
|
||||||
the Close Function used:
|
|
||||||
- Close Function 010b closes the session and keeps the media appendable
|
|
||||||
(same as with DVD+R)
|
|
||||||
- Close Function 110b finalizes the media and makes it read-only.
|
|
||||||
(differs from libburn DVD+R procedure which uses 101b)
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
Pseudo-OverWrite POW: (no used yet by libburn)
|
|
||||||
|
|
||||||
This enhancement of SRM emulates overwriting of existing data blocks.
|
|
||||||
(mmc5r03c.pdf 4.5.3.5.4)
|
|
||||||
|
|
||||||
POW establishes a virtual vLBA space on top of the real address space rLBA.
|
|
||||||
All read and write commands deal with vLBA. It seems that track NWAs are
|
|
||||||
assumed to be identical in vLBA space and in rLBA space.
|
|
||||||
It is not clear whether one may write to vLBA blocks which are neither written
|
|
||||||
yet nor at one of the track NWAs. Probably not, or else one could make NWAs run
|
|
||||||
into vLBAs which are associated with older rLBAs.
|
|
||||||
|
|
||||||
Replacing invalidated blocks consumes addresses in rLBA space at the NWA of
|
|
||||||
some track. I.e. no spares are consumed by POW. Nevertheless it is costly by
|
|
||||||
a special map called Orphanage. It covers rLBA which have been consumed
|
|
||||||
by differing vLBAs. It never shrinks and can grow with each write to remapped
|
|
||||||
addresses.
|
|
||||||
To avoid heavy Orphanage growth it is advised to write mostly to vLBA which
|
|
||||||
still coincide with their rLBA. E.g. those addresses which have neither been
|
|
||||||
written as rLBA nor as vLBA yet. So one should begin the vLBA of new sessions
|
|
||||||
at the NWA of a sufficiently sized track.
|
|
||||||
(mmc5r03c.pdf 4.5.3.5.4.2 , 4.5.3.6.9)
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
|
@ -154,6 +154,13 @@ 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.
|
||||||
|
1198
doc/mediainfo.txt
1198
doc/mediainfo.txt
File diff suppressed because it is too large
Load Diff
239
libburn/async.c
239
libburn/async.c
@ -1,9 +1,5 @@
|
|||||||
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||||
|
|
||||||
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
|
|
||||||
Copyright (c) 2006 - 2010 Thomas Schmitt <scdbackup@gmx.net>
|
|
||||||
Provided under GPL version 2 or later.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* ts A71019 */
|
/* ts A71019 */
|
||||||
|
|
||||||
@ -23,9 +19,6 @@
|
|||||||
#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"
|
||||||
@ -43,7 +36,6 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <signal.h>
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
#include <a ssert.h>
|
#include <a ssert.h>
|
||||||
@ -143,7 +135,7 @@ static void add_worker(int w_type, struct burn_drive *d,
|
|||||||
pthread_attr_t attr;
|
pthread_attr_t attr;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
a = calloc(1, sizeof(struct w_list));
|
a = malloc(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;
|
||||||
@ -236,22 +228,6 @@ static void *scan_worker_func(struct w_list *w)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void reset_progress(struct burn_drive *d, int sessions, int tracks,
|
|
||||||
int indices, int sectors, int flag)
|
|
||||||
{
|
|
||||||
/* reset the progress indicator */
|
|
||||||
d->progress.session = 0;
|
|
||||||
d->progress.sessions = sessions;
|
|
||||||
d->progress.track = 0;
|
|
||||||
d->progress.tracks = tracks;
|
|
||||||
d->progress.index = 0;
|
|
||||||
d->progress.indices = indices;
|
|
||||||
d->progress.start_sector = 0;
|
|
||||||
d->progress.sectors = sectors;
|
|
||||||
d->progress.sector = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int burn_drive_scan(struct burn_drive_info *drives[], unsigned int *n_drives)
|
int burn_drive_scan(struct burn_drive_info *drives[], unsigned int *n_drives)
|
||||||
{
|
{
|
||||||
struct scan_opts o;
|
struct scan_opts o;
|
||||||
@ -321,27 +297,8 @@ drive_is_active:;
|
|||||||
|
|
||||||
static void *erase_worker_func(struct w_list *w)
|
static void *erase_worker_func(struct w_list *w)
|
||||||
{
|
{
|
||||||
|
|
||||||
#define Libburn_protect_erase_threaD 1
|
|
||||||
|
|
||||||
#ifdef Libburn_protect_erase_threaD
|
|
||||||
sigset_t sigset, oldset;
|
|
||||||
|
|
||||||
/* Protect blank thread from being interrupted by external signals */
|
|
||||||
sigfillset(&sigset);
|
|
||||||
sigdelset(&sigset, SIGSEGV);
|
|
||||||
sigdelset(&sigset, SIGILL);
|
|
||||||
pthread_sigmask(SIG_SETMASK, &sigset, &oldset);
|
|
||||||
#endif /* Libburn_protect_erase_threaD */
|
|
||||||
|
|
||||||
burn_disc_erase_sync(w->u.erase.drive, w->u.erase.fast);
|
burn_disc_erase_sync(w->u.erase.drive, w->u.erase.fast);
|
||||||
remove_worker(pthread_self());
|
remove_worker(pthread_self());
|
||||||
|
|
||||||
#ifdef Libburn_protect_erase_threaD
|
|
||||||
/* (just in case it would not end with all signals blocked) */
|
|
||||||
pthread_sigmask(SIG_SETMASK, &oldset, NULL);
|
|
||||||
#endif /* Libburn_protect_erase_threaD */
|
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -353,7 +310,6 @@ void burn_disc_erase(struct burn_drive *drive, int fast)
|
|||||||
/* a ssert(drive); */
|
/* a ssert(drive); */
|
||||||
/* a ssert(!SCAN_GOING()); */
|
/* a ssert(!SCAN_GOING()); */
|
||||||
/* a ssert(!find_worker(drive)); */
|
/* a ssert(!find_worker(drive)); */
|
||||||
|
|
||||||
if((drive == NULL)) {
|
if((drive == NULL)) {
|
||||||
libdax_msgs_submit(libdax_messenger, drive->global_index,
|
libdax_msgs_submit(libdax_messenger, drive->global_index,
|
||||||
0x00020104,
|
0x00020104,
|
||||||
@ -369,9 +325,6 @@ void burn_disc_erase(struct burn_drive *drive, int fast)
|
|||||||
0, 0);
|
0, 0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
reset_progress(drive, 1, 1, 1, 0x10000, 0);
|
|
||||||
|
|
||||||
/* A70103 : will be set to 0 by burn_disc_erase_sync() */
|
/* A70103 : will be set to 0 by burn_disc_erase_sync() */
|
||||||
drive->cancel = 1;
|
drive->cancel = 1;
|
||||||
|
|
||||||
@ -412,28 +365,9 @@ void burn_disc_erase(struct burn_drive *drive, int fast)
|
|||||||
/* ts A61230 */
|
/* ts A61230 */
|
||||||
static void *format_worker_func(struct w_list *w)
|
static void *format_worker_func(struct w_list *w)
|
||||||
{
|
{
|
||||||
|
|
||||||
#define Libburn_protect_format_threaD 1
|
|
||||||
|
|
||||||
#ifdef Libburn_protect_format_threaD
|
|
||||||
sigset_t sigset, oldset;
|
|
||||||
|
|
||||||
/* Protect format thread from being interrupted by external signals */
|
|
||||||
sigfillset(&sigset);
|
|
||||||
sigdelset(&sigset, SIGSEGV);
|
|
||||||
sigdelset(&sigset, SIGILL);
|
|
||||||
pthread_sigmask(SIG_SETMASK, &sigset, &oldset);
|
|
||||||
#endif /* Libburn_protect_format_threaD */
|
|
||||||
|
|
||||||
burn_disc_format_sync(w->u.format.drive, w->u.format.size,
|
burn_disc_format_sync(w->u.format.drive, w->u.format.size,
|
||||||
w->u.format.flag);
|
w->u.format.flag);
|
||||||
remove_worker(pthread_self());
|
remove_worker(pthread_self());
|
||||||
|
|
||||||
#ifdef Libburn_protect_format_threaD
|
|
||||||
/* (just in case it would not end with all signals blocked) */
|
|
||||||
pthread_sigmask(SIG_SETMASK, &oldset, NULL);
|
|
||||||
#endif /* Libburn_protect_format_threaD */
|
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -442,11 +376,9 @@ static void *format_worker_func(struct w_list *w)
|
|||||||
void burn_disc_format(struct burn_drive *drive, off_t size, int flag)
|
void burn_disc_format(struct burn_drive *drive, off_t size, int flag)
|
||||||
{
|
{
|
||||||
struct format_opts o;
|
struct format_opts o;
|
||||||
int ok = 0, ret;
|
int ok = 0;
|
||||||
char msg[160];
|
char msg[160];
|
||||||
|
|
||||||
reset_progress(drive, 1, 1, 1, 0x10000, 0);
|
|
||||||
|
|
||||||
if ((SCAN_GOING()) || find_worker(drive) != NULL) {
|
if ((SCAN_GOING()) || find_worker(drive) != NULL) {
|
||||||
libdax_msgs_submit(libdax_messenger, drive->global_index,
|
libdax_msgs_submit(libdax_messenger, drive->global_index,
|
||||||
0x00020102,
|
0x00020102,
|
||||||
@ -477,82 +409,8 @@ void burn_disc_format(struct burn_drive *drive, off_t size, int flag)
|
|||||||
flag |= 4; /* format up to maximum size */
|
flag |= 4; /* format up to maximum size */
|
||||||
} else if (drive->current_profile == 0x12) {
|
} else if (drive->current_profile == 0x12) {
|
||||||
ok = 1; /* DVD-RAM */
|
ok = 1; /* DVD-RAM */
|
||||||
|
|
||||||
} else if (drive->current_profile == 0x41) {
|
|
||||||
/* BD-R SRM */
|
|
||||||
ok= 1;
|
|
||||||
ret = drive->read_format_capacities(drive, 0x00);
|
|
||||||
if (ret > 0 &&
|
|
||||||
drive->format_descr_type == BURN_FORMAT_IS_FORMATTED)
|
|
||||||
ok = 0;
|
|
||||||
if (drive->status != BURN_DISC_BLANK)
|
|
||||||
ok = 0;
|
|
||||||
if (!ok) {
|
|
||||||
libdax_msgs_submit(libdax_messenger,
|
|
||||||
drive->global_index, 0x00020162,
|
|
||||||
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
|
|
||||||
"BD-R not unformatted blank any more. Cannot format.",
|
|
||||||
0, 0);
|
|
||||||
drive->cancel = 1;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (flag & 32) {
|
|
||||||
libdax_msgs_submit(libdax_messenger,
|
|
||||||
drive->global_index, 0x00020163,
|
|
||||||
LIBDAX_MSGS_SEV_NOTE, LIBDAX_MSGS_PRIO_HIGH,
|
|
||||||
"Blank BD-R left unformatted for zero spare capacity.",
|
|
||||||
0, 0);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} else if (drive->current_profile == 0x43) {
|
} else if (drive->current_profile == 0x43) {
|
||||||
ok = 1; /* BD-RE */
|
ok = 1; /* BD-RE */
|
||||||
|
|
||||||
if ((flag & 32) && !(drive->current_feat23h_byte4 & 8)) {
|
|
||||||
libdax_msgs_submit(libdax_messenger,
|
|
||||||
drive->global_index, 0x00020164,
|
|
||||||
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
|
|
||||||
"Drive does not format BD-RE without spares.",
|
|
||||||
0, 0);
|
|
||||||
drive->cancel = 1;
|
|
||||||
return;
|
|
||||||
|
|
||||||
}
|
|
||||||
if ((flag & 6) != 6 || (flag & 128)) {
|
|
||||||
if ((flag & 64) && !(drive->current_feat23h_byte4 & 2)) {
|
|
||||||
if (drive->current_feat23h_byte4 & 1) {
|
|
||||||
libdax_msgs_submit(libdax_messenger,
|
|
||||||
drive->global_index, 0x00020165,
|
|
||||||
LIBDAX_MSGS_SEV_WARNING,
|
|
||||||
LIBDAX_MSGS_PRIO_HIGH,
|
|
||||||
"Drive does not support fast formatting",
|
|
||||||
0, 0);
|
|
||||||
flag &= ~64;
|
|
||||||
} else {
|
|
||||||
no_non_default_bd_re:;
|
|
||||||
libdax_msgs_submit(libdax_messenger,
|
|
||||||
drive->global_index, 0x00020167,
|
|
||||||
LIBDAX_MSGS_SEV_SORRY,
|
|
||||||
LIBDAX_MSGS_PRIO_HIGH,
|
|
||||||
"Drive does not support non-default formatting",
|
|
||||||
0, 0);
|
|
||||||
drive->cancel = 1;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ((!(flag & 64)) && !(drive->current_feat23h_byte4 & 1)){
|
|
||||||
if (drive->current_feat23h_byte4 & 2) {
|
|
||||||
libdax_msgs_submit(libdax_messenger,
|
|
||||||
drive->global_index, 0x00020166,
|
|
||||||
LIBDAX_MSGS_SEV_WARNING,
|
|
||||||
LIBDAX_MSGS_PRIO_HIGH,
|
|
||||||
"Drive does not support full formatting",
|
|
||||||
0, 0);
|
|
||||||
flag |= 64;
|
|
||||||
} else
|
|
||||||
goto no_non_default_bd_re;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ok) {
|
if (!ok) {
|
||||||
@ -576,22 +434,8 @@ no_non_default_bd_re:;
|
|||||||
static void *write_disc_worker_func(struct w_list *w)
|
static void *write_disc_worker_func(struct w_list *w)
|
||||||
{
|
{
|
||||||
struct burn_drive *d = w->u.write.drive;
|
struct burn_drive *d = w->u.write.drive;
|
||||||
char msg[80];
|
|
||||||
|
|
||||||
#define Libburn_protect_write_threaD 1
|
|
||||||
|
|
||||||
#ifdef Libburn_protect_write_threaD
|
|
||||||
sigset_t sigset, oldset;
|
|
||||||
|
|
||||||
/* Protect write thread from being interrupted by external signals */
|
|
||||||
sigfillset(&sigset);
|
|
||||||
sigdelset(&sigset, SIGSEGV);
|
|
||||||
sigdelset(&sigset, SIGILL);
|
|
||||||
pthread_sigmask(SIG_SETMASK, &sigset, &oldset);
|
|
||||||
#endif /* Libburn_protect_write_threaD */
|
|
||||||
|
|
||||||
d->thread_pid = getpid();
|
d->thread_pid = getpid();
|
||||||
d->thread_tid = pthread_self();
|
|
||||||
d->thread_pid_valid= 1;
|
d->thread_pid_valid= 1;
|
||||||
burn_disc_write_sync(w->u.write.opts, w->u.write.disc);
|
burn_disc_write_sync(w->u.write.opts, w->u.write.disc);
|
||||||
d->thread_pid_valid= 0;
|
d->thread_pid_valid= 0;
|
||||||
@ -601,19 +445,7 @@ static void *write_disc_worker_func(struct w_list *w)
|
|||||||
*/
|
*/
|
||||||
burn_write_opts_free(w->u.write.opts);
|
burn_write_opts_free(w->u.write.opts);
|
||||||
|
|
||||||
sprintf(msg, "Write thread on drive %d ended", d->global_index);
|
|
||||||
libdax_msgs_submit(libdax_messenger, d->global_index, 0x00020178,
|
|
||||||
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH,
|
|
||||||
msg, 0, 0);
|
|
||||||
|
|
||||||
remove_worker(pthread_self());
|
remove_worker(pthread_self());
|
||||||
d->busy = BURN_DRIVE_IDLE;
|
|
||||||
|
|
||||||
#ifdef Libburn_protect_write_threaD
|
|
||||||
/* (just in case it would not end with all signals blocked) */
|
|
||||||
pthread_sigmask(SIG_SETMASK, &oldset, NULL);
|
|
||||||
#endif /* Libburn_protect_write_threaD */
|
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -621,15 +453,12 @@ void burn_disc_write(struct burn_write_opts *opts, struct burn_disc *disc)
|
|||||||
{
|
{
|
||||||
struct write_opts o;
|
struct write_opts o;
|
||||||
char reasons[BURN_REASONS_LEN+80];
|
char reasons[BURN_REASONS_LEN+80];
|
||||||
struct burn_drive *d;
|
|
||||||
|
|
||||||
d = opts->drive;
|
|
||||||
|
|
||||||
/* ts A61006 */
|
/* ts A61006 */
|
||||||
/* a ssert(!SCAN_GOING()); */
|
/* a ssert(!SCAN_GOING()); */
|
||||||
/* a ssert(!find_worker(opts->drive)); */
|
/* a ssert(!find_worker(opts->drive)); */
|
||||||
if ((SCAN_GOING()) || find_worker(opts->drive) != NULL) {
|
if ((SCAN_GOING()) || find_worker(opts->drive) != NULL) {
|
||||||
libdax_msgs_submit(libdax_messenger, d->global_index,
|
libdax_msgs_submit(libdax_messenger, opts->drive->global_index,
|
||||||
0x00020102,
|
0x00020102,
|
||||||
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
|
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
"A drive operation is still going on (want to write)",
|
"A drive operation is still going on (want to write)",
|
||||||
@ -637,23 +466,15 @@ void burn_disc_write(struct burn_write_opts *opts, struct burn_disc *disc)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
reset_progress(d, disc->sessions, disc->session[0]->tracks,
|
|
||||||
disc->session[0]->track[0]->indices, 0, 0);
|
|
||||||
|
|
||||||
/* For the next lines any return indicates failure */
|
/* For the next lines any return indicates failure */
|
||||||
d->cancel = 1;
|
opts->drive->cancel = 1;
|
||||||
|
|
||||||
/* ts A70203 : people have been warned in API specs */
|
/* ts A70203 : people have been warned in API specs */
|
||||||
if (opts->write_type == BURN_WRITE_NONE) {
|
if (opts->write_type == BURN_WRITE_NONE)
|
||||||
libdax_msgs_submit(libdax_messenger, d->global_index,
|
|
||||||
0x0002017c,
|
|
||||||
LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH,
|
|
||||||
"No valid write type selected", 0, 0);
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
if (d->drive_role == 0) {
|
if (opts->drive->drive_role == 0) {
|
||||||
libdax_msgs_submit(libdax_messenger, d->global_index,
|
libdax_msgs_submit(libdax_messenger, opts->drive->global_index,
|
||||||
0x00020146,
|
0x00020146,
|
||||||
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
|
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
"Drive is a virtual placeholder (null-drive)", 0, 0);
|
"Drive is a virtual placeholder (null-drive)", 0, 0);
|
||||||
@ -661,9 +482,9 @@ void burn_disc_write(struct burn_write_opts *opts, struct burn_disc *disc)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* ts A61007 : obsolete Assert in spc_select_write_params() */
|
/* ts A61007 : obsolete Assert in spc_select_write_params() */
|
||||||
if (d->drive_role == 1 && d->mdata->valid <= 0) {
|
if (opts->drive->drive_role == 1 && !opts->drive->mdata->valid) {
|
||||||
libdax_msgs_submit(libdax_messenger,
|
libdax_msgs_submit(libdax_messenger,
|
||||||
d->global_index, 0x00020113,
|
opts->drive->global_index, 0x00020113,
|
||||||
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
|
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
"Drive capabilities not inquired yet", 0, 0);
|
"Drive capabilities not inquired yet", 0, 0);
|
||||||
return;
|
return;
|
||||||
@ -676,33 +497,21 @@ void burn_disc_write(struct burn_write_opts *opts, struct burn_disc *disc)
|
|||||||
if (burn_precheck_write(opts, disc, reasons + strlen(reasons), 1)
|
if (burn_precheck_write(opts, disc, reasons + strlen(reasons), 1)
|
||||||
<= 0) {
|
<= 0) {
|
||||||
libdax_msgs_submit(libdax_messenger,
|
libdax_msgs_submit(libdax_messenger,
|
||||||
d->global_index, 0x00020139,
|
opts->drive->global_index, 0x00020139,
|
||||||
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
|
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
reasons, 0, 0);
|
reasons, 0, 0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ts A90106 : early catching of unformatted BD-RE */
|
opts->drive->cancel = 0; /* End of the return = failure area */
|
||||||
if (d->current_profile == 0x43)
|
|
||||||
if (d->read_format_capacities(d, 0x00) > 0 &&
|
|
||||||
d->format_descr_type != BURN_FORMAT_IS_FORMATTED) {
|
|
||||||
libdax_msgs_submit(libdax_messenger,
|
|
||||||
d->global_index, 0x00020168,
|
|
||||||
LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH,
|
|
||||||
"Media not properly formatted. Cannot write.",
|
|
||||||
0, 0);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
d->cancel = 0; /* End of the return = failure area */
|
o.drive = opts->drive;
|
||||||
|
|
||||||
o.drive = d;
|
|
||||||
o.opts = opts;
|
o.opts = opts;
|
||||||
o.disc = disc;
|
o.disc = disc;
|
||||||
|
|
||||||
opts->refcount++;
|
opts->refcount++;
|
||||||
|
|
||||||
add_worker(Burnworker_type_writE, d,
|
add_worker(Burnworker_type_writE, opts->drive,
|
||||||
(WorkerFunc) write_disc_worker_func, &o);
|
(WorkerFunc) write_disc_worker_func, &o);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -711,30 +520,12 @@ static void *fifo_worker_func(struct w_list *w)
|
|||||||
{
|
{
|
||||||
int old;
|
int old;
|
||||||
|
|
||||||
#define Libburn_protect_fifo_threaD 1
|
|
||||||
|
|
||||||
#ifdef Libburn_protect_fifo_threaD
|
|
||||||
sigset_t sigset, oldset;
|
|
||||||
|
|
||||||
/* Protect fifo thread from being interrupted by external signals */
|
|
||||||
sigfillset(&sigset);
|
|
||||||
sigdelset(&sigset, SIGSEGV);
|
|
||||||
sigdelset(&sigset, SIGILL);
|
|
||||||
pthread_sigmask(SIG_SETMASK, &sigset, &oldset);
|
|
||||||
#endif /* Libburn_protect_fifo_threaD */
|
|
||||||
|
|
||||||
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &old);
|
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &old);
|
||||||
pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &old);
|
pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &old);
|
||||||
/* Note: Only burn_fifo_abort() shall cancel the fifo thread */
|
/* Note: Only burn_fifo_abort() shall cancel the fifo thread */
|
||||||
|
|
||||||
burn_fifo_source_shoveller(w->u.fifo.source, w->u.fifo.flag);
|
burn_fifo_source_shoveller(w->u.fifo.source, w->u.fifo.flag);
|
||||||
remove_worker(pthread_self());
|
remove_worker(pthread_self());
|
||||||
|
|
||||||
#ifdef Libburn_protect_fifo_threaD
|
|
||||||
/* (just in case it would not end with all signals blocked) */
|
|
||||||
pthread_sigmask(SIG_SETMASK, &oldset, NULL);
|
|
||||||
#endif /* Libburn_protect_fifo_threaD */
|
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -747,8 +538,7 @@ int burn_fifo_start(struct burn_source *source, int flag)
|
|||||||
fs->is_started = -1;
|
fs->is_started = -1;
|
||||||
|
|
||||||
/* create and set up ring buffer */;
|
/* create and set up ring buffer */;
|
||||||
fs->buf = burn_os_alloc_buffer(
|
fs->buf = calloc(fs->chunksize, fs->chunks);
|
||||||
((size_t) fs->chunksize) * (size_t) fs->chunks, 0);
|
|
||||||
if (fs->buf == NULL) {
|
if (fs->buf == NULL) {
|
||||||
/* >>> could not start ring buffer */;
|
/* >>> could not start ring buffer */;
|
||||||
return -1;
|
return -1;
|
||||||
@ -759,7 +549,6 @@ int burn_fifo_start(struct burn_source *source, int flag)
|
|||||||
add_worker(Burnworker_type_fifO, NULL,
|
add_worker(Burnworker_type_fifO, NULL,
|
||||||
(WorkerFunc) fifo_worker_func, &o);
|
(WorkerFunc) fifo_worker_func, &o);
|
||||||
fs->is_started = 1;
|
fs->is_started = 1;
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,4 @@
|
|||||||
/**
|
/**
|
||||||
Copyright (c) 2006 Thomas Schmitt <scdbackup@gmx.net>
|
|
||||||
Provided under GPL version 2 or later.
|
|
||||||
|
|
||||||
This file bundles variables which disable changes in libburn which are
|
This file bundles variables which disable changes in libburn which are
|
||||||
not yet completely accepted.
|
not yet completely accepted.
|
||||||
|
@ -3,17 +3,13 @@
|
|||||||
|
|
||||||
A signal handler which cleans up an application and exits.
|
A signal handler which cleans up an application and exits.
|
||||||
|
|
||||||
Provided under GPLv2+ license within GPL projects, BSD license elsewise.
|
Provided under GPL license within GPL projects, BSD license elsewise.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
cc -g -o cleanup -DCleanup_standalonE cleanup.c
|
cc -g -o cleanup -DCleanup_standalonE cleanup.c
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
#include "../config.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
@ -44,8 +40,7 @@ static int non_signal_list_count= BURN_OS_NON_SIGNAL_COUNT;
|
|||||||
#else /* ! Cleanup_has_no_libburn_os_H */
|
#else /* ! Cleanup_has_no_libburn_os_H */
|
||||||
|
|
||||||
|
|
||||||
/* Outdated. GNU/Linux only.
|
/* Outdated. Linux only. For backward compatibility with pre-libburn-0.2.3 */
|
||||||
For backward compatibility with pre-libburn-0.2.3 */
|
|
||||||
|
|
||||||
/* Signals to be caught */
|
/* Signals to be caught */
|
||||||
static int signal_list[]= {
|
static int signal_list[]= {
|
||||||
@ -102,8 +97,8 @@ static int Cleanup_handler_exit(int exit_value, int signum, int flag)
|
|||||||
return(2);
|
return(2);
|
||||||
}
|
}
|
||||||
if(cleanup_exiting) {
|
if(cleanup_exiting) {
|
||||||
fprintf(stderr,"cleanup: ABORT : repeat by pid=%.f, signum=%d\n",
|
fprintf(stderr,"cleanup: ABORT : repeat by pid=%d, signum=%d\n",
|
||||||
(double) getpid(), signum);
|
getpid(),signum);
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
cleanup_exiting= 1;
|
cleanup_exiting= 1;
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
A signal handler which cleans up an application and exits.
|
A signal handler which cleans up an application and exits.
|
||||||
|
|
||||||
Provided under GPLv2+ within GPL projects, BSD license elsewise.
|
Provided under GPL license within GPL projects, BSD license elsewise.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef Cleanup_includeD
|
#ifndef Cleanup_includeD
|
||||||
|
@ -1,9 +1,5 @@
|
|||||||
/* -*- 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] = {
|
||||||
@ -108,15 +104,6 @@ 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;
|
||||||
@ -125,20 +112,6 @@ unsigned short crc_ccitt(unsigned char *q, int len)
|
|||||||
crc = ccitt_table[(crc >> 8 ^ *q++) & 0xff] ^ (crc << 8);
|
crc = ccitt_table[(crc >> 8 ^ *q++) & 0xff] ^ (crc << 8);
|
||||||
return ~crc;
|
return ~crc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Exploration ts B00214 :
|
|
||||||
ECMA-130, 14.3 "EDC field"
|
|
||||||
"The EDC codeword must be divisible by the check polynomial:
|
|
||||||
P(x) = (x^16 + x^15 + x^2 + 1) . (x^16 + x^2 + x + 1)
|
|
||||||
"
|
|
||||||
|
|
||||||
>>> Test whether this coincides with CRC-32 IEEE 802.3
|
|
||||||
x^32 + x^26 + x^23 + x^22 + x^16 + x^12 + x^11 + x^10
|
|
||||||
+ x^8 + x^7 + x^5 + x^4 + x^2 + x + 1
|
|
||||||
|
|
||||||
Used for raw writing in sector.c
|
|
||||||
*/
|
|
||||||
unsigned int crc_32(unsigned char *data, int len)
|
unsigned int crc_32(unsigned char *data, int len)
|
||||||
{
|
{
|
||||||
unsigned int crc = 0;
|
unsigned int crc = 0;
|
||||||
|
@ -3,21 +3,7 @@
|
|||||||
#ifndef BURN__CRC_H
|
#ifndef BURN__CRC_H
|
||||||
#define BURN__CRC_H
|
#define BURN__CRC_H
|
||||||
|
|
||||||
|
|
||||||
#ifdef Xorriso_standalonE
|
|
||||||
/* Source module crc.c of yet unclear ancestry is excluded from GNU xorriso */
|
|
||||||
#ifndef Libburn_no_crc_C
|
|
||||||
#define Libburn_no_crc_C 1
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef Libburn_no_crc_C
|
|
||||||
|
|
||||||
unsigned short crc_ccitt(unsigned char *, int len);
|
unsigned short crc_ccitt(unsigned char *, int len);
|
||||||
unsigned int crc_32(unsigned char *, int len);
|
unsigned int crc_32(unsigned char *, int len);
|
||||||
|
|
||||||
#endif /* Libburn_no_crc_C */
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* BURN__CRC_H */
|
#endif /* BURN__CRC_H */
|
||||||
|
@ -22,10 +22,6 @@
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
#include "../config.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
@ -1,14 +1,5 @@
|
|||||||
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||||
|
|
||||||
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
|
|
||||||
Provided under GPL version 2 or later.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
#include "../config.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#endif
|
#endif
|
||||||
|
529
libburn/drive.c
529
libburn/drive.c
@ -1,17 +1,10 @@
|
|||||||
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||||
|
|
||||||
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
|
|
||||||
Copyright (c) 2006 - 2010 Thomas Schmitt <scdbackup@gmx.net>
|
|
||||||
Provided under GPL version 2 or later.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
#include "../config.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
|
||||||
|
/* #include <m alloc.h> ts A61013 : not in Linux man 3 malloc */
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
@ -47,9 +40,6 @@
|
|||||||
/* A70903 : for burn_scsi_setup_drive() */
|
/* A70903 : for burn_scsi_setup_drive() */
|
||||||
#include "spc.h"
|
#include "spc.h"
|
||||||
|
|
||||||
/* A90815 : for mmc_obtain_profile_name() */
|
|
||||||
#include "mmc.h"
|
|
||||||
|
|
||||||
#include "libdax_msgs.h"
|
#include "libdax_msgs.h"
|
||||||
extern struct libdax_msgs *libdax_messenger;
|
extern struct libdax_msgs *libdax_messenger;
|
||||||
|
|
||||||
@ -72,7 +62,6 @@ int burn_setup_drive(struct burn_drive *d, char *fname)
|
|||||||
d->stdio_fd = -1;
|
d->stdio_fd = -1;
|
||||||
d->status = BURN_DISC_UNREADY;
|
d->status = BURN_DISC_UNREADY;
|
||||||
d->do_stream_recording = 0;
|
d->do_stream_recording = 0;
|
||||||
d->stream_recording_start= 0;
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -97,7 +86,6 @@ void burn_drive_free_subs(struct burn_drive *d)
|
|||||||
if (d->stdio_fd >= 0)
|
if (d->stdio_fd >= 0)
|
||||||
close (d->stdio_fd);
|
close (d->stdio_fd);
|
||||||
d->stdio_fd = -1;
|
d->stdio_fd = -1;
|
||||||
sg_dispose_drive(d, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -243,7 +231,7 @@ int burn_drive_inquire_media(struct burn_drive *d)
|
|||||||
/* ts A61020 : d->status was set to BURN_DISC_BLANK as pure guess */
|
/* ts A61020 : d->status was set to BURN_DISC_BLANK as pure guess */
|
||||||
|
|
||||||
/* ts A71128 : run read_disc_info() for any recognizeable profile */
|
/* ts A71128 : run read_disc_info() for any recognizeable profile */
|
||||||
if (d->current_profile > 0 || d->current_is_guessed_profile ||
|
if (d->current_profile > 0 ||
|
||||||
d->mdata->cdr_write || d->mdata->cdrw_write ||
|
d->mdata->cdr_write || d->mdata->cdrw_write ||
|
||||||
d->mdata->dvdr_write || d->mdata->dvdram_write) {
|
d->mdata->dvdr_write || d->mdata->dvdram_write) {
|
||||||
|
|
||||||
@ -377,7 +365,6 @@ struct burn_drive *burn_drive_register(struct burn_drive *d)
|
|||||||
d->busy = BURN_DRIVE_IDLE;
|
d->busy = BURN_DRIVE_IDLE;
|
||||||
d->thread_pid = 0;
|
d->thread_pid = 0;
|
||||||
d->thread_pid_valid = 0;
|
d->thread_pid_valid = 0;
|
||||||
memset(&(d->thread_tid), 0, sizeof(d->thread_tid));
|
|
||||||
d->toc_entries = 0;
|
d->toc_entries = 0;
|
||||||
d->toc_entry = NULL;
|
d->toc_entry = NULL;
|
||||||
d->disc = NULL;
|
d->disc = NULL;
|
||||||
@ -430,8 +417,9 @@ int burn_drive_unregister(struct burn_drive *d)
|
|||||||
struct burn_drive *burn_drive_finish_enum(struct burn_drive *d)
|
struct burn_drive *burn_drive_finish_enum(struct burn_drive *d)
|
||||||
{
|
{
|
||||||
struct burn_drive *t;
|
struct burn_drive *t;
|
||||||
char msg[BURN_DRIVE_ADR_LEN + 160];
|
/* ts A60821
|
||||||
int ret;
|
<<< debug: for tracing calls which might use open drive fds */
|
||||||
|
int mmc_function_spy(struct burn_drive *d, char * text);
|
||||||
|
|
||||||
d->drive_role = 1; /* MMC drive */
|
d->drive_role = 1; /* MMC drive */
|
||||||
|
|
||||||
@ -441,19 +429,13 @@ struct burn_drive *burn_drive_finish_enum(struct burn_drive *d)
|
|||||||
mmc_function_spy(NULL, "enumerate_common : -------- doing grab");
|
mmc_function_spy(NULL, "enumerate_common : -------- doing grab");
|
||||||
|
|
||||||
/* try to get the drive info */
|
/* try to get the drive info */
|
||||||
ret = t->grab(t);
|
if (t->grab(t)) {
|
||||||
if (ret) {
|
|
||||||
burn_print(2, "getting drive info\n");
|
burn_print(2, "getting drive info\n");
|
||||||
t->getcaps(t);
|
t->getcaps(t);
|
||||||
t->unlock(t);
|
t->unlock(t);
|
||||||
t->released = 1;
|
t->released = 1;
|
||||||
} else {
|
} else {
|
||||||
/* ts A90602 */
|
burn_print(2, "unable to grab new located drive\n");
|
||||||
d->mdata->valid = -1;
|
|
||||||
sprintf(msg, "Unable to grab scanned drive %s", d->devname);
|
|
||||||
libdax_msgs_submit(libdax_messenger, d->global_index,
|
|
||||||
0x0002016f, LIBDAX_MSGS_SEV_DEBUG,
|
|
||||||
LIBDAX_MSGS_PRIO_LOW, msg, 0, 0);
|
|
||||||
burn_drive_unregister(t);
|
burn_drive_unregister(t);
|
||||||
t = NULL;
|
t = NULL;
|
||||||
}
|
}
|
||||||
@ -526,7 +508,6 @@ int burn_drive_release_fl(struct burn_drive *d, int flag)
|
|||||||
d->unlock(d);
|
d->unlock(d);
|
||||||
if ((flag & 7) == 1)
|
if ((flag & 7) == 1)
|
||||||
d->eject(d);
|
d->eject(d);
|
||||||
burn_drive_snooze(d, 0);
|
|
||||||
d->release(d);
|
d->release(d);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -539,22 +520,6 @@ int burn_drive_release_fl(struct burn_drive *d, int flag)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* API */
|
|
||||||
/* ts A90824
|
|
||||||
@param flag bit0= wake up (else start snoozing)
|
|
||||||
*/
|
|
||||||
int burn_drive_snooze(struct burn_drive *d, int flag)
|
|
||||||
{
|
|
||||||
if (d->drive_role != 1)
|
|
||||||
return 0;
|
|
||||||
if (flag & 1)
|
|
||||||
d->start_unit(d);
|
|
||||||
else
|
|
||||||
d->stop_unit(d);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* API */
|
/* API */
|
||||||
void burn_drive_release(struct burn_drive *d, int le)
|
void burn_drive_release(struct burn_drive *d, int le)
|
||||||
{
|
{
|
||||||
@ -623,9 +588,8 @@ void burn_disc_erase_sync(struct burn_drive *d, int fast)
|
|||||||
d->idata->product);
|
d->idata->product);
|
||||||
|
|
||||||
d->cancel = 0;
|
d->cancel = 0;
|
||||||
|
d->busy = BURN_DRIVE_ERASING;
|
||||||
#ifdef Libburn_reset_progress_asynC
|
d->erase(d, fast);
|
||||||
/* <<< This is now done in async.c */
|
|
||||||
/* reset the progress */
|
/* reset the progress */
|
||||||
d->progress.session = 0;
|
d->progress.session = 0;
|
||||||
d->progress.sessions = 1;
|
d->progress.sessions = 1;
|
||||||
@ -636,11 +600,6 @@ void burn_disc_erase_sync(struct burn_drive *d, int fast)
|
|||||||
d->progress.start_sector = 0;
|
d->progress.start_sector = 0;
|
||||||
d->progress.sectors = 0x10000;
|
d->progress.sectors = 0x10000;
|
||||||
d->progress.sector = 0;
|
d->progress.sector = 0;
|
||||||
#endif /* Libburn_reset_progress_asynC */
|
|
||||||
|
|
||||||
d->erase(d, fast);
|
|
||||||
d->busy = BURN_DRIVE_ERASING;
|
|
||||||
|
|
||||||
/* read the initial 0 stage */
|
/* read the initial 0 stage */
|
||||||
while (!d->test_unit_ready(d) && d->get_erase_progress(d) == 0)
|
while (!d->test_unit_ready(d) && d->get_erase_progress(d) == 0)
|
||||||
sleep(1);
|
sleep(1);
|
||||||
@ -667,8 +626,6 @@ void burn_disc_format_sync(struct burn_drive *d, off_t size, int flag)
|
|||||||
char msg[80];
|
char msg[80];
|
||||||
struct buffer buf, *buf_mem = d->buffer;
|
struct buffer buf, *buf_mem = d->buffer;
|
||||||
|
|
||||||
#ifdef Libburn_reset_progress_asynC
|
|
||||||
/* <<< This is now done in async.c */
|
|
||||||
/* reset the progress */
|
/* reset the progress */
|
||||||
d->progress.session = 0;
|
d->progress.session = 0;
|
||||||
d->progress.sessions = 1;
|
d->progress.sessions = 1;
|
||||||
@ -679,8 +636,6 @@ void burn_disc_format_sync(struct burn_drive *d, off_t size, int flag)
|
|||||||
d->progress.start_sector = 0;
|
d->progress.start_sector = 0;
|
||||||
d->progress.sectors = 0x10000;
|
d->progress.sectors = 0x10000;
|
||||||
d->progress.sector = 0;
|
d->progress.sector = 0;
|
||||||
#endif /* Libburn_reset_progress_asynC */
|
|
||||||
|
|
||||||
stages = 1 + ((flag & 1) && size > 1024 * 1024);
|
stages = 1 + ((flag & 1) && size > 1024 * 1024);
|
||||||
d->cancel = 0;
|
d->cancel = 0;
|
||||||
d->busy = BURN_DRIVE_FORMATTING;
|
d->busy = BURN_DRIVE_FORMATTING;
|
||||||
@ -817,22 +772,10 @@ int burn_disc_erasable(struct burn_drive *d)
|
|||||||
enum burn_drive_status burn_drive_get_status(struct burn_drive *d,
|
enum burn_drive_status burn_drive_get_status(struct burn_drive *d,
|
||||||
struct burn_progress *p)
|
struct burn_progress *p)
|
||||||
{
|
{
|
||||||
/* --- Part of asynchronous signal handling --- */
|
|
||||||
/* This frequently used call may be used to react on messages from
|
|
||||||
the libburn built-in signal handler.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* ts B00225 :
|
|
||||||
If aborting with action 2:
|
|
||||||
catch control thread after it returned from signal handler.
|
|
||||||
Let it run burn_abort(4440,...)
|
|
||||||
*/
|
|
||||||
burn_init_catch_on_abort(0);
|
|
||||||
|
|
||||||
/* ts A70928 : inform control thread of signal in sub-threads */
|
/* ts A70928 : inform control thread of signal in sub-threads */
|
||||||
if (burn_builtin_triggered_action < 2 && burn_global_abort_level > 0)
|
if (burn_global_abort_level > 0)
|
||||||
burn_global_abort_level++;
|
burn_global_abort_level++;
|
||||||
if (burn_builtin_triggered_action < 2 && burn_global_abort_level > 5) {
|
if (burn_global_abort_level > 5) {
|
||||||
if (burn_global_signal_handler == NULL)
|
if (burn_global_signal_handler == NULL)
|
||||||
kill(getpid(), burn_global_abort_signum);
|
kill(getpid(), burn_global_abort_signum);
|
||||||
else
|
else
|
||||||
@ -842,9 +785,6 @@ enum burn_drive_status burn_drive_get_status(struct burn_drive *d,
|
|||||||
burn_global_abort_level = -1;
|
burn_global_abort_level = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* --- End of asynchronous signal handling --- */
|
|
||||||
|
|
||||||
|
|
||||||
if (p != NULL) {
|
if (p != NULL) {
|
||||||
memcpy(p, &(d->progress), sizeof(struct burn_progress));
|
memcpy(p, &(d->progress), sizeof(struct burn_progress));
|
||||||
/* TODO: add mutex */
|
/* TODO: add mutex */
|
||||||
@ -852,27 +792,11 @@ enum burn_drive_status burn_drive_get_status(struct burn_drive *d,
|
|||||||
return d->busy;
|
return d->busy;
|
||||||
}
|
}
|
||||||
|
|
||||||
int burn_drive_set_stream_recording(struct burn_drive *d, int recmode,
|
|
||||||
int start, int flag)
|
|
||||||
{
|
|
||||||
|
|
||||||
if (recmode == 1)
|
|
||||||
d->do_stream_recording = 1;
|
|
||||||
else if (recmode == -1)
|
|
||||||
d->do_stream_recording = 0;
|
|
||||||
d->stream_recording_start = start;
|
|
||||||
return(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
void burn_drive_cancel(struct burn_drive *d)
|
void burn_drive_cancel(struct burn_drive *d)
|
||||||
{
|
{
|
||||||
/* ts B00225 : these mutexes are unnecessary because "= 1" is atomar.
|
|
||||||
pthread_mutex_lock(&d->access_lock);
|
pthread_mutex_lock(&d->access_lock);
|
||||||
*/
|
|
||||||
d->cancel = 1;
|
d->cancel = 1;
|
||||||
/*
|
|
||||||
pthread_mutex_unlock(&d->access_lock);
|
pthread_mutex_unlock(&d->access_lock);
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ts A61007 : defunct because unused */
|
/* ts A61007 : defunct because unused */
|
||||||
@ -918,7 +842,7 @@ static int drive_getcaps(struct burn_drive *d, struct burn_drive_info *out)
|
|||||||
a ssert(d->mdata);
|
a ssert(d->mdata);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if(d->idata->valid <= 0 || d->mdata->valid <= 0)
|
if (!d->idata->valid || !d->mdata->valid)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
id = (struct burn_scsi_inquiry_data *)d->idata;
|
id = (struct burn_scsi_inquiry_data *)d->idata;
|
||||||
@ -944,29 +868,6 @@ static int drive_getcaps(struct burn_drive *d, struct burn_drive_info *out)
|
|||||||
out->write_simulate = !!d->mdata->simulate;
|
out->write_simulate = !!d->mdata->simulate;
|
||||||
out->c2_errors = !!d->mdata->c2_pointers;
|
out->c2_errors = !!d->mdata->c2_pointers;
|
||||||
out->drive = d;
|
out->drive = d;
|
||||||
|
|
||||||
#ifdef Libburn_dummy_probe_write_modeS
|
|
||||||
|
|
||||||
/* ts A91112 */
|
|
||||||
/* Set default block types. The call d->probe_write_modes() is quite
|
|
||||||
obtrusive. It may be performed explicitely by new API call
|
|
||||||
burn_drive_probe_cd_write_modes().
|
|
||||||
*/
|
|
||||||
if (out->write_dvdram || out->write_dvdr ||
|
|
||||||
out->write_cdrw || out->write_cdr) {
|
|
||||||
out->tao_block_types = d->block_types[BURN_WRITE_TAO] =
|
|
||||||
BURN_BLOCK_MODE1 | BURN_BLOCK_RAW0;
|
|
||||||
out->sao_block_types = d->block_types[BURN_WRITE_SAO] =
|
|
||||||
BURN_BLOCK_SAO;
|
|
||||||
} else {
|
|
||||||
out->tao_block_types = d->block_types[BURN_WRITE_TAO] = 0;
|
|
||||||
out->sao_block_types = d->block_types[BURN_WRITE_SAO] = 0;
|
|
||||||
}
|
|
||||||
out->raw_block_types = d->block_types[BURN_WRITE_RAW] = 0;
|
|
||||||
out->packet_block_types = 0;
|
|
||||||
|
|
||||||
#else /* Libburn_dummy_probe_write_modeS */
|
|
||||||
|
|
||||||
/* update available block types for burners */
|
/* update available block types for burners */
|
||||||
if (out->write_dvdram || out->write_dvdr ||
|
if (out->write_dvdram || out->write_dvdr ||
|
||||||
out->write_cdrw || out->write_cdr)
|
out->write_cdrw || out->write_cdr)
|
||||||
@ -975,30 +876,6 @@ static int drive_getcaps(struct burn_drive *d, struct burn_drive_info *out)
|
|||||||
out->sao_block_types = d->block_types[BURN_WRITE_SAO];
|
out->sao_block_types = d->block_types[BURN_WRITE_SAO];
|
||||||
out->raw_block_types = d->block_types[BURN_WRITE_RAW];
|
out->raw_block_types = d->block_types[BURN_WRITE_RAW];
|
||||||
out->packet_block_types = d->block_types[BURN_WRITE_PACKET];
|
out->packet_block_types = d->block_types[BURN_WRITE_PACKET];
|
||||||
|
|
||||||
#endif /* ! Libburn_dummy_probe_write_modeS */
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* ts A91112 - B00114 API */
|
|
||||||
/* Probe available CD write modes and block types.
|
|
||||||
*/
|
|
||||||
int burn_drive_probe_cd_write_modes(struct burn_drive_info *dinfo)
|
|
||||||
{
|
|
||||||
struct burn_drive *d = dinfo->drive;
|
|
||||||
|
|
||||||
if (d == NULL)
|
|
||||||
return 0;
|
|
||||||
if (dinfo->write_dvdram || dinfo->write_dvdr ||
|
|
||||||
dinfo->write_cdrw || dinfo->write_cdr)
|
|
||||||
d->probe_write_modes(d);
|
|
||||||
dinfo->tao_block_types = d->block_types[BURN_WRITE_TAO];
|
|
||||||
dinfo->sao_block_types = d->block_types[BURN_WRITE_SAO];
|
|
||||||
dinfo->raw_block_types = d->block_types[BURN_WRITE_RAW];
|
|
||||||
dinfo->packet_block_types = d->block_types[BURN_WRITE_PACKET];
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1031,7 +908,7 @@ int burn_drive_scan_sync(struct burn_drive_info *drives[],
|
|||||||
*/
|
*/
|
||||||
unsigned char scanned[32];
|
unsigned char scanned[32];
|
||||||
unsigned count = 0;
|
unsigned count = 0;
|
||||||
int i, ret;
|
int i;
|
||||||
|
|
||||||
/* ts A61007 : moved up to burn_drive_scan() */
|
/* ts A61007 : moved up to burn_drive_scan() */
|
||||||
/* a ssert(burn_running); */
|
/* a ssert(burn_running); */
|
||||||
@ -1088,22 +965,13 @@ int burn_drive_scan_sync(struct burn_drive_info *drives[],
|
|||||||
if (drive_array[i].global_index < 0)
|
if (drive_array[i].global_index < 0)
|
||||||
continue; /* invalid device */
|
continue; /* invalid device */
|
||||||
|
|
||||||
/* ts A90602 : This old loop is not plausible. See A70907.
|
while (!drive_getcaps(&drive_array[i],
|
||||||
while (!drive_getcaps(&drive_array[i],
|
&(*drives)[*n_drives])) {
|
||||||
&(*drives)[*n_drives])) {
|
|
||||||
sleep(1);
|
sleep(1);
|
||||||
}
|
}
|
||||||
*/
|
(*n_drives)++;
|
||||||
/* ts A90602 : A single call shall do (rather than a loop) */
|
|
||||||
ret = drive_getcaps(&drive_array[i], &(*drives)[*n_drives]);
|
|
||||||
if (ret > 0)
|
|
||||||
(*n_drives)++;
|
|
||||||
scanned[i / 8] |= 1 << (i % 8);
|
scanned[i / 8] |= 1 << (i % 8);
|
||||||
}
|
}
|
||||||
if (*drives != NULL && *n_drives == 0) {
|
|
||||||
free ((char *) *drives);
|
|
||||||
*drives = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return(1);
|
return(1);
|
||||||
}
|
}
|
||||||
@ -1259,14 +1127,14 @@ void burn_sectors_to_msf(int sectors, int *m, int *s, int *f)
|
|||||||
|
|
||||||
int burn_drive_get_read_speed(struct burn_drive *d)
|
int burn_drive_get_read_speed(struct burn_drive *d)
|
||||||
{
|
{
|
||||||
if(d->mdata->valid <= 0)
|
if(!d->mdata->valid)
|
||||||
return 0;
|
return 0;
|
||||||
return d->mdata->max_read_speed;
|
return d->mdata->max_read_speed;
|
||||||
}
|
}
|
||||||
|
|
||||||
int burn_drive_get_write_speed(struct burn_drive *d)
|
int burn_drive_get_write_speed(struct burn_drive *d)
|
||||||
{
|
{
|
||||||
if(d->mdata->valid <= 0)
|
if(!d->mdata->valid)
|
||||||
return 0;
|
return 0;
|
||||||
return d->mdata->max_write_speed;
|
return d->mdata->max_write_speed;
|
||||||
}
|
}
|
||||||
@ -1274,7 +1142,7 @@ int burn_drive_get_write_speed(struct burn_drive *d)
|
|||||||
/* ts A61021 : New API function */
|
/* ts A61021 : New API function */
|
||||||
int burn_drive_get_min_write_speed(struct burn_drive *d)
|
int burn_drive_get_min_write_speed(struct burn_drive *d)
|
||||||
{
|
{
|
||||||
if(d->mdata->valid <= 0)
|
if(!d->mdata->valid)
|
||||||
return 0;
|
return 0;
|
||||||
return d->mdata->min_write_speed;
|
return d->mdata->min_write_speed;
|
||||||
}
|
}
|
||||||
@ -1294,7 +1162,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 = calloc(1, strlen(device_address) + 1);
|
new_item = malloc(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);
|
||||||
@ -1359,10 +1227,8 @@ int burn_drive__fd_from_special_adr(char *adr)
|
|||||||
int burn_drive_grab_dummy(struct burn_drive_info *drive_infos[], char *fname)
|
int burn_drive_grab_dummy(struct burn_drive_info *drive_infos[], char *fname)
|
||||||
{
|
{
|
||||||
int ret = -1, fd = -1, role = 0;
|
int ret = -1, fd = -1, role = 0;
|
||||||
int is_block_dev = 0;
|
|
||||||
/* divided by 512 it needs to fit into a signed long integer */
|
/* divided by 512 it needs to fit into a signed long integer */
|
||||||
off_t size = ((off_t) (512 * 1024 * 1024 - 1) * (off_t) 2048);
|
off_t size = ((off_t) (512 * 1024 * 1024 - 1) * (off_t) 2048);
|
||||||
off_t read_size = -1;
|
|
||||||
struct burn_drive *d= NULL, *regd_d;
|
struct burn_drive *d= NULL, *regd_d;
|
||||||
struct stat stbuf;
|
struct stat stbuf;
|
||||||
|
|
||||||
@ -1375,19 +1241,8 @@ int burn_drive_grab_dummy(struct burn_drive_info *drive_infos[], char *fname)
|
|||||||
ret = fstat(fd, &stbuf);
|
ret = fstat(fd, &stbuf);
|
||||||
else
|
else
|
||||||
ret = stat(fname, &stbuf);
|
ret = stat(fname, &stbuf);
|
||||||
if (ret != -1) {
|
if (ret == -1 || S_ISBLK(stbuf.st_mode) ||
|
||||||
is_block_dev = burn_os_is_2k_seekrw(fname, 0);
|
S_ISREG(stbuf.st_mode)) {
|
||||||
if (S_ISREG(stbuf.st_mode))
|
|
||||||
read_size = stbuf.st_size;
|
|
||||||
else if (is_block_dev) {
|
|
||||||
ret = burn_os_stdio_capacity(fname,
|
|
||||||
&read_size);
|
|
||||||
if (ret <= 0)
|
|
||||||
read_size = (off_t) 0x7ffffff0 *
|
|
||||||
(off_t) 2048;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (ret == -1 || is_block_dev || S_ISREG(stbuf.st_mode)) {
|
|
||||||
ret = burn_os_stdio_capacity(fname, &size);
|
ret = burn_os_stdio_capacity(fname, &size);
|
||||||
if (ret == -1) {
|
if (ret == -1) {
|
||||||
libdax_msgs_submit(libdax_messenger, -1,
|
libdax_msgs_submit(libdax_messenger, -1,
|
||||||
@ -1444,10 +1299,6 @@ int burn_drive_grab_dummy(struct burn_drive_info *drive_infos[], char *fname)
|
|||||||
d->current_is_supported_profile = 1;
|
d->current_is_supported_profile = 1;
|
||||||
d->block_types[BURN_WRITE_TAO] = BURN_BLOCK_MODE1;
|
d->block_types[BURN_WRITE_TAO] = BURN_BLOCK_MODE1;
|
||||||
d->block_types[BURN_WRITE_SAO] = BURN_BLOCK_SAO;
|
d->block_types[BURN_WRITE_SAO] = BURN_BLOCK_SAO;
|
||||||
if (read_size >= 0)
|
|
||||||
/* despite its name : last valid address, not size */
|
|
||||||
d->media_read_capacity =
|
|
||||||
read_size / 2048 - !(read_size % 2048);
|
|
||||||
burn_drive_set_media_capacity_remaining(d, size);
|
burn_drive_set_media_capacity_remaining(d, size);
|
||||||
|
|
||||||
/* >>> ? open file for a test ? (>>> beware of "-" = stdin) */;
|
/* >>> ? open file for a test ? (>>> beware of "-" = stdin) */;
|
||||||
@ -1603,23 +1454,14 @@ int burn_drive_is_enumerable_adr(char *adr)
|
|||||||
#define BURN_DRIVE_MAX_LINK_DEPTH 20
|
#define BURN_DRIVE_MAX_LINK_DEPTH 20
|
||||||
|
|
||||||
/* ts A60922 ticket 33 */
|
/* ts A60922 ticket 33 */
|
||||||
/* @param flag bit0= no debug messages
|
int burn_drive_resolve_link(char *path, char adr[], int *recursion_count)
|
||||||
bit1= resolve only links,
|
|
||||||
do not rely on drive list for resolving via st_rdev
|
|
||||||
*/
|
|
||||||
int burn_drive_resolve_link(char *path, char adr[], int *recursion_count,
|
|
||||||
int flag)
|
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
char link_target[4096], msg[4096+100], link_adr[4096], *adrpt;
|
char link_target[4096], msg[4096+100], link_adr[4096], *adrpt;
|
||||||
struct stat stbuf;
|
|
||||||
|
|
||||||
if (flag & 1)
|
burn_drive_adr_debug_msg("burn_drive_resolve_link( %s )", path);
|
||||||
burn_drive_adr_debug_msg("burn_drive_resolve_link( %s )",
|
|
||||||
path);
|
|
||||||
if (*recursion_count >= BURN_DRIVE_MAX_LINK_DEPTH) {
|
if (*recursion_count >= BURN_DRIVE_MAX_LINK_DEPTH) {
|
||||||
if (flag & 1)
|
burn_drive_adr_debug_msg(
|
||||||
burn_drive_adr_debug_msg(
|
|
||||||
"burn_drive_resolve_link aborts because link too deep",
|
"burn_drive_resolve_link aborts because link too deep",
|
||||||
NULL);
|
NULL);
|
||||||
return 0;
|
return 0;
|
||||||
@ -1627,15 +1469,12 @@ int burn_drive_resolve_link(char *path, char adr[], int *recursion_count,
|
|||||||
(*recursion_count)++;
|
(*recursion_count)++;
|
||||||
ret = readlink(path, link_target, sizeof(link_target));
|
ret = readlink(path, link_target, sizeof(link_target));
|
||||||
if (ret == -1) {
|
if (ret == -1) {
|
||||||
if (flag & 1)
|
burn_drive_adr_debug_msg("readlink( %s ) returns -1", path);
|
||||||
burn_drive_adr_debug_msg("readlink( %s ) returns -1",
|
|
||||||
path);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (ret >= sizeof(link_target) - 1) {
|
if (ret >= sizeof(link_target) - 1) {
|
||||||
sprintf(msg,"readlink( %s ) returns %d (too much)", path, ret);
|
sprintf(msg,"readlink( %s ) returns %d (too much)", path, ret);
|
||||||
if (flag & 1)
|
burn_drive_adr_debug_msg(msg, NULL);
|
||||||
burn_drive_adr_debug_msg(msg, NULL);
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
link_target[ret] = 0;
|
link_target[ret] = 0;
|
||||||
@ -1648,25 +1487,10 @@ int burn_drive_resolve_link(char *path, char adr[], int *recursion_count,
|
|||||||
} else
|
} else
|
||||||
adrpt = link_target;
|
adrpt = link_target;
|
||||||
}
|
}
|
||||||
if (flag & 2) {
|
ret = burn_drive_convert_fs_adr_sub(adrpt, adr, recursion_count);
|
||||||
/* Link-only recursion */
|
sprintf(msg,"burn_drive_convert_fs_adr( %s ) returns %d",
|
||||||
if (lstat(adrpt, &stbuf) == -1) {
|
link_target, ret);
|
||||||
;
|
burn_drive_adr_debug_msg(msg, NULL);
|
||||||
} else if((stbuf.st_mode & S_IFMT) == S_IFLNK) {
|
|
||||||
ret = burn_drive_resolve_link(adrpt, adr,
|
|
||||||
recursion_count, flag);
|
|
||||||
} else {
|
|
||||||
strcpy(adr, adrpt);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
/* Link and device number recursion */
|
|
||||||
ret = burn_drive_convert_fs_adr_sub(adrpt, adr,
|
|
||||||
recursion_count);
|
|
||||||
sprintf(msg,"burn_drive_convert_fs_adr( %s ) returns %d",
|
|
||||||
link_target, ret);
|
|
||||||
}
|
|
||||||
if (flag & 1)
|
|
||||||
burn_drive_adr_debug_msg(msg, NULL);
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1840,7 +1664,7 @@ int burn_drive_convert_fs_adr_sub(char *path, char adr[], int *rec_count)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if((stbuf.st_mode & S_IFMT) == S_IFLNK) {
|
if((stbuf.st_mode & S_IFMT) == S_IFLNK) {
|
||||||
ret = burn_drive_resolve_link(path, adr, rec_count, 0);
|
ret = burn_drive_resolve_link(path, adr, rec_count);
|
||||||
if(ret > 0)
|
if(ret > 0)
|
||||||
return 1;
|
return 1;
|
||||||
burn_drive_adr_debug_msg("link fallback via stat( %s )", path);
|
burn_drive_adr_debug_msg("link fallback via stat( %s )", path);
|
||||||
@ -1889,108 +1713,6 @@ int burn_abort_pacifier(void *handle, int patience, int elapsed)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ts B00226 : Outsourced backend of burn_abort()
|
|
||||||
@param flag bit0= do not call burn_finish()
|
|
||||||
*/
|
|
||||||
int burn_abort_5(int patience,
|
|
||||||
int (*pacifier_func)(void *handle, int patience, int elapsed),
|
|
||||||
void *handle, int elapsed, int flag)
|
|
||||||
{
|
|
||||||
int ret, i, occup, still_not_done= 1, pacifier_off= 0, first_round= 1;
|
|
||||||
unsigned long wait_grain= 100000;
|
|
||||||
time_t start_time, current_time, pacifier_time, end_time;
|
|
||||||
|
|
||||||
#ifndef NIX
|
|
||||||
time_t stdio_patience = 3;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
fprintf(stderr,
|
|
||||||
"libburn_EXPERIMENTAL: burn_abort_5(%d,%d)\n", patience, flag);
|
|
||||||
*/
|
|
||||||
|
|
||||||
current_time = start_time = pacifier_time = time(0);
|
|
||||||
start_time -= elapsed;
|
|
||||||
end_time = start_time + patience;
|
|
||||||
|
|
||||||
/* >>> ts A71002 : are there any threads at work ?
|
|
||||||
If not, then one can force abort because the drives will not
|
|
||||||
change status on their own.
|
|
||||||
*/
|
|
||||||
|
|
||||||
while(current_time < end_time || (patience <= 0 && first_round)) {
|
|
||||||
still_not_done = 0;
|
|
||||||
|
|
||||||
for(i = 0; i < drivetop + 1; i++) {
|
|
||||||
occup = burn_drive_is_occupied(&(drive_array[i]));
|
|
||||||
if(occup == -2)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if(drive_array[i].drive_role != 1) {
|
|
||||||
|
|
||||||
#ifdef NIX
|
|
||||||
|
|
||||||
/* ts A90302
|
|
||||||
<<< this causes a race condition with drive
|
|
||||||
usage and drive disposal.
|
|
||||||
*/
|
|
||||||
drive_array[i].busy = BURN_DRIVE_IDLE;
|
|
||||||
burn_drive_forget(&(drive_array[i]), 1);
|
|
||||||
continue;
|
|
||||||
|
|
||||||
#else /* NIX */
|
|
||||||
|
|
||||||
/* ts A90318
|
|
||||||
>>> but if a pipe breaks then the drive
|
|
||||||
never gets idle.
|
|
||||||
So for now with a short patience timespan
|
|
||||||
and eventually a deliberate memory leak.
|
|
||||||
*/
|
|
||||||
if (current_time - start_time >
|
|
||||||
stdio_patience) {
|
|
||||||
drive_array[i].global_index = -1;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* ! NIX */
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
if(occup <= 10) {
|
|
||||||
if (drive_array[i].drive_role != 1)
|
|
||||||
/* occup == -1 comes early */
|
|
||||||
usleep(1000000);
|
|
||||||
burn_drive_forget(&(drive_array[i]), 1);
|
|
||||||
} else if(occup <= 100) {
|
|
||||||
if(first_round)
|
|
||||||
burn_drive_cancel(&(drive_array[i]));
|
|
||||||
still_not_done++;
|
|
||||||
} else if(occup <= 1000) {
|
|
||||||
still_not_done++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
first_round = 0;
|
|
||||||
|
|
||||||
if(still_not_done == 0 || patience <= 0)
|
|
||||||
break;
|
|
||||||
usleep(wait_grain);
|
|
||||||
current_time = time(0);
|
|
||||||
if(current_time>pacifier_time) {
|
|
||||||
if(pacifier_func != NULL && !pacifier_off) {
|
|
||||||
ret = (*pacifier_func)(handle, patience,
|
|
||||||
current_time-start_time);
|
|
||||||
pacifier_off = (ret <= 0);
|
|
||||||
}
|
|
||||||
pacifier_time = current_time;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!(flag & 1))
|
|
||||||
burn_finish();
|
|
||||||
return(still_not_done == 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/** Abort any running drive operation and finish libburn.
|
/** Abort any running drive operation and finish libburn.
|
||||||
@param patience Maximum number of seconds to wait for drives to finish
|
@param patience Maximum number of seconds to wait for drives to finish
|
||||||
@param pacifier_func Function to produce appeasing messages. See
|
@param pacifier_func Function to produce appeasing messages. See
|
||||||
@ -2003,14 +1725,55 @@ int burn_abort(int patience,
|
|||||||
int (*pacifier_func)(void *handle, int patience, int elapsed),
|
int (*pacifier_func)(void *handle, int patience, int elapsed),
|
||||||
void *handle)
|
void *handle)
|
||||||
{
|
{
|
||||||
int ret, flg = 0;
|
int ret, i, occup, still_not_done= 1, pacifier_off= 0, first_round= 1;
|
||||||
|
unsigned long wait_grain= 100000;
|
||||||
|
time_t start_time, current_time, pacifier_time, end_time;
|
||||||
|
|
||||||
if (patience < 0) {
|
current_time = start_time = pacifier_time = time(0);
|
||||||
patience = 0;
|
end_time = start_time + patience;
|
||||||
flg |= 1;
|
|
||||||
|
/* >>> ts A71002 : are there any threads at work ?
|
||||||
|
If not, then one can force abort because the drives will not
|
||||||
|
change status on their own.
|
||||||
|
*/
|
||||||
|
|
||||||
|
while(current_time-end_time < patience) {
|
||||||
|
still_not_done = 0;
|
||||||
|
|
||||||
|
for(i = 0; i < drivetop + 1; i++) {
|
||||||
|
occup = burn_drive_is_occupied(&(drive_array[i]));
|
||||||
|
if(occup == -2)
|
||||||
|
continue;
|
||||||
|
if(drive_array[i].drive_role != 1) {
|
||||||
|
drive_array[i].busy = BURN_DRIVE_IDLE;
|
||||||
|
burn_drive_forget(&(drive_array[i]), 1);
|
||||||
|
} else if(occup <= 10) {
|
||||||
|
burn_drive_forget(&(drive_array[i]), 1);
|
||||||
|
} else if(occup <= 100) {
|
||||||
|
if(first_round)
|
||||||
|
burn_drive_cancel(&(drive_array[i]));
|
||||||
|
still_not_done++;
|
||||||
|
} else if(occup <= 1000) {
|
||||||
|
still_not_done++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
first_round = 0;
|
||||||
|
|
||||||
|
if(still_not_done == 0)
|
||||||
|
break;
|
||||||
|
usleep(wait_grain);
|
||||||
|
current_time = time(0);
|
||||||
|
if(current_time>pacifier_time) {
|
||||||
|
if(pacifier_func != NULL && !pacifier_off) {
|
||||||
|
ret = (*pacifier_func)(handle, patience,
|
||||||
|
current_time-start_time);
|
||||||
|
pacifier_off = (ret <= 0);
|
||||||
|
}
|
||||||
|
pacifier_time = current_time;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
ret = burn_abort_5(patience, pacifier_func, handle, 0, flg);
|
burn_finish();
|
||||||
return ret;
|
return(still_not_done == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -2063,16 +1826,11 @@ int burn_disc_read_atip(struct burn_drive *d)
|
|||||||
}
|
}
|
||||||
if(d->drive_role != 1)
|
if(d->drive_role != 1)
|
||||||
return 0;
|
return 0;
|
||||||
if ((d->current_profile == -1 || d->current_is_cd_profile)
|
if (d->current_profile == -1 || d->current_is_cd_profile) {
|
||||||
&& (d->mdata->cdrw_write || d->current_profile != 0x08)) {
|
|
||||||
d->read_atip(d);
|
d->read_atip(d);
|
||||||
/* >>> some control of success would be nice :) */
|
/* >>> some control of success would be nice :) */
|
||||||
} else {
|
} else {
|
||||||
/* mmc5r03c.pdf 6.26.3.6.3 : ATIP is undefined for non-CD
|
/* mmc5r03c.pdf 6.26.3.6.3 : ATIP is undefined for non-CD */;
|
||||||
(and it seems meaningless for non-burners).
|
|
||||||
ts A90823: Pseudo-CD U3 memory stick stalls with ATIP.
|
|
||||||
It is !cdrw_write and profile is 0x08.
|
|
||||||
*/
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
@ -2180,30 +1938,6 @@ int burn_disc_get_profile(struct burn_drive *d, int *pno, char name[80])
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ts A90815 : New API function */
|
|
||||||
int burn_drive_get_all_profiles(struct burn_drive *d, int *num_profiles,
|
|
||||||
int profiles[64], char is_current[64])
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
*num_profiles = d->num_profiles;
|
|
||||||
for (i = 0; i < d->num_profiles; i++) {
|
|
||||||
profiles[i] = (d->all_profiles[i * 4] << 8) |
|
|
||||||
d->all_profiles[i * 4 + 1];
|
|
||||||
is_current[i] = d->all_profiles[i * 4 + 2] & 1;
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* ts A90815 : New API function */
|
|
||||||
int burn_obtain_profile_name(int profile_number, char name[80])
|
|
||||||
{
|
|
||||||
strcpy(name, mmc_obtain_profile_name(profile_number));
|
|
||||||
return(name[0] != 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* ts A61223 : New API function */
|
/* ts A61223 : New API function */
|
||||||
int burn_drive_wrote_well(struct burn_drive *d)
|
int burn_drive_wrote_well(struct burn_drive *d)
|
||||||
{
|
{
|
||||||
@ -2218,7 +1952,7 @@ int burn_speed_descriptor_new(struct burn_speed_descriptor **s,
|
|||||||
{
|
{
|
||||||
struct burn_speed_descriptor *o;
|
struct burn_speed_descriptor *o;
|
||||||
|
|
||||||
(*s) = o = calloc(1, sizeof(struct burn_speed_descriptor));
|
(*s) = o = malloc(sizeof(struct burn_speed_descriptor));
|
||||||
if (o == NULL)
|
if (o == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
o->source = 0;
|
o->source = 0;
|
||||||
@ -2303,7 +2037,7 @@ int burn_drive_get_speedlist(struct burn_drive *d,
|
|||||||
struct burn_speed_descriptor *sd, *csd = NULL;
|
struct burn_speed_descriptor *sd, *csd = NULL;
|
||||||
|
|
||||||
(*speed_list) = NULL;
|
(*speed_list) = NULL;
|
||||||
if(d->mdata->valid <= 0)
|
if(!d->mdata->valid)
|
||||||
return 0;
|
return 0;
|
||||||
for (sd = d->mdata->speed_descriptors; sd != NULL; sd = sd->next) {
|
for (sd = d->mdata->speed_descriptors; sd != NULL; sd = sd->next) {
|
||||||
ret = burn_speed_descriptor_new(&csd, NULL, csd, 0);
|
ret = burn_speed_descriptor_new(&csd, NULL, csd, 0);
|
||||||
@ -2328,7 +2062,7 @@ int burn_drive_get_best_speed(struct burn_drive *d, int speed_goal,
|
|||||||
if (speed_goal < 0)
|
if (speed_goal < 0)
|
||||||
best_speed = 2000000000;
|
best_speed = 2000000000;
|
||||||
*best_descr = NULL;
|
*best_descr = NULL;
|
||||||
if(d->mdata->valid <= 0)
|
if(!d->mdata->valid)
|
||||||
return 0;
|
return 0;
|
||||||
for (sd = d->mdata->speed_descriptors; sd != NULL; sd = sd->next) {
|
for (sd = d->mdata->speed_descriptors; sd != NULL; sd = sd->next) {
|
||||||
if (flag & 1)
|
if (flag & 1)
|
||||||
@ -2389,7 +2123,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 *)
|
||||||
calloc(1, sizeof(struct burn_multi_caps));
|
malloc(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 */
|
||||||
@ -2512,9 +2246,8 @@ int burn_disc_get_multi_caps(struct burn_drive *d, enum burn_write_types wt,
|
|||||||
o->might_do_sao = 4;
|
o->might_do_sao = 4;
|
||||||
o->might_do_tao = 2;
|
o->might_do_tao = 2;
|
||||||
o->advised_write_mode = BURN_WRITE_TAO;
|
o->advised_write_mode = BURN_WRITE_TAO;
|
||||||
} else if (d->current_profile == 0x1b || d->current_profile == 0x2b ||
|
} else if (d->current_profile == 0x1b || d->current_profile == 0x2b) {
|
||||||
d->current_profile == 0x41) {
|
/* DVD+R , DVD+R/DL */
|
||||||
/* DVD+R , DVD+R/DL , BD-R SRM */
|
|
||||||
o->multi_session = o->multi_track = 1;
|
o->multi_session = o->multi_track = 1;
|
||||||
o->might_do_tao = 2;
|
o->might_do_tao = 2;
|
||||||
o->might_do_sao = 1;
|
o->might_do_sao = 1;
|
||||||
@ -2708,9 +2441,6 @@ int burn_drive_equals_adr(struct burn_drive *d1, char *adr2_in, int role2)
|
|||||||
if (S_ISBLK(stbuf1.st_mode) && S_ISBLK(stbuf2.st_mode) &&
|
if (S_ISBLK(stbuf1.st_mode) && S_ISBLK(stbuf2.st_mode) &&
|
||||||
stbuf1.st_rdev == stbuf2.st_rdev)
|
stbuf1.st_rdev == stbuf2.st_rdev)
|
||||||
return 1; /* same major,minor device number */
|
return 1; /* same major,minor device number */
|
||||||
if (S_ISCHR(stbuf1.st_mode) && S_ISCHR(stbuf2.st_mode) &&
|
|
||||||
stbuf1.st_rdev == stbuf2.st_rdev)
|
|
||||||
return 1; /* same major,minor device number */
|
|
||||||
|
|
||||||
/* Are both filesystem objects related to the same MMC drive */
|
/* Are both filesystem objects related to the same MMC drive */
|
||||||
if (conv_ret2 <= 0)
|
if (conv_ret2 <= 0)
|
||||||
@ -2747,8 +2477,7 @@ int burn_drive_equals_adr(struct burn_drive *d1, char *adr2_in, int role2)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int burn_drive_find_by_thread_pid(struct burn_drive **d, pid_t pid,
|
int burn_drive_find_by_thread_pid(struct burn_drive **d, pid_t pid)
|
||||||
pthread_t tid)
|
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
@ -2760,8 +2489,7 @@ int burn_drive_find_by_thread_pid(struct burn_drive **d, pid_t pid,
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
if (drive_array[i].thread_pid_valid &&
|
if (drive_array[i].thread_pid_valid &&
|
||||||
drive_array[i].thread_pid == pid &&
|
drive_array[i].thread_pid == pid) {
|
||||||
pthread_equal(drive_array[i].thread_tid, tid)) {
|
|
||||||
*d = &(drive_array[i]);
|
*d = &(drive_array[i]);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -2778,76 +2506,3 @@ int burn_drive_set_media_capacity_remaining(struct burn_drive *d, off_t value)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ts A81215 : API */
|
|
||||||
int burn_get_read_capacity(struct burn_drive *d, int *capacity, int flag)
|
|
||||||
{
|
|
||||||
*capacity = d->media_read_capacity + 1;
|
|
||||||
return (d->media_read_capacity != 0x7fffffff);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* ts A90903 : API */
|
|
||||||
int burn_disc_get_media_id(struct burn_drive *d,
|
|
||||||
char **product_id, char **media_code1, char **media_code2,
|
|
||||||
char **book_type, int flag)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
*product_id = *media_code1 = *media_code2 = *book_type = NULL;
|
|
||||||
if (burn_drive_get_drive_role(d) != 1)
|
|
||||||
return 0;
|
|
||||||
ret = mmc_get_media_product_id(d,
|
|
||||||
product_id, media_code1, media_code2, book_type,
|
|
||||||
flag & 1);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* ts A90909 : API */
|
|
||||||
/**
|
|
||||||
@param valid Replies bits which indicate the validity of other reply
|
|
||||||
parameters or the state of certain CD info bits:
|
|
||||||
bit0= disc_type valid
|
|
||||||
bit1= disc_id valid
|
|
||||||
bit2= bar_code valid
|
|
||||||
bit3= disc_app_code valid
|
|
||||||
bit4= Disc is unrestricted (URU bit)
|
|
||||||
bit5= Disc is nominally erasable (Erasable bit)
|
|
||||||
This will be set with overwriteable media which
|
|
||||||
libburn normally considers to be unerasable blank.
|
|
||||||
*/
|
|
||||||
int burn_disc_get_cd_info(struct burn_drive *d, char disc_type[80],
|
|
||||||
unsigned int *disc_id, char bar_code[9], int *app_code,
|
|
||||||
int *valid)
|
|
||||||
{
|
|
||||||
if (d->disc_type == 0x00) {
|
|
||||||
strcpy(disc_type, "CD-DA or CD-ROM");
|
|
||||||
} else if (d->disc_type == 0x10) {
|
|
||||||
strcpy(disc_type, "CD-I");
|
|
||||||
} else if (d->disc_type == 0x20) {
|
|
||||||
strcpy(disc_type, "CD-ROM XA");
|
|
||||||
} else {
|
|
||||||
strcpy(disc_type, "undefined");
|
|
||||||
}
|
|
||||||
*disc_id = d->disc_id;
|
|
||||||
memcpy(bar_code, d->disc_bar_code, 8);
|
|
||||||
bar_code[9]= 0;
|
|
||||||
*app_code = d->disc_app_code;
|
|
||||||
*valid = d->disc_info_valid;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* ts B00924 : API */
|
|
||||||
int burn_disc_get_bd_spare_info(struct burn_drive *d,
|
|
||||||
int *alloc_blocks, int *free_blocks, int flag)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
if (burn_drive_get_drive_role(d) != 1)
|
|
||||||
return 0;
|
|
||||||
*alloc_blocks = *free_blocks = 0;
|
|
||||||
ret = mmc_get_bd_spare_info(d, alloc_blocks, free_blocks, 0);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
@ -1,11 +1,5 @@
|
|||||||
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||||
|
|
||||||
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
|
|
||||||
Copyright (c) 2006 - 2010 Thomas Schmitt <scdbackup@gmx.net>
|
|
||||||
Provided under GPL version 2 or later.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef __DRIVE
|
#ifndef __DRIVE
|
||||||
#define __DRIVE
|
#define __DRIVE
|
||||||
|
|
||||||
@ -127,9 +121,8 @@ int burn_disc_get_write_mode_demands(struct burn_disc *disc,
|
|||||||
int burn_drive__fd_from_special_adr(char *adr);
|
int burn_drive__fd_from_special_adr(char *adr);
|
||||||
|
|
||||||
|
|
||||||
/* ts A70929 : Find the drive which is being worked on by pid , tid */
|
/* ts A70929 : Find the drive which is being worked on by pid */
|
||||||
int burn_drive_find_by_thread_pid(struct burn_drive **d, pid_t pid,
|
int burn_drive_find_by_thread_pid(struct burn_drive **d, pid_t pid);
|
||||||
pthread_t tid);
|
|
||||||
|
|
||||||
|
|
||||||
/* ts A51221 - A80731 : Whitelist inquiry functions */
|
/* ts A51221 - A80731 : Whitelist inquiry functions */
|
||||||
@ -142,12 +135,4 @@ char *burn_drive_whitelist_item(int idx, int flag);
|
|||||||
int burn_drive_is_listed(char *path, struct burn_drive **found, int flag);
|
int burn_drive_is_listed(char *path, struct burn_drive **found, int flag);
|
||||||
|
|
||||||
|
|
||||||
/* ts B00226 : Outsourced backend of burn_abort()
|
|
||||||
@param elapsed to be subtracted from start time
|
|
||||||
@param flag bit0= do not shutdown the library
|
|
||||||
*/
|
|
||||||
int burn_abort_5(int patience,
|
|
||||||
int (*pacifier_func)(void *handle, int patience, int elapsed),
|
|
||||||
void *handle, int elapsed, int flag);
|
|
||||||
|
|
||||||
#endif /* __DRIVE */
|
#endif /* __DRIVE */
|
||||||
|
@ -1,855 +0,0 @@
|
|||||||
|
|
||||||
/* -*- 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
|
|
||||||
|
|
||||||
Copyright 2009, Thomas Schmitt <scdbackup@gmx.net>, libburnia-project.org
|
|
||||||
Provided under GPL version 2 or later.
|
|
||||||
|
|
||||||
This code module implements the production of RSPC parity bytes (P- and Q-
|
|
||||||
parity) and the scrambling of raw CD-ROM sectors as specified in ECMA-130:
|
|
||||||
http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-130.pdf
|
|
||||||
|
|
||||||
The following statements about Galois Fields have been learned mostly from
|
|
||||||
http://www.cs.utk.edu/~plank/plank/papers/CS-96-332.pdf
|
|
||||||
by James S. Plank after an e-mail exchange with Norbert Preining.
|
|
||||||
|
|
||||||
The output has been compared with the output of the old code of libburn
|
|
||||||
which was labeled "borrowed HEAVILY from cdrdao" and claimed by Joerg
|
|
||||||
Schilling to stem from code by Heiko Eissfeldt.
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------
|
|
||||||
Note: In this text, "^" denotes exponentiation and not the binary exor
|
|
||||||
operation. Confusingly in the C code "^" is said exor.
|
|
||||||
Note: This is not C1, C2 which is rather mentioned in ECMA-130 Annex C and
|
|
||||||
always performed inside the drive.
|
|
||||||
-------------------------------------------------------------------------
|
|
||||||
|
|
||||||
|
|
||||||
RSPC resp. P- and Q-Parity
|
|
||||||
|
|
||||||
ECMA-130 Annex A prescribes to compute the parity bytes for P-columns and
|
|
||||||
Q-diagonals by RSPC based on a Galois Field GF(2^8) with enumerating
|
|
||||||
polynomials x^8+x^4+x^3+x^2+1 (i.e. 0x11d) and x^1 (i.e. 0x02).
|
|
||||||
Bytes 12 to 2075 of a audio-sized sector get ordered in two byte words
|
|
||||||
as 24 rows and 43 columns. Then this matrix is split into a LSB matrix
|
|
||||||
and a MSB matrix of the same layout. Parity bytes are to be computed
|
|
||||||
from these 8-bit values.
|
|
||||||
2 P-bytes cover each column of 24 bytes. They get appended to the matrix
|
|
||||||
as rows 24 and 25.
|
|
||||||
2 Q-bytes cover each the 26 diagonals of the extended matrix.
|
|
||||||
|
|
||||||
Both parity byte pairs have to be computed so that extended rows or
|
|
||||||
diagonals match this linear equation:
|
|
||||||
H x V = (0,0)
|
|
||||||
H is a 2-row matrix of size n matching the length of the V ectors
|
|
||||||
[ 1 1 ... 1 1 ]
|
|
||||||
[ x^(n-1) x^(n-2) x^1 1 ]
|
|
||||||
Vp represents a P-row. It is a byte vector consisting of row bytes at
|
|
||||||
position 0 to 23 and the two parity bytes which shall be determined
|
|
||||||
at position 24 and 25. So Hp has 26 columns.
|
|
||||||
Vq represents a Q-diagonal. It is a byte vector consisting of diagonal
|
|
||||||
bytes at position 0 to 42 and the two parity bytes at position 43 and 44.
|
|
||||||
So Hq has 45 columns. The Q-diagonals cover P-parity bytes.
|
|
||||||
|
|
||||||
By applying some high school algebra one gets the parity bytes b0, b1 of
|
|
||||||
vector V = (n_payload_bytes, b0 , b1) as
|
|
||||||
|
|
||||||
b0 = ( H[n] * SUM(n_payload_bytes) - H[0..(n-1)] x n_payload_bytes )
|
|
||||||
/ (H[n+1] - H[n])
|
|
||||||
b1 = - SUM(n_payload_bytes) - b0
|
|
||||||
|
|
||||||
H[i] is the i-the element of the second row of matrix H. E.g. H[0] = x^(n-1)
|
|
||||||
The result has to be computed by Galois field arithmetics. See below.
|
|
||||||
|
|
||||||
The P-parity bytes of each column get reunited as LSB and MSB of two words.
|
|
||||||
word1 gets written to positions 1032 to 1074, word0 to 1075 to 1117.
|
|
||||||
The Q-parity bytes of each diagonal get reunited too. word1 goes to 1118
|
|
||||||
to 1143, word0 to 1144 to 1169.
|
|
||||||
>>> I do not read this swap of word1 and word0 from ECMA-130 Annex A.
|
|
||||||
>>> But the new output matches the old output only if it is done that way.
|
|
||||||
>>> See correctness reservation below.
|
|
||||||
|
|
||||||
Algebra on Galois fields is the same as on Rational Numbers.
|
|
||||||
But arithmetics is defined by operations on polynomials rather than the
|
|
||||||
usual integer arithmetics on binary numbers.
|
|
||||||
Addition and subtraction are identical with the binary exor operator.
|
|
||||||
Multiplication and division would demand polynomial division, e.g. by the
|
|
||||||
euclidian algorithm. The computing path over logarithms and powers follows
|
|
||||||
algebra and allows to reduce the arithmetic task to table lookups, additions
|
|
||||||
modulo 255, and exor operations. Note that the logarithms are natural
|
|
||||||
numbers, not polynomials. They get added or subtracted by the usual addition
|
|
||||||
(not by exor) and their polynomial power depends on their value modulo 255.
|
|
||||||
|
|
||||||
Needed are a logarithm table and a power table (or inverse logarithm table)
|
|
||||||
for Galois Field GF(2^8) which will serve to perform the peculiar
|
|
||||||
multiplication and division operation of Galois fields.
|
|
||||||
|
|
||||||
The power table is simply an enumeration of x^n accorting to
|
|
||||||
GF-multiplication. It also serves as second line of matrix H for the parity
|
|
||||||
equations:
|
|
||||||
Hp[i] = gfpow[25-i] , i out of {0,..,25}
|
|
||||||
Hq[i] = gfpow[44-i] , i out of {0,..,44}
|
|
||||||
|
|
||||||
The logarithm table is the inverse permutation of the power table.
|
|
||||||
|
|
||||||
Some simplifications apply to the implementation:
|
|
||||||
In the world of Galois fields there is no difference between - and +.
|
|
||||||
The term (H[n+1] - H[n]) is constant: 3.
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------
|
|
||||||
|
|
||||||
|
|
||||||
Scrambling
|
|
||||||
|
|
||||||
ECMA-130 Annex B prescribes to exor the byte stream of an audio-sized sector
|
|
||||||
with a sequence of pseudo random bytes. It mentions polynomial x^15+x+1 and
|
|
||||||
a 15-bit register.
|
|
||||||
It shows a diagram of a Feedback Shift Register with 16 bit boxes, though.
|
|
||||||
|
|
||||||
Comparing this with explanations in
|
|
||||||
http://www.newwaveinstruments.com/resources/articles/m_sequence_linear_feedback_shift_register_lfsr.htm
|
|
||||||
one can recognize the diagram as a Fibonacci Implementation. But there seems
|
|
||||||
really to be one bit box too many.
|
|
||||||
|
|
||||||
The difference of both lengths is expressed in function next_bit() by
|
|
||||||
the constants 0x3fff,0x4000 for 15 bit versus 0x7fff,0x8000 for 16 bits.
|
|
||||||
Comparing the output of both alternatives with the old scrambler output
|
|
||||||
lets 15 bit win for now.
|
|
||||||
|
|
||||||
So the prescription is to start with 15 bit value 1, to use the lowest bit
|
|
||||||
as output, to shift the bits down by one, to exor the output bit with the
|
|
||||||
next lowest bit, and to put that exor result into bit 14 of the register.
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------
|
|
||||||
|
|
||||||
|
|
||||||
Correctness Reservation
|
|
||||||
|
|
||||||
In both cases, parity and scrambling, the goal for now is to replicate the
|
|
||||||
output of the dismissed old lec.c by output which is based on published
|
|
||||||
specs and own implementation code. Whether they comply to ECMA-130 is a
|
|
||||||
different question which can only be answered by real test cases for
|
|
||||||
raw CD recording.
|
|
||||||
|
|
||||||
Of course this implementation will be corrected so that it really complies
|
|
||||||
to ECMA-130 as soon as evidence emerges that it does not yet.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------- */
|
|
||||||
|
|
||||||
|
|
||||||
/* Power and logarithm tables for GF(2^8), parity matrices for ECMA-130.
|
|
||||||
Generated by burn_rspc_setup_tables() and burn_rspc_print_tables().
|
|
||||||
|
|
||||||
The highest possible sum of gflog[] values is is 508. So the table gfpow[]
|
|
||||||
with period 255 was manually unrolled to 509 elements to avoid one modulo
|
|
||||||
255 operation in burn_rspc_mult().
|
|
||||||
Proposed by D. Hugh Redelmeier.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
static unsigned char gfpow[509] = {
|
|
||||||
1, 2, 4, 8, 16, 32, 64, 128, 29, 58,
|
|
||||||
116, 232, 205, 135, 19, 38, 76, 152, 45, 90,
|
|
||||||
180, 117, 234, 201, 143, 3, 6, 12, 24, 48,
|
|
||||||
96, 192, 157, 39, 78, 156, 37, 74, 148, 53,
|
|
||||||
106, 212, 181, 119, 238, 193, 159, 35, 70, 140,
|
|
||||||
5, 10, 20, 40, 80, 160, 93, 186, 105, 210,
|
|
||||||
185, 111, 222, 161, 95, 190, 97, 194, 153, 47,
|
|
||||||
94, 188, 101, 202, 137, 15, 30, 60, 120, 240,
|
|
||||||
253, 231, 211, 187, 107, 214, 177, 127, 254, 225,
|
|
||||||
223, 163, 91, 182, 113, 226, 217, 175, 67, 134,
|
|
||||||
17, 34, 68, 136, 13, 26, 52, 104, 208, 189,
|
|
||||||
103, 206, 129, 31, 62, 124, 248, 237, 199, 147,
|
|
||||||
59, 118, 236, 197, 151, 51, 102, 204, 133, 23,
|
|
||||||
46, 92, 184, 109, 218, 169, 79, 158, 33, 66,
|
|
||||||
132, 21, 42, 84, 168, 77, 154, 41, 82, 164,
|
|
||||||
85, 170, 73, 146, 57, 114, 228, 213, 183, 115,
|
|
||||||
230, 209, 191, 99, 198, 145, 63, 126, 252, 229,
|
|
||||||
215, 179, 123, 246, 241, 255, 227, 219, 171, 75,
|
|
||||||
150, 49, 98, 196, 149, 55, 110, 220, 165, 87,
|
|
||||||
174, 65, 130, 25, 50, 100, 200, 141, 7, 14,
|
|
||||||
28, 56, 112, 224, 221, 167, 83, 166, 81, 162,
|
|
||||||
89, 178, 121, 242, 249, 239, 195, 155, 43, 86,
|
|
||||||
172, 69, 138, 9, 18, 36, 72, 144, 61, 122,
|
|
||||||
244, 245, 247, 243, 251, 235, 203, 139, 11, 22,
|
|
||||||
44, 88, 176, 125, 250, 233, 207, 131, 27, 54,
|
|
||||||
108, 216, 173, 71, 142,
|
|
||||||
1, 2, 4, 8, 16, 32, 64, 128, 29, 58,
|
|
||||||
116, 232, 205, 135, 19, 38, 76, 152, 45, 90,
|
|
||||||
180, 117, 234, 201, 143, 3, 6, 12, 24, 48,
|
|
||||||
96, 192, 157, 39, 78, 156, 37, 74, 148, 53,
|
|
||||||
106, 212, 181, 119, 238, 193, 159, 35, 70, 140,
|
|
||||||
5, 10, 20, 40, 80, 160, 93, 186, 105, 210,
|
|
||||||
185, 111, 222, 161, 95, 190, 97, 194, 153, 47,
|
|
||||||
94, 188, 101, 202, 137, 15, 30, 60, 120, 240,
|
|
||||||
253, 231, 211, 187, 107, 214, 177, 127, 254, 225,
|
|
||||||
223, 163, 91, 182, 113, 226, 217, 175, 67, 134,
|
|
||||||
17, 34, 68, 136, 13, 26, 52, 104, 208, 189,
|
|
||||||
103, 206, 129, 31, 62, 124, 248, 237, 199, 147,
|
|
||||||
59, 118, 236, 197, 151, 51, 102, 204, 133, 23,
|
|
||||||
46, 92, 184, 109, 218, 169, 79, 158, 33, 66,
|
|
||||||
132, 21, 42, 84, 168, 77, 154, 41, 82, 164,
|
|
||||||
85, 170, 73, 146, 57, 114, 228, 213, 183, 115,
|
|
||||||
230, 209, 191, 99, 198, 145, 63, 126, 252, 229,
|
|
||||||
215, 179, 123, 246, 241, 255, 227, 219, 171, 75,
|
|
||||||
150, 49, 98, 196, 149, 55, 110, 220, 165, 87,
|
|
||||||
174, 65, 130, 25, 50, 100, 200, 141, 7, 14,
|
|
||||||
28, 56, 112, 224, 221, 167, 83, 166, 81, 162,
|
|
||||||
89, 178, 121, 242, 249, 239, 195, 155, 43, 86,
|
|
||||||
172, 69, 138, 9, 18, 36, 72, 144, 61, 122,
|
|
||||||
244, 245, 247, 243, 251, 235, 203, 139, 11, 22,
|
|
||||||
44, 88, 176, 125, 250, 233, 207, 131, 27, 54,
|
|
||||||
108, 216, 173, 71,
|
|
||||||
};
|
|
||||||
|
|
||||||
static unsigned char gflog[256] = {
|
|
||||||
0, 0, 1, 25, 2, 50, 26, 198, 3, 223,
|
|
||||||
51, 238, 27, 104, 199, 75, 4, 100, 224, 14,
|
|
||||||
52, 141, 239, 129, 28, 193, 105, 248, 200, 8,
|
|
||||||
76, 113, 5, 138, 101, 47, 225, 36, 15, 33,
|
|
||||||
53, 147, 142, 218, 240, 18, 130, 69, 29, 181,
|
|
||||||
194, 125, 106, 39, 249, 185, 201, 154, 9, 120,
|
|
||||||
77, 228, 114, 166, 6, 191, 139, 98, 102, 221,
|
|
||||||
48, 253, 226, 152, 37, 179, 16, 145, 34, 136,
|
|
||||||
54, 208, 148, 206, 143, 150, 219, 189, 241, 210,
|
|
||||||
19, 92, 131, 56, 70, 64, 30, 66, 182, 163,
|
|
||||||
195, 72, 126, 110, 107, 58, 40, 84, 250, 133,
|
|
||||||
186, 61, 202, 94, 155, 159, 10, 21, 121, 43,
|
|
||||||
78, 212, 229, 172, 115, 243, 167, 87, 7, 112,
|
|
||||||
192, 247, 140, 128, 99, 13, 103, 74, 222, 237,
|
|
||||||
49, 197, 254, 24, 227, 165, 153, 119, 38, 184,
|
|
||||||
180, 124, 17, 68, 146, 217, 35, 32, 137, 46,
|
|
||||||
55, 63, 209, 91, 149, 188, 207, 205, 144, 135,
|
|
||||||
151, 178, 220, 252, 190, 97, 242, 86, 211, 171,
|
|
||||||
20, 42, 93, 158, 132, 60, 57, 83, 71, 109,
|
|
||||||
65, 162, 31, 45, 67, 216, 183, 123, 164, 118,
|
|
||||||
196, 23, 73, 236, 127, 12, 111, 246, 108, 161,
|
|
||||||
59, 82, 41, 157, 85, 170, 251, 96, 134, 177,
|
|
||||||
187, 204, 62, 90, 203, 89, 95, 176, 156, 169,
|
|
||||||
160, 81, 11, 245, 22, 235, 122, 117, 44, 215,
|
|
||||||
79, 174, 213, 233, 230, 231, 173, 232, 116, 214,
|
|
||||||
244, 234, 168, 80, 88, 175
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
#define Libburn_use_h_matriceS 1
|
|
||||||
|
|
||||||
#ifdef Libburn_use_h_matriceS
|
|
||||||
|
|
||||||
/* On my AMD 2x64 bit 3000 MHz processor h[i] costs about 7 % more time
|
|
||||||
than using gfpow[25-i] resp. gfpow[44-1]. I blame this on the more
|
|
||||||
condensed data representation which slightly increases the rate of cache
|
|
||||||
hits.
|
|
||||||
Nevertheless this effect is very likely depending on the exact cache
|
|
||||||
size and architecture. In general, using h[] saves more than 8000
|
|
||||||
subtractions per sector.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Parity matrices H as prescribed by ECMA-130 Annex A.
|
|
||||||
Actually just reverted order start pieces of gfpow[].
|
|
||||||
*/
|
|
||||||
static unsigned char h26[26] = {
|
|
||||||
3, 143, 201, 234, 117, 180, 90, 45, 152, 76,
|
|
||||||
38, 19, 135, 205, 232, 116, 58, 29, 128, 64,
|
|
||||||
32, 16, 8, 4, 2, 1,
|
|
||||||
};
|
|
||||||
|
|
||||||
static unsigned char h45[45] = {
|
|
||||||
238, 119, 181, 212, 106, 53, 148, 74, 37, 156,
|
|
||||||
78, 39, 157, 192, 96, 48, 24, 12, 6, 3,
|
|
||||||
143, 201, 234, 117, 180, 90, 45, 152, 76, 38,
|
|
||||||
19, 135, 205, 232, 116, 58, 29, 128, 64, 32,
|
|
||||||
16, 8, 4, 2, 1,
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /* Libburn_use_h_matriceS */
|
|
||||||
|
|
||||||
|
|
||||||
/* Pseudo-random bytes which of course are exactly the same as with the
|
|
||||||
previously used code.
|
|
||||||
Generated by function print_ecma_130_scrambler().
|
|
||||||
*/
|
|
||||||
static unsigned char ecma_130_annex_b[2340] = {
|
|
||||||
1, 128, 0, 96, 0, 40, 0, 30, 128, 8,
|
|
||||||
96, 6, 168, 2, 254, 129, 128, 96, 96, 40,
|
|
||||||
40, 30, 158, 136, 104, 102, 174, 170, 252, 127,
|
|
||||||
1, 224, 0, 72, 0, 54, 128, 22, 224, 14,
|
|
||||||
200, 4, 86, 131, 126, 225, 224, 72, 72, 54,
|
|
||||||
182, 150, 246, 238, 198, 204, 82, 213, 253, 159,
|
|
||||||
1, 168, 0, 126, 128, 32, 96, 24, 40, 10,
|
|
||||||
158, 135, 40, 98, 158, 169, 168, 126, 254, 160,
|
|
||||||
64, 120, 48, 34, 148, 25, 175, 74, 252, 55,
|
|
||||||
1, 214, 128, 94, 224, 56, 72, 18, 182, 141,
|
|
||||||
182, 229, 182, 203, 54, 215, 86, 222, 190, 216,
|
|
||||||
112, 90, 164, 59, 59, 83, 83, 125, 253, 225,
|
|
||||||
129, 136, 96, 102, 168, 42, 254, 159, 0, 104,
|
|
||||||
0, 46, 128, 28, 96, 9, 232, 6, 206, 130,
|
|
||||||
212, 97, 159, 104, 104, 46, 174, 156, 124, 105,
|
|
||||||
225, 238, 200, 76, 86, 181, 254, 247, 0, 70,
|
|
||||||
128, 50, 224, 21, 136, 15, 38, 132, 26, 227,
|
|
||||||
75, 9, 247, 70, 198, 178, 210, 245, 157, 135,
|
|
||||||
41, 162, 158, 249, 168, 66, 254, 177, 128, 116,
|
|
||||||
96, 39, 104, 26, 174, 139, 60, 103, 81, 234,
|
|
||||||
188, 79, 49, 244, 20, 71, 79, 114, 180, 37,
|
|
||||||
183, 91, 54, 187, 86, 243, 126, 197, 224, 83,
|
|
||||||
8, 61, 198, 145, 146, 236, 109, 141, 237, 165,
|
|
||||||
141, 187, 37, 179, 91, 53, 251, 87, 3, 126,
|
|
||||||
129, 224, 96, 72, 40, 54, 158, 150, 232, 110,
|
|
||||||
206, 172, 84, 125, 255, 97, 128, 40, 96, 30,
|
|
||||||
168, 8, 126, 134, 160, 98, 248, 41, 130, 158,
|
|
||||||
225, 168, 72, 126, 182, 160, 118, 248, 38, 194,
|
|
||||||
154, 209, 171, 28, 127, 73, 224, 54, 200, 22,
|
|
||||||
214, 142, 222, 228, 88, 75, 122, 183, 99, 54,
|
|
||||||
169, 214, 254, 222, 192, 88, 80, 58, 188, 19,
|
|
||||||
49, 205, 212, 85, 159, 127, 40, 32, 30, 152,
|
|
||||||
8, 106, 134, 175, 34, 252, 25, 129, 202, 224,
|
|
||||||
87, 8, 62, 134, 144, 98, 236, 41, 141, 222,
|
|
||||||
229, 152, 75, 42, 183, 95, 54, 184, 22, 242,
|
|
||||||
142, 197, 164, 83, 59, 125, 211, 97, 157, 232,
|
|
||||||
105, 142, 174, 228, 124, 75, 97, 247, 104, 70,
|
|
||||||
174, 178, 252, 117, 129, 231, 32, 74, 152, 55,
|
|
||||||
42, 150, 159, 46, 232, 28, 78, 137, 244, 102,
|
|
||||||
199, 106, 210, 175, 29, 188, 9, 177, 198, 244,
|
|
||||||
82, 199, 125, 146, 161, 173, 184, 125, 178, 161,
|
|
||||||
181, 184, 119, 50, 166, 149, 186, 239, 51, 12,
|
|
||||||
21, 197, 207, 19, 20, 13, 207, 69, 148, 51,
|
|
||||||
47, 85, 220, 63, 25, 208, 10, 220, 7, 25,
|
|
||||||
194, 138, 209, 167, 28, 122, 137, 227, 38, 201,
|
|
||||||
218, 214, 219, 30, 219, 72, 91, 118, 187, 102,
|
|
||||||
243, 106, 197, 239, 19, 12, 13, 197, 197, 147,
|
|
||||||
19, 45, 205, 221, 149, 153, 175, 42, 252, 31,
|
|
||||||
1, 200, 0, 86, 128, 62, 224, 16, 72, 12,
|
|
||||||
54, 133, 214, 227, 30, 201, 200, 86, 214, 190,
|
|
||||||
222, 240, 88, 68, 58, 179, 83, 53, 253, 215,
|
|
||||||
1, 158, 128, 104, 96, 46, 168, 28, 126, 137,
|
|
||||||
224, 102, 200, 42, 214, 159, 30, 232, 8, 78,
|
|
||||||
134, 180, 98, 247, 105, 134, 174, 226, 252, 73,
|
|
||||||
129, 246, 224, 70, 200, 50, 214, 149, 158, 239,
|
|
||||||
40, 76, 30, 181, 200, 119, 22, 166, 142, 250,
|
|
||||||
228, 67, 11, 113, 199, 100, 82, 171, 125, 191,
|
|
||||||
97, 176, 40, 116, 30, 167, 72, 122, 182, 163,
|
|
||||||
54, 249, 214, 194, 222, 209, 152, 92, 106, 185,
|
|
||||||
239, 50, 204, 21, 149, 207, 47, 20, 28, 15,
|
|
||||||
73, 196, 54, 211, 86, 221, 254, 217, 128, 90,
|
|
||||||
224, 59, 8, 19, 70, 141, 242, 229, 133, 139,
|
|
||||||
35, 39, 89, 218, 186, 219, 51, 27, 85, 203,
|
|
||||||
127, 23, 96, 14, 168, 4, 126, 131, 96, 97,
|
|
||||||
232, 40, 78, 158, 180, 104, 119, 110, 166, 172,
|
|
||||||
122, 253, 227, 1, 137, 192, 102, 208, 42, 220,
|
|
||||||
31, 25, 200, 10, 214, 135, 30, 226, 136, 73,
|
|
||||||
166, 182, 250, 246, 195, 6, 209, 194, 220, 81,
|
|
||||||
153, 252, 106, 193, 239, 16, 76, 12, 53, 197,
|
|
||||||
215, 19, 30, 141, 200, 101, 150, 171, 46, 255,
|
|
||||||
92, 64, 57, 240, 18, 196, 13, 147, 69, 173,
|
|
||||||
243, 61, 133, 209, 163, 28, 121, 201, 226, 214,
|
|
||||||
201, 158, 214, 232, 94, 206, 184, 84, 114, 191,
|
|
||||||
101, 176, 43, 52, 31, 87, 72, 62, 182, 144,
|
|
||||||
118, 236, 38, 205, 218, 213, 155, 31, 43, 72,
|
|
||||||
31, 118, 136, 38, 230, 154, 202, 235, 23, 15,
|
|
||||||
78, 132, 52, 99, 87, 105, 254, 174, 192, 124,
|
|
||||||
80, 33, 252, 24, 65, 202, 176, 87, 52, 62,
|
|
||||||
151, 80, 110, 188, 44, 113, 221, 228, 89, 139,
|
|
||||||
122, 231, 99, 10, 169, 199, 62, 210, 144, 93,
|
|
||||||
172, 57, 189, 210, 241, 157, 132, 105, 163, 110,
|
|
||||||
249, 236, 66, 205, 241, 149, 132, 111, 35, 108,
|
|
||||||
25, 237, 202, 205, 151, 21, 174, 143, 60, 100,
|
|
||||||
17, 235, 76, 79, 117, 244, 39, 7, 90, 130,
|
|
||||||
187, 33, 179, 88, 117, 250, 167, 3, 58, 129,
|
|
||||||
211, 32, 93, 216, 57, 154, 146, 235, 45, 143,
|
|
||||||
93, 164, 57, 187, 82, 243, 125, 133, 225, 163,
|
|
||||||
8, 121, 198, 162, 210, 249, 157, 130, 233, 161,
|
|
||||||
142, 248, 100, 66, 171, 113, 191, 100, 112, 43,
|
|
||||||
100, 31, 107, 72, 47, 118, 156, 38, 233, 218,
|
|
||||||
206, 219, 20, 91, 79, 123, 116, 35, 103, 89,
|
|
||||||
234, 186, 207, 51, 20, 21, 207, 79, 20, 52,
|
|
||||||
15, 87, 68, 62, 179, 80, 117, 252, 39, 1,
|
|
||||||
218, 128, 91, 32, 59, 88, 19, 122, 141, 227,
|
|
||||||
37, 137, 219, 38, 219, 90, 219, 123, 27, 99,
|
|
||||||
75, 105, 247, 110, 198, 172, 82, 253, 253, 129,
|
|
||||||
129, 160, 96, 120, 40, 34, 158, 153, 168, 106,
|
|
||||||
254, 175, 0, 124, 0, 33, 192, 24, 80, 10,
|
|
||||||
188, 7, 49, 194, 148, 81, 175, 124, 124, 33,
|
|
||||||
225, 216, 72, 90, 182, 187, 54, 243, 86, 197,
|
|
||||||
254, 211, 0, 93, 192, 57, 144, 18, 236, 13,
|
|
||||||
141, 197, 165, 147, 59, 45, 211, 93, 157, 249,
|
|
||||||
169, 130, 254, 225, 128, 72, 96, 54, 168, 22,
|
|
||||||
254, 142, 192, 100, 80, 43, 124, 31, 97, 200,
|
|
||||||
40, 86, 158, 190, 232, 112, 78, 164, 52, 123,
|
|
||||||
87, 99, 126, 169, 224, 126, 200, 32, 86, 152,
|
|
||||||
62, 234, 144, 79, 44, 52, 29, 215, 73, 158,
|
|
||||||
182, 232, 118, 206, 166, 212, 122, 223, 99, 24,
|
|
||||||
41, 202, 158, 215, 40, 94, 158, 184, 104, 114,
|
|
||||||
174, 165, 188, 123, 49, 227, 84, 73, 255, 118,
|
|
||||||
192, 38, 208, 26, 220, 11, 25, 199, 74, 210,
|
|
||||||
183, 29, 182, 137, 182, 230, 246, 202, 198, 215,
|
|
||||||
18, 222, 141, 152, 101, 170, 171, 63, 63, 80,
|
|
||||||
16, 60, 12, 17, 197, 204, 83, 21, 253, 207,
|
|
||||||
1, 148, 0, 111, 64, 44, 48, 29, 212, 9,
|
|
||||||
159, 70, 232, 50, 206, 149, 148, 111, 47, 108,
|
|
||||||
28, 45, 201, 221, 150, 217, 174, 218, 252, 91,
|
|
||||||
1, 251, 64, 67, 112, 49, 228, 20, 75, 79,
|
|
||||||
119, 116, 38, 167, 90, 250, 187, 3, 51, 65,
|
|
||||||
213, 240, 95, 4, 56, 3, 82, 129, 253, 160,
|
|
||||||
65, 184, 48, 114, 148, 37, 175, 91, 60, 59,
|
|
||||||
81, 211, 124, 93, 225, 249, 136, 66, 230, 177,
|
|
||||||
138, 244, 103, 7, 106, 130, 175, 33, 188, 24,
|
|
||||||
113, 202, 164, 87, 59, 126, 147, 96, 109, 232,
|
|
||||||
45, 142, 157, 164, 105, 187, 110, 243, 108, 69,
|
|
||||||
237, 243, 13, 133, 197, 163, 19, 57, 205, 210,
|
|
||||||
213, 157, 159, 41, 168, 30, 254, 136, 64, 102,
|
|
||||||
176, 42, 244, 31, 7, 72, 2, 182, 129, 182,
|
|
||||||
224, 118, 200, 38, 214, 154, 222, 235, 24, 79,
|
|
||||||
74, 180, 55, 55, 86, 150, 190, 238, 240, 76,
|
|
||||||
68, 53, 243, 87, 5, 254, 131, 0, 97, 192,
|
|
||||||
40, 80, 30, 188, 8, 113, 198, 164, 82, 251,
|
|
||||||
125, 131, 97, 161, 232, 120, 78, 162, 180, 121,
|
|
||||||
183, 98, 246, 169, 134, 254, 226, 192, 73, 144,
|
|
||||||
54, 236, 22, 205, 206, 213, 148, 95, 47, 120,
|
|
||||||
28, 34, 137, 217, 166, 218, 250, 219, 3, 27,
|
|
||||||
65, 203, 112, 87, 100, 62, 171, 80, 127, 124,
|
|
||||||
32, 33, 216, 24, 90, 138, 187, 39, 51, 90,
|
|
||||||
149, 251, 47, 3, 92, 1, 249, 192, 66, 208,
|
|
||||||
49, 156, 20, 105, 207, 110, 212, 44, 95, 93,
|
|
||||||
248, 57, 130, 146, 225, 173, 136, 125, 166, 161,
|
|
||||||
186, 248, 115, 2, 165, 193, 187, 16, 115, 76,
|
|
||||||
37, 245, 219, 7, 27, 66, 139, 113, 167, 100,
|
|
||||||
122, 171, 99, 63, 105, 208, 46, 220, 28, 89,
|
|
||||||
201, 250, 214, 195, 30, 209, 200, 92, 86, 185,
|
|
||||||
254, 242, 192, 69, 144, 51, 44, 21, 221, 207,
|
|
||||||
25, 148, 10, 239, 71, 12, 50, 133, 213, 163,
|
|
||||||
31, 57, 200, 18, 214, 141, 158, 229, 168, 75,
|
|
||||||
62, 183, 80, 118, 188, 38, 241, 218, 196, 91,
|
|
||||||
19, 123, 77, 227, 117, 137, 231, 38, 202, 154,
|
|
||||||
215, 43, 30, 159, 72, 104, 54, 174, 150, 252,
|
|
||||||
110, 193, 236, 80, 77, 252, 53, 129, 215, 32,
|
|
||||||
94, 152, 56, 106, 146, 175, 45, 188, 29, 177,
|
|
||||||
201, 180, 86, 247, 126, 198, 160, 82, 248, 61,
|
|
||||||
130, 145, 161, 172, 120, 125, 226, 161, 137, 184,
|
|
||||||
102, 242, 170, 197, 191, 19, 48, 13, 212, 5,
|
|
||||||
159, 67, 40, 49, 222, 148, 88, 111, 122, 172,
|
|
||||||
35, 61, 217, 209, 154, 220, 107, 25, 239, 74,
|
|
||||||
204, 55, 21, 214, 143, 30, 228, 8, 75, 70,
|
|
||||||
183, 114, 246, 165, 134, 251, 34, 195, 89, 145,
|
|
||||||
250, 236, 67, 13, 241, 197, 132, 83, 35, 125,
|
|
||||||
217, 225, 154, 200, 107, 22, 175, 78, 252, 52,
|
|
||||||
65, 215, 112, 94, 164, 56, 123, 82, 163, 125,
|
|
||||||
185, 225, 178, 200, 117, 150, 167, 46, 250, 156,
|
|
||||||
67, 41, 241, 222, 196, 88, 83, 122, 189, 227,
|
|
||||||
49, 137, 212, 102, 223, 106, 216, 47, 26, 156,
|
|
||||||
11, 41, 199, 94, 210, 184, 93, 178, 185, 181,
|
|
||||||
178, 247, 53, 134, 151, 34, 238, 153, 140, 106,
|
|
||||||
229, 239, 11, 12, 7, 69, 194, 179, 17, 181,
|
|
||||||
204, 119, 21, 230, 143, 10, 228, 7, 11, 66,
|
|
||||||
135, 113, 162, 164, 121, 187, 98, 243, 105, 133,
|
|
||||||
238, 227, 12, 73, 197, 246, 211, 6, 221, 194,
|
|
||||||
217, 145, 154, 236, 107, 13, 239, 69, 140, 51,
|
|
||||||
37, 213, 219, 31, 27, 72, 11, 118, 135, 102,
|
|
||||||
226, 170, 201, 191, 22, 240, 14, 196, 4, 83,
|
|
||||||
67, 125, 241, 225, 132, 72, 99, 118, 169, 230,
|
|
||||||
254, 202, 192, 87, 16, 62, 140, 16, 101, 204,
|
|
||||||
43, 21, 223, 79, 24, 52, 10, 151, 71, 46,
|
|
||||||
178, 156, 117, 169, 231, 62, 202, 144, 87, 44,
|
|
||||||
62, 157, 208, 105, 156, 46, 233, 220, 78, 217,
|
|
||||||
244, 90, 199, 123, 18, 163, 77, 185, 245, 178,
|
|
||||||
199, 53, 146, 151, 45, 174, 157, 188, 105, 177,
|
|
||||||
238, 244, 76, 71, 117, 242, 167, 5, 186, 131,
|
|
||||||
51, 33, 213, 216, 95, 26, 184, 11, 50, 135,
|
|
||||||
85, 162, 191, 57, 176, 18, 244, 13, 135, 69,
|
|
||||||
162, 179, 57, 181, 210, 247, 29, 134, 137, 162,
|
|
||||||
230, 249, 138, 194, 231, 17, 138, 140, 103, 37,
|
|
||||||
234, 155, 15, 43, 68, 31, 115, 72, 37, 246,
|
|
||||||
155, 6, 235, 66, 207, 113, 148, 36, 111, 91,
|
|
||||||
108, 59, 109, 211, 109, 157, 237, 169, 141, 190,
|
|
||||||
229, 176, 75, 52, 55, 87, 86, 190, 190, 240,
|
|
||||||
112, 68, 36, 51, 91, 85, 251, 127, 3, 96,
|
|
||||||
1, 232, 0, 78, 128, 52, 96, 23, 104, 14,
|
|
||||||
174, 132, 124, 99, 97, 233, 232, 78, 206, 180,
|
|
||||||
84, 119, 127, 102, 160, 42, 248, 31, 2, 136,
|
|
||||||
1, 166, 128, 122, 224, 35, 8, 25, 198, 138,
|
|
||||||
210, 231, 29, 138, 137, 167, 38, 250, 154, 195,
|
|
||||||
43, 17, 223, 76, 88, 53, 250, 151, 3, 46,
|
|
||||||
129, 220, 96, 89, 232, 58, 206, 147, 20, 109,
|
|
||||||
207, 109, 148, 45, 175, 93, 188, 57, 177, 210,
|
|
||||||
244, 93, 135, 121, 162, 162, 249, 185, 130, 242,
|
|
||||||
225, 133, 136, 99, 38, 169, 218, 254, 219, 0,
|
|
||||||
91, 64, 59, 112, 19, 100, 13, 235, 69, 143,
|
|
||||||
115, 36, 37, 219, 91, 27, 123, 75, 99, 119,
|
|
||||||
105, 230, 174, 202, 252, 87, 1, 254, 128, 64,
|
|
||||||
96, 48, 40, 20, 30, 143, 72, 100, 54, 171,
|
|
||||||
86, 255, 126, 192, 32, 80, 24, 60, 10, 145,
|
|
||||||
199, 44, 82, 157, 253, 169, 129, 190, 224, 112,
|
|
||||||
72, 36, 54, 155, 86, 235, 126, 207, 96, 84,
|
|
||||||
40, 63, 94, 144, 56, 108, 18, 173, 205, 189,
|
|
||||||
149, 177, 175, 52, 124, 23, 97, 206, 168, 84,
|
|
||||||
126, 191, 96, 112, 40, 36, 30, 155, 72, 107,
|
|
||||||
118, 175, 102, 252, 42, 193, 223, 16, 88, 12,
|
|
||||||
58, 133, 211, 35, 29, 217, 201, 154, 214, 235,
|
|
||||||
30, 207, 72, 84, 54, 191, 86, 240, 62, 196,
|
|
||||||
16, 83, 76, 61, 245, 209, 135, 28, 98, 137,
|
|
||||||
233, 166, 206, 250, 212, 67, 31, 113, 200, 36,
|
|
||||||
86, 155, 126, 235, 96, 79, 104, 52, 46, 151,
|
|
||||||
92, 110, 185, 236, 114, 205, 229, 149, 139, 47,
|
|
||||||
39, 92, 26, 185, 203, 50, 215, 85, 158, 191,
|
|
||||||
40, 112, 30, 164, 8, 123, 70, 163, 114, 249,
|
|
||||||
229, 130, 203, 33, 151, 88, 110, 186, 172, 115,
|
|
||||||
61, 229, 209, 139, 28, 103, 73, 234, 182, 207,
|
|
||||||
54, 212, 22, 223, 78, 216, 52, 90, 151, 123,
|
|
||||||
46, 163, 92, 121, 249, 226, 194, 201, 145, 150,
|
|
||||||
236, 110, 205, 236, 85, 141, 255, 37, 128, 27,
|
|
||||||
32, 11, 88, 7, 122, 130, 163, 33, 185, 216,
|
|
||||||
114, 218, 165, 155, 59, 43, 83, 95, 125, 248,
|
|
||||||
33, 130, 152, 97, 170, 168, 127, 62, 160, 16,
|
|
||||||
120, 12, 34, 133, 217, 163, 26, 249, 203, 2,
|
|
||||||
215, 65, 158, 176, 104, 116, 46, 167, 92, 122,
|
|
||||||
185, 227, 50, 201, 213, 150, 223, 46, 216, 28,
|
|
||||||
90, 137, 251, 38, 195, 90, 209, 251, 28, 67,
|
|
||||||
73, 241, 246, 196, 70, 211, 114, 221, 229, 153
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------- */
|
|
||||||
|
|
||||||
|
|
||||||
/* This is the new implementation of P- and Q-parity generation.
|
|
||||||
It needs about the same computing time as the old implementation (both
|
|
||||||
with gcc -O2 on AMD 64 bit). Measurements indicate that about 280 MIPS
|
|
||||||
are needed for 48x CD speed (7.1 MB/s).
|
|
||||||
*/
|
|
||||||
|
|
||||||
static unsigned char burn_rspc_mult(unsigned char a, unsigned char b)
|
|
||||||
{
|
|
||||||
if (a == 0 || b == 0)
|
|
||||||
return 0;
|
|
||||||
/* Optimization of (a == 0 || b == 0) by D. Hugh Redelmeier
|
|
||||||
if((((int)a - 1) | ((int)b - 1)) < 0)
|
|
||||||
return 0;
|
|
||||||
*/
|
|
||||||
|
|
||||||
return gfpow[gflog[a] + gflog[b]];
|
|
||||||
/* % 255 not necessary because gfpow is unrolled up to index 510 */
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Divide by polynomial 0x03. Derived from burn_rspc_div() and using the
|
|
||||||
unrolled size of the gfpow[] array.
|
|
||||||
*/
|
|
||||||
static unsigned char burn_rspc_div_3(unsigned char a)
|
|
||||||
{
|
|
||||||
if (a == 0)
|
|
||||||
return 0;
|
|
||||||
return gfpow[230 + gflog[a]];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void burn_rspc_p0p1(unsigned char *sector, int col,
|
|
||||||
unsigned char *p0_lsb, unsigned char *p0_msb,
|
|
||||||
unsigned char *p1_lsb, unsigned char *p1_msb)
|
|
||||||
{
|
|
||||||
unsigned char *start, b;
|
|
||||||
unsigned int i, sum_v_lsb = 0, sum_v_msb = 0;
|
|
||||||
unsigned int hxv_lsb = 0, hxv_msb = 0;
|
|
||||||
|
|
||||||
start = sector + 12 + 2 * col;
|
|
||||||
for(i = 0; i < 24; i++) {
|
|
||||||
b = *start;
|
|
||||||
sum_v_lsb ^= b;
|
|
||||||
|
|
||||||
#ifdef Libburn_use_h_matriceS
|
|
||||||
hxv_lsb ^= burn_rspc_mult(b, h26[i]);
|
|
||||||
#else
|
|
||||||
hxv_lsb ^= burn_rspc_mult(b, gfpow[25 - i]);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
b = *(start + 1);
|
|
||||||
sum_v_msb ^= b;
|
|
||||||
|
|
||||||
#ifdef Libburn_use_h_matriceS
|
|
||||||
hxv_msb ^= burn_rspc_mult(b, h26[i]);
|
|
||||||
#else
|
|
||||||
hxv_msb ^= burn_rspc_mult(b, gfpow[25 - i]);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
start += 86;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 3 = gfpow[1] ^ gfpow[0] , 2 = gfpow[1] */
|
|
||||||
*p0_lsb = burn_rspc_div_3(burn_rspc_mult(2, sum_v_lsb) ^ hxv_lsb);
|
|
||||||
*p0_msb = burn_rspc_div_3(burn_rspc_mult(2, sum_v_msb) ^ hxv_msb);
|
|
||||||
*p1_lsb = sum_v_lsb ^ *p0_lsb;
|
|
||||||
*p1_msb = sum_v_msb ^ *p0_msb;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void burn_rspc_parity_p(unsigned char *sector)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
unsigned char p0_lsb, p0_msb, p1_lsb, p1_msb;
|
|
||||||
|
|
||||||
/* Loop over P columns */
|
|
||||||
for(i = 0; i < 43; i++) {
|
|
||||||
burn_rspc_p0p1(sector, i, &p0_lsb, &p0_msb, &p1_lsb, &p1_msb);
|
|
||||||
sector[2162 + 2 * i] = p0_lsb;
|
|
||||||
sector[2162 + 2 * i + 1] = p0_msb;
|
|
||||||
sector[2076 + 2 * i] = p1_lsb;
|
|
||||||
sector[2076 + 2 * i + 1] = p1_msb;
|
|
||||||
|
|
||||||
#ifdef Libburn_with_lec_generatoR
|
|
||||||
if(verbous) {
|
|
||||||
printf("p %2d : %2.2X %2.2X ", i,
|
|
||||||
(unsigned int) p0_lsb, (unsigned int) p0_msb);
|
|
||||||
printf("%2.2X %2.2X ",
|
|
||||||
(unsigned int) p1_lsb, (unsigned int) p1_msb);
|
|
||||||
printf("-> %d,%d\n", 2162 + 2 * i, 2076 + 2 * i);
|
|
||||||
}
|
|
||||||
#endif /* Libburn_with_lec_generatoR */
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void burn_rspc_q0q1(unsigned char *sector, int diag,
|
|
||||||
unsigned char *q0_lsb, unsigned char *q0_msb,
|
|
||||||
unsigned char *q1_lsb, unsigned char *q1_msb)
|
|
||||||
{
|
|
||||||
unsigned char *start, b;
|
|
||||||
unsigned int i, idx, sum_v_lsb = 0, sum_v_msb = 0;
|
|
||||||
unsigned int hxv_lsb = 0, hxv_msb = 0;
|
|
||||||
|
|
||||||
start = sector + 12;
|
|
||||||
idx = 2 * 43 * diag;
|
|
||||||
for(i = 0; i < 43; i++) {
|
|
||||||
if (idx >= 2236)
|
|
||||||
idx -= 2236;
|
|
||||||
b = start[idx];
|
|
||||||
sum_v_lsb ^= b;
|
|
||||||
|
|
||||||
#ifdef Libburn_use_h_matriceS
|
|
||||||
hxv_lsb ^= burn_rspc_mult(b, h45[i]);
|
|
||||||
#else
|
|
||||||
hxv_lsb ^= burn_rspc_mult(b, gfpow[44 - i]);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
b = start[idx + 1];
|
|
||||||
sum_v_msb ^= b;
|
|
||||||
|
|
||||||
#ifdef Libburn_use_h_matriceS
|
|
||||||
hxv_msb ^= burn_rspc_mult(b, h45[i]);
|
|
||||||
#else
|
|
||||||
hxv_msb ^= burn_rspc_mult(b, gfpow[44 - i]);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
idx += 88;
|
|
||||||
}
|
|
||||||
/* 3 = gfpow[1] ^ gfpow[0] , 2 = gfpow[1] */
|
|
||||||
*q0_lsb = burn_rspc_div_3(burn_rspc_mult(2, sum_v_lsb) ^ hxv_lsb);
|
|
||||||
*q0_msb = burn_rspc_div_3(burn_rspc_mult(2, sum_v_msb) ^ hxv_msb);
|
|
||||||
*q1_lsb = sum_v_lsb ^ *q0_lsb;
|
|
||||||
*q1_msb = sum_v_msb ^ *q0_msb;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void burn_rspc_parity_q(unsigned char *sector)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
unsigned char q0_lsb, q0_msb, q1_lsb, q1_msb;
|
|
||||||
|
|
||||||
/* Loop over Q diagonals */
|
|
||||||
for(i = 0; i < 26; i++) {
|
|
||||||
burn_rspc_q0q1(sector, i, &q0_lsb, &q0_msb, &q1_lsb, &q1_msb);
|
|
||||||
sector[2300 + 2 * i] = q0_lsb;
|
|
||||||
sector[2300 + 2 * i + 1] = q0_msb;
|
|
||||||
sector[2248 + 2 * i] = q1_lsb;
|
|
||||||
sector[2248 + 2 * i + 1] = q1_msb;
|
|
||||||
|
|
||||||
#ifdef Libburn_with_lec_generatoR
|
|
||||||
if(verbous) {
|
|
||||||
printf("q %2d : %2.2X %2.2X ", i,
|
|
||||||
(unsigned int) q0_lsb, (unsigned int) q0_msb);
|
|
||||||
printf("%2.2X %2.2X ",
|
|
||||||
(unsigned int) q1_lsb, (unsigned int) q1_msb);
|
|
||||||
printf("-> %d,%d\n", 2300 + 2 * i, 2248 + 2 * i);
|
|
||||||
}
|
|
||||||
#endif /* Libburn_with_lec_generatoR */
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------- */
|
|
||||||
|
|
||||||
|
|
||||||
/* The new implementation of the ECMA-130 Annex B scrambler.
|
|
||||||
It is totally unoptimized. One should make use of larger word operations.
|
|
||||||
Measurements indicate that about 50 MIPS are needed for 48x CD speed.
|
|
||||||
*/
|
|
||||||
|
|
||||||
void burn_ecma130_scramble(unsigned char *sector)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
unsigned char *s;
|
|
||||||
|
|
||||||
s = sector + 12;
|
|
||||||
for (i = 0; i < 2340; i++)
|
|
||||||
s[i] ^= ecma_130_annex_b[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------- */
|
|
||||||
|
|
||||||
|
|
||||||
/* The following code is not needed for libburn but rather documents the
|
|
||||||
origin of the tables above. In libburn it will not be compiled.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef Libburn_with_lec_generatoR
|
|
||||||
|
|
||||||
|
|
||||||
/* This function produced the content of gflog[] and gfpow[]
|
|
||||||
*/
|
|
||||||
static int burn_rspc_setup_tables(void)
|
|
||||||
{
|
|
||||||
unsigned int b, l;
|
|
||||||
|
|
||||||
memset(gflog, 0, sizeof(gflog));
|
|
||||||
memset(gfpow, 0, sizeof(gfpow));
|
|
||||||
b = 1;
|
|
||||||
for (l = 0; l < 255; l++) {
|
|
||||||
gfpow[l] = (unsigned char) b;
|
|
||||||
gflog[b] = (unsigned char) l;
|
|
||||||
b = b << 1;
|
|
||||||
if (b & 256)
|
|
||||||
b = b ^ 0x11d;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* This function printed the content of gflog[] and gfpow[] as C code
|
|
||||||
and compared the content with the tables of the old implementation.
|
|
||||||
h26[] and h45[] are reverted order copies of gfpow[]
|
|
||||||
*/
|
|
||||||
static int burn_rspc_print_tables(void)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
printf("static unsigned char gfpow[255] = {");
|
|
||||||
printf("\n\t");
|
|
||||||
for(i= 0; i < 255; i++) {
|
|
||||||
printf("%3u, ", gfpow[i]);
|
|
||||||
|
|
||||||
#ifdef Libburn_with_old_lec_comparisoN
|
|
||||||
if(gfpow[i] != gf8_ilog[i])
|
|
||||||
fprintf(stderr, "*** ILOG %d : %d != %d ***\n", i, gfpow[i], gf8_ilog[i]);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if((i % 10) == 9)
|
|
||||||
printf("\n\t");
|
|
||||||
}
|
|
||||||
printf("\n};\n\n");
|
|
||||||
|
|
||||||
printf("static unsigned char gflog[256] = {");
|
|
||||||
printf("\n\t");
|
|
||||||
for(i= 0; i < 256; i++) {
|
|
||||||
printf(" %3u,", gflog[i]);
|
|
||||||
|
|
||||||
#ifdef Libburn_with_old_lec_comparisoN
|
|
||||||
if(gflog[i] != gf8_log[i])
|
|
||||||
fprintf(stderr, "*** LOG %d : %d != %d ***\n", i, gflog[i], gf8_log[i]);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if((i % 10) == 9)
|
|
||||||
printf("\n\t");
|
|
||||||
}
|
|
||||||
printf("\n};\n\n");
|
|
||||||
|
|
||||||
printf("static unsigned char h26[26] = {");
|
|
||||||
printf("\n\t");
|
|
||||||
for(i= 0; i < 26; i++) {
|
|
||||||
printf(" %3u,", gfpow[25 - i]);
|
|
||||||
if((i % 10) == 9)
|
|
||||||
printf("\n\t");
|
|
||||||
}
|
|
||||||
printf("\n};\n\n");
|
|
||||||
|
|
||||||
printf("static unsigned char h45[45] = {");
|
|
||||||
printf("\n\t");
|
|
||||||
for(i= 0; i < 45; i++) {
|
|
||||||
printf(" %3u,",gfpow[44 - i]);
|
|
||||||
if((i % 10) == 9)
|
|
||||||
printf("\n\t");
|
|
||||||
}
|
|
||||||
printf("\n};\n\n");
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* This code was used to generate the content of array ecma_130_annex_b[].
|
|
||||||
*/
|
|
||||||
static unsigned short ecma_130_fsr = 1;
|
|
||||||
|
|
||||||
static int next_bit(void)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
ret = ecma_130_fsr & 1;
|
|
||||||
ecma_130_fsr = (ecma_130_fsr >> 1) & 0x3fff;
|
|
||||||
if (ret ^ (ecma_130_fsr & 1))
|
|
||||||
ecma_130_fsr |= 0x4000;
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int print_ecma_130_scrambler(void)
|
|
||||||
{
|
|
||||||
int i, j, b;
|
|
||||||
|
|
||||||
ecma_130_fsr = 1;
|
|
||||||
printf("static unsigned char ecma_130_annex_b[2340] = {");
|
|
||||||
printf("\n\t");
|
|
||||||
for (i = 0; i < 2340; i++) {
|
|
||||||
b = 0;
|
|
||||||
for (j = 0; j < 8; j++)
|
|
||||||
b |= next_bit() << j;
|
|
||||||
|
|
||||||
printf("%3u, ", b);
|
|
||||||
if ((i % 10) == 9)
|
|
||||||
printf("\n\t");
|
|
||||||
}
|
|
||||||
printf("\n};\n");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef Libburn_with_general_rspc_diV
|
|
||||||
|
|
||||||
/* This is a general polynomial division function.
|
|
||||||
burn_rspc_div_3() has been derived from this by setting b to constant 3.
|
|
||||||
*/
|
|
||||||
static unsigned char burn_rspc_div(unsigned char a, unsigned char b)
|
|
||||||
{
|
|
||||||
int d;
|
|
||||||
|
|
||||||
if (a == 0)
|
|
||||||
return 0;
|
|
||||||
if (b == 0)
|
|
||||||
return -1;
|
|
||||||
d = gflog[a] - gflog[b];
|
|
||||||
if (d < 0)
|
|
||||||
d += 255;
|
|
||||||
return gfpow[d];
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* Libburn_with_general_rspc_diV */
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* Libburn_with_lec_generatoR */
|
|
||||||
|
|
@ -1,24 +0,0 @@
|
|||||||
|
|
||||||
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
|
||||||
|
|
||||||
/* ts A91016 : libburn/ecma130ab.h is the replacement for old libburn/lec.h
|
|
||||||
|
|
||||||
Copyright 2009, Thomas Schmitt <scdbackup@gmx.net>, libburnia-project.org
|
|
||||||
Provided under GPL version 2 or later.
|
|
||||||
|
|
||||||
This code module implements the computations prescribed in ECMA-130 Annex A
|
|
||||||
and B. For explanations of the underlying mathematics see ecma130ab.c .
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef Libburn_ecma130ab_includeD
|
|
||||||
#define Libburn_ecma130ab_includeD 1
|
|
||||||
|
|
||||||
void burn_rspc_parity_p(unsigned char *sector);
|
|
||||||
|
|
||||||
void burn_rspc_parity_q(unsigned char *sector);
|
|
||||||
|
|
||||||
void burn_ecma130_scramble(unsigned char *sector);
|
|
||||||
|
|
||||||
#endif /* ! Libburn_ecma130ab_includeD */
|
|
||||||
|
|
377
libburn/file.c
377
libburn/file.c
@ -1,16 +1,5 @@
|
|||||||
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||||
|
|
||||||
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
|
|
||||||
Copyright (c) 2006 - 2010 Thomas Schmitt <scdbackup@gmx.net>
|
|
||||||
Provided under GPL version 2 or later.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
#include "../config.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@ -38,6 +27,8 @@ an unreadable disc */
|
|||||||
/* This is a generic OS oriented function wrapper which compensates
|
/* This is a generic OS oriented function wrapper which compensates
|
||||||
shortcommings of read() in respect to a guaranteed amount of return data.
|
shortcommings of read() in respect to a guaranteed amount of return data.
|
||||||
See man 2 read , paragraph "RETURN VALUE".
|
See man 2 read , paragraph "RETURN VALUE".
|
||||||
|
Possibly libburn/file.c is not the right storage location for this.
|
||||||
|
To make it ready for a move, this function is not declared static.
|
||||||
*/
|
*/
|
||||||
static int read_full_buffer(int fd, unsigned char *buffer, int size)
|
static int read_full_buffer(int fd, unsigned char *buffer, int size)
|
||||||
{
|
{
|
||||||
@ -93,9 +84,7 @@ static off_t file_size(struct burn_source *source)
|
|||||||
|
|
||||||
if (fs->fixed_size > 0)
|
if (fs->fixed_size > 0)
|
||||||
return fs->fixed_size;
|
return fs->fixed_size;
|
||||||
if (fstat(fs->datafd, &buf) != 0)
|
if (fstat(fs->datafd, &buf) == -1)
|
||||||
return (off_t) 0;
|
|
||||||
if ((buf.st_mode & S_IFMT) != S_IFREG)
|
|
||||||
return (off_t) 0;
|
return (off_t) 0;
|
||||||
return (off_t) buf.st_size;
|
return (off_t) buf.st_size;
|
||||||
}
|
}
|
||||||
@ -129,7 +118,7 @@ struct burn_source *burn_file_source_new(const char *path, const char *subpath)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fs = calloc(1, sizeof(struct burn_source_file));
|
fs = malloc(sizeof(struct burn_source_file));
|
||||||
|
|
||||||
/* ts A70825 */
|
/* ts A70825 */
|
||||||
if (fs == NULL) {
|
if (fs == NULL) {
|
||||||
@ -175,7 +164,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 = calloc(1, sizeof(struct burn_source_file));
|
fs = malloc(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;
|
||||||
@ -222,7 +211,7 @@ static int fifo_read(struct burn_source *source,
|
|||||||
int size)
|
int size)
|
||||||
{
|
{
|
||||||
struct burn_source_fifo *fs = source->data;
|
struct burn_source_fifo *fs = source->data;
|
||||||
int ret, todo, rpos, bufsize, diff, counted = 0;
|
int ret, todo, rpos, bufsize, diff;
|
||||||
|
|
||||||
if (fs->end_of_consumption) {
|
if (fs->end_of_consumption) {
|
||||||
/* ??? msg: reading has been ended already */;
|
/* ??? msg: reading has been ended already */;
|
||||||
@ -267,9 +256,6 @@ static int fifo_read(struct burn_source *source,
|
|||||||
"Forwarded input error ends output", 0, 0);
|
"Forwarded input error ends output", 0, 0);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (!counted)
|
|
||||||
fs->empty_counter++;
|
|
||||||
counted = 1;
|
|
||||||
fifo_sleep(0);
|
fifo_sleep(0);
|
||||||
}
|
}
|
||||||
diff = fs->buf_writepos - rpos; /* read volatile only once */
|
diff = fs->buf_writepos - rpos; /* read volatile only once */
|
||||||
@ -299,7 +285,6 @@ static int fifo_read(struct burn_source *source,
|
|||||||
(size - todo), fs->buf_readpos, (double) fs->out_counter);
|
(size - todo), fs->buf_readpos, (double) fs->out_counter);
|
||||||
*/
|
*/
|
||||||
|
|
||||||
fs->get_counter++;
|
|
||||||
return (size - todo);
|
return (size - todo);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -327,10 +312,8 @@ static void fifo_free(struct burn_source *source)
|
|||||||
burn_fifo_abort(fs, 0);
|
burn_fifo_abort(fs, 0);
|
||||||
if (fs->inp != NULL)
|
if (fs->inp != NULL)
|
||||||
burn_source_free(fs->inp);
|
burn_source_free(fs->inp);
|
||||||
|
|
||||||
if (fs->buf != NULL)
|
if (fs->buf != NULL)
|
||||||
burn_os_free_buffer(fs->buf,
|
free(fs->buf);
|
||||||
((size_t) fs->chunksize) * (size_t) fs->chunks, 0);
|
|
||||||
free((char *) fs);
|
free((char *) fs);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -338,8 +321,7 @@ static void fifo_free(struct burn_source *source)
|
|||||||
int burn_fifo_source_shoveller(struct burn_source *source, int flag)
|
int burn_fifo_source_shoveller(struct burn_source *source, int flag)
|
||||||
{
|
{
|
||||||
struct burn_source_fifo *fs = source->data;
|
struct burn_source_fifo *fs = source->data;
|
||||||
int ret, bufsize, diff, wpos, rpos, trans_end, free_bytes, fill;
|
int ret, bufsize, diff, wpos, rpos, trans_end, free_bytes;
|
||||||
int counted;
|
|
||||||
char *bufpt;
|
char *bufpt;
|
||||||
pthread_t thread_handle_storage;
|
pthread_t thread_handle_storage;
|
||||||
|
|
||||||
@ -353,7 +335,6 @@ int burn_fifo_source_shoveller(struct burn_source *source, int flag)
|
|||||||
|
|
||||||
/* wait for enough buffer space available */
|
/* wait for enough buffer space available */
|
||||||
wpos = fs->buf_writepos;
|
wpos = fs->buf_writepos;
|
||||||
counted = 0;
|
|
||||||
while (1) {
|
while (1) {
|
||||||
rpos = fs->buf_readpos;
|
rpos = fs->buf_readpos;
|
||||||
diff = rpos - wpos;
|
diff = rpos - wpos;
|
||||||
@ -364,28 +345,18 @@ int burn_fifo_source_shoveller(struct burn_source *source, int flag)
|
|||||||
free_bytes = diff - 1;
|
free_bytes = diff - 1;
|
||||||
else {
|
else {
|
||||||
free_bytes = (bufsize - wpos) + rpos - 1;
|
free_bytes = (bufsize - wpos) + rpos - 1;
|
||||||
if (bufsize - wpos < fs->inp_read_size)
|
if (bufsize - wpos < fs->chunksize)
|
||||||
trans_end = 1;
|
trans_end = 1;
|
||||||
}
|
}
|
||||||
if (free_bytes >= fs->inp_read_size)
|
if (free_bytes >= fs->chunksize)
|
||||||
break;
|
break;
|
||||||
if (!counted)
|
|
||||||
fs->full_counter++;
|
|
||||||
counted = 1;
|
|
||||||
fifo_sleep(0);
|
fifo_sleep(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
fill = bufsize - free_bytes - 1;
|
|
||||||
if (fill < fs->total_min_fill)
|
|
||||||
fs->total_min_fill = fill;
|
|
||||||
if (fill < fs->interval_min_fill)
|
|
||||||
fs->interval_min_fill = fill;
|
|
||||||
|
|
||||||
/* prepare the receiving memory */
|
/* prepare the receiving memory */
|
||||||
bufpt = fs->buf + wpos;
|
bufpt = fs->buf + wpos;
|
||||||
if (trans_end) {
|
if (trans_end) {
|
||||||
bufpt = burn_os_alloc_buffer(
|
bufpt = calloc(fs->chunksize, 1);
|
||||||
(size_t) fs->inp_read_size, 0);
|
|
||||||
if (bufpt == NULL) {
|
if (bufpt == NULL) {
|
||||||
libdax_msgs_submit(libdax_messenger, -1,
|
libdax_msgs_submit(libdax_messenger, -1,
|
||||||
0x00000003,
|
0x00000003,
|
||||||
@ -399,17 +370,15 @@ int burn_fifo_source_shoveller(struct burn_source *source, int flag)
|
|||||||
/* Obtain next chunk */
|
/* Obtain next chunk */
|
||||||
if (fs->inp->read != NULL)
|
if (fs->inp->read != NULL)
|
||||||
ret = fs->inp->read(fs->inp,
|
ret = fs->inp->read(fs->inp,
|
||||||
(unsigned char *) bufpt, fs->inp_read_size);
|
(unsigned char *) bufpt, fs->chunksize);
|
||||||
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->chunksize);
|
||||||
if (ret == 0) {
|
if (ret > 0)
|
||||||
|
fs->in_counter += ret;
|
||||||
/* >>> ??? ts B00326 */
|
else if (ret == 0)
|
||||||
/* >>> report EOF of fifo input and fs->in_counter */;
|
|
||||||
|
|
||||||
break; /* EOF */
|
break; /* EOF */
|
||||||
} else if (ret < 0) {
|
else {
|
||||||
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);
|
||||||
@ -418,21 +387,17 @@ int burn_fifo_source_shoveller(struct burn_source *source, int flag)
|
|||||||
fs->input_error = EIO;
|
fs->input_error = EIO;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
fs->in_counter += ret;
|
|
||||||
fs->put_counter++;
|
|
||||||
|
|
||||||
/* activate read chunk */
|
/* activate read chunk */
|
||||||
if (ret > fs->inp_read_size)
|
if (ret > fs->chunksize) /* beware of ill custom burn_source */
|
||||||
/* beware of ill custom burn_source */
|
ret = fs->chunksize;
|
||||||
ret = fs->inp_read_size;
|
|
||||||
if (trans_end) {
|
if (trans_end) {
|
||||||
/* copy to end of buffer */
|
/* copy to end of buffer */
|
||||||
memcpy(fs->buf + wpos, bufpt, bufsize - wpos);
|
memcpy(fs->buf + wpos, bufpt, bufsize - wpos);
|
||||||
/* copy to start of buffer */
|
/* copy to start of buffer */
|
||||||
memcpy(fs->buf, bufpt + (bufsize - wpos),
|
memcpy(fs->buf, bufpt + (bufsize - wpos),
|
||||||
fs->inp_read_size - (bufsize - wpos));
|
fs->chunksize - (bufsize - wpos));
|
||||||
burn_os_free_buffer(bufpt, (size_t) fs->inp_read_size,
|
free(bufpt);
|
||||||
0);
|
|
||||||
if (ret >= bufsize - wpos)
|
if (ret >= bufsize - wpos)
|
||||||
fs->buf_writepos = ret - (bufsize - wpos);
|
fs->buf_writepos = ret - (bufsize - wpos);
|
||||||
else
|
else
|
||||||
@ -468,9 +433,7 @@ int burn_fifo_source_shoveller(struct burn_source *source, int flag)
|
|||||||
So in both cases the consumer is aware that reading is futile
|
So in both cases the consumer is aware that reading is futile
|
||||||
or even fatal.
|
or even fatal.
|
||||||
*/
|
*/
|
||||||
if(fs->buf != NULL)
|
free(fs->buf); /* Give up fifo buffer. Next fifo might start soon. */
|
||||||
burn_os_free_buffer(fs->buf,
|
|
||||||
((size_t) fs->chunksize) * (size_t) fs->chunks, 0);
|
|
||||||
fs->buf = NULL;
|
fs->buf = NULL;
|
||||||
|
|
||||||
fs->thread_handle= NULL;
|
fs->thread_handle= NULL;
|
||||||
@ -481,16 +444,13 @@ int burn_fifo_source_shoveller(struct burn_source *source, int flag)
|
|||||||
|
|
||||||
int burn_fifo_cancel(struct burn_source *source)
|
int burn_fifo_cancel(struct burn_source *source)
|
||||||
{
|
{
|
||||||
int ret;
|
|
||||||
struct burn_source_fifo *fs = source->data;
|
struct burn_source_fifo *fs = source->data;
|
||||||
|
|
||||||
ret = burn_source_cancel(fs->inp);
|
burn_source_cancel(fs->inp);
|
||||||
return ret;
|
return(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
@param flag bit0= allow larger read chunks
|
|
||||||
*/
|
|
||||||
struct burn_source *burn_fifo_source_new(struct burn_source *inp,
|
struct burn_source *burn_fifo_source_new(struct burn_source *inp,
|
||||||
int chunksize, int chunks, int flag)
|
int chunksize, int chunks, int flag)
|
||||||
{
|
{
|
||||||
@ -509,7 +469,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 = calloc(1, sizeof(struct burn_source_fifo));
|
fs = malloc(sizeof(struct burn_source_fifo));
|
||||||
if (fs == NULL)
|
if (fs == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
fs->is_started = 0;
|
fs->is_started = 0;
|
||||||
@ -517,10 +477,6 @@ struct burn_source *burn_fifo_source_new(struct burn_source *inp,
|
|||||||
fs->thread_pid = 0;
|
fs->thread_pid = 0;
|
||||||
fs->thread_is_valid = 0;
|
fs->thread_is_valid = 0;
|
||||||
fs->inp = NULL; /* set later */
|
fs->inp = NULL; /* set later */
|
||||||
if (flag & 1)
|
|
||||||
fs->inp_read_size = 32 * 1024;
|
|
||||||
else
|
|
||||||
fs->inp_read_size = chunksize;
|
|
||||||
fs->chunksize = chunksize;
|
fs->chunksize = chunksize;
|
||||||
fs->chunks = chunks;
|
fs->chunks = chunks;
|
||||||
fs->buf = NULL;
|
fs->buf = NULL;
|
||||||
@ -529,9 +485,6 @@ struct burn_source *burn_fifo_source_new(struct burn_source *inp,
|
|||||||
fs->input_error = 0;
|
fs->input_error = 0;
|
||||||
fs->end_of_consumption = 0;
|
fs->end_of_consumption = 0;
|
||||||
fs->in_counter = fs->out_counter = 0;
|
fs->in_counter = fs->out_counter = 0;
|
||||||
fs->total_min_fill = fs->interval_min_fill = 0;
|
|
||||||
fs->put_counter = fs->get_counter = 0;
|
|
||||||
fs->empty_counter = fs->full_counter = 0;
|
|
||||||
|
|
||||||
src = burn_source_new();
|
src = burn_source_new();
|
||||||
if (src == NULL) {
|
if (src == NULL) {
|
||||||
@ -597,89 +550,34 @@ int burn_fifo_inquire_status(struct burn_source *source,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ts A91125 : API */
|
int burn_fifo_peek_data(struct burn_source *source, char *buf, int bufsize,
|
||||||
void burn_fifo_get_statistics(struct burn_source *source,
|
|
||||||
int *total_min_fill, int *interval_min_fill,
|
|
||||||
int *put_counter, int *get_counter,
|
|
||||||
int *empty_counter, int *full_counter)
|
|
||||||
{
|
|
||||||
struct burn_source_fifo *fs = source->data;
|
|
||||||
|
|
||||||
*total_min_fill = fs->total_min_fill;
|
|
||||||
*interval_min_fill = fs->interval_min_fill;
|
|
||||||
*put_counter = fs->put_counter;
|
|
||||||
*get_counter = fs->get_counter;
|
|
||||||
*empty_counter = fs->empty_counter;
|
|
||||||
*full_counter = fs->full_counter;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* ts A91125 : API */
|
|
||||||
void burn_fifo_next_interval(struct burn_source *source,
|
|
||||||
int *interval_min_fill)
|
|
||||||
{
|
|
||||||
struct burn_source_fifo *fs = source->data;
|
|
||||||
int size, free_bytes, ret;
|
|
||||||
char *status_text;
|
|
||||||
|
|
||||||
*interval_min_fill = fs->interval_min_fill;
|
|
||||||
ret = burn_fifo_inquire_status(source,
|
|
||||||
&size, &free_bytes, &status_text);
|
|
||||||
fs->interval_min_fill = size - free_bytes - 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* @param flag bit0= do not copy to buf but only wait until the fifo has read
|
|
||||||
bufsize or input ended.
|
|
||||||
The same happens if buf is NULL.
|
|
||||||
bit1= fill to max fifo size
|
|
||||||
*/
|
|
||||||
int burn_fifo_fill_data(struct burn_source *source, char *buf, int bufsize,
|
|
||||||
int flag)
|
int flag)
|
||||||
{
|
{
|
||||||
int size, free_bytes, ret, wait_count= 0;
|
int size, free_bytes, ret, wait_count= 0;
|
||||||
char *status_text;
|
char *status_text;
|
||||||
struct burn_source_fifo *fs = source->data;
|
struct burn_source_fifo *fs = source->data;
|
||||||
|
|
||||||
if (buf == NULL)
|
|
||||||
flag |= 1;
|
|
||||||
|
|
||||||
/* Eventually start fifo thread by reading 0 bytes */
|
/* Eventually start fifo thread by reading 0 bytes */
|
||||||
ret = fifo_read(source, (unsigned char *) NULL, 0);
|
ret = fifo_read(source, (unsigned char *) NULL, 0);
|
||||||
if (ret<0)
|
if (ret<0)
|
||||||
{ret = 0; goto ex;}
|
return 0;
|
||||||
|
|
||||||
/* wait for at least bufsize bytes being ready */
|
/* wait for at least bufsize bytes being ready */
|
||||||
while (1) {
|
while (1) {
|
||||||
ret= burn_fifo_inquire_status(source,
|
ret= burn_fifo_inquire_status(source,
|
||||||
&size, &free_bytes, &status_text);
|
&size, &free_bytes, &status_text);
|
||||||
if (flag & 2) {
|
if (size < bufsize) {
|
||||||
bufsize = size - (size % fs->inp_read_size) -
|
libdax_msgs_submit(libdax_messenger, -1, 0x0002015c,
|
||||||
fs->inp_read_size;
|
LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
if (bufsize <= 0)
|
"Fifo size is smaller than desired peek buffer", 0, 0);
|
||||||
{ret = 0; goto ex;}
|
return -1;
|
||||||
}
|
|
||||||
if (size - fs->inp_read_size < bufsize) {
|
|
||||||
if (flag & 1) {
|
|
||||||
bufsize = size - (size % fs->inp_read_size) -
|
|
||||||
fs->inp_read_size;
|
|
||||||
if (bufsize <= 0)
|
|
||||||
{ret = 0; goto ex;}
|
|
||||||
} else {
|
|
||||||
libdax_msgs_submit(libdax_messenger, -1,
|
|
||||||
0x0002015c, LIBDAX_MSGS_SEV_FAILURE,
|
|
||||||
LIBDAX_MSGS_PRIO_HIGH,
|
|
||||||
"Fifo size too small for desired peek buffer",
|
|
||||||
0, 0);
|
|
||||||
{ret = -1; goto ex;}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (fs->out_counter > 0 || (ret & 4) || fs->buf == NULL) {
|
if (fs->out_counter > 0 || (ret & 4) || fs->buf == NULL) {
|
||||||
libdax_msgs_submit(libdax_messenger, -1, 0x0002015e,
|
libdax_msgs_submit(libdax_messenger, -1, 0x0002015e,
|
||||||
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
|
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
"Fifo is already under consumption when peeking is desired",
|
"Fifo is already under consumption when peeking is desired",
|
||||||
0, 0);
|
0, 0);
|
||||||
{ret = -1; goto ex;}
|
return -1;
|
||||||
}
|
}
|
||||||
if(size - free_bytes >= bufsize) {
|
if(size - free_bytes >= bufsize) {
|
||||||
|
|
||||||
@ -688,33 +586,17 @@ int burn_fifo_fill_data(struct burn_source *source, char *buf, int bufsize,
|
|||||||
"libburn_DEBUG: after waiting cycle %d : fifo %s , %d bytes\n",
|
"libburn_DEBUG: after waiting cycle %d : fifo %s , %d bytes\n",
|
||||||
wait_count, status_text, size - free_bytes);
|
wait_count, status_text, size - free_bytes);
|
||||||
*/
|
*/
|
||||||
if(!(flag & 1))
|
|
||||||
memcpy(buf, fs->buf, bufsize);
|
|
||||||
{ret = 1; goto ex;}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ret & 2) {
|
memcpy(buf, fs->buf, bufsize);
|
||||||
/* input has ended, not enough data arrived */
|
return 1;
|
||||||
if (flag & 1)
|
}
|
||||||
{ret = 0; goto ex;}
|
if (ret&2) { /* input has ended, not enough data arrived */
|
||||||
libdax_msgs_submit(libdax_messenger, -1, 0x0002015d,
|
libdax_msgs_submit(libdax_messenger, -1, 0x0002015d,
|
||||||
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
|
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
"Fifo input ended short of desired peek buffer size",
|
"Fifo input ended short of desired peek buffer size",
|
||||||
0, 0);
|
0, 0);
|
||||||
{ret = 0; goto ex;}
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (free_bytes < fs->inp_read_size) {
|
|
||||||
/* Usable fifo size filled, not enough data arrived */
|
|
||||||
if (flag & 1)
|
|
||||||
{ret = 0; goto ex;}
|
|
||||||
libdax_msgs_submit(libdax_messenger, -1, 0x00020174,
|
|
||||||
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
|
|
||||||
"Fifo alignment does not allow desired read size",
|
|
||||||
0, 0);
|
|
||||||
{ret = 0; goto ex;}
|
|
||||||
}
|
|
||||||
|
|
||||||
usleep(100000);
|
usleep(100000);
|
||||||
wait_count++;
|
wait_count++;
|
||||||
|
|
||||||
@ -726,184 +608,5 @@ int burn_fifo_fill_data(struct burn_source *source, char *buf, int bufsize,
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
}
|
}
|
||||||
ret = 0;
|
return(0);
|
||||||
ex:;
|
|
||||||
fs->total_min_fill = fs->interval_min_fill = fs->buf_writepos;
|
|
||||||
return(ret);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ts A80713 : API */
|
|
||||||
int burn_fifo_peek_data(struct burn_source *source, char *buf, int bufsize,
|
|
||||||
int flag)
|
|
||||||
{
|
|
||||||
return burn_fifo_fill_data(source, buf, bufsize, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* ts A91125 : API */
|
|
||||||
int burn_fifo_fill(struct burn_source *source, int bufsize, int flag)
|
|
||||||
{
|
|
||||||
return burn_fifo_fill_data(source, NULL, bufsize,
|
|
||||||
1 | ((flag & 1) << 1));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* ----------------------------- Offset source ----------------------------- */
|
|
||||||
/* ts B00922 */
|
|
||||||
|
|
||||||
static void offst_free(struct burn_source *source);
|
|
||||||
|
|
||||||
static struct burn_source_offst *offst_auth(struct burn_source *source)
|
|
||||||
{
|
|
||||||
if (source->free_data != offst_free) {
|
|
||||||
libdax_msgs_submit(libdax_messenger, -1, 0x0002017a,
|
|
||||||
LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH,
|
|
||||||
"Expected offset source object as parameter",
|
|
||||||
0, 0);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
return (struct burn_source_offst *) source->data;
|
|
||||||
}
|
|
||||||
|
|
||||||
static off_t offst_get_size(struct burn_source *source)
|
|
||||||
{
|
|
||||||
struct burn_source_offst *fs;
|
|
||||||
|
|
||||||
if ((fs = offst_auth(source)) == NULL)
|
|
||||||
return (off_t) 0;
|
|
||||||
return fs->size;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int offst_set_size(struct burn_source *source, off_t size)
|
|
||||||
{
|
|
||||||
struct burn_source_offst *fs;
|
|
||||||
|
|
||||||
if ((fs = offst_auth(source)) == NULL)
|
|
||||||
return 0;
|
|
||||||
fs->size = size;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void offst_free(struct burn_source *source)
|
|
||||||
{
|
|
||||||
struct burn_source_offst *fs;
|
|
||||||
|
|
||||||
if ((fs = offst_auth(source)) == NULL)
|
|
||||||
return;
|
|
||||||
if (fs->prev != NULL)
|
|
||||||
offst_auth(fs->prev)->next = fs->next;
|
|
||||||
if (fs->next != NULL)
|
|
||||||
offst_auth(fs->next)->prev = fs->prev;
|
|
||||||
if (fs->inp != NULL)
|
|
||||||
burn_source_free(fs->inp); /* i.e. decrement refcount */
|
|
||||||
free(source->data);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int offst_read(struct burn_source *source, unsigned char *buffer,
|
|
||||||
int size)
|
|
||||||
{
|
|
||||||
int ret, to_read, todo;
|
|
||||||
struct burn_source_offst *fs;
|
|
||||||
|
|
||||||
if ((fs = offst_auth(source)) == NULL)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
/* Eventually skip bytes up to start position */;
|
|
||||||
if (!fs->running) {
|
|
||||||
if (fs->prev != NULL)
|
|
||||||
fs->pos = offst_auth(fs->prev)->pos;
|
|
||||||
fs->running= 1;
|
|
||||||
}
|
|
||||||
if(fs->pos < fs->start) {
|
|
||||||
todo = fs->start - fs->pos;
|
|
||||||
while (todo > 0) {
|
|
||||||
to_read = todo;
|
|
||||||
if (to_read > size)
|
|
||||||
to_read = size;
|
|
||||||
ret = burn_source_read(fs->inp, buffer, to_read);
|
|
||||||
if (ret <= 0)
|
|
||||||
return ret;
|
|
||||||
todo -= ret;
|
|
||||||
fs->pos += ret;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Produce EOF if source size is exhausted.
|
|
||||||
burn_source delivers no incomplete sector buffers.
|
|
||||||
*/
|
|
||||||
if (fs->pos + size > fs->start + fs->size)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
/* Read payload */
|
|
||||||
ret = burn_source_read(fs->inp, buffer, size);
|
|
||||||
if (ret > 0)
|
|
||||||
fs->pos += ret;
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int offst_cancel(struct burn_source *source)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
struct burn_source_offst *fs;
|
|
||||||
|
|
||||||
if ((fs = offst_auth(source)) == NULL)
|
|
||||||
return -1;
|
|
||||||
ret = burn_source_cancel(fs->inp);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct burn_source *burn_offst_source_new(
|
|
||||||
struct burn_source *inp, struct burn_source *prev,
|
|
||||||
off_t start, off_t size, int flag)
|
|
||||||
{
|
|
||||||
struct burn_source *src;
|
|
||||||
struct burn_source_offst *fs, *prev_fs = NULL;
|
|
||||||
|
|
||||||
if (prev != NULL)
|
|
||||||
if ((prev_fs = offst_auth(prev)) == NULL)
|
|
||||||
return NULL; /* Not type burn_source_offst */
|
|
||||||
|
|
||||||
fs = calloc(1, sizeof(struct burn_source_offst));
|
|
||||||
if (fs == NULL)
|
|
||||||
return NULL;
|
|
||||||
src = burn_source_new();
|
|
||||||
if (src == NULL) {
|
|
||||||
free((char *) fs);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
src->read = NULL;
|
|
||||||
src->read_sub = NULL;
|
|
||||||
src->get_size = offst_get_size;
|
|
||||||
src->set_size = offst_set_size;
|
|
||||||
src->free_data = offst_free;
|
|
||||||
src->data = fs;
|
|
||||||
src->version= 1;
|
|
||||||
src->read_xt = offst_read;
|
|
||||||
src->cancel= offst_cancel;
|
|
||||||
fs->inp = inp;
|
|
||||||
fs->prev = prev;
|
|
||||||
fs->next = NULL;
|
|
||||||
if (prev != NULL) {
|
|
||||||
if (prev_fs->next != NULL) {
|
|
||||||
offst_auth(prev_fs->next)->prev = src;
|
|
||||||
fs->next = prev_fs->next;
|
|
||||||
}
|
|
||||||
prev_fs->next = src;
|
|
||||||
if (prev_fs->start + prev_fs->size > start) {
|
|
||||||
libdax_msgs_submit(libdax_messenger, -1, 0x00020179,
|
|
||||||
LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH,
|
|
||||||
"Offset source start address is before end of previous source",
|
|
||||||
0, 0);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fs->start = start;
|
|
||||||
fs->size = size;
|
|
||||||
fs->running = 0;
|
|
||||||
fs->pos = 0;
|
|
||||||
inp->refcount++; /* make sure inp lives longer than src */
|
|
||||||
|
|
||||||
return src;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
@ -1,10 +1,5 @@
|
|||||||
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||||
|
|
||||||
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
|
|
||||||
Copyright (c) 2006 - 2010 Thomas Schmitt <scdbackup@gmx.net>
|
|
||||||
Provided under GPL version 2 or later.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef BURN__FILE_H
|
#ifndef BURN__FILE_H
|
||||||
#define BURN__FILE_H
|
#define BURN__FILE_H
|
||||||
|
|
||||||
@ -40,7 +35,6 @@ struct burn_source_fifo {
|
|||||||
|
|
||||||
/* the burn_source for which this fifo is acting as proxy */
|
/* the burn_source for which this fifo is acting as proxy */
|
||||||
struct burn_source *inp;
|
struct burn_source *inp;
|
||||||
int inp_read_size;
|
|
||||||
|
|
||||||
/* <<< up to now it was only a pipe. This is on its way out. */
|
/* <<< up to now it was only a pipe. This is on its way out. */
|
||||||
int outlet[2];
|
int outlet[2];
|
||||||
@ -57,14 +51,6 @@ struct burn_source_fifo {
|
|||||||
|
|
||||||
off_t in_counter;
|
off_t in_counter;
|
||||||
off_t out_counter;
|
off_t out_counter;
|
||||||
|
|
||||||
int total_min_fill;
|
|
||||||
int interval_min_fill;
|
|
||||||
int put_counter;
|
|
||||||
int get_counter;
|
|
||||||
int empty_counter;
|
|
||||||
int full_counter;
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -74,22 +60,4 @@ struct burn_source_fifo {
|
|||||||
int burn_fifo_source_shoveller(struct burn_source *source, int flag);
|
int burn_fifo_source_shoveller(struct burn_source *source, int flag);
|
||||||
|
|
||||||
|
|
||||||
/* ts B00922 */
|
|
||||||
struct burn_source_offst {
|
|
||||||
|
|
||||||
/* See burn_offst_source_new() */
|
|
||||||
struct burn_source *inp;
|
|
||||||
struct burn_source *prev;
|
|
||||||
off_t start;
|
|
||||||
off_t size;
|
|
||||||
|
|
||||||
/* To help offst_free() */
|
|
||||||
struct burn_source *next;
|
|
||||||
|
|
||||||
/* The current reading position */
|
|
||||||
int running;
|
|
||||||
off_t pos;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /* LIBBURN__FILE_H */
|
#endif /* LIBBURN__FILE_H */
|
||||||
|
177
libburn/init.c
177
libburn/init.c
@ -1,15 +1,5 @@
|
|||||||
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||||
|
|
||||||
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
|
|
||||||
Copyright (c) 2006 - 2010 Thomas Schmitt <scdbackup@gmx.net>
|
|
||||||
Provided under GPL version 2 or later.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
#include "../config.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
/* ts A61007 */
|
/* ts A61007 */
|
||||||
@ -19,7 +9,6 @@
|
|||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <pthread.h>
|
|
||||||
|
|
||||||
/* ts A70928 : init.h is for others, not for init .c
|
/* ts A70928 : init.h is for others, not for init .c
|
||||||
#include "init.h"
|
#include "init.h"
|
||||||
@ -43,16 +32,14 @@ struct libdax_msgs *libdax_messenger= NULL;
|
|||||||
|
|
||||||
int burn_running = 0;
|
int burn_running = 0;
|
||||||
|
|
||||||
/* ts A60813 : GNU/Linux: whether to use O_EXCL on open() of device files
|
/* ts A60813 : Linux: wether to use O_EXCL on open() of device files */
|
||||||
ts B00212 : FreeBSD: whether to use flock(LOCK_EX) after open()
|
|
||||||
*/
|
|
||||||
int burn_sg_open_o_excl = 1;
|
int burn_sg_open_o_excl = 1;
|
||||||
|
|
||||||
/* ts A70403 : GNU/Linux: wether to use fcntl(,F_SETLK,)
|
/* ts A70403 : Linux: wether to use fcntl(,F_SETLK,)
|
||||||
after open() of device files */
|
after open() of device files */
|
||||||
int burn_sg_fcntl_f_setlk = 1;
|
int burn_sg_fcntl_f_setlk = 1;
|
||||||
|
|
||||||
/* ts A70314 : GNU/Linux: what device family to use :
|
/* ts A70314 : Linux: what device family to use :
|
||||||
0= default family
|
0= default family
|
||||||
1= sr
|
1= sr
|
||||||
2= scd
|
2= scd
|
||||||
@ -72,12 +59,6 @@ int burn_sg_open_o_nonblock = 1;
|
|||||||
to unconditional abort of the process */
|
to unconditional abort of the process */
|
||||||
int burn_sg_open_abort_busy = 0;
|
int burn_sg_open_abort_busy = 0;
|
||||||
|
|
||||||
|
|
||||||
/* The message returned from sg_id_string() and/or sg_initialize()
|
|
||||||
*/
|
|
||||||
static char sg_initialize_msg[1024] = {""};
|
|
||||||
|
|
||||||
|
|
||||||
/* ts A61002 */
|
/* ts A61002 */
|
||||||
|
|
||||||
#include "cleanup.h"
|
#include "cleanup.h"
|
||||||
@ -85,25 +66,15 @@ static char sg_initialize_msg[1024] = {""};
|
|||||||
/* Parameters for builtin abort handler */
|
/* Parameters for builtin abort handler */
|
||||||
static char abort_message_prefix[81] = {"libburn : "};
|
static char abort_message_prefix[81] = {"libburn : "};
|
||||||
static pid_t abort_control_pid= 0;
|
static pid_t abort_control_pid= 0;
|
||||||
static pthread_t abort_control_thread;
|
|
||||||
volatile int burn_global_abort_level= 0;
|
volatile int burn_global_abort_level= 0;
|
||||||
int burn_global_abort_signum= 0;
|
int burn_global_abort_signum= 0;
|
||||||
void *burn_global_signal_handle = NULL;
|
void *burn_global_signal_handle = NULL;
|
||||||
burn_abort_handler_t burn_global_signal_handler = NULL;
|
burn_abort_handler_t burn_global_signal_handler = NULL;
|
||||||
int burn_builtin_signal_action = 0; /* burn_set_signal_handling() */
|
|
||||||
volatile int burn_builtin_triggered_action = 0; /* burn_is_aborting() */
|
|
||||||
|
|
||||||
|
|
||||||
/* ts A70223 : wether implemented untested profiles are supported */
|
/* ts A70223 : wether implemented untested profiles are supported */
|
||||||
int burn_support_untested_profiles = 0;
|
int burn_support_untested_profiles = 0;
|
||||||
|
|
||||||
/* ts A91111 :
|
|
||||||
whether to log SCSI commands (to be implemented in sg-*.c)
|
|
||||||
bit0= log in /tmp/libburn_sg_command_log
|
|
||||||
bit1= log to stderr
|
|
||||||
bit2= flush every line
|
|
||||||
*/
|
|
||||||
int burn_sg_log_scsi = 0;
|
|
||||||
|
|
||||||
/* ts A60925 : ticket 74 */
|
/* ts A60925 : ticket 74 */
|
||||||
/** Create the messenger object for libburn. */
|
/** Create the messenger object for libburn. */
|
||||||
@ -132,14 +103,6 @@ int burn_initialize(void)
|
|||||||
ret = burn_msgs_initialize();
|
ret = burn_msgs_initialize();
|
||||||
if (ret <= 0)
|
if (ret <= 0)
|
||||||
return 0;
|
return 0;
|
||||||
ret = sg_initialize(sg_initialize_msg, 0);
|
|
||||||
if (ret <= 0) {
|
|
||||||
libdax_msgs_submit(libdax_messenger, -1,
|
|
||||||
0x00020175,
|
|
||||||
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
|
|
||||||
sg_initialize_msg, 0, 0);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
burn_running = 1;
|
burn_running = 1;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -167,22 +130,10 @@ void burn_finish(void)
|
|||||||
/* ts A60924 : ticket 74 */
|
/* ts A60924 : ticket 74 */
|
||||||
libdax_msgs_destroy(&libdax_messenger,0);
|
libdax_msgs_destroy(&libdax_messenger,0);
|
||||||
|
|
||||||
sg_shutdown(0);
|
|
||||||
|
|
||||||
burn_running = 0;
|
burn_running = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ts A91226 */
|
|
||||||
/** API function. See libburn.h */
|
|
||||||
char *burn_scsi_transport_id(int flag)
|
|
||||||
{
|
|
||||||
if (!burn_running)
|
|
||||||
sg_id_string(sg_initialize_msg, 0);
|
|
||||||
return sg_initialize_msg;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* ts A60813 */
|
/* ts A60813 */
|
||||||
/** API function. See libburn.h */
|
/** API function. See libburn.h */
|
||||||
void burn_preset_device_open(int exclusive, int blocking, int abort_on_busy)
|
void burn_preset_device_open(int exclusive, int blocking, int abort_on_busy)
|
||||||
@ -337,20 +288,6 @@ int burn_sev_to_text(int severity_number, char **severity_name, int flag)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ts B00224 */
|
|
||||||
char *burn_util_thread_id(pid_t pid, pthread_t tid, char text[80])
|
|
||||||
{
|
|
||||||
int i, l;
|
|
||||||
|
|
||||||
sprintf(text, "[%lu,", (unsigned long int) getpid());
|
|
||||||
l= strlen(text);
|
|
||||||
for(i= 0; i < sizeof(pthread_t) && 2 * i < 80 - l - 3; i++)
|
|
||||||
sprintf(text + l + 2 * i,
|
|
||||||
"%2.2X", ((unsigned char *) &tid)[i]);
|
|
||||||
|
|
||||||
sprintf(text + l + 2 * i, "]");
|
|
||||||
return text;
|
|
||||||
}
|
|
||||||
|
|
||||||
int burn_builtin_abort_handler(void *handle, int signum, int flag)
|
int burn_builtin_abort_handler(void *handle, int signum, int flag)
|
||||||
{
|
{
|
||||||
@ -359,53 +296,15 @@ int burn_builtin_abort_handler(void *handle, int signum, int flag)
|
|||||||
/*
|
/*
|
||||||
#define Libburn_signal_handler_verbouS 1
|
#define Libburn_signal_handler_verbouS 1
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int ret;
|
int ret;
|
||||||
struct burn_drive *d;
|
struct burn_drive *d;
|
||||||
|
|
||||||
#ifdef Libburn_signal_handler_verbouS
|
#ifdef Libburn_signal_handler_verbouS
|
||||||
char text[80];
|
fprintf(stderr,
|
||||||
|
"libburn_ABORT: pid = %d , abort_control_pid = %d , sig= %d\n",
|
||||||
fprintf(stderr, "libburn_ABORT: in = %s\n",
|
getpid(), abort_control_pid, signum);
|
||||||
burn_util_thread_id(getpid(), pthread_self(), text));
|
|
||||||
fprintf(stderr, "libburn_ABORT: ctrl = %s\n",
|
|
||||||
burn_util_thread_id(abort_control_pid, abort_control_thread,
|
|
||||||
text));
|
|
||||||
if (burn_global_signal_handler == burn_builtin_abort_handler)
|
|
||||||
fprintf(stderr, "libburn_ABORT: signal action = %d\n",
|
|
||||||
burn_builtin_signal_action);
|
|
||||||
|
|
||||||
/* >>> find writing drives and report their tid
|
|
||||||
fprintf(stderr, "libburn_ABORT: wrt = %s\n",
|
|
||||||
burn_util_thread_id(0, burn_write_thread_id, text));
|
|
||||||
fprintf(stderr, "libburn_ABORT: sig= %d\n", signum);
|
|
||||||
*/
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
burn_builtin_triggered_action = burn_builtin_signal_action;
|
|
||||||
burn_global_abort_level = -1;
|
|
||||||
|
|
||||||
if (burn_builtin_signal_action > 1) {
|
|
||||||
Cleanup_set_handlers(NULL, NULL, 2);
|
|
||||||
if (burn_builtin_signal_action == 4)
|
|
||||||
return -2;
|
|
||||||
fprintf(stderr,"%sABORT : Trying to shut down busy drives\n",
|
|
||||||
abort_message_prefix);
|
|
||||||
fprintf(stderr,
|
|
||||||
"%sABORT : Wait the normal burning time before any kill -9\n",
|
|
||||||
abort_message_prefix);
|
|
||||||
burn_abort_5(0, burn_abort_pacifier, abort_message_prefix,
|
|
||||||
0, 1);
|
|
||||||
libdax_msgs_submit(libdax_messenger, -1, 0x00020177,
|
|
||||||
LIBDAX_MSGS_SEV_ABORT, LIBDAX_MSGS_PRIO_HIGH,
|
|
||||||
"Urged drive worker threads to do emergency halt",
|
|
||||||
0, 0);
|
|
||||||
return -2;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* ---- old deprecated stuck-in-abort-handler loop ---- */
|
|
||||||
|
|
||||||
/* ts A70928:
|
/* ts A70928:
|
||||||
Must be quick. Allowed to coincide with other thread and to share
|
Must be quick. Allowed to coincide with other thread and to share
|
||||||
the increment with that one. It must not decrease, though, and
|
the increment with that one. It must not decrease, though, and
|
||||||
@ -418,8 +317,7 @@ int burn_builtin_abort_handler(void *handle, int signum, int flag)
|
|||||||
|
|
||||||
#ifdef Libburn_new_thread_signal_handleR
|
#ifdef Libburn_new_thread_signal_handleR
|
||||||
|
|
||||||
ret = burn_drive_find_by_thread_pid(&d, getpid(),
|
ret = burn_drive_find_by_thread_pid(&d, getpid());
|
||||||
pthread_self());
|
|
||||||
if (ret > 0 && d->busy == BURN_DRIVE_WRITING) {
|
if (ret > 0 && d->busy == BURN_DRIVE_WRITING) {
|
||||||
/* This is an active writer thread */
|
/* This is an active writer thread */
|
||||||
|
|
||||||
@ -459,13 +357,13 @@ int burn_builtin_abort_handler(void *handle, int signum, int flag)
|
|||||||
}
|
}
|
||||||
burn_global_abort_level = -1;
|
burn_global_abort_level = -1;
|
||||||
Cleanup_set_handlers(NULL, NULL, 2);
|
Cleanup_set_handlers(NULL, NULL, 2);
|
||||||
|
|
||||||
fprintf(stderr,"%sABORT : Trying to shut down drive and library\n",
|
fprintf(stderr,"%sABORT : Trying to shut down drive and library\n",
|
||||||
abort_message_prefix);
|
abort_message_prefix);
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"%sABORT : Wait the normal burning time before any kill -9\n",
|
"%sABORT : Wait the normal burning time before any kill -9\n",
|
||||||
abort_message_prefix);
|
abort_message_prefix);
|
||||||
close(0); /* somehow stdin as input blocks abort until EOF */
|
close(0); /* somehow stdin as input blocks abort until EOF */
|
||||||
|
|
||||||
burn_abort(4440, burn_abort_pacifier, abort_message_prefix);
|
burn_abort(4440, burn_abort_pacifier, abort_message_prefix);
|
||||||
|
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
@ -475,71 +373,28 @@ int burn_builtin_abort_handler(void *handle, int signum, int flag)
|
|||||||
return(1);
|
return(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ts A61002 : API */
|
|
||||||
void burn_set_signal_handling(void *handle, burn_abort_handler_t handler,
|
void burn_set_signal_handling(void *handle, burn_abort_handler_t handler,
|
||||||
int mode)
|
int mode)
|
||||||
{
|
{
|
||||||
|
if(handler == NULL && mode == 0) {
|
||||||
/*
|
|
||||||
fprintf(stderr, "libburn_experimental: burn_set_signal_handling, handler==%lx mode=%d\n", (unsigned long) handler, mode);
|
|
||||||
*/
|
|
||||||
|
|
||||||
if(handler == NULL) {
|
|
||||||
handler = burn_builtin_abort_handler;
|
handler = burn_builtin_abort_handler;
|
||||||
/*
|
/*
|
||||||
if ((mode & ~4) == 0)
|
fprintf(stderr, "libburn_experimental: activated burn_builtin_abort_handler() with handle '%s'\n",(handle==NULL ? "libburn : " : (char *) handle));
|
||||||
fprintf(stderr, "libburn_experimental: activated burn_builtin_abort_handler() with handle '%s'\n",(handle==NULL ? "libburn : " : (char *) handle));
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
}
|
}
|
||||||
strcpy(abort_message_prefix, "libburn : ");
|
strcpy(abort_message_prefix, "libburn : ");
|
||||||
abort_message_prefix[0] = 0;
|
if(handle != NULL)
|
||||||
if(handle != NULL && handler == burn_builtin_abort_handler)
|
|
||||||
strncpy(abort_message_prefix, (char *) handle,
|
strncpy(abort_message_prefix, (char *) handle,
|
||||||
sizeof(abort_message_prefix)-1);
|
sizeof(abort_message_prefix)-1);
|
||||||
abort_message_prefix[sizeof(abort_message_prefix)-1] = 0;
|
abort_message_prefix[sizeof(abort_message_prefix)-1] = 0;
|
||||||
abort_control_pid = getpid();
|
abort_control_pid = getpid();
|
||||||
abort_control_thread = pthread_self();
|
Cleanup_set_handlers(handle, (Cleanup_app_handler_T) handler, mode|4);
|
||||||
burn_builtin_signal_action = (mode >> 4) & 15;
|
|
||||||
if((mode & 11) != 0)
|
|
||||||
burn_builtin_signal_action = 0;
|
|
||||||
if(burn_builtin_signal_action > 1)
|
|
||||||
burn_builtin_triggered_action = 0;
|
|
||||||
if(burn_builtin_signal_action == 0)
|
|
||||||
burn_builtin_signal_action = 1;
|
|
||||||
Cleanup_set_handlers(handle, (Cleanup_app_handler_T) handler,
|
|
||||||
(mode & 15) | 4);
|
|
||||||
burn_global_signal_handle = handle;
|
burn_global_signal_handle = handle;
|
||||||
burn_global_signal_handler = handler;
|
burn_global_signal_handler = handler;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ts B00304 : API */
|
|
||||||
int burn_is_aborting(int flag)
|
|
||||||
{
|
|
||||||
return burn_builtin_triggered_action;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* ts B00225 */
|
|
||||||
/* @return 0= no abort action 2 pending , 1= not control thread
|
|
||||||
*/
|
|
||||||
int burn_init_catch_on_abort(int flag)
|
|
||||||
{
|
|
||||||
if (burn_builtin_triggered_action != 2)
|
|
||||||
return 0;
|
|
||||||
if (abort_control_pid != getpid() ||
|
|
||||||
abort_control_thread != pthread_self())
|
|
||||||
return 1;
|
|
||||||
burn_abort(4440, burn_abort_pacifier, abort_message_prefix);
|
|
||||||
fprintf(stderr,
|
|
||||||
"\n%sABORT : Program done. Even if you do not see a shell prompt.\n\n",
|
|
||||||
abort_message_prefix);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* ts A70223 : API */
|
/* ts A70223 : API */
|
||||||
void burn_allow_untested_profiles(int yes)
|
void burn_allow_untested_profiles(int yes)
|
||||||
{
|
{
|
||||||
@ -559,9 +414,3 @@ int burn_set_messenger(void *messenger)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ts A91111 API */
|
|
||||||
void burn_set_scsi_logging(int flag)
|
|
||||||
{
|
|
||||||
burn_sg_log_scsi = flag & 7;
|
|
||||||
}
|
|
||||||
|
@ -17,15 +17,5 @@ extern int burn_global_abort_signum;
|
|||||||
extern void *burn_global_signal_handle;
|
extern void *burn_global_signal_handle;
|
||||||
extern burn_abort_handler_t burn_global_signal_handler;
|
extern burn_abort_handler_t burn_global_signal_handler;
|
||||||
|
|
||||||
extern int burn_builtin_signal_action; /* burn_set_signal_handling() */
|
|
||||||
extern volatile int burn_builtin_triggered_action; /* burn_is_aborting() */
|
|
||||||
|
|
||||||
|
|
||||||
/* ts B00225 */
|
|
||||||
/* @return 0= no abort pending , 1= not control thread ,
|
|
||||||
-1= surprisingly burn_abort returned
|
|
||||||
*/
|
|
||||||
int burn_init_catch_on_abort(int flag);
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* BURN__INIT_H */
|
#endif /* BURN__INIT_H */
|
||||||
|
451
libburn/lec.c
Normal file
451
libburn/lec.c
Normal file
@ -0,0 +1,451 @@
|
|||||||
|
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||||
|
|
||||||
|
/* borrowed HEAVILY from cdrdao */
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include "lec.h"
|
||||||
|
|
||||||
|
#define LEC_HEADER_OFFSET 12
|
||||||
|
#define LEC_MODE1_P_PARITY_OFFSET 2076
|
||||||
|
#define LEC_MODE1_Q_PARITY_OFFSET 2248
|
||||||
|
|
||||||
|
static unsigned char gf8_ilog[255] = {
|
||||||
|
1, 2, 4, 8, 16, 32, 64, 128, 29, 58, 116, 232, 205, 135, 19, 38, 76,
|
||||||
|
152, 45, 90, 180, 117, 234, 201, 143, 3, 6, 12, 24, 48, 96,
|
||||||
|
192, 157, 39, 78, 156, 37, 74, 148, 53, 106, 212, 181, 119,
|
||||||
|
238, 193, 159, 35, 70, 140, 5, 10, 20, 40, 80, 160, 93, 186,
|
||||||
|
105, 210, 185, 111, 222, 161, 95, 190, 97, 194, 153, 47, 94,
|
||||||
|
188, 101, 202, 137, 15, 30, 60, 120, 240, 253, 231, 211, 187,
|
||||||
|
107, 214, 177, 127, 254, 225, 223, 163, 91, 182, 113, 226, 217,
|
||||||
|
175, 67, 134, 17, 34, 68, 136, 13, 26, 52, 104, 208, 189, 103,
|
||||||
|
206, 129, 31, 62, 124, 248, 237, 199, 147, 59, 118, 236, 197,
|
||||||
|
151, 51, 102, 204, 133, 23, 46, 92, 184, 109, 218, 169, 79,
|
||||||
|
158, 33, 66, 132, 21, 42, 84, 168, 77, 154, 41, 82, 164, 85,
|
||||||
|
170, 73, 146, 57, 114, 228, 213, 183, 115, 230, 209, 191, 99,
|
||||||
|
198, 145, 63, 126, 252, 229, 215, 179, 123, 246, 241, 255, 227,
|
||||||
|
219, 171, 75, 150, 49, 98, 196, 149, 55, 110, 220, 165, 87,
|
||||||
|
174, 65, 130, 25, 50, 100, 200, 141, 7, 14, 28, 56, 112, 224,
|
||||||
|
221, 167, 83, 166, 81, 162, 89, 178, 121, 242, 249, 239, 195,
|
||||||
|
155, 43, 86, 172, 69, 138, 9, 18, 36, 72, 144, 61, 122, 244,
|
||||||
|
245, 247, 243, 251, 235, 203, 139, 11, 22, 44, 88, 176, 125,
|
||||||
|
250, 233, 207, 131, 27, 54, 108, 216, 173, 71, 142,
|
||||||
|
};
|
||||||
|
static unsigned char gf8_log[256] = {
|
||||||
|
0, 0, 1, 25, 2, 50, 26, 198, 3, 223, 51, 238, 27, 104, 199, 75, 4, 100,
|
||||||
|
224, 14, 52, 141, 239, 129, 28, 193, 105, 248, 200, 8, 76, 113,
|
||||||
|
5, 138, 101, 47, 225, 36, 15, 33, 53, 147, 142, 218, 240, 18,
|
||||||
|
130, 69, 29, 181, 194, 125, 106, 39, 249, 185, 201, 154, 9,
|
||||||
|
120, 77, 228, 114, 166, 6, 191, 139, 98, 102, 221, 48, 253,
|
||||||
|
226, 152, 37, 179, 16, 145, 34, 136, 54, 208, 148, 206, 143,
|
||||||
|
150, 219, 189, 241, 210, 19, 92, 131, 56, 70, 64, 30, 66, 182,
|
||||||
|
163, 195, 72, 126, 110, 107, 58, 40, 84, 250, 133, 186, 61,
|
||||||
|
202, 94, 155, 159, 10, 21, 121, 43, 78, 212, 229, 172, 115,
|
||||||
|
243, 167, 87, 7, 112, 192, 247, 140, 128, 99, 13, 103, 74, 222,
|
||||||
|
237, 49, 197, 254, 24, 227, 165, 153, 119, 38, 184, 180, 124,
|
||||||
|
17, 68, 146, 217, 35, 32, 137, 46, 55, 63, 209, 91, 149, 188,
|
||||||
|
207, 205, 144, 135, 151, 178, 220, 252, 190, 97, 242, 86, 211,
|
||||||
|
171, 20, 42, 93, 158, 132, 60, 57, 83, 71, 109, 65, 162, 31,
|
||||||
|
45, 67, 216, 183, 123, 164, 118, 196, 23, 73, 236, 127, 12,
|
||||||
|
111, 246, 108, 161, 59, 82, 41, 157, 85, 170, 251, 96, 134,
|
||||||
|
177, 187, 204, 62, 90, 203, 89, 95, 176, 156, 169, 160, 81, 11,
|
||||||
|
245, 22, 235, 122, 117, 44, 215, 79, 174, 213, 233, 230, 231,
|
||||||
|
173, 232, 116, 214, 244, 234, 168, 80, 88, 175,
|
||||||
|
};
|
||||||
|
static unsigned char gf8_q_coeffs[2][45] = {
|
||||||
|
{97, 251, 133, 60, 82, 160, 155, 201, 8, 112, 246, 11, 21, 42, 157,
|
||||||
|
169, 80, 174, 232, 230, 172, 211, 241, 18, 68, 216, 44, 121, 9, 200,
|
||||||
|
75, 103, 221, 252, 96, 176, 88, 167, 114, 76, 199, 26, 1, 0, 0},
|
||||||
|
{190, 96, 250, 132, 59, 81, 159, 154, 200, 7, 111, 245, 10, 20, 41,
|
||||||
|
156, 168, 79, 173, 231, 229, 171, 210, 240, 17, 67, 215, 43, 120, 8,
|
||||||
|
199, 74, 102, 220, 251, 95, 175, 87, 166, 113, 75, 198, 25, 0, 0}
|
||||||
|
};
|
||||||
|
static unsigned char gf8_p_coeffs[2][26] = {
|
||||||
|
{230, 172, 211, 241, 18, 68, 216, 44, 121, 9, 200, 75, 103, 221, 252,
|
||||||
|
96, 176, 88, 167, 114, 76, 199, 26, 1, 0, 0},
|
||||||
|
{231, 229, 171, 210, 240, 17, 67, 215, 43, 120, 8, 199, 74, 102, 220,
|
||||||
|
251, 95, 175, 87, 166, 113, 75, 198, 25, 0, 0}
|
||||||
|
};
|
||||||
|
|
||||||
|
static unsigned char yellowbook_scrambler[2340] = {
|
||||||
|
1, 128, 0, 96, 0, 40, 0, 30, 128, 8, 96, 6, 168, 2, 254, 129, 128, 96,
|
||||||
|
96, 40, 40, 30, 158,
|
||||||
|
136, 104, 102, 174, 170, 252, 127, 1, 224, 0, 72, 0, 54, 128, 22, 224,
|
||||||
|
14, 200, 4, 86, 131, 126, 225,
|
||||||
|
224, 72, 72, 54, 182, 150, 246, 238, 198, 204, 82, 213, 253, 159, 1,
|
||||||
|
168, 0, 126, 128, 32, 96, 24, 40,
|
||||||
|
10, 158, 135, 40, 98, 158, 169, 168, 126, 254, 160, 64, 120, 48, 34,
|
||||||
|
148, 25, 175, 74, 252, 55, 1, 214,
|
||||||
|
128, 94, 224, 56, 72, 18, 182, 141, 182, 229, 182, 203, 54, 215, 86,
|
||||||
|
222, 190, 216, 112, 90, 164, 59, 59,
|
||||||
|
83, 83, 125, 253, 225, 129, 136, 96, 102, 168, 42, 254, 159, 0, 104, 0,
|
||||||
|
46, 128, 28, 96, 9, 232, 6,
|
||||||
|
206, 130, 212, 97, 159, 104, 104, 46, 174, 156, 124, 105, 225, 238,
|
||||||
|
200, 76, 86, 181, 254, 247, 0, 70, 128,
|
||||||
|
50, 224, 21, 136, 15, 38, 132, 26, 227, 75, 9, 247, 70, 198, 178, 210,
|
||||||
|
245, 157, 135, 41, 162, 158, 249,
|
||||||
|
168, 66, 254, 177, 128, 116, 96, 39, 104, 26, 174, 139, 60, 103, 81,
|
||||||
|
234, 188, 79, 49, 244, 20, 71, 79,
|
||||||
|
114, 180, 37, 183, 91, 54, 187, 86, 243, 126, 197, 224, 83, 8, 61, 198,
|
||||||
|
145, 146, 236, 109, 141, 237, 165,
|
||||||
|
141, 187, 37, 179, 91, 53, 251, 87, 3, 126, 129, 224, 96, 72, 40, 54,
|
||||||
|
158, 150, 232, 110, 206, 172, 84,
|
||||||
|
125, 255, 97, 128, 40, 96, 30, 168, 8, 126, 134, 160, 98, 248, 41, 130,
|
||||||
|
158, 225, 168, 72, 126, 182, 160,
|
||||||
|
118, 248, 38, 194, 154, 209, 171, 28, 127, 73, 224, 54, 200, 22, 214,
|
||||||
|
142, 222, 228, 88, 75, 122, 183, 99,
|
||||||
|
54, 169, 214, 254, 222, 192, 88, 80, 58, 188, 19, 49, 205, 212, 85,
|
||||||
|
159, 127, 40, 32, 30, 152, 8, 106,
|
||||||
|
134, 175, 34, 252, 25, 129, 202, 224, 87, 8, 62, 134, 144, 98, 236, 41,
|
||||||
|
141, 222, 229, 152, 75, 42, 183,
|
||||||
|
95, 54, 184, 22, 242, 142, 197, 164, 83, 59, 125, 211, 97, 157, 232,
|
||||||
|
105, 142, 174, 228, 124, 75, 97, 247,
|
||||||
|
104, 70, 174, 178, 252, 117, 129, 231, 32, 74, 152, 55, 42, 150, 159,
|
||||||
|
46, 232, 28, 78, 137, 244, 102, 199,
|
||||||
|
106, 210, 175, 29, 188, 9, 177, 198, 244, 82, 199, 125, 146, 161, 173,
|
||||||
|
184, 125, 178, 161, 181, 184, 119, 50,
|
||||||
|
166, 149, 186, 239, 51, 12, 21, 197, 207, 19, 20, 13, 207, 69, 148, 51,
|
||||||
|
47, 85, 220, 63, 25, 208, 10,
|
||||||
|
220, 7, 25, 194, 138, 209, 167, 28, 122, 137, 227, 38, 201, 218, 214,
|
||||||
|
219, 30, 219, 72, 91, 118, 187, 102,
|
||||||
|
243, 106, 197, 239, 19, 12, 13, 197, 197, 147, 19, 45, 205, 221, 149,
|
||||||
|
153, 175, 42, 252, 31, 1, 200, 0,
|
||||||
|
86, 128, 62, 224, 16, 72, 12, 54, 133, 214, 227, 30, 201, 200, 86, 214,
|
||||||
|
190, 222, 240, 88, 68, 58, 179,
|
||||||
|
83, 53, 253, 215, 1, 158, 128, 104, 96, 46, 168, 28, 126, 137, 224,
|
||||||
|
102, 200, 42, 214, 159, 30, 232, 8,
|
||||||
|
78, 134, 180, 98, 247, 105, 134, 174, 226, 252, 73, 129, 246, 224, 70,
|
||||||
|
200, 50, 214, 149, 158, 239, 40, 76,
|
||||||
|
30, 181, 200, 119, 22, 166, 142, 250, 228, 67, 11, 113, 199, 100, 82,
|
||||||
|
171, 125, 191, 97, 176, 40, 116, 30,
|
||||||
|
167, 72, 122, 182, 163, 54, 249, 214, 194, 222, 209, 152, 92, 106, 185,
|
||||||
|
239, 50, 204, 21, 149, 207, 47, 20,
|
||||||
|
28, 15, 73, 196, 54, 211, 86, 221, 254, 217, 128, 90, 224, 59, 8, 19,
|
||||||
|
70, 141, 242, 229, 133, 139, 35,
|
||||||
|
39, 89, 218, 186, 219, 51, 27, 85, 203, 127, 23, 96, 14, 168, 4, 126,
|
||||||
|
131, 96, 97, 232, 40, 78, 158,
|
||||||
|
180, 104, 119, 110, 166, 172, 122, 253, 227, 1, 137, 192, 102, 208, 42,
|
||||||
|
220, 31, 25, 200, 10, 214, 135, 30,
|
||||||
|
226, 136, 73, 166, 182, 250, 246, 195, 6, 209, 194, 220, 81, 153, 252,
|
||||||
|
106, 193, 239, 16, 76, 12, 53, 197,
|
||||||
|
215, 19, 30, 141, 200, 101, 150, 171, 46, 255, 92, 64, 57, 240, 18,
|
||||||
|
196, 13, 147, 69, 173, 243, 61, 133,
|
||||||
|
209, 163, 28, 121, 201, 226, 214, 201, 158, 214, 232, 94, 206, 184, 84,
|
||||||
|
114, 191, 101, 176, 43, 52, 31, 87,
|
||||||
|
72, 62, 182, 144, 118, 236, 38, 205, 218, 213, 155, 31, 43, 72, 31,
|
||||||
|
118, 136, 38, 230, 154, 202, 235, 23,
|
||||||
|
15, 78, 132, 52, 99, 87, 105, 254, 174, 192, 124, 80, 33, 252, 24, 65,
|
||||||
|
202, 176, 87, 52, 62, 151, 80,
|
||||||
|
110, 188, 44, 113, 221, 228, 89, 139, 122, 231, 99, 10, 169, 199, 62,
|
||||||
|
210, 144, 93, 172, 57, 189, 210, 241,
|
||||||
|
157, 132, 105, 163, 110, 249, 236, 66, 205, 241, 149, 132, 111, 35,
|
||||||
|
108, 25, 237, 202, 205, 151, 21, 174, 143,
|
||||||
|
60, 100, 17, 235, 76, 79, 117, 244, 39, 7, 90, 130, 187, 33, 179, 88,
|
||||||
|
117, 250, 167, 3, 58, 129, 211,
|
||||||
|
32, 93, 216, 57, 154, 146, 235, 45, 143, 93, 164, 57, 187, 82, 243,
|
||||||
|
125, 133, 225, 163, 8, 121, 198, 162,
|
||||||
|
210, 249, 157, 130, 233, 161, 142, 248, 100, 66, 171, 113, 191, 100,
|
||||||
|
112, 43, 100, 31, 107, 72, 47, 118, 156,
|
||||||
|
38, 233, 218, 206, 219, 20, 91, 79, 123, 116, 35, 103, 89, 234, 186,
|
||||||
|
207, 51, 20, 21, 207, 79, 20, 52,
|
||||||
|
15, 87, 68, 62, 179, 80, 117, 252, 39, 1, 218, 128, 91, 32, 59, 88, 19,
|
||||||
|
122, 141, 227, 37, 137, 219,
|
||||||
|
38, 219, 90, 219, 123, 27, 99, 75, 105, 247, 110, 198, 172, 82, 253,
|
||||||
|
253, 129, 129, 160, 96, 120, 40, 34,
|
||||||
|
158, 153, 168, 106, 254, 175, 0, 124, 0, 33, 192, 24, 80, 10, 188, 7,
|
||||||
|
49, 194, 148, 81, 175, 124, 124,
|
||||||
|
33, 225, 216, 72, 90, 182, 187, 54, 243, 86, 197, 254, 211, 0, 93, 192,
|
||||||
|
57, 144, 18, 236, 13, 141, 197,
|
||||||
|
165, 147, 59, 45, 211, 93, 157, 249, 169, 130, 254, 225, 128, 72, 96,
|
||||||
|
54, 168, 22, 254, 142, 192, 100, 80,
|
||||||
|
43, 124, 31, 97, 200, 40, 86, 158, 190, 232, 112, 78, 164, 52, 123, 87,
|
||||||
|
99, 126, 169, 224, 126, 200, 32,
|
||||||
|
86, 152, 62, 234, 144, 79, 44, 52, 29, 215, 73, 158, 182, 232, 118,
|
||||||
|
206, 166, 212, 122, 223, 99, 24, 41,
|
||||||
|
202, 158, 215, 40, 94, 158, 184, 104, 114, 174, 165, 188, 123, 49, 227,
|
||||||
|
84, 73, 255, 118, 192, 38, 208, 26,
|
||||||
|
220, 11, 25, 199, 74, 210, 183, 29, 182, 137, 182, 230, 246, 202, 198,
|
||||||
|
215, 18, 222, 141, 152, 101, 170, 171,
|
||||||
|
63, 63, 80, 16, 60, 12, 17, 197, 204, 83, 21, 253, 207, 1, 148, 0, 111,
|
||||||
|
64, 44, 48, 29, 212, 9,
|
||||||
|
159, 70, 232, 50, 206, 149, 148, 111, 47, 108, 28, 45, 201, 221, 150,
|
||||||
|
217, 174, 218, 252, 91, 1, 251, 64,
|
||||||
|
67, 112, 49, 228, 20, 75, 79, 119, 116, 38, 167, 90, 250, 187, 3, 51,
|
||||||
|
65, 213, 240, 95, 4, 56, 3,
|
||||||
|
82, 129, 253, 160, 65, 184, 48, 114, 148, 37, 175, 91, 60, 59, 81, 211,
|
||||||
|
124, 93, 225, 249, 136, 66, 230,
|
||||||
|
177, 138, 244, 103, 7, 106, 130, 175, 33, 188, 24, 113, 202, 164, 87,
|
||||||
|
59, 126, 147, 96, 109, 232, 45, 142,
|
||||||
|
157, 164, 105, 187, 110, 243, 108, 69, 237, 243, 13, 133, 197, 163, 19,
|
||||||
|
57, 205, 210, 213, 157, 159, 41, 168,
|
||||||
|
30, 254, 136, 64, 102, 176, 42, 244, 31, 7, 72, 2, 182, 129, 182, 224,
|
||||||
|
118, 200, 38, 214, 154, 222, 235,
|
||||||
|
24, 79, 74, 180, 55, 55, 86, 150, 190, 238, 240, 76, 68, 53, 243, 87,
|
||||||
|
5, 254, 131, 0, 97, 192, 40,
|
||||||
|
80, 30, 188, 8, 113, 198, 164, 82, 251, 125, 131, 97, 161, 232, 120,
|
||||||
|
78, 162, 180, 121, 183, 98, 246, 169,
|
||||||
|
134, 254, 226, 192, 73, 144, 54, 236, 22, 205, 206, 213, 148, 95, 47,
|
||||||
|
120, 28, 34, 137, 217, 166, 218, 250,
|
||||||
|
219, 3, 27, 65, 203, 112, 87, 100, 62, 171, 80, 127, 124, 32, 33, 216,
|
||||||
|
24, 90, 138, 187, 39, 51, 90,
|
||||||
|
149, 251, 47, 3, 92, 1, 249, 192, 66, 208, 49, 156, 20, 105, 207, 110,
|
||||||
|
212, 44, 95, 93, 248, 57, 130,
|
||||||
|
146, 225, 173, 136, 125, 166, 161, 186, 248, 115, 2, 165, 193, 187, 16,
|
||||||
|
115, 76, 37, 245, 219, 7, 27, 66,
|
||||||
|
139, 113, 167, 100, 122, 171, 99, 63, 105, 208, 46, 220, 28, 89, 201,
|
||||||
|
250, 214, 195, 30, 209, 200, 92, 86,
|
||||||
|
185, 254, 242, 192, 69, 144, 51, 44, 21, 221, 207, 25, 148, 10, 239,
|
||||||
|
71, 12, 50, 133, 213, 163, 31, 57,
|
||||||
|
200, 18, 214, 141, 158, 229, 168, 75, 62, 183, 80, 118, 188, 38, 241,
|
||||||
|
218, 196, 91, 19, 123, 77, 227, 117,
|
||||||
|
137, 231, 38, 202, 154, 215, 43, 30, 159, 72, 104, 54, 174, 150, 252,
|
||||||
|
110, 193, 236, 80, 77, 252, 53, 129,
|
||||||
|
215, 32, 94, 152, 56, 106, 146, 175, 45, 188, 29, 177, 201, 180, 86,
|
||||||
|
247, 126, 198, 160, 82, 248, 61, 130,
|
||||||
|
145, 161, 172, 120, 125, 226, 161, 137, 184, 102, 242, 170, 197, 191,
|
||||||
|
19, 48, 13, 212, 5, 159, 67, 40, 49,
|
||||||
|
222, 148, 88, 111, 122, 172, 35, 61, 217, 209, 154, 220, 107, 25, 239,
|
||||||
|
74, 204, 55, 21, 214, 143, 30, 228,
|
||||||
|
8, 75, 70, 183, 114, 246, 165, 134, 251, 34, 195, 89, 145, 250, 236,
|
||||||
|
67, 13, 241, 197, 132, 83, 35, 125,
|
||||||
|
217, 225, 154, 200, 107, 22, 175, 78, 252, 52, 65, 215, 112, 94, 164,
|
||||||
|
56, 123, 82, 163, 125, 185, 225, 178,
|
||||||
|
200, 117, 150, 167, 46, 250, 156, 67, 41, 241, 222, 196, 88, 83, 122,
|
||||||
|
189, 227, 49, 137, 212, 102, 223, 106,
|
||||||
|
216, 47, 26, 156, 11, 41, 199, 94, 210, 184, 93, 178, 185, 181, 178,
|
||||||
|
247, 53, 134, 151, 34, 238, 153, 140,
|
||||||
|
106, 229, 239, 11, 12, 7, 69, 194, 179, 17, 181, 204, 119, 21, 230,
|
||||||
|
143, 10, 228, 7, 11, 66, 135, 113,
|
||||||
|
162, 164, 121, 187, 98, 243, 105, 133, 238, 227, 12, 73, 197, 246, 211,
|
||||||
|
6, 221, 194, 217, 145, 154, 236, 107,
|
||||||
|
13, 239, 69, 140, 51, 37, 213, 219, 31, 27, 72, 11, 118, 135, 102, 226,
|
||||||
|
170, 201, 191, 22, 240, 14, 196,
|
||||||
|
4, 83, 67, 125, 241, 225, 132, 72, 99, 118, 169, 230, 254, 202, 192,
|
||||||
|
87, 16, 62, 140, 16, 101, 204, 43,
|
||||||
|
21, 223, 79, 24, 52, 10, 151, 71, 46, 178, 156, 117, 169, 231, 62, 202,
|
||||||
|
144, 87, 44, 62, 157, 208, 105,
|
||||||
|
156, 46, 233, 220, 78, 217, 244, 90, 199, 123, 18, 163, 77, 185, 245,
|
||||||
|
178, 199, 53, 146, 151, 45, 174, 157,
|
||||||
|
188, 105, 177, 238, 244, 76, 71, 117, 242, 167, 5, 186, 131, 51, 33,
|
||||||
|
213, 216, 95, 26, 184, 11, 50, 135,
|
||||||
|
85, 162, 191, 57, 176, 18, 244, 13, 135, 69, 162, 179, 57, 181, 210,
|
||||||
|
247, 29, 134, 137, 162, 230, 249, 138,
|
||||||
|
194, 231, 17, 138, 140, 103, 37, 234, 155, 15, 43, 68, 31, 115, 72, 37,
|
||||||
|
246, 155, 6, 235, 66, 207, 113,
|
||||||
|
148, 36, 111, 91, 108, 59, 109, 211, 109, 157, 237, 169, 141, 190, 229,
|
||||||
|
176, 75, 52, 55, 87, 86, 190, 190,
|
||||||
|
240, 112, 68, 36, 51, 91, 85, 251, 127, 3, 96, 1, 232, 0, 78, 128, 52,
|
||||||
|
96, 23, 104, 14, 174, 132,
|
||||||
|
124, 99, 97, 233, 232, 78, 206, 180, 84, 119, 127, 102, 160, 42, 248,
|
||||||
|
31, 2, 136, 1, 166, 128, 122, 224,
|
||||||
|
35, 8, 25, 198, 138, 210, 231, 29, 138, 137, 167, 38, 250, 154, 195,
|
||||||
|
43, 17, 223, 76, 88, 53, 250, 151,
|
||||||
|
3, 46, 129, 220, 96, 89, 232, 58, 206, 147, 20, 109, 207, 109, 148, 45,
|
||||||
|
175, 93, 188, 57, 177, 210, 244,
|
||||||
|
93, 135, 121, 162, 162, 249, 185, 130, 242, 225, 133, 136, 99, 38, 169,
|
||||||
|
218, 254, 219, 0, 91, 64, 59, 112,
|
||||||
|
19, 100, 13, 235, 69, 143, 115, 36, 37, 219, 91, 27, 123, 75, 99, 119,
|
||||||
|
105, 230, 174, 202, 252, 87, 1,
|
||||||
|
254, 128, 64, 96, 48, 40, 20, 30, 143, 72, 100, 54, 171, 86, 255, 126,
|
||||||
|
192, 32, 80, 24, 60, 10, 145,
|
||||||
|
199, 44, 82, 157, 253, 169, 129, 190, 224, 112, 72, 36, 54, 155, 86,
|
||||||
|
235, 126, 207, 96, 84, 40, 63, 94,
|
||||||
|
144, 56, 108, 18, 173, 205, 189, 149, 177, 175, 52, 124, 23, 97, 206,
|
||||||
|
168, 84, 126, 191, 96, 112, 40, 36,
|
||||||
|
30, 155, 72, 107, 118, 175, 102, 252, 42, 193, 223, 16, 88, 12, 58,
|
||||||
|
133, 211, 35, 29, 217, 201, 154, 214,
|
||||||
|
235, 30, 207, 72, 84, 54, 191, 86, 240, 62, 196, 16, 83, 76, 61, 245,
|
||||||
|
209, 135, 28, 98, 137, 233, 166,
|
||||||
|
206, 250, 212, 67, 31, 113, 200, 36, 86, 155, 126, 235, 96, 79, 104,
|
||||||
|
52, 46, 151, 92, 110, 185, 236, 114,
|
||||||
|
205, 229, 149, 139, 47, 39, 92, 26, 185, 203, 50, 215, 85, 158, 191,
|
||||||
|
40, 112, 30, 164, 8, 123, 70, 163,
|
||||||
|
114, 249, 229, 130, 203, 33, 151, 88, 110, 186, 172, 115, 61, 229, 209,
|
||||||
|
139, 28, 103, 73, 234, 182, 207, 54,
|
||||||
|
212, 22, 223, 78, 216, 52, 90, 151, 123, 46, 163, 92, 121, 249, 226,
|
||||||
|
194, 201, 145, 150, 236, 110, 205, 236,
|
||||||
|
85, 141, 255, 37, 128, 27, 32, 11, 88, 7, 122, 130, 163, 33, 185, 216,
|
||||||
|
114, 218, 165, 155, 59, 43, 83,
|
||||||
|
95, 125, 248, 33, 130, 152, 97, 170, 168, 127, 62, 160, 16, 120, 12,
|
||||||
|
34, 133, 217, 163, 26, 249, 203, 2,
|
||||||
|
215, 65, 158, 176, 104, 116, 46, 167, 92, 122, 185, 227, 50, 201, 213,
|
||||||
|
150, 223, 46, 216, 28, 90, 137, 251,
|
||||||
|
38, 195, 90, 209, 251, 28, 67, 73, 241, 246, 196, 70, 211, 114, 221,
|
||||||
|
229, 153,
|
||||||
|
};
|
||||||
|
|
||||||
|
void scramble(unsigned char *inout)
|
||||||
|
{
|
||||||
|
unsigned char *r = inout + 12;
|
||||||
|
unsigned char *s = yellowbook_scrambler;
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
for (i = 2340; i; i--) {
|
||||||
|
*r++ ^= *s++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Calculate the P parities for the sector.
|
||||||
|
* The 43 P vectors of length 24 are combined with the GF8_P_COEFFS.
|
||||||
|
*/
|
||||||
|
void parity_p(unsigned char *sector)
|
||||||
|
{
|
||||||
|
int i, j;
|
||||||
|
unsigned char p0_msb, p1_msb;
|
||||||
|
unsigned char p0_lsb, p1_lsb;
|
||||||
|
unsigned char *p_msb_start, *p_lsb_start;
|
||||||
|
unsigned char *p_msb, *p_lsb;
|
||||||
|
unsigned char *coeffs0, *coeffs1;
|
||||||
|
unsigned char *p0, *p1;
|
||||||
|
unsigned char d;
|
||||||
|
unsigned short c;
|
||||||
|
|
||||||
|
p_lsb_start = sector + LEC_HEADER_OFFSET;
|
||||||
|
p_msb_start = sector + LEC_HEADER_OFFSET + 1;
|
||||||
|
|
||||||
|
p1 = sector + LEC_MODE1_P_PARITY_OFFSET;
|
||||||
|
p0 = sector + LEC_MODE1_P_PARITY_OFFSET + 2 * 43;
|
||||||
|
|
||||||
|
for (i = 0; i <= 42; i++) {
|
||||||
|
p_lsb = p_lsb_start;
|
||||||
|
p_msb = p_msb_start;
|
||||||
|
|
||||||
|
coeffs0 = gf8_p_coeffs[0];
|
||||||
|
coeffs1 = gf8_p_coeffs[1];
|
||||||
|
|
||||||
|
p0_lsb = p1_lsb = p0_msb = p1_msb = 0;
|
||||||
|
|
||||||
|
for (j = 0; j <= 23; j++) {
|
||||||
|
d = *p_lsb;
|
||||||
|
|
||||||
|
if (d != 0) {
|
||||||
|
c = gf8_log[d] + *coeffs0;
|
||||||
|
if (c >= 255)
|
||||||
|
c -= 255;
|
||||||
|
p0_lsb ^= gf8_ilog[c];
|
||||||
|
|
||||||
|
c = gf8_log[d] + *coeffs1;
|
||||||
|
if (c >= 255)
|
||||||
|
c -= 255;
|
||||||
|
p1_lsb ^= gf8_ilog[c];
|
||||||
|
}
|
||||||
|
|
||||||
|
d = *p_msb;
|
||||||
|
|
||||||
|
if (d != 0) {
|
||||||
|
c = gf8_log[d] + *coeffs0;
|
||||||
|
if (c >= 255)
|
||||||
|
c -= 255;
|
||||||
|
p0_msb ^= gf8_ilog[c];
|
||||||
|
|
||||||
|
c = gf8_log[d] + *coeffs1;
|
||||||
|
if (c >= 255)
|
||||||
|
c -= 255;
|
||||||
|
p1_msb ^= gf8_ilog[c];
|
||||||
|
}
|
||||||
|
|
||||||
|
coeffs0++;
|
||||||
|
coeffs1++;
|
||||||
|
|
||||||
|
p_lsb += 2 * 43;
|
||||||
|
p_msb += 2 * 43;
|
||||||
|
}
|
||||||
|
|
||||||
|
*p0 = p0_lsb;
|
||||||
|
*(p0 + 1) = p0_msb;
|
||||||
|
|
||||||
|
*p1 = p1_lsb;
|
||||||
|
*(p1 + 1) = p1_msb;
|
||||||
|
|
||||||
|
p0 += 2;
|
||||||
|
p1 += 2;
|
||||||
|
|
||||||
|
p_lsb_start += 2;
|
||||||
|
p_msb_start += 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Calculate the Q parities for the sector.
|
||||||
|
* The 26 Q vectors of length 43 are combined with the GF8_Q_COEFFS.
|
||||||
|
*/
|
||||||
|
void parity_q(unsigned char *sector)
|
||||||
|
{
|
||||||
|
int i, j;
|
||||||
|
unsigned char q0_msb, q1_msb;
|
||||||
|
unsigned char q0_lsb, q1_lsb;
|
||||||
|
unsigned char *q_msb_start, *q_lsb_start;
|
||||||
|
unsigned char *q_msb, *q_lsb;
|
||||||
|
unsigned char *coeffs0, *coeffs1;
|
||||||
|
unsigned char *q0, *q1, *q_start;
|
||||||
|
unsigned char d;
|
||||||
|
unsigned short c;
|
||||||
|
|
||||||
|
q_lsb_start = sector + LEC_HEADER_OFFSET;
|
||||||
|
q_msb_start = sector + LEC_HEADER_OFFSET + 1;
|
||||||
|
|
||||||
|
q_start = sector + LEC_MODE1_Q_PARITY_OFFSET;
|
||||||
|
q1 = sector + LEC_MODE1_Q_PARITY_OFFSET;
|
||||||
|
q0 = sector + LEC_MODE1_Q_PARITY_OFFSET + 2 * 26;
|
||||||
|
|
||||||
|
for (i = 0; i <= 25; i++) {
|
||||||
|
q_lsb = q_lsb_start;
|
||||||
|
q_msb = q_msb_start;
|
||||||
|
|
||||||
|
coeffs0 = gf8_q_coeffs[0];
|
||||||
|
coeffs1 = gf8_q_coeffs[1];
|
||||||
|
|
||||||
|
q0_lsb = q1_lsb = q0_msb = q1_msb = 0;
|
||||||
|
|
||||||
|
for (j = 0; j <= 42; j++) {
|
||||||
|
d = *q_lsb;
|
||||||
|
|
||||||
|
if (d != 0) {
|
||||||
|
c = gf8_log[d] + *coeffs0;
|
||||||
|
if (c >= 255)
|
||||||
|
c -= 255;
|
||||||
|
q0_lsb ^= gf8_ilog[c];
|
||||||
|
|
||||||
|
c = gf8_log[d] + *coeffs1;
|
||||||
|
if (c >= 255)
|
||||||
|
c -= 255;
|
||||||
|
q1_lsb ^= gf8_ilog[c];
|
||||||
|
}
|
||||||
|
|
||||||
|
d = *q_msb;
|
||||||
|
|
||||||
|
if (d != 0) {
|
||||||
|
c = gf8_log[d] + *coeffs0;
|
||||||
|
if (c >= 255)
|
||||||
|
c -= 255;
|
||||||
|
q0_msb ^= gf8_ilog[c];
|
||||||
|
|
||||||
|
c = gf8_log[d] + *coeffs1;
|
||||||
|
if (c >= 255)
|
||||||
|
c -= 255;
|
||||||
|
q1_msb ^= gf8_ilog[c];
|
||||||
|
}
|
||||||
|
|
||||||
|
coeffs0++;
|
||||||
|
coeffs1++;
|
||||||
|
|
||||||
|
q_lsb += 2 * 44;
|
||||||
|
q_msb += 2 * 44;
|
||||||
|
|
||||||
|
if (q_lsb >= q_start) {
|
||||||
|
q_msb -= 2 * 1118;
|
||||||
|
q_lsb -= 2 * 1118;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*q0 = q0_lsb;
|
||||||
|
*(q0 + 1) = q0_msb;
|
||||||
|
|
||||||
|
*q1 = q1_lsb;
|
||||||
|
*(q1 + 1) = q1_msb;
|
||||||
|
|
||||||
|
q0 += 2;
|
||||||
|
q1 += 2;
|
||||||
|
|
||||||
|
q_lsb_start += 2 * 43;
|
||||||
|
q_msb_start += 2 * 43;
|
||||||
|
}
|
||||||
|
}
|
12
libburn/lec.h
Normal file
12
libburn/lec.h
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||||
|
|
||||||
|
#ifndef __LEC
|
||||||
|
#define __LEC
|
||||||
|
|
||||||
|
#define RS_L12_BITS 8
|
||||||
|
|
||||||
|
void scramble(unsigned char *);
|
||||||
|
void parity_p(unsigned char *in);
|
||||||
|
void parity_q(unsigned char *in);
|
||||||
|
|
||||||
|
#endif /* __LEC */
|
File diff suppressed because it is too large
Load Diff
@ -1,167 +0,0 @@
|
|||||||
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_bd_spare_info;
|
|
||||||
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_offst_source_new;
|
|
||||||
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: *;
|
|
||||||
};
|
|
@ -1,13 +1,9 @@
|
|||||||
|
|
||||||
/* libdax_audioxtr
|
/* libdax_audioxtr
|
||||||
Audio track data extraction facility of libdax and libburn.
|
Audio track data extraction facility of libdax and libburn.
|
||||||
Copyright (C) 2006 Thomas Schmitt <scdbackup@gmx.net>, provided under GPLv2+
|
Copyright (C) 2006 Thomas Schmitt <scdbackup@gmx.net>, provided under GPL
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#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>
|
||||||
@ -25,8 +21,7 @@ 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 or include libburn.h */
|
/* All clients of the extraction facility must do this */
|
||||||
#define LIBDAX_AUDIOXTR_H_PUBLIC 1
|
|
||||||
#include "libdax_audioxtr.h"
|
#include "libdax_audioxtr.h"
|
||||||
|
|
||||||
|
|
||||||
@ -35,7 +30,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 *) calloc(1, sizeof(struct libdax_audioxtr));
|
o= *xtr= (struct libdax_audioxtr *) malloc(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);
|
||||||
|
@ -1,19 +1,12 @@
|
|||||||
|
|
||||||
/* libdax_audioxtr
|
/* libdax_audioxtr
|
||||||
Audio track data extraction facility of libdax and libburn.
|
Audio track data extraction facility of libdax and libburn.
|
||||||
Copyright (C) 2006 Thomas Schmitt <scdbackup@gmx.net>, provided under GPLv2+
|
Copyright (C) 2006 Thomas Schmitt <scdbackup@gmx.net>, provided under GPL
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#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 */
|
||||||
@ -117,16 +110,15 @@ 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 LIBDAX_AUDIOXTR________________
|
#ifdef LIDBAX_AUDIOXTR________________
|
||||||
|
|
||||||
|
|
||||||
-- place documentation text here ---
|
-- place documentation text here ---
|
||||||
|
|
||||||
|
|
||||||
#endif /* LIBDAX_AUDIOXTR_________________ */
|
#endif /* LIDBAX_AUDIOXTR_________________ */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,14 +1,10 @@
|
|||||||
|
|
||||||
/* libdax_msgs
|
/* libdax_msgs
|
||||||
Message handling facility of libdax.
|
Message handling facility of libdax.
|
||||||
Copyright (C) 2006 - 2010 Thomas Schmitt <scdbackup@gmx.net>,
|
Copyright (C) 2006 - 2008 Thomas Schmitt <scdbackup@gmx.net>,
|
||||||
provided under GPL version 2 or later.
|
provided under GPL version 2
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#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>
|
||||||
@ -16,7 +12,6 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#include <pthread.h>
|
|
||||||
|
|
||||||
/* Only this single source module is entitled to do this */
|
/* Only this single source module is entitled to do this */
|
||||||
#define LIBDAX_MSGS_H_INTERNAL 1
|
#define LIBDAX_MSGS_H_INTERNAL 1
|
||||||
@ -37,7 +32,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 *) calloc(1, sizeof(struct libdax_msgs_item));
|
(struct libdax_msgs_item *) malloc(sizeof(struct libdax_msgs_item));
|
||||||
if(o==NULL)
|
if(o==NULL)
|
||||||
return(-1);
|
return(-1);
|
||||||
o->timestamp= 0.0;
|
o->timestamp= 0.0;
|
||||||
@ -140,7 +135,7 @@ int libdax_msgs_new(struct libdax_msgs **m, int flag)
|
|||||||
{
|
{
|
||||||
struct libdax_msgs *o;
|
struct libdax_msgs *o;
|
||||||
|
|
||||||
(*m)= o= (struct libdax_msgs *) calloc(1, sizeof(struct libdax_msgs));
|
(*m)= o= (struct libdax_msgs *) malloc(sizeof(struct libdax_msgs));
|
||||||
if(o==NULL)
|
if(o==NULL)
|
||||||
return(-1);
|
return(-1);
|
||||||
o->refcount= 1;
|
o->refcount= 1;
|
||||||
@ -370,7 +365,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= calloc(1, strlen(msg_text)+1);
|
item->msg_text= malloc(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);
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
|
|
||||||
/* libdax_msgs
|
/* libdax_msgs
|
||||||
Message handling facility of libdax.
|
Message handling facility of libdax.
|
||||||
Copyright (C) 2006-2010 Thomas Schmitt <scdbackup@gmx.net>,
|
Copyright (C) 2006-2008 Thomas Schmitt <scdbackup@gmx.net>,
|
||||||
provided under GPL version 2 or later.
|
provided under GPL version 2
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
@ -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 LIBDAX_MSGS_________________
|
#ifdef LIDBAX_MSGS_________________
|
||||||
|
|
||||||
|
|
||||||
/* Registered Error Codes */
|
/* Registered Error Codes */
|
||||||
@ -434,8 +434,6 @@ 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:
|
||||||
|
|
||||||
@ -530,41 +528,12 @@ Range "scdbackup" : 0x00020000 to 0x0002ffff
|
|||||||
0x00020159 (DEBUG,HIGH) = TOC Format 0 returns inconsistent data
|
0x00020159 (DEBUG,HIGH) = TOC Format 0 returns inconsistent data
|
||||||
0x0002015a (NOTE,HIGH) = Could not examine busy device
|
0x0002015a (NOTE,HIGH) = Could not examine busy device
|
||||||
0x0002015b (HINT,HIGH) = Busy '...' seems to be a hard disk, as '...1' exists
|
0x0002015b (HINT,HIGH) = Busy '...' seems to be a hard disk, as '...1' exists
|
||||||
0x0002015c (FAILURE,HIGH) = Fifo size too small for desired peek buffer
|
0x0002015c (FAILURE,HIGH) = Fifo size is smaller than desired peek buffer
|
||||||
0x0002015d (FAILURE,HIGH) = Fifo input ended short of desired peek buffer size
|
0x0002015d (FAILURE,HIGH) = Fifo input ended short of desired peek buffer size
|
||||||
0x0002015e (FATAL,HIGH) = Fifo is already under consumption when peeking
|
0x0002015e (FATAL,HIGH) = Fifo is already under consumption when peeking
|
||||||
0x0002015f (MISHAP,HIGH) = Damaged CD table-of-content detected and truncated
|
0x0002015f (MISHAP,HIGH) = Damaged CD table-of-content detected and truncated
|
||||||
0x00020160 (WARNING,HIGH) = Session without leadout encountered
|
0x00020160 (WARNING,HIGH) = Session without leadout encountered
|
||||||
0x00020161 (WARNING,HIGH) = Empty session deleted
|
0x00020161 (WARNING,HIGH) = Empty session deleted
|
||||||
0x00020162 (SORRY,HIGH) = BD-R not unformatted blank any more. Cannot format
|
|
||||||
0x00020163 (NOTE,HIGH) = Blank BD-R left unformatted for zero spare capacity
|
|
||||||
0x00020164 (SORRY,HIGH) = Drive does not format BD-RE without spares
|
|
||||||
0x00020165 (WARNING,HIGH) = Drive does not support fast formatting
|
|
||||||
0x00020166 (WARNING,HIGH) = Drive does not support full formatting
|
|
||||||
0x00020167 (SORRY,HIGH) = Drive does not support non-default formatting
|
|
||||||
0x00020168 (FAILURE,HIGH) = Media not properly formatted. Cannot write.
|
|
||||||
0x00020169 (WARNING,HIGH) = Last session on media is still open
|
|
||||||
0x0002016a (FAILURE,HIGH) = No MMC transport adapter is present
|
|
||||||
0x0002016b (WARNING,HIGH) = No MMC transport adapter is present
|
|
||||||
0x0002016c (DEBUG,HIGH) = No MMC transport adapter is present
|
|
||||||
0x0002016e (DEBUG,HIGH) = MODE SENSE page 2A too short
|
|
||||||
0x0002016f (DEBUG,HIGH) = Unable to grab scanned drive
|
|
||||||
0x00020170 (NOTE,HIGH) = Closing open session before writing new one
|
|
||||||
0x00020171 (NOTE,HIGH) = Closing BD-R with accidently open session
|
|
||||||
0x00020172 (SORRY,HIGH) = Read start address larger than number of readable blocks
|
|
||||||
0x00020173 (FAILURE,HIGH) = Drive tells NWA smaller than last written address
|
|
||||||
0x00020174 (SORRY,HIGH) = Fifo alignment does not allow desired read size
|
|
||||||
0x00020175 (FATAL,HIGH) = Supporting library is too old
|
|
||||||
0x00020176 (NOTE,HIGH) = Stream recording disabled because of small OS buffer
|
|
||||||
0x00020177 (ABORT,HIGH) = Urged drive worker threads to do emergency halt
|
|
||||||
0x00020178 (DEBUG,HIGH) = Write thread ended
|
|
||||||
0x00020179 (FAILURE,HIGH) = Offset source start address is before end of previous source
|
|
||||||
0x0002017a (FAILURE,HIGH) = Expected offset source object as parameter
|
|
||||||
0x0002017b (WARNING,HIGH) = Sequential BD-R media likely to soon fail writing
|
|
||||||
0x0002017c (FAILURE,HIGH) = No valid write type selected
|
|
||||||
0x0002017d (FATAL,HIGH) = Invalid file descriptor with stdio pseudo-drive
|
|
||||||
0x0002017e (FAILURE,HIGH) = Failed to close track, session, or disc
|
|
||||||
0x0002017f (FAILURE,HIGH) = Failed to synchronize drive cache
|
|
||||||
|
|
||||||
libdax_audioxtr:
|
libdax_audioxtr:
|
||||||
0x00020200 (SORRY,HIGH) = Cannot open audio source file
|
0x00020200 (SORRY,HIGH) = Cannot open audio source file
|
||||||
@ -685,7 +654,7 @@ Range "libisoburn" : 0x00060000 to 0x00006ffff
|
|||||||
|
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
#endif /* LIBDAX_MSGS_________________ */
|
#endif /* LIDBAX_MSGS_________________ */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
1300
libburn/mmc.c
1300
libburn/mmc.c
File diff suppressed because it is too large
Load Diff
@ -1,11 +1,5 @@
|
|||||||
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||||
|
|
||||||
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
|
|
||||||
Copyright (c) 2006 - 2010 Thomas Schmitt <scdbackup@gmx.net>
|
|
||||||
Provided under GPL version 2 or later.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef __MMC
|
#ifndef __MMC
|
||||||
#define __MMC
|
#define __MMC
|
||||||
|
|
||||||
@ -74,40 +68,13 @@ int mmc_compose_mode_page_5(struct burn_drive *d,
|
|||||||
const struct burn_write_opts *o,
|
const struct burn_write_opts *o,
|
||||||
unsigned char *pd);
|
unsigned char *pd);
|
||||||
|
|
||||||
/* ts A70201 */
|
|
||||||
int mmc_four_char_to_int(unsigned char *data);
|
|
||||||
|
|
||||||
/* ts A70812 : return 0 = ok , return BE_CANCELLED = error occured */
|
/* ts A70812 : return 0 = ok , return BE_CANCELLED = error occured */
|
||||||
int mmc_read_10(struct burn_drive *d, int start, int amount,
|
int mmc_read_10(struct burn_drive *d, int start, int amount,
|
||||||
struct buffer *buf);
|
struct buffer *buf);
|
||||||
|
|
||||||
/* ts A81210 : Determine the upper limit of readable data size */
|
|
||||||
int mmc_read_capacity(struct burn_drive *d);
|
|
||||||
|
|
||||||
/* ts A61201 */
|
|
||||||
char *mmc_obtain_profile_name(int profile_number);
|
|
||||||
|
|
||||||
|
|
||||||
/* mmc5r03c.pdf 4.3.4.4.1 d) "The maximum number of RZones is 2 302." */
|
/* mmc5r03c.pdf 4.3.4.4.1 d) "The maximum number of RZones is 2 302." */
|
||||||
#define BURN_MMC_FAKE_TOC_MAX_SIZE 2302
|
#define BURN_MMC_FAKE_TOC_MAX_SIZE 2302
|
||||||
|
|
||||||
|
|
||||||
/* ts A90903 */
|
|
||||||
/* MMC backend of API call burn_get_media_product_id()
|
|
||||||
*/
|
|
||||||
int mmc_get_media_product_id(struct burn_drive *d,
|
|
||||||
char **product_id, char **media_code1, char **media_code2,
|
|
||||||
char **book_type, int flag);
|
|
||||||
|
|
||||||
|
|
||||||
/* ts A60910 (estimated) */
|
|
||||||
int mmc_function_spy(struct burn_drive *d, char * text);
|
|
||||||
|
|
||||||
/* ts A91118 */
|
|
||||||
int mmc_start_if_needed(struct burn_drive *d, int flag);
|
|
||||||
|
|
||||||
/* ts B00924 */
|
|
||||||
int mmc_get_bd_spare_info(struct burn_drive *d,
|
|
||||||
int *alloc_blocks, int *free_blocks, int flag);
|
|
||||||
|
|
||||||
#endif /*__MMC*/
|
#endif /*__MMC*/
|
||||||
|
@ -1,14 +1,5 @@
|
|||||||
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||||
|
|
||||||
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
|
|
||||||
Provided under GPL version 2 or later.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
#include "../config.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "null.h"
|
#include "null.h"
|
||||||
#include "libburn.h"
|
#include "libburn.h"
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@ -24,7 +15,7 @@ struct burn_source *burn_null_source_new(void)
|
|||||||
{
|
{
|
||||||
struct burn_source *src;
|
struct burn_source *src;
|
||||||
|
|
||||||
src = calloc(1, sizeof(struct burn_source));
|
src = malloc(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;
|
||||||
|
@ -1,13 +1,3 @@
|
|||||||
|
|
||||||
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
|
|
||||||
Copyright (c) 2006 - 2010 Thomas Schmitt <scdbackup@gmx.net>
|
|
||||||
Provided under GPL version 2 or later.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
#include "../config.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "libburn.h"
|
#include "libburn.h"
|
||||||
#include "options.h"
|
#include "options.h"
|
||||||
#include "drive.h"
|
#include "drive.h"
|
||||||
@ -27,7 +17,7 @@ struct burn_write_opts *burn_write_opts_new(struct burn_drive *drive)
|
|||||||
{
|
{
|
||||||
struct burn_write_opts *opts;
|
struct burn_write_opts *opts;
|
||||||
|
|
||||||
opts = calloc(1, sizeof(struct burn_write_opts));
|
opts = malloc(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,
|
||||||
@ -49,8 +39,6 @@ struct burn_write_opts *burn_write_opts_new(struct burn_drive *drive)
|
|||||||
opts->fill_up_media = 0;
|
opts->fill_up_media = 0;
|
||||||
opts->force_is_set = 0;
|
opts->force_is_set = 0;
|
||||||
opts->do_stream_recording = 0;
|
opts->do_stream_recording = 0;
|
||||||
opts->dvd_obs_override = 0;
|
|
||||||
opts->stdio_fsync_size = Libburn_stdio_fsync_limiT;
|
|
||||||
opts->has_mediacatalog = 0;
|
opts->has_mediacatalog = 0;
|
||||||
opts->format = BURN_CDROM;
|
opts->format = BURN_CDROM;
|
||||||
opts->multi = 0;
|
opts->multi = 0;
|
||||||
@ -68,7 +56,7 @@ struct burn_read_opts *burn_read_opts_new(struct burn_drive *drive)
|
|||||||
{
|
{
|
||||||
struct burn_read_opts *opts;
|
struct burn_read_opts *opts;
|
||||||
|
|
||||||
opts = calloc(1, sizeof(struct burn_read_opts));
|
opts = malloc(sizeof(struct burn_read_opts));
|
||||||
opts->drive = drive;
|
opts->drive = drive;
|
||||||
opts->refcount = 1;
|
opts->refcount = 1;
|
||||||
opts->raw = 0;
|
opts->raw = 0;
|
||||||
@ -125,7 +113,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 = calloc(count, sizeof(struct burn_toc_entry));
|
opts->toc_entry = malloc(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);
|
||||||
}
|
}
|
||||||
@ -155,7 +143,7 @@ int burn_write_opts_set_simulate(struct burn_write_opts *opts, int sim)
|
|||||||
int burn_write_opts_set_underrun_proof(struct burn_write_opts *opts,
|
int burn_write_opts_set_underrun_proof(struct burn_write_opts *opts,
|
||||||
int underrun_proof)
|
int underrun_proof)
|
||||||
{
|
{
|
||||||
if (opts->drive->mdata->valid <= 0)
|
if (!opts->drive->mdata->valid)
|
||||||
return 0;
|
return 0;
|
||||||
if (opts->drive->mdata->underrun_proof) {
|
if (opts->drive->mdata->underrun_proof) {
|
||||||
opts->underrun_proof = underrun_proof;
|
opts->underrun_proof = underrun_proof;
|
||||||
@ -397,29 +385,10 @@ void burn_write_opts_set_force(struct burn_write_opts *opts, int use_force)
|
|||||||
void burn_write_opts_set_stream_recording(struct burn_write_opts *opts,
|
void burn_write_opts_set_stream_recording(struct burn_write_opts *opts,
|
||||||
int value)
|
int value)
|
||||||
{
|
{
|
||||||
opts->do_stream_recording = value;
|
opts->do_stream_recording = !!value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ts A91115: API */
|
|
||||||
void burn_write_opts_set_dvd_obs(struct burn_write_opts *opts, int obs)
|
|
||||||
{
|
|
||||||
if (obs != 0 && obs != 32 * 1024 && obs != 64 * 1024)
|
|
||||||
return;
|
|
||||||
opts->dvd_obs_override = obs;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* ts A91115: API */
|
|
||||||
void burn_write_opts_set_stdio_fsync(struct burn_write_opts *opts, int rythm)
|
|
||||||
{
|
|
||||||
if (rythm == -1)
|
|
||||||
opts->stdio_fsync_size = 0;
|
|
||||||
else if (rythm == 0)
|
|
||||||
opts->stdio_fsync_size = Libburn_stdio_fsync_limiT;
|
|
||||||
else if (rythm >= 32)
|
|
||||||
opts->stdio_fsync_size = rythm;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* ts A70901: API */
|
/* ts A70901: API */
|
||||||
|
@ -1,9 +1,3 @@
|
|||||||
|
|
||||||
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
|
|
||||||
Copyright (c) 2006 - 2010 Thomas Schmitt <scdbackup@gmx.net>
|
|
||||||
Provided under GPL version 2 or later.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef BURN__OPTIONS_H
|
#ifndef BURN__OPTIONS_H
|
||||||
#define BURN__OPTIONS_H
|
#define BURN__OPTIONS_H
|
||||||
|
|
||||||
@ -57,19 +51,9 @@ struct burn_write_opts
|
|||||||
|
|
||||||
/* ts A80412 : whether to use WRITE12 with Streaming bit set
|
/* ts A80412 : whether to use WRITE12 with Streaming bit set
|
||||||
rather than WRITE10. Speeds up DVD-RAM. Might help with BD-RE.
|
rather than WRITE10. Speeds up DVD-RAM. Might help with BD-RE.
|
||||||
This gets transferred to burn_drive.do_stream_recording
|
This gets transferred to burn_drive.do_stream_recording */
|
||||||
*/
|
|
||||||
int do_stream_recording;
|
int do_stream_recording;
|
||||||
|
|
||||||
/* ts A91115 : override value for .obs on DVD media.
|
|
||||||
Only values 0, 32K and 64K are allowed for now. */
|
|
||||||
int dvd_obs_override;
|
|
||||||
|
|
||||||
/* ts A91115 : size of the fsync() interval for stdio writing.
|
|
||||||
Values 0 or >= 32 counted in 2 KB blocks. */
|
|
||||||
int stdio_fsync_size;
|
|
||||||
|
|
||||||
|
|
||||||
/** A disc can have a media catalog number */
|
/** A disc can have a media catalog number */
|
||||||
int has_mediacatalog;
|
int has_mediacatalog;
|
||||||
unsigned char mediacatalog[13];
|
unsigned char mediacatalog[13];
|
||||||
@ -80,11 +64,6 @@ struct burn_write_opts
|
|||||||
unsigned char multi;
|
unsigned char multi;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Default value for burn_write_opts.stdio_flush_size
|
|
||||||
*/
|
|
||||||
#define Libburn_stdio_fsync_limiT 8192
|
|
||||||
|
|
||||||
|
|
||||||
/** Options for disc reading operations. This should be created with
|
/** Options for disc reading operations. This should be created with
|
||||||
burn_read_opts_new() and freed with burn_read_opts_free(). */
|
burn_read_opts_new() and freed with burn_read_opts_free(). */
|
||||||
struct burn_read_opts
|
struct burn_read_opts
|
||||||
|
@ -1,88 +0,0 @@
|
|||||||
|
|
||||||
/* os-dummy.h
|
|
||||||
Operating system specific libburn definitions and declarations. Included
|
|
||||||
by os.h in case of compilation for
|
|
||||||
Unknown POSIX like systems
|
|
||||||
with the dummy MMC transport adapter sg-dummy.c
|
|
||||||
|
|
||||||
Copyright (C) 2009 Thomas Schmitt <scdbackup@gmx.net>, provided under GPLv2+
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
/** List of all signals which shall be caught by signal handlers and trigger
|
|
||||||
a graceful abort of libburn. (See man 7 signal.)
|
|
||||||
*/
|
|
||||||
/* Once as system defined macros */
|
|
||||||
#define BURN_OS_SIGNAL_MACRO_LIST \
|
|
||||||
SIGHUP, SIGINT, SIGQUIT, SIGILL, SIGABRT, \
|
|
||||||
SIGFPE, SIGSEGV, SIGPIPE, SIGALRM, SIGTERM, \
|
|
||||||
SIGUSR1, SIGUSR2, SIGXCPU, SIGTSTP, SIGTTIN, \
|
|
||||||
SIGTTOU
|
|
||||||
|
|
||||||
/* Once as text 1:1 list of strings for messages and interpreters */
|
|
||||||
#define BURN_OS_SIGNAL_NAME_LIST \
|
|
||||||
"SIGHUP", "SIGINT", "SIGQUIT", "SIGILL", "SIGABRT", \
|
|
||||||
"SIGFPE", "SIGSEGV", "SIGPIPE", "SIGALRM", "SIGTERM", \
|
|
||||||
"SIGUSR1", "SIGUSR2", "SIGXCPU", "SIGTSTP", "SIGTTIN", \
|
|
||||||
"SIGTTOU"
|
|
||||||
|
|
||||||
/* The number of above list items */
|
|
||||||
#define BURN_OS_SIGNAL_COUNT 16
|
|
||||||
|
|
||||||
/** 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 \
|
|
||||||
SIGKILL, SIGCHLD, SIGSTOP BURN_OS_SIG_WINCH BURN_OS_SIG_URG
|
|
||||||
|
|
||||||
/* The number of above list items */
|
|
||||||
#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 */
|
|
||||||
/* Important : MUST be at least 32768 ! */
|
|
||||||
#define BURN_OS_TRANSPORT_BUFFER_SIZE 65536
|
|
||||||
|
|
||||||
|
|
||||||
/* To hold the position of the most recently delivered address from
|
|
||||||
device enumeration.
|
|
||||||
*/
|
|
||||||
struct burn_drive_enumerator_struct {
|
|
||||||
int pos;
|
|
||||||
int info_count;
|
|
||||||
char **info_list;
|
|
||||||
};
|
|
||||||
|
|
||||||
#define BURN_OS_DEFINE_DRIVE_ENUMERATOR_T \
|
|
||||||
typedef struct burn_drive_enumerator_struct burn_drive_enumerator_t;
|
|
||||||
|
|
||||||
|
|
||||||
/* The list of operating system dependent elements in struct burn_drive.
|
|
||||||
Usually they are initialized in sg-*.c:enumerate_common().
|
|
||||||
*/
|
|
||||||
#define BURN_OS_TRANSPORT_DRIVE_ELEMENTS \
|
|
||||||
int just_a_dummy;
|
|
||||||
|
|
@ -4,8 +4,7 @@
|
|||||||
by os.h in case of compilation for
|
by os.h in case of compilation for
|
||||||
FreeBSD with CAM
|
FreeBSD with CAM
|
||||||
|
|
||||||
Copyright (C) 2006 - 2010 Thomas Schmitt <scdbackup@gmx.net>,
|
Copyright (C) 2006 Thomas Schmitt <scdbackup@gmx.net>, provided under GPL
|
||||||
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
|
||||||
@ -42,11 +41,7 @@ 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 ! */
|
||||||
/* Older BSD info says that 32 kB is maximum. But 64 kB seems to work well
|
#define BURN_OS_TRANSPORT_BUFFER_SIZE 32768
|
||||||
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
|
||||||
@ -62,8 +57,5 @@ typedef struct burn_drive_enumeration_state *burn_drive_enumerator_t;
|
|||||||
To be initialized and used within sg-*.c .
|
To be initialized and used within sg-*.c .
|
||||||
*/
|
*/
|
||||||
#define BURN_OS_TRANSPORT_DRIVE_ELEMENTS \
|
#define BURN_OS_TRANSPORT_DRIVE_ELEMENTS \
|
||||||
struct cam_device* cam; \
|
struct cam_device* cam;
|
||||||
int lock_fd; \
|
|
||||||
int is_ahci; \
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,95 +0,0 @@
|
|||||||
|
|
||||||
/* os-libcdio.h
|
|
||||||
Operating system specific libburn definitions and declarations. Included
|
|
||||||
by os.h in case of compilation for
|
|
||||||
Unknown X/Open-like systems
|
|
||||||
with GNU libcdio MMC transport adapter sg-libcdio.c
|
|
||||||
|
|
||||||
Copyright (C) 2009 Thomas Schmitt <scdbackup@gmx.net>, provided under GPLv2+
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
/** List of all signals which shall be caught by signal handlers and trigger
|
|
||||||
a graceful abort of libburn. (See man 7 signal.)
|
|
||||||
*/
|
|
||||||
/* Once as system defined macros */
|
|
||||||
#define BURN_OS_SIGNAL_MACRO_LIST \
|
|
||||||
SIGHUP, SIGINT, SIGQUIT, SIGILL, SIGABRT, \
|
|
||||||
SIGFPE, SIGSEGV, SIGPIPE, SIGALRM, SIGTERM, \
|
|
||||||
SIGUSR1, SIGUSR2, SIGXCPU, SIGTSTP, SIGTTIN, \
|
|
||||||
SIGTTOU
|
|
||||||
|
|
||||||
/* Once as text 1:1 list of strings for messages and interpreters */
|
|
||||||
#define BURN_OS_SIGNAL_NAME_LIST \
|
|
||||||
"SIGHUP", "SIGINT", "SIGQUIT", "SIGILL", "SIGABRT", \
|
|
||||||
"SIGFPE", "SIGSEGV", "SIGPIPE", "SIGALRM", "SIGTERM", \
|
|
||||||
"SIGUSR1", "SIGUSR2", "SIGXCPU", "SIGTSTP", "SIGTTIN", \
|
|
||||||
"SIGTTOU"
|
|
||||||
|
|
||||||
/* The number of above list items */
|
|
||||||
#define BURN_OS_SIGNAL_COUNT 16
|
|
||||||
|
|
||||||
|
|
||||||
/** 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 \
|
|
||||||
SIGKILL, SIGCHLD, SIGSTOP BURN_OS_SIG_WINCH BURN_OS_SIG_URG
|
|
||||||
|
|
||||||
/* The number of above list items */
|
|
||||||
#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 */
|
|
||||||
/* 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.
|
|
||||||
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.
|
|
||||||
*/
|
|
||||||
/* Important : MUST be at least 32768 ! */
|
|
||||||
#define BURN_OS_TRANSPORT_BUFFER_SIZE 65536
|
|
||||||
|
|
||||||
|
|
||||||
/* To hold the position of the most recently delivered address from
|
|
||||||
device enumeration.
|
|
||||||
*/
|
|
||||||
struct burn_drive_enumerator_struct {
|
|
||||||
char **ppsz_cd_drives;
|
|
||||||
char **pos;
|
|
||||||
};
|
|
||||||
|
|
||||||
#define BURN_OS_DEFINE_DRIVE_ENUMERATOR_T \
|
|
||||||
typedef struct burn_drive_enumerator_struct burn_drive_enumerator_t;
|
|
||||||
|
|
||||||
|
|
||||||
/* The list of operating system dependent elements in struct burn_drive.
|
|
||||||
Usually they are initialized in sg-*.c:enumerate_common().
|
|
||||||
*/
|
|
||||||
#define BURN_OS_TRANSPORT_DRIVE_ELEMENTS \
|
|
||||||
void *p_cdio; /* actually a pointer to CdIo_t */ \
|
|
||||||
char libcdio_name[4096]; /* The drive path as used by libcdio */ \
|
|
||||||
|
|
@ -2,10 +2,9 @@
|
|||||||
/* os-linux.h
|
/* os-linux.h
|
||||||
Operating system specific libburn definitions and declarations. Included
|
Operating system specific libburn definitions and declarations. Included
|
||||||
by os.h in case of compilation for
|
by os.h in case of compilation for
|
||||||
Linux kernels 2.4 and 2.6, GNU/Linux SCSI Generic (sg)
|
Linux kernels 2.4 and 2.6 with Linux SCSI Generic (sg)
|
||||||
|
|
||||||
Copyright (C) 2006 - 2010 Thomas Schmitt <scdbackup@gmx.net>
|
Copyright (C) 2006 Thomas Schmitt <scdbackup@gmx.net>, provided under GPL
|
||||||
Provided under GPL version 2 or later.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,66 +0,0 @@
|
|||||||
|
|
||||||
/* 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;
|
|
||||||
|
|
54
libburn/os.h
54
libburn/os.h
@ -3,7 +3,7 @@
|
|||||||
Operating system specific libburn definitions and declarations.
|
Operating system specific libburn definitions and declarations.
|
||||||
The macros defined here are used by libburn modules in order to
|
The macros defined here are used by libburn modules in order to
|
||||||
avoid own system dependent case distinctions.
|
avoid own system dependent case distinctions.
|
||||||
Copyright (C) 2009 Thomas Schmitt <scdbackup@gmx.net>, provided under GPLv2+
|
Copyright (C) 2006 Thomas Schmitt <scdbackup@gmx.net>, provided under GPL
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef BURN_OS_H_INCLUDED
|
#ifndef BURN_OS_H_INCLUDED
|
||||||
@ -13,23 +13,6 @@
|
|||||||
Operating system case distinction
|
Operating system case distinction
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#ifdef Libburn_use_sg_dummY
|
|
||||||
|
|
||||||
|
|
||||||
/* --------- Any other system. With dummy MMC transport sg-dummy.c --------- */
|
|
||||||
#include "os-dummy.h"
|
|
||||||
|
|
||||||
|
|
||||||
#else
|
|
||||||
#ifdef Libburn_use_libcdiO
|
|
||||||
|
|
||||||
|
|
||||||
/* -------------------------- X/Open with GNU libcdio ---------------------- */
|
|
||||||
#include "os-libcdio.h"
|
|
||||||
|
|
||||||
|
|
||||||
#else
|
|
||||||
#ifdef __FreeBSD__
|
#ifdef __FreeBSD__
|
||||||
|
|
||||||
|
|
||||||
@ -37,43 +20,14 @@
|
|||||||
#include "os-freebsd.h"
|
#include "os-freebsd.h"
|
||||||
|
|
||||||
|
|
||||||
#else
|
#else /* operating system case distinction */
|
||||||
#ifdef __FreeBSD_kernel__
|
|
||||||
|
|
||||||
|
|
||||||
/* ----------------------- FreeBSD with CAM under Debian ------------------- */
|
/* --------- Linux kernels 2.4 and 2.6 with Linux SCSI Generic (sg) -------- */
|
||||||
#include "os-freebsd.h"
|
|
||||||
|
|
||||||
|
|
||||||
#else
|
|
||||||
#ifdef __linux
|
|
||||||
|
|
||||||
|
|
||||||
/* ------- Linux kernels 2.4 and 2.6 with GNU/Linux SCSI Generic (sg) ------ */
|
|
||||||
#include "os-linux.h"
|
#include "os-linux.h"
|
||||||
|
|
||||||
|
|
||||||
#else
|
#endif /* End of operating system case distinction */
|
||||||
#ifdef __sun
|
|
||||||
|
|
||||||
|
|
||||||
/* ------- Solaris (e.g. SunOS 5.11) with uscsi ------ */
|
|
||||||
#include "os-solaris.h"
|
|
||||||
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
|
|
||||||
/* --------- Any other system. With dummy MMC transport sg-dummy.c --------- */
|
|
||||||
#include "os-dummy.h"
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* ! __sun*/
|
|
||||||
#endif /* ! __linux */
|
|
||||||
#endif /* ! __FreeBSD__kernel__ */
|
|
||||||
#endif /* ! __FreeBSD__ */
|
|
||||||
#endif /* ! Libburn_use_libcdiO */
|
|
||||||
#endif /* ! Libburn_use_sg_dummY */
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* ! BURN_OS_H_INCLUDED */
|
#endif /* ! BURN_OS_H_INCLUDED */
|
||||||
|
@ -1,13 +1,6 @@
|
|||||||
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||||
|
|
||||||
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
|
/* #include <m alloc.h> ts A61013 : not in Linux man 3 malloc */
|
||||||
Copyright (c) 2006 - 2010 Thomas Schmitt <scdbackup@gmx.net>
|
|
||||||
Provided under GPL version 2 or later.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
#include "../config.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
@ -34,6 +27,7 @@
|
|||||||
#include "crc.h"
|
#include "crc.h"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
#include "init.h"
|
#include "init.h"
|
||||||
|
#include "lec.h"
|
||||||
#include "toc.h"
|
#include "toc.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "sg.h"
|
#include "sg.h"
|
||||||
@ -101,13 +95,7 @@ drive, or only store a subset of the _opts structs in drives */
|
|||||||
fakesub[20] = 2;
|
fakesub[20] = 2;
|
||||||
fakesub[12] = (d->toc->toc_entry[0].control << 4) +
|
fakesub[12] = (d->toc->toc_entry[0].control << 4) +
|
||||||
d->toc->toc_entry[0].adr;
|
d->toc->toc_entry[0].adr;
|
||||||
|
|
||||||
#ifdef Libburn_no_crc_C
|
|
||||||
crc = 0; /* dummy */
|
|
||||||
#else
|
|
||||||
crc = crc_ccitt(fakesub + 12, 10);
|
crc = crc_ccitt(fakesub + 12, 10);
|
||||||
#endif
|
|
||||||
|
|
||||||
fakesub[22] = crc >> 8;
|
fakesub[22] = crc >> 8;
|
||||||
fakesub[23] = crc & 0xFF;
|
fakesub[23] = crc & 0xFF;
|
||||||
write(o->subfd, fakesub, 96);
|
write(o->subfd, fakesub, 96);
|
||||||
@ -254,8 +242,6 @@ void burn_packet_process(struct burn_drive *d, unsigned char *data,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
crc = (*(sub + 22) << 8) + *(sub + 23);
|
crc = (*(sub + 22) << 8) + *(sub + 23);
|
||||||
|
|
||||||
#ifndef Libburn_no_crc_C
|
|
||||||
if (crc != crc_ccitt(sub + 12, 10)) {
|
if (crc != crc_ccitt(sub + 12, 10)) {
|
||||||
burn_print(1, "sending error on %s %s\n",
|
burn_print(1, "sending error on %s %s\n",
|
||||||
d->idata->vendor, d->idata->product);
|
d->idata->vendor, d->idata->product);
|
||||||
@ -264,8 +250,6 @@ void burn_packet_process(struct burn_drive *d, unsigned char *data,
|
|||||||
*/
|
*/
|
||||||
burn_print(1, "crc mismatch in Q\n");
|
burn_print(1, "crc mismatch in Q\n");
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
/* else process_q(d, sub + 12); */
|
/* else process_q(d, sub + 12); */
|
||||||
/*
|
/*
|
||||||
if (o->subfd != -1) write(o->subfd, sub, 96); */
|
if (o->subfd != -1) write(o->subfd, sub, 96); */
|
||||||
@ -387,20 +371,6 @@ int burn_read_data(struct burn_drive *d, off_t byte_address,
|
|||||||
msg, 0, 0);
|
msg, 0, 0);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (d->media_read_capacity != 0x7fffffff && byte_address >=
|
|
||||||
((off_t) d->media_read_capacity + (off_t) 1) * (off_t) 2048) {
|
|
||||||
if (!(flag & 2)) {
|
|
||||||
sprintf(msg,
|
|
||||||
"Read start address %ds larger than number of readable blocks %d",
|
|
||||||
(int) (byte_address / 2048 + !!(byte_address % 2048)),
|
|
||||||
d->media_read_capacity);
|
|
||||||
libdax_msgs_submit(libdax_messenger, d->global_index,
|
|
||||||
0x00020172,
|
|
||||||
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
|
|
||||||
msg, 0, 0);
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (d->busy != BURN_DRIVE_IDLE) {
|
if (d->busy != BURN_DRIVE_IDLE) {
|
||||||
libdax_msgs_submit(libdax_messenger,
|
libdax_msgs_submit(libdax_messenger,
|
||||||
|
118
libburn/sbc.c
118
libburn/sbc.c
@ -2,15 +2,6 @@
|
|||||||
|
|
||||||
/* scsi block commands */
|
/* scsi block commands */
|
||||||
|
|
||||||
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
|
|
||||||
Copyright (c) 2006 - 2010 Thomas Schmitt <scdbackup@gmx.net>
|
|
||||||
Provided under GPL version 2 or later.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
#include "../config.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
@ -26,31 +17,10 @@
|
|||||||
int mmc_function_spy(struct burn_drive *d, char * text);
|
int mmc_function_spy(struct burn_drive *d, char * text);
|
||||||
|
|
||||||
|
|
||||||
/* START STOP UNIT as of SBC-1 and SBC-2
|
/* spc command set */
|
||||||
0: Opcode 0x1B
|
|
||||||
1: bit0= Immed
|
|
||||||
bit1-7= reserved
|
|
||||||
2: reserved
|
|
||||||
3: reserved
|
|
||||||
4: bit0= Start (else Stop unit)
|
|
||||||
bit1= Load/Eject (according to Start resp. Stop)
|
|
||||||
bit2-3= reserved
|
|
||||||
bit4-7= Power Condition
|
|
||||||
0= Start Valid: process Start and Load/Eject bits
|
|
||||||
1= assume Active state
|
|
||||||
2= assume Idle state
|
|
||||||
3= assume Stanby state
|
|
||||||
(5= SBC-1 only: assume Sleep state)
|
|
||||||
7= transfer control of power conditions to logical unit
|
|
||||||
10= force idle condition timer to 0
|
|
||||||
11= force standby condition timer to 0
|
|
||||||
All others are reserved.
|
|
||||||
5: Control (set to 0)
|
|
||||||
*/
|
|
||||||
static unsigned char SBC_LOAD[] = { 0x1b, 0, 0, 0, 3, 0 };
|
static unsigned char SBC_LOAD[] = { 0x1b, 0, 0, 0, 3, 0 };
|
||||||
static unsigned char SBC_UNLOAD[] = { 0x1b, 0, 0, 0, 2, 0 };
|
static unsigned char SBC_UNLOAD[] = { 0x1b, 0, 0, 0, 2, 0 };
|
||||||
static unsigned char SBC_START_UNIT[] = { 0x1b, 0, 0, 0, 1, 0 };
|
static unsigned char SBC_START_UNIT[] = { 0x1b, 0, 0, 0, 1, 0 };
|
||||||
static unsigned char SBC_STOP_UNIT[] = { 0x1b, 0, 0, 0, 0, 0 };
|
|
||||||
|
|
||||||
void sbc_load(struct burn_drive *d)
|
void sbc_load(struct burn_drive *d)
|
||||||
{
|
{
|
||||||
@ -60,6 +30,11 @@ void sbc_load(struct burn_drive *d)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
scsi_init_command(&c, SBC_LOAD, sizeof(SBC_LOAD));
|
scsi_init_command(&c, SBC_LOAD, sizeof(SBC_LOAD));
|
||||||
|
/*
|
||||||
|
memcpy(c.opcode, SBC_LOAD, sizeof(SBC_LOAD));
|
||||||
|
c.oplen = sizeof(SBC_LOAD);
|
||||||
|
c.page = NULL;
|
||||||
|
*/
|
||||||
c.retry = 1;
|
c.retry = 1;
|
||||||
|
|
||||||
/* ts A70921 : Had to revoke Immed because of LG GSA-4082B */
|
/* ts A70921 : Had to revoke Immed because of LG GSA-4082B */
|
||||||
@ -83,87 +58,50 @@ void sbc_eject(struct burn_drive *d)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
scsi_init_command(&c, SBC_UNLOAD, sizeof(SBC_UNLOAD));
|
scsi_init_command(&c, SBC_UNLOAD, sizeof(SBC_UNLOAD));
|
||||||
/* c.opcode[1] |= 1; / * ts A70918 : Immed , ts B00109 : revoked */
|
/*
|
||||||
|
memcpy(c.opcode, SBC_UNLOAD, sizeof(SBC_UNLOAD));
|
||||||
|
c.oplen = sizeof(SBC_UNLOAD);
|
||||||
|
c.page = NULL;
|
||||||
|
*/
|
||||||
|
|
||||||
|
c.opcode[1] |= 1; /* ts A70918 : Immed */
|
||||||
|
|
||||||
c.page = NULL;
|
c.page = NULL;
|
||||||
c.dir = NO_TRANSFER;
|
c.dir = NO_TRANSFER;
|
||||||
d->issue_command(d, &c);
|
d->issue_command(d, &c);
|
||||||
/* ts A70918 : Wait long. A late eject could surprise or hurt user.
|
|
||||||
ts B00109 : Asynchronous eject revoked, as one cannot reliably
|
|
||||||
distinguish out from unready.
|
|
||||||
if (c.error)
|
if (c.error)
|
||||||
return;
|
return;
|
||||||
|
/* ts A70918 : Wait long. A late eject could surprise or hurt user. */
|
||||||
spc_wait_unit_attention(d, 1800, "STOP UNIT (+ EJECT)", 0);
|
spc_wait_unit_attention(d, 1800, "STOP UNIT (+ EJECT)", 0);
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ts A61118 : is it necessary to tell the drive to get ready for use ? */
|
||||||
/* ts A91112 : Now with flag */
|
int sbc_start_unit(struct burn_drive *d)
|
||||||
/* @param flag bit0= asynchronous waiting
|
|
||||||
*/
|
|
||||||
int sbc_start_unit_flag(struct burn_drive *d, int flag)
|
|
||||||
{
|
{
|
||||||
struct command c;
|
struct command c;
|
||||||
int ret;
|
|
||||||
|
|
||||||
if (mmc_function_spy(d, "start_unit") <= 0)
|
if (mmc_function_spy(d, "start_unit") <= 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
scsi_init_command(&c, SBC_START_UNIT, sizeof(SBC_START_UNIT));
|
scsi_init_command(&c, SBC_START_UNIT, sizeof(SBC_START_UNIT));
|
||||||
|
/*
|
||||||
|
memcpy(c.opcode, SBC_START_UNIT, sizeof(SBC_START_UNIT));
|
||||||
|
c.oplen = sizeof(SBC_START_UNIT);
|
||||||
|
c.page = NULL;
|
||||||
|
*/
|
||||||
c.retry = 1;
|
c.retry = 1;
|
||||||
c.opcode[1] |= (flag & 1); /* ts A70918 : Immed */
|
|
||||||
|
c.opcode[1] |= 1; /* ts A70918 : Immed */
|
||||||
|
|
||||||
c.dir = NO_TRANSFER;
|
c.dir = NO_TRANSFER;
|
||||||
d->issue_command(d, &c);
|
d->issue_command(d, &c);
|
||||||
if (c.error)
|
if (c.error)
|
||||||
return 0;
|
return 0;
|
||||||
if (!(flag & 1))
|
/* ts A70918 : now asynchronous */
|
||||||
return 1;
|
return spc_wait_unit_attention(d, 1800, "START UNIT", 0);
|
||||||
/* ts A70918 : asynchronous */
|
|
||||||
ret = spc_wait_unit_attention(d, 1800, "START UNIT", 0);
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int sbc_start_unit(struct burn_drive *d)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
d->is_stopped = 0; /* no endless starting attempts */
|
|
||||||
|
|
||||||
/* Asynchronous, not to block controller by waiting */
|
|
||||||
ret = sbc_start_unit_flag(d, 1);
|
|
||||||
if (ret <= 0)
|
|
||||||
return ret;
|
|
||||||
/* Synchronous to catch Pioneer DVR-216D which is ready too early.
|
|
||||||
A pending START UNIT can prevent ejecting of the tray.
|
|
||||||
*/
|
|
||||||
ret = sbc_start_unit_flag(d, 0);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* ts A90824 : Trying to reduce drive noise */
|
|
||||||
int sbc_stop_unit(struct burn_drive *d)
|
|
||||||
{
|
|
||||||
struct command c;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
if (mmc_function_spy(d, "stop_unit") <= 0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
scsi_init_command(&c, SBC_STOP_UNIT, sizeof(SBC_STOP_UNIT));
|
|
||||||
c.retry = 0;
|
|
||||||
c.opcode[1] |= 1; /* Immed */
|
|
||||||
c.dir = NO_TRANSFER;
|
|
||||||
d->issue_command(d, &c);
|
|
||||||
if (c.error)
|
|
||||||
return 0;
|
|
||||||
ret = spc_wait_unit_attention(d, 1800, "STOP UNIT", 0);
|
|
||||||
d->is_stopped = 1;
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* ts A61021 : the sbc specific part of sg.c:enumerate_common()
|
/* ts A61021 : the sbc specific part of sg.c:enumerate_common()
|
||||||
*/
|
*/
|
||||||
int sbc_setup_drive(struct burn_drive *d)
|
int sbc_setup_drive(struct burn_drive *d)
|
||||||
@ -171,8 +109,6 @@ int sbc_setup_drive(struct burn_drive *d)
|
|||||||
d->eject = sbc_eject;
|
d->eject = sbc_eject;
|
||||||
d->load = sbc_load;
|
d->load = sbc_load;
|
||||||
d->start_unit = sbc_start_unit;
|
d->start_unit = sbc_start_unit;
|
||||||
d->stop_unit = sbc_stop_unit;
|
|
||||||
d->is_stopped = 0;
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,11 +1,5 @@
|
|||||||
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||||
|
|
||||||
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
|
|
||||||
Copyright (c) 2006 - 2010 Thomas Schmitt <scdbackup@gmx.net>
|
|
||||||
Provided under GPL version 2 or later.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef __SBC
|
#ifndef __SBC
|
||||||
#define __SBC
|
#define __SBC
|
||||||
|
|
||||||
|
155
libburn/sector.c
155
libburn/sector.c
@ -1,14 +1,5 @@
|
|||||||
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||||
|
|
||||||
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
|
|
||||||
Copyright (c) 2006 - 2011 Thomas Schmitt <scdbackup@gmx.net>
|
|
||||||
Provided under GPL version 2 or later.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
#include "../config.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
/* ts A61010 */
|
/* ts A61010 */
|
||||||
@ -24,17 +15,13 @@
|
|||||||
#include "sector.h"
|
#include "sector.h"
|
||||||
#include "crc.h"
|
#include "crc.h"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
|
#include "lec.h"
|
||||||
#include "toc.h"
|
#include "toc.h"
|
||||||
#include "write.h"
|
#include "write.h"
|
||||||
|
|
||||||
#include "libdax_msgs.h"
|
|
||||||
extern struct libdax_msgs *libdax_messenger;
|
|
||||||
|
|
||||||
#include "ecma130ab.h"
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef Libburn_log_in_and_out_streaM
|
#ifdef Libburn_log_in_and_out_streaM
|
||||||
/* ts A61031 */
|
/* <<< ts A61031 */
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
@ -105,7 +92,7 @@ static void get_bytes(struct burn_track *track, int count, unsigned char *data)
|
|||||||
int valid, shortage, curr, i, tr;
|
int valid, shortage, curr, i, tr;
|
||||||
|
|
||||||
#ifdef Libburn_log_in_and_out_streaM
|
#ifdef Libburn_log_in_and_out_streaM
|
||||||
/* ts A61031 */
|
/* <<< ts A61031 */
|
||||||
static int tee_fd= -1;
|
static int tee_fd= -1;
|
||||||
if(tee_fd==-1)
|
if(tee_fd==-1)
|
||||||
tee_fd= open("/tmp/libburn_sg_readin",
|
tee_fd= open("/tmp/libburn_sg_readin",
|
||||||
@ -151,7 +138,7 @@ static void get_bytes(struct burn_track *track, int count, unsigned char *data)
|
|||||||
track->sourcecount += valid;
|
track->sourcecount += valid;
|
||||||
|
|
||||||
#ifdef Libburn_log_in_and_out_streaM
|
#ifdef Libburn_log_in_and_out_streaM
|
||||||
/* ts A61031 */
|
/* <<< ts A61031 */
|
||||||
if(tee_fd!=-1 && valid>0) {
|
if(tee_fd!=-1 && valid>0) {
|
||||||
write(tee_fd, data + curr, valid);
|
write(tee_fd, data + curr, valid);
|
||||||
}
|
}
|
||||||
@ -179,14 +166,10 @@ static void get_bytes(struct burn_track *track, int count, unsigned char *data)
|
|||||||
if (!shortage)
|
if (!shortage)
|
||||||
goto ex;
|
goto ex;
|
||||||
|
|
||||||
/* ts A61031 - B10103 */
|
/* ts A61031 */
|
||||||
if (shortage >= count)
|
if (shortage >= count)
|
||||||
track->track_data_done = 1;
|
track->track_data_done = 1;
|
||||||
if (track->end_on_premature_eoi && !track->open_ended) {
|
if (track->open_ended)
|
||||||
/* Memorize that premature end of input happened */
|
|
||||||
track->end_on_premature_eoi = 2;
|
|
||||||
}
|
|
||||||
if (track->open_ended || track->end_on_premature_eoi)
|
|
||||||
goto ex;
|
goto ex;
|
||||||
|
|
||||||
/* If we're still short, and there's a "next" pointer, we pull from that.
|
/* If we're still short, and there's a "next" pointer, we pull from that.
|
||||||
@ -223,7 +206,8 @@ static unsigned char *get_sector(struct burn_write_opts *opts,
|
|||||||
{
|
{
|
||||||
struct burn_drive *d = opts->drive;
|
struct burn_drive *d = opts->drive;
|
||||||
struct buffer *out = d->buffer;
|
struct buffer *out = d->buffer;
|
||||||
int outmode, seclen;
|
int outmode;
|
||||||
|
int seclen;
|
||||||
unsigned char *ret;
|
unsigned char *ret;
|
||||||
|
|
||||||
outmode = get_outmode(opts);
|
outmode = get_outmode(opts);
|
||||||
@ -239,7 +223,6 @@ static unsigned char *get_sector(struct burn_write_opts *opts,
|
|||||||
seclen += burn_subcode_length(outmode);
|
seclen += burn_subcode_length(outmode);
|
||||||
|
|
||||||
/* ts A61219 : opts->obs is eventually a 32k trigger for DVD */
|
/* ts A61219 : opts->obs is eventually a 32k trigger for DVD */
|
||||||
/* (there is enough buffer size reserve for track->cdxa_conversion) */
|
|
||||||
if (out->bytes + seclen > BUFFER_SIZE ||
|
if (out->bytes + seclen > BUFFER_SIZE ||
|
||||||
(opts->obs > 0 && out->bytes + seclen > opts->obs)) {
|
(opts->obs > 0 && out->bytes + seclen > opts->obs)) {
|
||||||
int err;
|
int err;
|
||||||
@ -259,6 +242,7 @@ static unsigned char *get_sector(struct burn_write_opts *opts,
|
|||||||
out->bytes = 0;
|
out->bytes = 0;
|
||||||
out->sectors = 0;
|
out->sectors = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = out->data + out->bytes;
|
ret = out->data + out->bytes;
|
||||||
out->bytes += seclen;
|
out->bytes += seclen;
|
||||||
out->sectors++;
|
out->sectors++;
|
||||||
@ -315,17 +299,7 @@ static int convert_data(struct burn_write_opts *o, struct burn_track *track,
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if ((outmode & BURN_MODE_BITS) == (inmode & BURN_MODE_BITS)) {
|
if ((outmode & BURN_MODE_BITS) == (inmode & BURN_MODE_BITS)) {
|
||||||
/* see MMC-5 4.2.3.8.5.3 Block Format for Mode 2 form 1 Data
|
|
||||||
Table 24 Mode 2 Formed Sector Sub-header Format */
|
|
||||||
if (track != NULL)
|
|
||||||
if (track->cdxa_conversion == 1)
|
|
||||||
inlen += 8;
|
|
||||||
|
|
||||||
get_bytes(track, inlen, data);
|
get_bytes(track, inlen, data);
|
||||||
|
|
||||||
if (track != NULL)
|
|
||||||
if (track->cdxa_conversion == 1)
|
|
||||||
memmove(data, data + 8, inlen - 8);
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -418,13 +392,7 @@ a2 - lout ctrl
|
|||||||
q[7] = dec_to_bcd(d->toc_entry[track].pmin);
|
q[7] = dec_to_bcd(d->toc_entry[track].pmin);
|
||||||
q[8] = dec_to_bcd(d->toc_entry[track].psec);
|
q[8] = dec_to_bcd(d->toc_entry[track].psec);
|
||||||
q[9] = dec_to_bcd(d->toc_entry[track].pframe);
|
q[9] = dec_to_bcd(d->toc_entry[track].pframe);
|
||||||
|
|
||||||
#ifdef Libburn_no_crc_C
|
|
||||||
crc = 0; /* dummy */
|
|
||||||
#else
|
|
||||||
crc = crc_ccitt(q, 10);
|
crc = crc_ccitt(q, 10);
|
||||||
#endif
|
|
||||||
|
|
||||||
q[10] = crc >> 8;
|
q[10] = crc >> 8;
|
||||||
q[11] = crc & 0xFF;
|
q[11] = crc & 0xFF;
|
||||||
d->toc_temp++;
|
d->toc_temp++;
|
||||||
@ -445,8 +413,7 @@ int sector_toc(struct burn_write_opts *o, int mode)
|
|||||||
return 0;
|
return 0;
|
||||||
subcode_toc(d, mode, subs);
|
subcode_toc(d, mode, subs);
|
||||||
convert_subs(o, mode, subs, data);
|
convert_subs(o, mode, subs, data);
|
||||||
if (sector_headers(o, data, mode, 1) <= 0)
|
sector_headers(o, data, mode, 1);
|
||||||
return 0;
|
|
||||||
sector_common(++)
|
sector_common(++)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -466,8 +433,7 @@ int sector_pregap(struct burn_write_opts *o,
|
|||||||
return 0;
|
return 0;
|
||||||
subcode_user(o, subs, tno, control, 0, NULL, 1);
|
subcode_user(o, subs, tno, control, 0, NULL, 1);
|
||||||
convert_subs(o, mode, subs, data);
|
convert_subs(o, mode, subs, data);
|
||||||
if (sector_headers(o, data, mode, 0) <= 0)
|
sector_headers(o, data, mode, 0);
|
||||||
return 0;
|
|
||||||
sector_common(--)
|
sector_common(--)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -484,12 +450,11 @@ int sector_postgap(struct burn_write_opts *o,
|
|||||||
return 0;
|
return 0;
|
||||||
/* ts A61010 */
|
/* ts A61010 */
|
||||||
if (convert_data(o, NULL, mode, data) <= 0)
|
if (convert_data(o, NULL, mode, data) <= 0)
|
||||||
return 0;
|
return 0;;
|
||||||
/* use last index in track */
|
/* use last index in track */
|
||||||
subcode_user(o, subs, tno, control, 1, NULL, 1);
|
subcode_user(o, subs, tno, control, 1, NULL, 1);
|
||||||
convert_subs(o, mode, subs, data);
|
convert_subs(o, mode, subs, data);
|
||||||
if (sector_headers(o, data, mode, 0) <= 0)
|
sector_headers(o, data, mode, 0);
|
||||||
return 0;
|
|
||||||
sector_common(++)
|
sector_common(++)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -521,13 +486,7 @@ static void subcode_lout(struct burn_write_opts *o, unsigned char control,
|
|||||||
q[7] = dec_to_bcd(min);
|
q[7] = dec_to_bcd(min);
|
||||||
q[8] = dec_to_bcd(sec);
|
q[8] = dec_to_bcd(sec);
|
||||||
q[9] = dec_to_bcd(frame);
|
q[9] = dec_to_bcd(frame);
|
||||||
|
|
||||||
#ifdef Libburn_no_crc_C
|
|
||||||
crc = 0; /* dummy */
|
|
||||||
#else
|
|
||||||
crc = crc_ccitt(q, 10);
|
crc = crc_ccitt(q, 10);
|
||||||
#endif
|
|
||||||
|
|
||||||
q[10] = crc >> 8;
|
q[10] = crc >> 8;
|
||||||
q[11] = crc & 0xFF;
|
q[11] = crc & 0xFF;
|
||||||
}
|
}
|
||||||
@ -647,13 +606,7 @@ void subcode_user(struct burn_write_opts *o, unsigned char *subcodes,
|
|||||||
}
|
}
|
||||||
q[0] = (control << 4) + qmode;
|
q[0] = (control << 4) + qmode;
|
||||||
|
|
||||||
|
|
||||||
#ifdef Libburn_no_crc_C
|
|
||||||
crc = 0; /* dummy */
|
|
||||||
#else
|
|
||||||
crc = crc_ccitt(q, 10);
|
crc = crc_ccitt(q, 10);
|
||||||
#endif
|
|
||||||
|
|
||||||
q[10] = crc >> 8;
|
q[10] = crc >> 8;
|
||||||
q[11] = crc & 0xff;
|
q[11] = crc & 0xff;
|
||||||
}
|
}
|
||||||
@ -672,8 +625,7 @@ int sector_lout(struct burn_write_opts *o, unsigned char control, int mode)
|
|||||||
return 0;
|
return 0;
|
||||||
subcode_lout(o, control, subs);
|
subcode_lout(o, control, subs);
|
||||||
convert_subs(o, mode, subs, data);
|
convert_subs(o, mode, subs, data);
|
||||||
if (sector_headers(o, data, mode, 0) <= 0)
|
sector_headers(o, data, mode, 0);
|
||||||
return 0;
|
|
||||||
sector_common(++)
|
sector_common(++)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -685,14 +637,14 @@ int sector_data(struct burn_write_opts *o, struct burn_track *t, int psub)
|
|||||||
unsigned char *data;
|
unsigned char *data;
|
||||||
|
|
||||||
data = get_sector(o, t, t->mode);
|
data = get_sector(o, t, t->mode);
|
||||||
if (data == NULL)
|
if (!data)
|
||||||
return 0;
|
return 0;
|
||||||
/* ts A61010 */
|
/* ts A61010 */
|
||||||
if (convert_data(o, t, t->mode, data) <= 0)
|
if (convert_data(o, t, t->mode, data) <= 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* ts A61031 */
|
/* ts A61031 */
|
||||||
if ((t->open_ended || t->end_on_premature_eoi) && t->track_data_done) {
|
if (t->open_ended && t->track_data_done) {
|
||||||
unget_sector(o, t->mode);
|
unget_sector(o, t->mode);
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
@ -708,8 +660,7 @@ int sector_data(struct burn_write_opts *o, struct burn_track *t, int psub)
|
|||||||
t->entry->control, 1, &t->isrc, psub);
|
t->entry->control, 1, &t->isrc, psub);
|
||||||
convert_subs(o, t->mode, subs, data);
|
convert_subs(o, t->mode, subs, data);
|
||||||
|
|
||||||
if (sector_headers(o, data, t->mode, 0) <= 0)
|
sector_headers(o, data, t->mode, 0);
|
||||||
return 0;
|
|
||||||
sector_common(++)
|
sector_common(++)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -760,27 +711,42 @@ int sector_headers_is_ok(struct burn_write_opts *o, int mode)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ts A90830 : changed return type to int
|
void sector_headers(struct burn_write_opts *o, unsigned char *out,
|
||||||
@return 0= failure
|
|
||||||
1= success
|
|
||||||
*/
|
|
||||||
int sector_headers(struct burn_write_opts *o, unsigned char *out,
|
|
||||||
int mode, int leadin)
|
int mode, int leadin)
|
||||||
{
|
{
|
||||||
|
|
||||||
#ifdef Libburn_ecma130ab_includeD
|
|
||||||
|
|
||||||
struct burn_drive *d = o->drive;
|
struct burn_drive *d = o->drive;
|
||||||
unsigned int crc;
|
unsigned int crc;
|
||||||
int min, sec, frame;
|
int min, sec, frame;
|
||||||
int modebyte = -1;
|
int modebyte = -1;
|
||||||
|
|
||||||
|
/* ts A61009 */
|
||||||
|
#if 1
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = sector_headers_is_ok(o, mode);
|
ret = sector_headers_is_ok(o, mode);
|
||||||
if (ret != 2)
|
if (ret != 2)
|
||||||
return !!ret;
|
return;
|
||||||
modebyte = 1;
|
modebyte = 1;
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
if (mode & BURN_AUDIO) /* no headers for "audio" */
|
||||||
|
return;
|
||||||
|
if (o->write_type == BURN_WRITE_SAO)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* ts A61031 */
|
||||||
|
if (o->write_type == BURN_WRITE_TAO)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (mode & BURN_MODE1)
|
||||||
|
modebyte = 1;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* ts A61009 : now ensured by burn_disc_write_is_ok() */
|
||||||
|
/* a ssert(modebyte == 1); */
|
||||||
|
|
||||||
out[0] = 0;
|
out[0] = 0;
|
||||||
memset(out + 1, 0xFF, 10); /* sync */
|
memset(out + 1, 0xFF, 10); /* sync */
|
||||||
out[11] = 0;
|
out[11] = 0;
|
||||||
@ -799,13 +765,7 @@ int sector_headers(struct burn_write_opts *o, unsigned char *out,
|
|||||||
out[15] = modebyte;
|
out[15] = modebyte;
|
||||||
}
|
}
|
||||||
if (mode & BURN_MODE1) {
|
if (mode & BURN_MODE1) {
|
||||||
|
|
||||||
#ifdef Libburn_no_crc_C
|
|
||||||
crc = 0; /* dummy */
|
|
||||||
#else
|
|
||||||
crc = crc_32(out, 2064);
|
crc = crc_32(out, 2064);
|
||||||
#endif
|
|
||||||
|
|
||||||
out[2064] = crc & 0xFF;
|
out[2064] = crc & 0xFF;
|
||||||
crc >>= 8;
|
crc >>= 8;
|
||||||
out[2065] = crc & 0xFF;
|
out[2065] = crc & 0xFF;
|
||||||
@ -816,33 +776,10 @@ int sector_headers(struct burn_write_opts *o, unsigned char *out,
|
|||||||
}
|
}
|
||||||
if (mode & BURN_MODE1) {
|
if (mode & BURN_MODE1) {
|
||||||
memset(out + 2068, 0, 8);
|
memset(out + 2068, 0, 8);
|
||||||
burn_rspc_parity_p(out);
|
parity_p(out);
|
||||||
burn_rspc_parity_q(out);
|
parity_q(out);
|
||||||
}
|
}
|
||||||
burn_ecma130_scramble(out);
|
scramble(out);
|
||||||
return 1;
|
|
||||||
|
|
||||||
#else /* Libburn_ecma130ab_includeD */
|
|
||||||
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
ret = sector_headers_is_ok(o, mode);
|
|
||||||
if (ret != 2)
|
|
||||||
return (!! ret);
|
|
||||||
|
|
||||||
/* ts A90830 : lec.c is copied from cdrdao.
|
|
||||||
I have no idea yet how lec.c implements the Reed-Solomon encoding
|
|
||||||
which is described in ECMA-130 for CD-ROM.
|
|
||||||
So this got removed for now.
|
|
||||||
*/
|
|
||||||
libdax_msgs_submit(libdax_messenger, o->drive->global_index,
|
|
||||||
0x0002010a,
|
|
||||||
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
|
|
||||||
"Raw CD write modes are not supported", 0, 0);
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
#endif /* ! Libburn_ecma130ab_includeD */
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
@ -898,14 +835,12 @@ void process_q(struct burn_drive *d, unsigned char *q)
|
|||||||
*/
|
*/
|
||||||
int sector_identify(unsigned char *data)
|
int sector_identify(unsigned char *data)
|
||||||
{
|
{
|
||||||
|
scramble(data);
|
||||||
/*
|
/*
|
||||||
burn_ecma130_scramble(data);
|
|
||||||
check mode byte for 1 or 2
|
check mode byte for 1 or 2
|
||||||
test parity to see if it's a valid sector
|
test parity to see if it's a valid sector
|
||||||
if invalid, return BURN_MODE_AUDIO;
|
if invalid, return BURN_MODE_AUDIO;
|
||||||
else return mode byte (what about mode 2 formless? heh)
|
else return mode byte (what about mode 2 formless? heh)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
return BURN_MODE1;
|
return BURN_MODE1;
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,5 @@
|
|||||||
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||||
|
|
||||||
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
|
|
||||||
Copyright (c) 2006 - 2010 Thomas Schmitt <scdbackup@gmx.net>
|
|
||||||
Provided under GPL version 2 or later.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __SECTOR
|
#ifndef __SECTOR
|
||||||
#define __SECTOR
|
#define __SECTOR
|
||||||
|
|
||||||
@ -27,7 +22,7 @@ int sector_data(struct burn_write_opts *, struct burn_track *t, int psub);
|
|||||||
/* ts A61009 */
|
/* ts A61009 */
|
||||||
int sector_headers_is_ok(struct burn_write_opts *o, int mode);
|
int sector_headers_is_ok(struct burn_write_opts *o, int mode);
|
||||||
|
|
||||||
int sector_headers(struct burn_write_opts *, unsigned char *,
|
void sector_headers(struct burn_write_opts *, unsigned char *,
|
||||||
int mode, int leadin);
|
int mode, int leadin);
|
||||||
void subcode_user(struct burn_write_opts *, unsigned char *s,
|
void subcode_user(struct burn_write_opts *, unsigned char *s,
|
||||||
unsigned char tno, unsigned char control,
|
unsigned char tno, unsigned char control,
|
||||||
|
@ -1,346 +0,0 @@
|
|||||||
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
|
||||||
|
|
||||||
/*
|
|
||||||
Copyright (c) 2009 - 2010 Thomas Schmitt <scdbackup@gmx.net>
|
|
||||||
Provided under GPL version 2 or later.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
#include "../config.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
|
|
||||||
This is the main operating system dependent SCSI part of libburn. It implements
|
|
||||||
the transport level aspects of SCSI control and command i/o.
|
|
||||||
|
|
||||||
Present implementation: default dummy which enables libburn only to work
|
|
||||||
with stdio: pseudo drive addresses.
|
|
||||||
For real implementations see sg-linux.c, sg-freebsd.c,
|
|
||||||
sg-libcdio.c
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
#ifdef Libburn_os_has_statvfS
|
|
||||||
#include <sys/statvfs.h>
|
|
||||||
#endif /* Libburn_os_has_stavtfS */
|
|
||||||
|
|
||||||
#include "transport.h"
|
|
||||||
#include "drive.h"
|
|
||||||
#include "sg.h"
|
|
||||||
#include "spc.h"
|
|
||||||
#include "mmc.h"
|
|
||||||
#include "sbc.h"
|
|
||||||
#include "debug.h"
|
|
||||||
#include "toc.h"
|
|
||||||
#include "util.h"
|
|
||||||
|
|
||||||
#include "libdax_msgs.h"
|
|
||||||
extern struct libdax_msgs *libdax_messenger;
|
|
||||||
|
|
||||||
|
|
||||||
/** Returns the id string of the SCSI transport adapter and eventually
|
|
||||||
needed operating system facilities.
|
|
||||||
This call is usable even if sg_initialize() was not called yet. In that
|
|
||||||
case a preliminary constant message might be issued if detailed info is
|
|
||||||
not available yet.
|
|
||||||
@param msg returns id string
|
|
||||||
@param flag unused yet, submit 0
|
|
||||||
@return 1 = success, <=0 = failure
|
|
||||||
*/
|
|
||||||
int sg_id_string(char msg[1024], int flag)
|
|
||||||
{
|
|
||||||
strcpy(msg, "internal X/Open adapter sg-dummy");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/** Performs global initialization of the SCSI transport adapter and eventually
|
|
||||||
needed operating system facilities. Checks for compatibility supporting
|
|
||||||
software components.
|
|
||||||
@param msg returns ids and/or error messages of eventual helpers
|
|
||||||
@param flag unused yet, submit 0
|
|
||||||
@return 1 = success, <=0 = failure
|
|
||||||
*/
|
|
||||||
int sg_initialize(char msg[1024], int flag)
|
|
||||||
{
|
|
||||||
return sg_id_string(msg, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/** Performs global finalization of the SCSI transport adapter and eventually
|
|
||||||
needed operating system facilities. Releases globally aquired resources.
|
|
||||||
@param flag unused yet, submit 0
|
|
||||||
@return 1 = success, <=0 = failure
|
|
||||||
*/
|
|
||||||
int sg_shutdown(int flag)
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/** Finalizes BURN_OS_TRANSPORT_DRIVE_ELEMENTS, the components of
|
|
||||||
struct burn_drive which are defined in os-*.h.
|
|
||||||
This will be called when a burn_drive gets disposed.
|
|
||||||
@param d the drive to be finalized
|
|
||||||
@param flag unused yet, submit 0
|
|
||||||
@return 1 = success, <=0 = failure
|
|
||||||
*/
|
|
||||||
int sg_dispose_drive(struct burn_drive *d, int flag)
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/** Returns the next index number and the next enumerated drive address.
|
|
||||||
The enumeration has to cover all available and accessible drives. It is
|
|
||||||
allowed to return addresses of drives which are not available but under
|
|
||||||
some (even exotic) circumstances could be available. It is on the other
|
|
||||||
hand allowed, only to hand out addresses which can really be used right
|
|
||||||
in the moment of this call. (This implementation chooses the former.)
|
|
||||||
@param idx An opaque handle. Make no own theories about it.
|
|
||||||
@param adr Takes the reply
|
|
||||||
@param adr_size Gives maximum size of reply including final 0
|
|
||||||
@param initialize 1 = start new,
|
|
||||||
0 = continue, use no other values for now
|
|
||||||
-1 = finish
|
|
||||||
@return 1 = reply is a valid address , 0 = no further address available
|
|
||||||
-1 = severe error (e.g. adr_size too small)
|
|
||||||
*/
|
|
||||||
int sg_give_next_adr(burn_drive_enumerator_t *idx,
|
|
||||||
char adr[], int adr_size, int initialize)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/** Brings all available, not-whitelist-banned, and accessible drives into
|
|
||||||
libburn's list of drives.
|
|
||||||
*/
|
|
||||||
/* ts A61115: replacing call to sg-implementation internals from drive.c */
|
|
||||||
int scsi_enumerate_drives(void)
|
|
||||||
{
|
|
||||||
libdax_msgs_submit(libdax_messenger, -1, 0x0002016b,
|
|
||||||
LIBDAX_MSGS_SEV_WARNING, LIBDAX_MSGS_PRIO_HIGH,
|
|
||||||
"No MMC transport adapter is present. Running on sg-dummy.c.",
|
|
||||||
0, 0);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/** Tells wether libburn has the given drive in use or exclusively reserved.
|
|
||||||
If it is "open" then libburn will eventually call sg_release() on it when
|
|
||||||
it is time to give up usage resp. reservation.
|
|
||||||
*/
|
|
||||||
/** Published as burn_drive.drive_is_open() */
|
|
||||||
int sg_drive_is_open(struct burn_drive * d)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/** Opens the drive for SCSI commands and - if burn activities are prone
|
|
||||||
to external interference on your system - obtains an exclusive access lock
|
|
||||||
on the drive. (Note: this is not physical tray locking.)
|
|
||||||
A drive that has been opened with sg_grab() will eventually be handed
|
|
||||||
over to sg_release() for closing and unreserving.
|
|
||||||
*/
|
|
||||||
int sg_grab(struct burn_drive *d)
|
|
||||||
{
|
|
||||||
libdax_msgs_submit(libdax_messenger, d->global_index, 0x0002016a,
|
|
||||||
LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH,
|
|
||||||
"No MMC transport adapter is present. Running on sg-dummy.c.",
|
|
||||||
0, 0);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/** Gives up the drive for SCSI commands and releases eventual access locks.
|
|
||||||
(Note: this is not physical tray locking.)
|
|
||||||
*/
|
|
||||||
int sg_release(struct burn_drive *d)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/** Sends a SCSI command to the drive, receives reply and evaluates wether
|
|
||||||
the command succeeded or shall be retried or finally failed.
|
|
||||||
Returned SCSI errors shall not lead to a return value indicating failure.
|
|
||||||
The callers get notified by c->error. An SCSI failure which leads not to
|
|
||||||
a retry shall be notified via scsi_notify_error().
|
|
||||||
The Libburn_log_sg_commandS facility might be of help when problems with
|
|
||||||
a drive have to be examined. It shall stay disabled for normal use.
|
|
||||||
@return: 1 success , <=0 failure
|
|
||||||
*/
|
|
||||||
int sg_issue_command(struct burn_drive *d, struct command *c)
|
|
||||||
{
|
|
||||||
libdax_msgs_submit(libdax_messenger, d->global_index, 0x0002016a,
|
|
||||||
LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH,
|
|
||||||
"No MMC transport adapter is present. Running on sg-dummy.c.",
|
|
||||||
0, 0);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/** Tries to obtain SCSI address parameters.
|
|
||||||
@return 1 is success , 0 is failure
|
|
||||||
*/
|
|
||||||
int sg_obtain_scsi_adr(char *path, int *bus_no, int *host_no, int *channel_no,
|
|
||||||
int *target_no, int *lun_no)
|
|
||||||
{
|
|
||||||
libdax_msgs_submit(libdax_messenger, -1, 0x0002016c,
|
|
||||||
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH,
|
|
||||||
"No MMC transport adapter is present. Running on sg-dummy.c.",
|
|
||||||
0, 0);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/** Tells wether a text is a persistent address as listed by the enumeration
|
|
||||||
functions.
|
|
||||||
*/
|
|
||||||
int sg_is_enumerable_adr(char *adr)
|
|
||||||
{
|
|
||||||
return(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* 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;
|
|
||||||
|
|
||||||
#ifdef Libburn_if_this_was_linuX
|
|
||||||
|
|
||||||
} else if(S_ISBLK(stbuf.st_mode)) {
|
|
||||||
fd = open(path, open_mode);
|
|
||||||
if (fd == -1)
|
|
||||||
return -2;
|
|
||||||
ret = ioctl(fd, BLKGETSIZE, &blocks);
|
|
||||||
close(fd);
|
|
||||||
if (ret == -1)
|
|
||||||
return -2;
|
|
||||||
*bytes = ((off_t) blocks) * (off_t) 512;
|
|
||||||
|
|
||||||
#endif /* Libburn_if_this_was_linuX */
|
|
||||||
|
|
||||||
} else if(S_ISREG(stbuf.st_mode)) {
|
|
||||||
add_size = stbuf.st_blocks * (off_t) 512;
|
|
||||||
strcpy(testpath, path);
|
|
||||||
} else
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (testpath[0]) {
|
|
||||||
|
|
||||||
#ifdef Libburn_os_has_statvfS
|
|
||||||
|
|
||||||
if (statvfs(testpath, &vfsbuf) == -1)
|
|
||||||
return -2;
|
|
||||||
*bytes = add_size + ((off_t) vfsbuf.f_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;
|
|
||||||
}
|
|
||||||
|
|
@ -1,11 +1,5 @@
|
|||||||
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||||
|
|
||||||
/*
|
|
||||||
Copyright (c) 2006 - 2010 Thomas Schmitt <scdbackup@gmx.net>
|
|
||||||
Provided under GPL version 2 or later.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
||||||
This is the main operating system dependent SCSI part of libburn. It implements
|
This is the main operating system dependent SCSI part of libburn. It implements
|
||||||
@ -35,28 +29,12 @@ and of deriving the following system specific files from existing examples:
|
|||||||
Said sg-*.c operations are defined by a public function interface, which has
|
Said sg-*.c operations are defined by a public function interface, which has
|
||||||
to be implemented in a way that provides libburn with the desired services:
|
to be implemented in a way that provides libburn with the desired services:
|
||||||
|
|
||||||
sg_id_string() returns an id string of the SCSI transport adapter.
|
|
||||||
It may be called before initialization but then may
|
|
||||||
return only a preliminary id.
|
|
||||||
|
|
||||||
sg_initialize() performs global initialization of the SCSI transport
|
|
||||||
adapter and eventually needed operating system
|
|
||||||
facilities. Checks for compatibility of supporting
|
|
||||||
software components.
|
|
||||||
|
|
||||||
sg_shutdown() performs global finalizations and releases golbally
|
|
||||||
aquired resources.
|
|
||||||
|
|
||||||
sg_give_next_adr() iterates over the set of potentially useful drive
|
sg_give_next_adr() iterates over the set of potentially useful drive
|
||||||
address strings.
|
address strings.
|
||||||
|
|
||||||
scsi_enumerate_drives() brings all available, not-whitelist-banned, and
|
scsi_enumerate_drives() brings all available, not-whitelist-banned, and
|
||||||
accessible drives into libburn's list of drives.
|
accessible drives into libburn's list of drives.
|
||||||
|
|
||||||
sg_dispose_drive() finalizes adapter specifics of struct burn_drive
|
|
||||||
on destruction. Releases resources which were aquired
|
|
||||||
underneath scsi_enumerate_drives().
|
|
||||||
|
|
||||||
sg_drive_is_open() tells wether libburn has the given drive in use.
|
sg_drive_is_open() tells wether libburn has the given drive in use.
|
||||||
|
|
||||||
sg_grab() opens the drive for SCSI commands and ensures
|
sg_grab() opens the drive for SCSI commands and ensures
|
||||||
@ -70,35 +48,14 @@ sg_issue_command() sends a SCSI command to the drive, receives reply,
|
|||||||
|
|
||||||
sg_obtain_scsi_adr() tries to obtain SCSI address parameters.
|
sg_obtain_scsi_adr() tries to obtain SCSI address parameters.
|
||||||
|
|
||||||
|
|
||||||
burn_os_is_2k_seekrw() tells whether the given path leads to a file object
|
|
||||||
that can be used in 2 kB granularity by lseek(2),
|
|
||||||
read(2), and possibly write(2) if not read-only.
|
|
||||||
E.g. a USB stick or a hard disk.
|
|
||||||
|
|
||||||
burn_os_stdio_capacity() estimates the emulated media space of stdio-drives.
|
burn_os_stdio_capacity() estimates the emulated media space of stdio-drives.
|
||||||
|
|
||||||
burn_os_open_track_src() opens a disk file in a way that allows best
|
|
||||||
throughput with file reading and/or SCSI write command
|
|
||||||
transmission.
|
|
||||||
|
|
||||||
burn_os_alloc_buffer() allocates a memory area that is suitable for file
|
|
||||||
descriptors issued by burn_os_open_track_src().
|
|
||||||
The buffer size may be rounded up for alignment
|
|
||||||
reasons.
|
|
||||||
|
|
||||||
burn_os_free_buffer() delete a buffer obtained by burn_os_alloc_buffer().
|
|
||||||
|
|
||||||
|
|
||||||
Porting hints are marked by the text "PORTING:".
|
Porting hints are marked by the text "PORTING:".
|
||||||
Send feedback to libburn-hackers@pykix.org .
|
Send feedback to libburn-hackers@pykix.org .
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
#include "../config.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/** PORTING : ------- OS dependent headers and definitions ------ */
|
/** PORTING : ------- OS dependent headers and definitions ------ */
|
||||||
|
|
||||||
@ -169,10 +126,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;
|
||||||
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 *)
|
idx->ccb.cdm.matches = (struct dev_match_result *)malloc(idx->bufsize);
|
||||||
calloc(1, idx->bufsize);
|
|
||||||
if (idx->ccb.cdm.matches == NULL) {
|
if (idx->ccb.cdm.matches == NULL) {
|
||||||
warnx("cannot allocate memory for matches");
|
warnx("can't malloc memory for matches");
|
||||||
close(idx->fd);
|
close(idx->fd);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -274,61 +230,6 @@ static void enumerate_common(char *fname, int bus_no, int host_no,
|
|||||||
/* ------------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------------ */
|
||||||
|
|
||||||
|
|
||||||
/** Returns the id string of the SCSI transport adapter and eventually
|
|
||||||
needed operating system facilities.
|
|
||||||
This call is usable even if sg_initialize() was not called yet. In that
|
|
||||||
case a preliminary constant message might be issued if detailed info is
|
|
||||||
not available yet.
|
|
||||||
@param msg returns id string
|
|
||||||
@param flag unused yet, submit 0
|
|
||||||
@return 1 = success, <=0 = failure
|
|
||||||
*/
|
|
||||||
int sg_id_string(char msg[1024], int flag)
|
|
||||||
{
|
|
||||||
strcpy(msg, "internal FreeBSD CAM adapter sg-freebsd-port");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/** Performs global initialization of the SCSI transport adapter and eventually
|
|
||||||
needed operating system facilities. Checks for compatibility supporting
|
|
||||||
software components.
|
|
||||||
@param msg returns ids and/or error messages of eventual helpers
|
|
||||||
@param flag unused yet, submit 0
|
|
||||||
@return 1 = success, <=0 = failure
|
|
||||||
*/
|
|
||||||
int sg_initialize(char msg[1024], int flag)
|
|
||||||
{
|
|
||||||
return sg_id_string(msg, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/** Performs global finalization of the SCSI transport adapter and eventually
|
|
||||||
needed operating system facilities. Releases globally aquired resources.
|
|
||||||
@param flag unused yet, submit 0
|
|
||||||
@return 1 = success, <=0 = failure
|
|
||||||
*/
|
|
||||||
int sg_shutdown(int flag)
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/** Finalizes BURN_OS_TRANSPORT_DRIVE_ELEMENTS, the components of
|
|
||||||
struct burn_drive which are defined in os-*.h.
|
|
||||||
The eventual initialization of those components was made underneath
|
|
||||||
scsi_enumerate_drives().
|
|
||||||
This will be called when a burn_drive gets disposed.
|
|
||||||
@param d the drive to be finalized
|
|
||||||
@param flag unused yet, submit 0
|
|
||||||
@return 1 = success, <=0 = failure
|
|
||||||
*/
|
|
||||||
int sg_dispose_drive(struct burn_drive *d, int flag)
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/** Returns the next index number and the next enumerated drive address.
|
/** Returns the next index number and the next enumerated drive address.
|
||||||
The enumeration has to cover all available and accessible drives. It is
|
The enumeration has to cover all available and accessible drives. It is
|
||||||
allowed to return addresses of drives which are not available but under
|
allowed to return addresses of drives which are not available but under
|
||||||
@ -398,7 +299,7 @@ try_item:; /* This spaghetti loop keeps the number of tabs small */
|
|||||||
break;
|
break;
|
||||||
snprintf(buf, sizeof (buf), "/dev/%s%d",
|
snprintf(buf, sizeof (buf), "/dev/%s%d",
|
||||||
result->periph_name, result->unit_number);
|
result->periph_name, result->unit_number);
|
||||||
if(adr_size <= strlen(buf))
|
if(adr_size <= strlen(buf)
|
||||||
return -1;
|
return -1;
|
||||||
strcpy(adr, buf);
|
strcpy(adr, buf);
|
||||||
|
|
||||||
@ -422,7 +323,7 @@ try_item:; /* This spaghetti loop keeps the number of tabs small */
|
|||||||
int scsi_enumerate_drives(void)
|
int scsi_enumerate_drives(void)
|
||||||
{
|
{
|
||||||
burn_drive_enumerator_t idx;
|
burn_drive_enumerator_t idx;
|
||||||
int initialize = 1, ret;
|
int initialize = 1;
|
||||||
char buf[64];
|
char buf[64];
|
||||||
|
|
||||||
while(1) {
|
while(1) {
|
||||||
@ -437,7 +338,6 @@ int scsi_enumerate_drives(void)
|
|||||||
idx.result->target_lun);
|
idx.result->target_lun);
|
||||||
}
|
}
|
||||||
sg_give_next_adr(&idx, buf, sizeof(buf), -1);
|
sg_give_next_adr(&idx, buf, sizeof(buf), -1);
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -460,12 +360,11 @@ int sg_drive_is_open(struct burn_drive * d)
|
|||||||
*/
|
*/
|
||||||
int sg_grab(struct burn_drive *d)
|
int sg_grab(struct burn_drive *d)
|
||||||
{
|
{
|
||||||
|
int count;
|
||||||
struct cam_device *cam;
|
struct cam_device *cam;
|
||||||
|
|
||||||
if(d->cam != NULL) {
|
if(d->cam != NULL)
|
||||||
d->released = 0;
|
return 0;
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
cam = cam_open_device(d->devname, O_RDWR);
|
cam = cam_open_device(d->devname, O_RDWR);
|
||||||
if (cam == NULL) {
|
if (cam == NULL) {
|
||||||
@ -616,7 +515,7 @@ int sg_obtain_scsi_adr(char *path, int *bus_no, int *host_no, int *channel_no,
|
|||||||
int *target_no, int *lun_no)
|
int *target_no, int *lun_no)
|
||||||
{
|
{
|
||||||
burn_drive_enumerator_t idx;
|
burn_drive_enumerator_t idx;
|
||||||
int initialize = 1, ret;
|
int initialize = 1;
|
||||||
char buf[64];
|
char buf[64];
|
||||||
struct periph_match_result* result;
|
struct periph_match_result* result;
|
||||||
|
|
||||||
@ -625,7 +524,7 @@ int sg_obtain_scsi_adr(char *path, int *bus_no, int *host_no, int *channel_no,
|
|||||||
initialize = 0;
|
initialize = 0;
|
||||||
if (ret <= 0)
|
if (ret <= 0)
|
||||||
break;
|
break;
|
||||||
if (strcmp(path, buf) != 0)
|
if (strcmp(adr, buf) != 0)
|
||||||
continue;
|
continue;
|
||||||
result = &(idx->ccb.cdm.matches[i].result.periph_result);
|
result = &(idx->ccb.cdm.matches[i].result.periph_result);
|
||||||
*bus_no = result->path_id;
|
*bus_no = result->path_id;
|
||||||
@ -647,7 +546,7 @@ int sg_obtain_scsi_adr(char *path, int *bus_no, int *host_no, int *channel_no,
|
|||||||
int sg_is_enumerable_adr(char* adr)
|
int sg_is_enumerable_adr(char* adr)
|
||||||
{
|
{
|
||||||
burn_drive_enumerator_t idx;
|
burn_drive_enumerator_t idx;
|
||||||
int initialize = 1, ret;
|
int initialize = 1;
|
||||||
char buf[64];
|
char buf[64];
|
||||||
|
|
||||||
while(1) {
|
while(1) {
|
||||||
@ -665,47 +564,6 @@ int sg_is_enumerable_adr(char* adr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ts B00115 */
|
|
||||||
/* Return 1 if the given path leads to a regular file or a device that can be
|
|
||||||
seeked, written, and read with 2 kB granularity.
|
|
||||||
*/
|
|
||||||
int burn_os_is_2k_seekrw(char *path, int flag)
|
|
||||||
{
|
|
||||||
struct stat stbuf;
|
|
||||||
char *spt;
|
|
||||||
int i, e;
|
|
||||||
|
|
||||||
if (stat(path, &stbuf) == -1)
|
|
||||||
return 0;
|
|
||||||
if (S_ISREG(stbuf.st_mode))
|
|
||||||
return 1;
|
|
||||||
if (!S_ISCHR(stbuf.st_mode))
|
|
||||||
return 0;
|
|
||||||
spt = strrchr(path, '/');
|
|
||||||
if (spt == NULL)
|
|
||||||
spt = path;
|
|
||||||
else
|
|
||||||
spt++;
|
|
||||||
e = strlen(spt);
|
|
||||||
for (i = strlen(spt) - 1; i > 0; i--)
|
|
||||||
if (spt[i] >= '0' && spt[i] <= '9')
|
|
||||||
e = i;
|
|
||||||
if (strncmp(spt, "da", e) == 0) /* SCSI disk. E.g. USB stick. */
|
|
||||||
return 1;
|
|
||||||
if (strncmp(spt, "cd", e) == 0) /* SCSI CD drive might be writeable. */
|
|
||||||
return 1;
|
|
||||||
if (strncmp(spt, "ad", e) == 0) /* IDE hard drive */
|
|
||||||
return 1;
|
|
||||||
if (strncmp(spt, "acd", e) == 0) /* IDE CD drive might be writeable */
|
|
||||||
return 1;
|
|
||||||
if (strncmp(spt, "fd", e) == 0) /* Floppy disk */
|
|
||||||
return 1;
|
|
||||||
if (strncmp(spt, "fla", e) == 0) /* Flash drive */
|
|
||||||
return 1;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* ts A70909 */
|
/* ts A70909 */
|
||||||
/** Estimate the potential payload capacity of a file address.
|
/** Estimate the potential payload capacity of a file address.
|
||||||
@param path The address of the file to be examined. If it does not
|
@param path The address of the file to be examined. If it does not
|
||||||
@ -765,45 +623,9 @@ int burn_os_stdio_capacity(char *path, off_t *bytes)
|
|||||||
if (testpath[0]) {
|
if (testpath[0]) {
|
||||||
if (statvfs(testpath, &vfsbuf) == -1)
|
if (statvfs(testpath, &vfsbuf) == -1)
|
||||||
return -2;
|
return -2;
|
||||||
*bytes = add_size + ((off_t) vfsbuf.f_frsize) *
|
*bytes = add_size + ((off_t) vfsbuf.f_bsize) *
|
||||||
(off_t) vfsbuf.f_bavail;
|
(off_t) vfsbuf.f_bavail;
|
||||||
}
|
}
|
||||||
return 1;
|
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
@ -1,14 +1,6 @@
|
|||||||
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||||
|
|
||||||
/*
|
#include <assert.h>
|
||||||
Copyright (c) 2006 - 2010 Thomas Schmitt <scdbackup@gmx.net>
|
|
||||||
Provided under GPL version 2 or later.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
#include "../config.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@ -16,7 +8,6 @@
|
|||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
#include <sys/file.h>
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <sys/poll.h>
|
#include <sys/poll.h>
|
||||||
@ -26,24 +17,10 @@
|
|||||||
|
|
||||||
#include <err.h> /* XXX */
|
#include <err.h> /* XXX */
|
||||||
|
|
||||||
|
|
||||||
/* ts A70909 */
|
/* ts A70909 */
|
||||||
#include <sys/statvfs.h>
|
#include <sys/statvfs.h>
|
||||||
|
|
||||||
/* ts B00121 */
|
|
||||||
#include <sys/disk.h> /* DIOCGMEDIASIZE */
|
|
||||||
|
|
||||||
|
|
||||||
/* ts B00326 : For use of CAM_PASS_ERR_RECOVER with ahci */
|
|
||||||
#define Libburn_for_freebsd_ahcI yes
|
|
||||||
|
|
||||||
/* ts B00327 : for debugging of cam_send_cdb() failures
|
|
||||||
# define Libburn_ahci_verbouS yes
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* ts B00327 : Apply CAM_PASS_ERR_RECOVER to drives even if not ahci
|
|
||||||
# define libburn_ahci_style_for_alL yes
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#include "transport.h"
|
#include "transport.h"
|
||||||
#include "drive.h"
|
#include "drive.h"
|
||||||
@ -78,79 +55,6 @@ int burn_drive_is_banned(char *device_address);
|
|||||||
int mmc_function_spy(struct burn_drive *d, char * text);
|
int mmc_function_spy(struct burn_drive *d, char * text);
|
||||||
|
|
||||||
|
|
||||||
/* ts B00113
|
|
||||||
Whether to log SCSI commands:
|
|
||||||
bit0= log in /tmp/libburn_sg_command_log
|
|
||||||
bit1= log to stderr
|
|
||||||
bit2= flush every line
|
|
||||||
*/
|
|
||||||
extern int burn_sg_log_scsi;
|
|
||||||
|
|
||||||
/* ts B00114 */
|
|
||||||
/* Storage object is in libburn/init.c
|
|
||||||
whether to strive for exclusive access to the drive
|
|
||||||
*/
|
|
||||||
extern int burn_sg_open_o_excl;
|
|
||||||
|
|
||||||
|
|
||||||
/* ts A91227 */
|
|
||||||
/** Returns the id string of the SCSI transport adapter and eventually
|
|
||||||
needed operating system facilities.
|
|
||||||
This call is usable even if sg_initialize() was not called yet. In that
|
|
||||||
case a preliminary constant message might be issued if detailed info is
|
|
||||||
not available yet.
|
|
||||||
@param msg returns id string
|
|
||||||
@param flag unused yet, submit 0
|
|
||||||
@return 1 = success, <=0 = failure
|
|
||||||
*/
|
|
||||||
int sg_id_string(char msg[1024], int flag)
|
|
||||||
{
|
|
||||||
strcpy(msg, "internal FreeBSD CAM adapter sg-freebsd");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* ts A91227 */
|
|
||||||
/** Performs global initialization of the SCSI transport adapter and eventually
|
|
||||||
needed operating system facilities. Checks for compatibility supporting
|
|
||||||
software components.
|
|
||||||
@param msg returns ids and/or error messages of eventual helpers
|
|
||||||
@param flag unused yet, submit 0
|
|
||||||
@return 1 = success, <=0 = failure
|
|
||||||
*/
|
|
||||||
int sg_initialize(char msg[1024], int flag)
|
|
||||||
{
|
|
||||||
return sg_id_string(msg, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* ts A91227 */
|
|
||||||
/** Performs global finalization of the SCSI transport adapter and eventually
|
|
||||||
needed operating system facilities. Releases globally aquired resources.
|
|
||||||
@param flag unused yet, submit 0
|
|
||||||
@return 1 = success, <=0 = failure
|
|
||||||
*/
|
|
||||||
int sg_shutdown(int flag)
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/** Finalizes BURN_OS_TRANSPORT_DRIVE_ELEMENTS, the components of
|
|
||||||
struct burn_drive which are defined in os-*.h.
|
|
||||||
The eventual initialization of those components was made underneath
|
|
||||||
scsi_enumerate_drives().
|
|
||||||
This will be called when a burn_drive gets disposed.
|
|
||||||
@param d the drive to be finalized
|
|
||||||
@param flag unused yet, submit 0
|
|
||||||
@return 1 = success, <=0 = failure
|
|
||||||
*/
|
|
||||||
int sg_dispose_drive(struct burn_drive *d, int flag)
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* ts A61021 : Moved most code from scsi_enumerate_drives under
|
/* ts A61021 : Moved most code from scsi_enumerate_drives under
|
||||||
sg_give_next_adr() */
|
sg_give_next_adr() */
|
||||||
/* Some helper functions for scsi_give_next_adr() */
|
/* Some helper functions for scsi_give_next_adr() */
|
||||||
@ -160,17 +64,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 = calloc(1, sizeof(*idx));
|
idx = malloc(sizeof(*idx));
|
||||||
if (idx == NULL) {
|
if (idx == NULL) {
|
||||||
warnx("cannot allocate memory for enumerator");
|
warnx("can't malloc 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("could not open %s", XPT_DEVICE);
|
warn("couldn't open %s", XPT_DEVICE);
|
||||||
free(idx);
|
|
||||||
idx = NULL;
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -183,9 +85,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 *) calloc(1, bufsize);
|
idx->ccb.cdm.matches = (struct dev_match_result *)malloc(bufsize);
|
||||||
if (idx->ccb.cdm.matches == NULL) {
|
if (idx->ccb.cdm.matches == NULL) {
|
||||||
warnx("cannot allocate memory for matches");
|
warnx("can't malloc memory for matches");
|
||||||
close(idx->fd);
|
close(idx->fd);
|
||||||
free(idx);
|
free(idx);
|
||||||
return -1;
|
return -1;
|
||||||
@ -242,7 +144,7 @@ static int sg_next_enumeration_buffer(burn_drive_enumerator_t *idx_)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** Returns the next index object state and the next enumerated drive address.
|
/** Returns the next index number and the next enumerated drive address.
|
||||||
@param idx An opaque handle. Make no own theories about it.
|
@param idx An opaque handle. Make no own theories about it.
|
||||||
@param adr Takes the reply
|
@param adr Takes the reply
|
||||||
@param adr_size Gives maximum size of reply including final 0
|
@param adr_size Gives maximum size of reply including final 0
|
||||||
@ -296,15 +198,9 @@ int sg_give_next_adr(burn_drive_enumerator_t *idx_,
|
|||||||
struct periph_match_result* result;
|
struct periph_match_result* result;
|
||||||
|
|
||||||
result = &(idx->ccb.cdm.matches[idx->i].result.periph_result);
|
result = &(idx->ccb.cdm.matches[idx->i].result.periph_result);
|
||||||
/* ts B00112 : we really want only "cd" devices.
|
|
||||||
|
|
||||||
if (idx->skip_device ||
|
if (idx->skip_device ||
|
||||||
strcmp(result->periph_name, "pass") == 0)
|
strcmp(result->periph_name, "pass") == 0)
|
||||||
break;
|
break;
|
||||||
*/
|
|
||||||
if (idx->skip_device ||
|
|
||||||
strcmp(result->periph_name, "cd") != 0)
|
|
||||||
break;
|
|
||||||
ret = snprintf(adr, adr_size, "/dev/%s%d",
|
ret = snprintf(adr, adr_size, "/dev/%s%d",
|
||||||
result->periph_name, result->unit_number);
|
result->periph_name, result->unit_number);
|
||||||
if(ret >= adr_size)
|
if(ret >= adr_size)
|
||||||
@ -315,7 +211,7 @@ int sg_give_next_adr(burn_drive_enumerator_t *idx_,
|
|||||||
|
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
/* fprintf(stderr, "unknown match type\n"); */
|
/* printf(stderr, "unknown match type\n"); */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
(idx->i)++;
|
(idx->i)++;
|
||||||
@ -390,10 +286,6 @@ int sg_close_drive(struct burn_drive * d)
|
|||||||
cam_close_device(d->cam);
|
cam_close_device(d->cam);
|
||||||
d->cam = NULL;
|
d->cam = NULL;
|
||||||
}
|
}
|
||||||
if (d->lock_fd > 0) {
|
|
||||||
close(d->lock_fd);
|
|
||||||
d->lock_fd = -1;
|
|
||||||
}
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -447,10 +339,7 @@ static void enumerate_common(char *fname, int bus_no, int host_no,
|
|||||||
out.lun = lun_no;
|
out.lun = lun_no;
|
||||||
|
|
||||||
out.devname = burn_strdup(fname);
|
out.devname = burn_strdup(fname);
|
||||||
|
|
||||||
out.cam = NULL;
|
out.cam = NULL;
|
||||||
out.lock_fd = -1;
|
|
||||||
out.is_ahci = 0;
|
|
||||||
|
|
||||||
out.start_lba= -2000000000;
|
out.start_lba= -2000000000;
|
||||||
out.end_lba= -2000000000;
|
out.end_lba= -2000000000;
|
||||||
@ -487,9 +376,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 = calloc(1, sizeof(struct burn_scsi_inquiry_data));
|
out.idata = malloc(sizeof(struct burn_scsi_inquiry_data));
|
||||||
out.idata->valid = 0;
|
out.idata->valid = 0;
|
||||||
out.mdata = calloc(1, sizeof(struct scsi_mode_data));
|
out.mdata = malloc(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,
|
||||||
@ -542,9 +431,6 @@ static void enumerate_common(char *fname, int bus_no, int host_no,
|
|||||||
/* Operating system adapter is CAM */
|
/* Operating system adapter is CAM */
|
||||||
/* Adapter specific handles and data */
|
/* Adapter specific handles and data */
|
||||||
out.cam = NULL;
|
out.cam = NULL;
|
||||||
out.lock_fd = -1;
|
|
||||||
out.is_ahci = 0;
|
|
||||||
|
|
||||||
/* Adapter specific functions */
|
/* Adapter specific functions */
|
||||||
out.grab = sg_grab;
|
out.grab = sg_grab;
|
||||||
out.release = sg_release;
|
out.release = sg_release;
|
||||||
@ -557,145 +443,15 @@ static void enumerate_common(char *fname, int bus_no, int host_no,
|
|||||||
|
|
||||||
#endif /* ! Scsi_freebsd_make_own_enumeratE */
|
#endif /* ! Scsi_freebsd_make_own_enumeratE */
|
||||||
|
|
||||||
|
/* ts A61021: do not believe this:
|
||||||
/* Lock the inode associated to dev_fd and the inode associated to devname.
|
we use the sg reference count to decide whether we can use the
|
||||||
Return OS errno, number of pass device of dev_fd, locked fd to devname,
|
drive or not.
|
||||||
error message.
|
if refcount is not one, drive is open somewhere else.
|
||||||
A return value of > 0 means success, <= 0 means failure.
|
|
||||||
*/
|
*/
|
||||||
static int freebsd_dev_lock(int dev_fd, char *devname,
|
|
||||||
int *os_errno, int *pass_dev_no, int *lock_fd, char msg[4096],
|
|
||||||
int flag)
|
|
||||||
{
|
|
||||||
int lock_denied = 0, fd_stbuf_valid, name_stbuf_valid, i, pass_l = 100;
|
|
||||||
int max_retry = 3, tries = 0;
|
|
||||||
struct stat fd_stbuf, name_stbuf;
|
|
||||||
char pass_name[16], *lock_name;
|
|
||||||
|
|
||||||
*os_errno = 0;
|
|
||||||
*pass_dev_no = -1;
|
|
||||||
*lock_fd = -1;
|
|
||||||
msg[0] = 0;
|
|
||||||
|
|
||||||
fd_stbuf_valid = !fstat(dev_fd, &fd_stbuf);
|
|
||||||
|
|
||||||
/* Try to find name of pass device by inode number */
|
|
||||||
lock_name = (char *) "effective device";
|
|
||||||
if(fd_stbuf_valid) {
|
|
||||||
for (i = 0; i < pass_l; i++) {
|
|
||||||
sprintf(pass_name, "/dev/pass%d", i);
|
|
||||||
if (stat(pass_name, &name_stbuf) != -1)
|
|
||||||
if(fd_stbuf.st_ino == name_stbuf.st_ino &&
|
|
||||||
fd_stbuf.st_dev == name_stbuf.st_dev)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (i < pass_l) {
|
|
||||||
lock_name = pass_name;
|
|
||||||
*pass_dev_no = i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
name_stbuf_valid = !stat(devname, &name_stbuf);
|
|
||||||
for (tries= 0; tries <= max_retry; tries++) {
|
|
||||||
lock_denied = flock(dev_fd, LOCK_EX | LOCK_NB);
|
|
||||||
*os_errno = errno;
|
|
||||||
if (lock_denied) {
|
|
||||||
if (errno == EAGAIN && tries < max_retry) {
|
|
||||||
/* <<< debugging
|
|
||||||
fprintf(stderr,
|
|
||||||
"\nlibcdio_DEBUG: EAGAIN pass, tries= %d\n",
|
|
||||||
tries);
|
|
||||||
*/
|
|
||||||
usleep(2000000);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
sprintf(msg,
|
|
||||||
"Device busy. flock(LOCK_EX) failed on %s of %s",
|
|
||||||
strlen(lock_name) > 2000 || *pass_dev_no < 0 ?
|
|
||||||
"pass device" : lock_name,
|
|
||||||
strlen(devname) > 2000 ? "drive" : devname);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
fprintf(stderr, "libburn_DEBUG: flock obtained on %s of %s\n",
|
|
||||||
lock_name, devname);
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Eventually lock the official device node too */
|
|
||||||
if (fd_stbuf_valid && name_stbuf_valid &&
|
|
||||||
(fd_stbuf.st_ino != name_stbuf.st_ino ||
|
|
||||||
fd_stbuf.st_dev != name_stbuf.st_dev)) {
|
|
||||||
|
|
||||||
*lock_fd = open(devname, O_RDONLY);
|
|
||||||
if (*lock_fd == 0) {
|
|
||||||
close(*lock_fd);
|
|
||||||
*lock_fd = -1;
|
|
||||||
} if (*lock_fd > 0) {
|
|
||||||
for (tries = 0; tries <= max_retry; tries++) {
|
|
||||||
lock_denied =
|
|
||||||
flock(*lock_fd, LOCK_EX | LOCK_NB);
|
|
||||||
if (lock_denied) {
|
|
||||||
if (errno == EAGAIN &&
|
|
||||||
tries < max_retry) {
|
|
||||||
/* <<< debugging
|
|
||||||
fprintf(stderr,
|
|
||||||
"\nlibcdio_DEBUG: EAGAIN dev, tries= %d\n",
|
|
||||||
tries);
|
|
||||||
*/
|
|
||||||
|
|
||||||
usleep(2000000);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
close(*lock_fd);
|
|
||||||
*lock_fd = -1;
|
|
||||||
sprintf(msg,
|
|
||||||
"Device busy. flock(LOCK_EX) failed on %s",
|
|
||||||
strlen(devname) > 4000 ? "drive" : devname);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
fprintf(stderr, "libburn_DEBUG: flock obtained on %s\n",
|
|
||||||
devname);
|
|
||||||
*/
|
|
||||||
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int sg_lock(struct burn_drive *d, int flag)
|
|
||||||
{
|
|
||||||
int ret, os_errno, pass_dev_no = -1, flock_fd = -1;
|
|
||||||
char msg[4096];
|
|
||||||
|
|
||||||
ret = freebsd_dev_lock(d->cam->fd, d->devname,
|
|
||||||
&os_errno, &pass_dev_no, &flock_fd, msg, 0);
|
|
||||||
if (ret <= 0) {
|
|
||||||
libdax_msgs_submit(libdax_messenger, d->global_index,
|
|
||||||
0x00020008,
|
|
||||||
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
|
|
||||||
msg, os_errno, 0);
|
|
||||||
sg_close_drive(d);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
if (d->lock_fd > 0)
|
|
||||||
close(d->lock_fd);
|
|
||||||
d->lock_fd = flock_fd;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int sg_grab(struct burn_drive *d)
|
int sg_grab(struct burn_drive *d)
|
||||||
{
|
{
|
||||||
|
int count;
|
||||||
struct cam_device *cam;
|
struct cam_device *cam;
|
||||||
char path_string[80];
|
|
||||||
|
|
||||||
if (mmc_function_spy(d, "sg_grab") <= 0)
|
if (mmc_function_spy(d, "sg_grab") <= 0)
|
||||||
return 0;
|
return 0;
|
||||||
@ -707,31 +463,22 @@ int sg_grab(struct burn_drive *d)
|
|||||||
|
|
||||||
cam = cam_open_device(d->devname, O_RDWR);
|
cam = cam_open_device(d->devname, O_RDWR);
|
||||||
if (cam == NULL) {
|
if (cam == NULL) {
|
||||||
libdax_msgs_submit(libdax_messenger, d->global_index,
|
libdax_msgs_submit(libdax_messenger, d->global_index, 0x00020003,
|
||||||
0x00020003,
|
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
|
"Could not grab drive", 0/*os_errno*/, 0);
|
||||||
"Could not grab drive", errno, 0);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
d->cam = cam;
|
/* er = ioctl(fd, SG_GET_ACCESS_COUNT, &count);*/
|
||||||
if (burn_sg_open_o_excl & 63)
|
count = 1;
|
||||||
if (sg_lock(d, 0) <= 0)
|
if (1 == count) {
|
||||||
return 0;
|
d->cam = cam;
|
||||||
fcntl(cam->fd, F_SETOWN, getpid());
|
fcntl(cam->fd, F_SETOWN, getpid());
|
||||||
|
d->released = 0;
|
||||||
cam_path_string(d->cam, path_string, sizeof(path_string));
|
return 1;
|
||||||
|
}
|
||||||
#ifdef Libburn_ahci_verbouS
|
burn_print(1, "could not acquire drive - already open\n");
|
||||||
fprintf(stderr, "libburn_EXPERIMENTAL: CAM path = %s\n", path_string);
|
sg_close_drive(d);
|
||||||
#endif
|
return 0;
|
||||||
|
|
||||||
if (strstr(path_string, ":ahcich") != NULL)
|
|
||||||
d->is_ahci = 1;
|
|
||||||
else
|
|
||||||
d->is_ahci = -1;
|
|
||||||
|
|
||||||
d->released = 0;
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -759,15 +506,12 @@ int sg_release(struct burn_drive *d)
|
|||||||
|
|
||||||
int sg_issue_command(struct burn_drive *d, struct command *c)
|
int sg_issue_command(struct burn_drive *d, struct command *c)
|
||||||
{
|
{
|
||||||
int done = 0, err, sense_len = 0, ret, ignore_error, no_retry = 0, i;
|
int done = 0;
|
||||||
int cam_pass_err_recover = 0, key, asc, ascq, timeout_ms;
|
int err;
|
||||||
union ccb *ccb;
|
union ccb *ccb;
|
||||||
char buf[161];
|
|
||||||
static FILE *fp = NULL;
|
|
||||||
time_t start_time;
|
|
||||||
|
|
||||||
snprintf(buf, sizeof (buf),
|
char buf[161];
|
||||||
"sg_issue_command d->cam=%p d->released=%d",
|
snprintf(buf, sizeof (buf), "sg_issue_command d->cam=%p d->released=%d",
|
||||||
(void*)d->cam, d->released);
|
(void*)d->cam, d->released);
|
||||||
mmc_function_spy(NULL, buf);
|
mmc_function_spy(NULL, buf);
|
||||||
|
|
||||||
@ -775,15 +519,6 @@ int sg_issue_command(struct burn_drive *d, struct command *c)
|
|||||||
c->error = 0;
|
c->error = 0;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (burn_sg_log_scsi & 1) {
|
|
||||||
if (fp == NULL) {
|
|
||||||
fp= fopen("/tmp/libburn_sg_command_log", "a");
|
|
||||||
fprintf(fp,
|
|
||||||
"\n-----------------------------------------\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (burn_sg_log_scsi & 3)
|
|
||||||
scsi_log_cmd(c,fp,0);
|
|
||||||
|
|
||||||
c->error = 0;
|
c->error = 0;
|
||||||
|
|
||||||
@ -810,23 +545,6 @@ 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);
|
||||||
|
|
||||||
@ -835,20 +553,11 @@ int sg_issue_command(struct burn_drive *d, struct command *c)
|
|||||||
if (c->page) {
|
if (c->page) {
|
||||||
ccb->csio.data_ptr = c->page->data;
|
ccb->csio.data_ptr = c->page->data;
|
||||||
if (c->dir == FROM_DRIVE) {
|
if (c->dir == FROM_DRIVE) {
|
||||||
|
ccb->csio.dxfer_len = BUFFER_SIZE;
|
||||||
/* ts A90430 : Ticket 148 , by jwehle :
|
|
||||||
"On ... FreeBSD 6.4 which has a usb memory reader in
|
|
||||||
addition to a ATAPI DVD burner sg_issue_command
|
|
||||||
will hang while the SCSI bus is being scanned"
|
|
||||||
*/
|
|
||||||
if (c->dxfer_len >= 0)
|
|
||||||
ccb->csio.dxfer_len = c->dxfer_len;
|
|
||||||
else
|
|
||||||
ccb->csio.dxfer_len = BUFFER_SIZE;
|
|
||||||
|
|
||||||
/* touch page so we can use valgrind */
|
/* touch page so we can use valgrind */
|
||||||
memset(c->page->data, 0, BUFFER_SIZE);
|
memset(c->page->data, 0, BUFFER_SIZE);
|
||||||
} else {
|
} else {
|
||||||
|
assert(c->page->bytes > 0);
|
||||||
ccb->csio.dxfer_len = c->page->bytes;
|
ccb->csio.dxfer_len = c->page->bytes;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -856,188 +565,44 @@ int sg_issue_command(struct burn_drive *d, struct command *c)
|
|||||||
ccb->csio.dxfer_len = 0;
|
ccb->csio.dxfer_len = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
start_time = time(NULL);
|
do {
|
||||||
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,
|
||||||
"Failed to transfer command to drive",
|
"Failed to transfer command to drive",
|
||||||
errno, 0);
|
errno, 0);
|
||||||
|
cam_freeccb(ccb);
|
||||||
sg_close_drive(d);
|
sg_close_drive(d);
|
||||||
d->released = 1;
|
d->released = 1;
|
||||||
d->busy = BURN_DRIVE_IDLE;
|
d->busy = BURN_DRIVE_IDLE;
|
||||||
c->error = 1;
|
c->error = 1;
|
||||||
{ret = -1; goto ex;}
|
return -1;
|
||||||
}
|
}
|
||||||
/* XXX */
|
/* XXX */
|
||||||
|
memcpy(c->sense, &ccb->csio.sense_data, ccb->csio.sense_len);
|
||||||
if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
|
if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
|
||||||
if (sense_len < 14) {
|
if (!c->retry) {
|
||||||
/*LOGICAL UNIT NOT READY,CAUSE NOT REPORTABLE*/
|
c->error = 1;
|
||||||
|
cam_freeccb(ccb);
|
||||||
#ifdef Libburn_ahci_verbouS
|
return 1;
|
||||||
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
|
switch (scsi_error(d, c->sense, 0)) {
|
||||||
|
case RETRY:
|
||||||
c->sense[0] = 0x70; /*Fixed format sense data*/
|
done = 0;
|
||||||
c->sense[2] = 0x02;
|
break;
|
||||||
c->sense[12] = 0x04;
|
case FAIL:
|
||||||
c->sense[13] = 0x00;
|
done = 1;
|
||||||
no_retry = 1;
|
c->error = 1;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* >>> Need own duration time measurement.
|
|
||||||
Then remove bit1 from flag.
|
|
||||||
*/
|
|
||||||
done = scsi_eval_cmd_outcome(d, c, fp, c->sense,
|
|
||||||
sense_len, 0, start_time,
|
|
||||||
timeout_ms, i,
|
|
||||||
2 | !!ignore_error);
|
|
||||||
} else {
|
} else {
|
||||||
done = 1;
|
done = 1;
|
||||||
}
|
}
|
||||||
} while (!done);
|
} while (!done);
|
||||||
ret = 1;
|
|
||||||
ex:;
|
|
||||||
cam_freeccb(ccb);
|
cam_freeccb(ccb);
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* ts B00115 */
|
|
||||||
/* Return 1 if the given path leads to a regular file or a device that can be
|
|
||||||
seeked, read and eventually written with 2 kB granularity.
|
|
||||||
*/
|
|
||||||
int burn_os_is_2k_seekrw(char *path, int flag)
|
|
||||||
{
|
|
||||||
struct stat stbuf;
|
|
||||||
char *spt;
|
|
||||||
int i, e;
|
|
||||||
#ifdef Libburn_DIOCGMEDIASIZE_ISBLK
|
|
||||||
int fd;
|
|
||||||
off_t add_size;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (stat(path, &stbuf) == -1)
|
|
||||||
return 0;
|
|
||||||
if (S_ISREG(stbuf.st_mode))
|
|
||||||
return 1;
|
|
||||||
if (!S_ISCHR(stbuf.st_mode))
|
|
||||||
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;
|
return 1;
|
||||||
|
|
||||||
#else /* Libburn_DIOCGMEDIASIZE_ISBLK */
|
|
||||||
|
|
||||||
spt = strrchr(path, '/');
|
|
||||||
if (spt == NULL)
|
|
||||||
spt = path;
|
|
||||||
else
|
|
||||||
spt++;
|
|
||||||
e = strlen(spt);
|
|
||||||
for (i = strlen(spt) - 1; i > 0; i--)
|
|
||||||
if (spt[i] >= '0' && spt[i] <= '9')
|
|
||||||
e = i;
|
|
||||||
if (strncmp(spt, "da", e) == 0) /* SCSI disk. E.g. USB stick. */
|
|
||||||
return 1;
|
|
||||||
if (strncmp(spt, "cd", e) == 0) /* SCSI CD drive might be writeable. */
|
|
||||||
return 1;
|
|
||||||
if (strncmp(spt, "ad", e) == 0) /* IDE hard drive */
|
|
||||||
return 1;
|
|
||||||
if (strncmp(spt, "acd", e) == 0) /* IDE CD drive might be writeable */
|
|
||||||
return 1;
|
|
||||||
if (strncmp(spt, "fd", e) == 0) /* Floppy disk */
|
|
||||||
return 1;
|
|
||||||
if (strncmp(spt, "fla", e) == 0) /* Flash drive */
|
|
||||||
return 1;
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
#endif /* ! Libburn_DIOCGMEDIASIZE_ISBLK */
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1058,7 +623,6 @@ int burn_os_stdio_capacity(char *path, off_t *bytes)
|
|||||||
char testpath[4096], *cpt;
|
char testpath[4096], *cpt;
|
||||||
long blocks;
|
long blocks;
|
||||||
off_t add_size = 0;
|
off_t add_size = 0;
|
||||||
int fd, ret;
|
|
||||||
|
|
||||||
testpath[0] = 0;
|
testpath[0] = 0;
|
||||||
blocks = *bytes / 512;
|
blocks = *bytes / 512;
|
||||||
@ -1093,15 +657,6 @@ int burn_os_stdio_capacity(char *path, off_t *bytes)
|
|||||||
#endif /* Libburn_if_this_was_linuX */
|
#endif /* Libburn_if_this_was_linuX */
|
||||||
|
|
||||||
|
|
||||||
} else if(S_ISCHR(stbuf.st_mode)) {
|
|
||||||
fd = open(path, O_RDONLY);
|
|
||||||
if (fd == -1)
|
|
||||||
return -2;
|
|
||||||
ret = ioctl(fd, DIOCGMEDIASIZE, &add_size);
|
|
||||||
close(fd);
|
|
||||||
if (ret == -1)
|
|
||||||
return -2;
|
|
||||||
*bytes = add_size;
|
|
||||||
} else if(S_ISREG(stbuf.st_mode)) {
|
} else if(S_ISREG(stbuf.st_mode)) {
|
||||||
add_size = stbuf.st_blocks * (off_t) 512;
|
add_size = stbuf.st_blocks * (off_t) 512;
|
||||||
strcpy(testpath, path);
|
strcpy(testpath, path);
|
||||||
@ -1111,45 +666,9 @@ int burn_os_stdio_capacity(char *path, off_t *bytes)
|
|||||||
if (testpath[0]) {
|
if (testpath[0]) {
|
||||||
if (statvfs(testpath, &vfsbuf) == -1)
|
if (statvfs(testpath, &vfsbuf) == -1)
|
||||||
return -2;
|
return -2;
|
||||||
*bytes = add_size + ((off_t) vfsbuf.f_frsize) *
|
*bytes = add_size + ((off_t) vfsbuf.f_bsize) *
|
||||||
(off_t) vfsbuf.f_bavail;
|
(off_t) vfsbuf.f_bavail;
|
||||||
}
|
}
|
||||||
return 1;
|
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
@ -1,973 +0,0 @@
|
|||||||
/* -*- 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: GNU libcdio , for X/Open compliant operating systems
|
|
||||||
|
|
||||||
|
|
||||||
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 <stdio.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
#ifdef Libburn_os_has_statvfS
|
|
||||||
#include <sys/statvfs.h>
|
|
||||||
#endif /* Libburn_os_has_stavtfS */
|
|
||||||
|
|
||||||
#ifdef __linux
|
|
||||||
/* for ioctl(BLKGETSIZE) */
|
|
||||||
#include <sys/ioctl.h>
|
|
||||||
#include <linux/fs.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __FreeBSD__
|
|
||||||
#define Libburn_is_on_freebsD 1
|
|
||||||
#endif
|
|
||||||
#ifdef __FreeBSD_kernel__
|
|
||||||
#define Libburn_is_on_freebsD 1
|
|
||||||
#endif
|
|
||||||
#ifdef Libburn_is_on_freebsD
|
|
||||||
/* To avoid ATAPI devices */
|
|
||||||
#define Libburn_guess_freebsd_atapi_devicE 1
|
|
||||||
/* To obtain size of disk-like devices */
|
|
||||||
#include <sys/disk.h> /* DIOCGMEDIASIZE */
|
|
||||||
#endif /* Libburn_is_on_freebsD */
|
|
||||||
|
|
||||||
#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/logging.h>
|
|
||||||
#include <cdio/mmc.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_libcdio_retry_usleeP 100000
|
|
||||||
#define Libburn_sg_libcdio_retry_incR 100000
|
|
||||||
|
|
||||||
|
|
||||||
/** PORTING : ------ libburn portable headers and definitions ----- */
|
|
||||||
|
|
||||||
#include "transport.h"
|
|
||||||
#include "drive.h"
|
|
||||||
#include "sg.h"
|
|
||||||
#include "spc.h"
|
|
||||||
/* collides with symbols of <cdio/mmc.h>
|
|
||||||
#include "mmc.h"
|
|
||||||
*/
|
|
||||||
#include "sbc.h"
|
|
||||||
#include "debug.h"
|
|
||||||
#include "toc.h"
|
|
||||||
#include "util.h"
|
|
||||||
|
|
||||||
#include "libdax_msgs.h"
|
|
||||||
extern struct libdax_msgs *libdax_messenger;
|
|
||||||
|
|
||||||
|
|
||||||
/* 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)
|
|
||||||
{
|
|
||||||
CdIo_t *p_cdio;
|
|
||||||
|
|
||||||
if (d->p_cdio != NULL) {
|
|
||||||
p_cdio = (CdIo_t *) d->p_cdio;
|
|
||||||
cdio_destroy(p_cdio);
|
|
||||||
d->p_cdio = NULL;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int sg_give_next_adr_raw(burn_drive_enumerator_t *idx,
|
|
||||||
char adr[], int adr_size, int initialize)
|
|
||||||
{
|
|
||||||
char **pos;
|
|
||||||
int count = 0;
|
|
||||||
|
|
||||||
if (initialize == 1) {
|
|
||||||
idx->pos = idx->ppsz_cd_drives =
|
|
||||||
cdio_get_devices(DRIVER_DEVICE);
|
|
||||||
if (idx->ppsz_cd_drives == NULL)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
for (pos = idx->ppsz_cd_drives ; pos != NULL; pos++) {
|
|
||||||
if (*pos == NULL)
|
|
||||||
break;
|
|
||||||
count++;
|
|
||||||
}
|
|
||||||
|
|
||||||
} else if (initialize == -1) {
|
|
||||||
if (idx->ppsz_cd_drives != NULL)
|
|
||||||
if (*(idx->ppsz_cd_drives) != NULL)
|
|
||||||
cdio_free_device_list(idx->ppsz_cd_drives);
|
|
||||||
idx->ppsz_cd_drives = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef Libburn_guess_freebsd_atapi_devicE
|
|
||||||
try_next:;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (idx->pos == NULL)
|
|
||||||
return 0;
|
|
||||||
if (*(idx->pos) == NULL)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
#ifdef Libburn_guess_freebsd_atapi_devicE
|
|
||||||
if (strncmp(*(idx->pos), "/dev/acd", 8) == 0) {
|
|
||||||
(idx->pos)++;
|
|
||||||
goto try_next;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (strlen(*(idx->pos)) >= adr_size)
|
|
||||||
return -1;
|
|
||||||
strcpy(adr, *(idx->pos));
|
|
||||||
(idx->pos)++;
|
|
||||||
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, char *cdio_name,
|
|
||||||
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 libcdio */
|
|
||||||
/* Adapter specific handles and data */
|
|
||||||
out.p_cdio = NULL;
|
|
||||||
strcpy(out.libcdio_name, fname);
|
|
||||||
if (strlen(cdio_name) < sizeof(out.libcdio_name))
|
|
||||||
strcpy(out.libcdio_name, cdio_name);
|
|
||||||
|
|
||||||
/* 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)
|
|
||||||
{
|
|
||||||
char *version_text;
|
|
||||||
|
|
||||||
sprintf(msg, "sg-libcdio h%d with libcdio ", LIBCDIO_VERSION_NUM);
|
|
||||||
|
|
||||||
#if LIBCDIO_VERSION_NUM < 83
|
|
||||||
|
|
||||||
LIBBURN_MISCONFIGURATION = 0;
|
|
||||||
INTENTIONAL_ABORT_OF_COMPILATION__HEADERFILE_cdio_version_dot_h_TOO_OLD__NEED_libcdio_VERSION_NUM_83 = 0;
|
|
||||||
LIBBURN_MISCONFIGURATION_ = 0;
|
|
||||||
|
|
||||||
#endif /* LIBCDIO_VERSION_NUM < 83 */
|
|
||||||
|
|
||||||
version_text = (char *) cdio_version_string;
|
|
||||||
strncat(msg, version_text, 800);
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
int cdio_ver;
|
|
||||||
char *msg_pt;
|
|
||||||
|
|
||||||
cdio_loglevel_default = CDIO_LOG_ASSERT;
|
|
||||||
|
|
||||||
msg[0] = 0;
|
|
||||||
sg_id_string(msg, 0);
|
|
||||||
cdio_ver = libcdio_version_num;
|
|
||||||
libdax_msgs_submit(libdax_messenger, -1, 0x00000002,
|
|
||||||
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH,
|
|
||||||
msg , 0, 0);
|
|
||||||
if (cdio_ver < LIBCDIO_VERSION_NUM) {
|
|
||||||
strcat(msg, " ---> ");
|
|
||||||
msg_pt = msg + strlen(msg);
|
|
||||||
sprintf(msg_pt,
|
|
||||||
"libcdio TOO OLD: numeric version %d , need at least %d",
|
|
||||||
cdio_ver, LIBCDIO_VERSION_NUM);
|
|
||||||
libdax_msgs_submit(libdax_messenger, -1,
|
|
||||||
0x00000002,
|
|
||||||
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH,
|
|
||||||
msg_pt, 0, 0);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/** 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, recursion_count = 0;
|
|
||||||
char path[4096];
|
|
||||||
#ifdef Libburn_is_on_solariS
|
|
||||||
int l;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
ret = sg_give_next_adr_raw(idx, adr, adr_size, initialize);
|
|
||||||
if (ret <= 0)
|
|
||||||
return ret;
|
|
||||||
if (strlen(adr) >= sizeof(path))
|
|
||||||
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);
|
|
||||||
return (ret >= 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/** 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, recursion_count = 0;
|
|
||||||
int i_host_no = -1, i_channel_no = -1, i_target_no = -1, i_lun_no = -1;
|
|
||||||
char buf[4096], target[4096];
|
|
||||||
#ifdef Libburn_is_on_solariS
|
|
||||||
int l;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
while(1) {
|
|
||||||
ret = sg_give_next_adr_raw(&idx, buf, sizeof(buf), initialize);
|
|
||||||
initialize = 0;
|
|
||||||
if (ret <= 0)
|
|
||||||
break;
|
|
||||||
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)
|
|
||||||
strcpy(target, buf);
|
|
||||||
if (burn_drive_is_banned(target))
|
|
||||||
continue;
|
|
||||||
sg_obtain_scsi_adr(buf, &i_bus_no, &i_host_no,
|
|
||||||
&i_channel_no, &i_target_no, &i_lun_no);
|
|
||||||
enumerate_common(target, 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->p_cdio != NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/** 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)
|
|
||||||
{
|
|
||||||
CdIo_t *p_cdio;
|
|
||||||
char *am_eff, msg[4096], *am_wanted;
|
|
||||||
int os_errno, second_try = 0;
|
|
||||||
|
|
||||||
if (d->p_cdio != NULL) {
|
|
||||||
d->released = 0;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
if (d->libcdio_name[0] == 0) /* just to be sure it is initialized */
|
|
||||||
strcpy(d->libcdio_name, d->devname);
|
|
||||||
am_wanted = (burn_sg_open_o_excl & 63) ? "MMC_RDWR_EXCL" : "MMC_RDWR";
|
|
||||||
try_to_open:;
|
|
||||||
p_cdio = cdio_open_am(d->libcdio_name, DRIVER_DEVICE, am_wanted);
|
|
||||||
if (p_cdio == NULL) {
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
am_eff = (char *) cdio_get_arg(p_cdio, "access-mode");
|
|
||||||
if (strncmp(am_eff, "MMC_RDWR", 8) != 0) {
|
|
||||||
cdio_destroy(p_cdio);
|
|
||||||
if (!second_try) {
|
|
||||||
am_wanted = (burn_sg_open_o_excl & 63) ?
|
|
||||||
"MMC_RDWR" : "MMC_RDWR_EXCL";
|
|
||||||
second_try = 1;
|
|
||||||
goto try_to_open;
|
|
||||||
}
|
|
||||||
libdax_msgs_submit(libdax_messenger, d->global_index,
|
|
||||||
0x00020003,
|
|
||||||
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
|
|
||||||
"libcdio provides no MMC_RDWR access mode", 0, 0);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
d->p_cdio = p_cdio;
|
|
||||||
d->released = 0;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/** 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->p_cdio == NULL) {
|
|
||||||
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 sense_valid = 0, i, timeout_ms, no_retry = 0;
|
|
||||||
int key = 0, asc = 0, ascq = 0, done = 0;
|
|
||||||
time_t start_time;
|
|
||||||
driver_return_code_t i_status;
|
|
||||||
unsigned int dxfer_len;
|
|
||||||
static FILE *fp = NULL;
|
|
||||||
mmc_cdb_t cdb = {{0, }};
|
|
||||||
cdio_mmc_direction_t e_direction;
|
|
||||||
CdIo_t *p_cdio;
|
|
||||||
unsigned char *sense_pt = NULL;
|
|
||||||
|
|
||||||
c->error = 0;
|
|
||||||
if (d->p_cdio == NULL) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
p_cdio = (CdIo_t *) d->p_cdio;
|
|
||||||
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);
|
|
||||||
|
|
||||||
memcpy(cdb.field, c->opcode, c->oplen);
|
|
||||||
if (c->dir == TO_DRIVE) {
|
|
||||||
dxfer_len = c->page->bytes;
|
|
||||||
e_direction = SCSI_MMC_DATA_WRITE;
|
|
||||||
} else if (c->dir == FROM_DRIVE) {
|
|
||||||
if (c->dxfer_len >= 0)
|
|
||||||
dxfer_len = c->dxfer_len;
|
|
||||||
else
|
|
||||||
dxfer_len = BUFFER_SIZE;
|
|
||||||
e_direction = SCSI_MMC_DATA_READ;
|
|
||||||
/* touch page so we can use valgrind */
|
|
||||||
memset(c->page->data, 0, BUFFER_SIZE);
|
|
||||||
} else {
|
|
||||||
dxfer_len = 0;
|
|
||||||
e_direction = SCSI_MMC_DATA_NONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* retry-loop */
|
|
||||||
start_time = time(NULL);
|
|
||||||
timeout_ms = 200000;
|
|
||||||
for(i = 0; !done; i++) {
|
|
||||||
|
|
||||||
i_status = mmc_run_cmd(p_cdio, timeout_ms, &cdb, e_direction,
|
|
||||||
dxfer_len, c->page->data);
|
|
||||||
sense_valid = mmc_last_cmd_sense(p_cdio, &sense_pt);
|
|
||||||
if (sense_valid >= 18) {
|
|
||||||
memcpy(c->sense, sense_pt,
|
|
||||||
sense_valid >= sizeof(c->sense) ?
|
|
||||||
sizeof(c->sense) : sense_valid );
|
|
||||||
spc_decode_sense(c->sense, 0, &key, &asc, &ascq);
|
|
||||||
} else
|
|
||||||
key = asc = ascq = 0;
|
|
||||||
if (sense_pt != NULL)
|
|
||||||
free(sense_pt);
|
|
||||||
|
|
||||||
/* Regrettably mmc_run_cmd() does not clearly distinguish between transport
|
|
||||||
failure and SCSI error reply.
|
|
||||||
This reaction here would be for transport failure:
|
|
||||||
|
|
||||||
if (i_status != 0 && i_status != DRIVER_OP_ERROR) {
|
|
||||||
libdax_msgs_submit(libdax_messenger,
|
|
||||||
d->global_index, 0x0002010c,
|
|
||||||
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
|
|
||||||
"Failed to transfer command to drive",
|
|
||||||
errno, 0);
|
|
||||||
sg_close_drive(d);
|
|
||||||
d->released = 1;
|
|
||||||
d->busy = BURN_DRIVE_IDLE;
|
|
||||||
c->error = 1;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
if ((!sense_valid) || (key == 0 && asc == 0 && ascq == 0)) {
|
|
||||||
memset(c->sense, 0, sizeof(c->sense));
|
|
||||||
if (i_status != 0) { /* set dummy sense */
|
|
||||||
/*LOGICAL UNIT NOT READY,
|
|
||||||
CAUSE NOT REPORTABLE*/
|
|
||||||
c->sense[0] = 0x70; /*Fixed format sense data*/
|
|
||||||
c->sense[2] = 0x02;
|
|
||||||
c->sense[12] = 0x04;
|
|
||||||
no_retry = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (i_status != 0 || (key || asc || ascq)) {
|
|
||||||
done = scsi_eval_cmd_outcome(d, c, fp, c->sense, 18,
|
|
||||||
0, start_time, timeout_ms, i, 2);
|
|
||||||
} else
|
|
||||||
done = 1;
|
|
||||||
|
|
||||||
} /* end of retry-loop */
|
|
||||||
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
CdIo_t *p_cdio;
|
|
||||||
char *tuple;
|
|
||||||
|
|
||||||
*bus_no = *host_no = *channel_no = *target_no = *lun_no = -1;
|
|
||||||
|
|
||||||
p_cdio = cdio_open(path, DRIVER_DEVICE);
|
|
||||||
if (p_cdio == NULL)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
/* Try whether a bus,host,channel,target,lun address tuple is
|
|
||||||
available */
|
|
||||||
tuple = (char *) cdio_get_arg(p_cdio, "scsi-tuple");
|
|
||||||
if (tuple != NULL) if (tuple[0]) {
|
|
||||||
sscanf(tuple, "%d,%d,%d,%d,%d",
|
|
||||||
bus_no, host_no, channel_no, target_no, lun_no);
|
|
||||||
}
|
|
||||||
|
|
||||||
cdio_destroy(p_cdio);
|
|
||||||
return (*bus_no >= 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/** Tells wether a text is a persistent address as listed by the enumeration
|
|
||||||
functions.
|
|
||||||
*/
|
|
||||||
int sg_is_enumerable_adr(char* adr)
|
|
||||||
{
|
|
||||||
burn_drive_enumerator_t idx;
|
|
||||||
int initialize = 1, ret;
|
|
||||||
char buf[64];
|
|
||||||
|
|
||||||
while(1) {
|
|
||||||
ret = sg_give_next_adr(&idx, buf, sizeof(buf), initialize);
|
|
||||||
initialize = 0;
|
|
||||||
if (ret <= 0)
|
|
||||||
break;
|
|
||||||
if (strcmp(adr, buf) == 0) {
|
|
||||||
sg_give_next_adr(&idx, buf, sizeof(buf), -1);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
sg_give_next_adr(&idx, buf, sizeof(buf), -1);
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef __FreeBSD__
|
|
||||||
#define Libburn_guess_block_devicE 1
|
|
||||||
#endif
|
|
||||||
#ifdef __FreeBSD_kernel__
|
|
||||||
#define Libburn_guess_block_devicE 1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef Libburn_guess_block_devicE
|
|
||||||
|
|
||||||
/* ts B00115 */
|
|
||||||
/* The FreeBSD implementation of burn_os_is_2k_seekrw().
|
|
||||||
On FreeBSD there are no block devices.
|
|
||||||
*/
|
|
||||||
static int freebsd_is_2k_seekrw(char *path, int flag)
|
|
||||||
{
|
|
||||||
struct stat stbuf;
|
|
||||||
char *spt;
|
|
||||||
int i, e;
|
|
||||||
|
|
||||||
if (stat(path, &stbuf) == -1)
|
|
||||||
return 0;
|
|
||||||
if (S_ISREG(stbuf.st_mode))
|
|
||||||
return 1;
|
|
||||||
if (!S_ISCHR(stbuf.st_mode))
|
|
||||||
return 0;
|
|
||||||
spt = strrchr(path, '/');
|
|
||||||
if (spt == NULL)
|
|
||||||
spt = path;
|
|
||||||
else
|
|
||||||
spt++;
|
|
||||||
e = strlen(spt);
|
|
||||||
for (i = strlen(spt) - 1; i > 0; i--)
|
|
||||||
if (spt[i] >= '0' && spt[i] <= '9')
|
|
||||||
e = i;
|
|
||||||
if (strncmp(spt, "da", e) == 0) /* SCSI disk. E.g. USB stick. */
|
|
||||||
return 1;
|
|
||||||
if (strncmp(spt, "cd", e) == 0) /* SCSI CD drive might be writeable. */
|
|
||||||
return 1;
|
|
||||||
if (strncmp(spt, "ad", e) == 0) /* IDE hard drive */
|
|
||||||
return 1;
|
|
||||||
if (strncmp(spt, "acd", e) == 0) /* IDE CD drive might be writeable */
|
|
||||||
return 1;
|
|
||||||
if (strncmp(spt, "fd", e) == 0) /* Floppy disk */
|
|
||||||
return 1;
|
|
||||||
if (strncmp(spt, "fla", e) == 0) /* Flash drive */
|
|
||||||
return 1;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* Libburn_guess_block_devicE */
|
|
||||||
|
|
||||||
|
|
||||||
/* 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)
|
|
||||||
{
|
|
||||||
#ifdef Libburn_guess_block_devicE
|
|
||||||
return freebsd_is_2k_seekrw(path, flag);
|
|
||||||
#else
|
|
||||||
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;
|
|
||||||
#endif /* ! Libburn_guess_block_devicE */
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/** Estimate the potential payload capacity of a file address.
|
|
||||||
@param path The address of the file to be examined. If it does not
|
|
||||||
exist yet, then the directory will be inquired.
|
|
||||||
@param bytes The pointed value gets modified, but only if an estimation is
|
|
||||||
possible.
|
|
||||||
@return -2 = cannot perform necessary operations on file object
|
|
||||||
-1 = neither path nor dirname of path exist
|
|
||||||
0 = could not estimate size capacity of file object
|
|
||||||
1 = estimation has been made, bytes was set
|
|
||||||
*/
|
|
||||||
int burn_os_stdio_capacity(char *path, off_t *bytes)
|
|
||||||
{
|
|
||||||
struct stat stbuf;
|
|
||||||
|
|
||||||
#ifdef Libburn_os_has_statvfS
|
|
||||||
struct statvfs vfsbuf;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
char testpath[4096], *cpt;
|
|
||||||
long blocks;
|
|
||||||
off_t add_size = 0;
|
|
||||||
|
|
||||||
testpath[0] = 0;
|
|
||||||
blocks = *bytes / 512;
|
|
||||||
if (stat(path, &stbuf) == -1) {
|
|
||||||
strcpy(testpath, path);
|
|
||||||
cpt = strrchr(testpath, '/');
|
|
||||||
if(cpt == NULL)
|
|
||||||
strcpy(testpath, ".");
|
|
||||||
else if(cpt == testpath)
|
|
||||||
testpath[1] = 0;
|
|
||||||
else
|
|
||||||
*cpt = 0;
|
|
||||||
if (stat(testpath, &stbuf) == -1)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
#ifdef __linux
|
|
||||||
|
|
||||||
/* GNU/Linux specific determination of block device size */
|
|
||||||
} else if(S_ISBLK(stbuf.st_mode)) {
|
|
||||||
int open_mode = O_RDONLY, fd, ret;
|
|
||||||
|
|
||||||
fd = open(path, open_mode);
|
|
||||||
if (fd == -1)
|
|
||||||
return -2;
|
|
||||||
ret = ioctl(fd, BLKGETSIZE, &blocks);
|
|
||||||
close(fd);
|
|
||||||
if (ret == -1)
|
|
||||||
return -2;
|
|
||||||
*bytes = ((off_t) blocks) * (off_t) 512;
|
|
||||||
|
|
||||||
#endif /* __linux */
|
|
||||||
|
|
||||||
#ifdef Libburn_is_on_freebsD
|
|
||||||
|
|
||||||
} else if(S_ISCHR(stbuf.st_mode)) {
|
|
||||||
int fd, ret;
|
|
||||||
|
|
||||||
fd = open(path, O_RDONLY);
|
|
||||||
if (fd == -1)
|
|
||||||
return -2;
|
|
||||||
ret = ioctl(fd, DIOCGMEDIASIZE, &add_size);
|
|
||||||
close(fd);
|
|
||||||
if (ret == -1)
|
|
||||||
return -2;
|
|
||||||
*bytes = add_size;
|
|
||||||
|
|
||||||
#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)) {
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
@ -1,23 +1,11 @@
|
|||||||
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||||
|
|
||||||
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
|
|
||||||
Copyright (c) 2006 - 2010 Thomas Schmitt <scdbackup@gmx.net>
|
|
||||||
Provided under GPL version 2 or later.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* <<< ts A91112 : experiments to get better speed with USB
|
|
||||||
#define Libburn_sgio_as_growisofS 1
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
||||||
This is the main operating system dependent SCSI part of libburn. It implements
|
This is the main operating system dependent SCSI part of libburn. It implements
|
||||||
the transport level aspects of SCSI control and command i/o.
|
the transport level aspects of SCSI control and command i/o.
|
||||||
|
|
||||||
Present implementation: GNU/Linux SCSI Generic (sg)
|
Present implementation: Linux SCSI Generic (sg)
|
||||||
|
|
||||||
|
|
||||||
PORTING:
|
PORTING:
|
||||||
@ -41,28 +29,12 @@ and of deriving the following system specific files from existing examples:
|
|||||||
Said sg-*.c operations are defined by a public function interface, which has
|
Said sg-*.c operations are defined by a public function interface, which has
|
||||||
to be implemented in a way that provides libburn with the desired services:
|
to be implemented in a way that provides libburn with the desired services:
|
||||||
|
|
||||||
sg_id_string() returns an id string of the SCSI transport adapter.
|
|
||||||
It may be called before initialization but then may
|
|
||||||
return only a preliminary id.
|
|
||||||
|
|
||||||
sg_initialize() performs global initialization of the SCSI transport
|
|
||||||
adapter and eventually needed operating system
|
|
||||||
facilities. Checks for compatibility of supporting
|
|
||||||
software components.
|
|
||||||
|
|
||||||
sg_shutdown() performs global finalizations and releases golbally
|
|
||||||
aquired resources.
|
|
||||||
|
|
||||||
sg_give_next_adr() iterates over the set of potentially useful drive
|
sg_give_next_adr() iterates over the set of potentially useful drive
|
||||||
address strings.
|
address strings.
|
||||||
|
|
||||||
scsi_enumerate_drives() brings all available, not-whitelist-banned, and
|
scsi_enumerate_drives() brings all available, not-whitelist-banned, and
|
||||||
accessible drives into libburn's list of drives.
|
accessible drives into libburn's list of drives.
|
||||||
|
|
||||||
sg_dispose_drive() finalizes adapter specifics of struct burn_drive
|
|
||||||
on destruction. Releases resources which were aquired
|
|
||||||
underneath scsi_enumerate_drives().
|
|
||||||
|
|
||||||
sg_drive_is_open() tells wether libburn has the given drive in use.
|
sg_drive_is_open() tells wether libburn has the given drive in use.
|
||||||
|
|
||||||
sg_grab() opens the drive for SCSI commands and ensures
|
sg_grab() opens the drive for SCSI commands and ensures
|
||||||
@ -76,25 +48,8 @@ sg_issue_command() sends a SCSI command to the drive, receives reply,
|
|||||||
|
|
||||||
sg_obtain_scsi_adr() tries to obtain SCSI address parameters.
|
sg_obtain_scsi_adr() tries to obtain SCSI address parameters.
|
||||||
|
|
||||||
|
|
||||||
burn_os_is_2k_seekrw() tells whether the given path leads to a file object
|
|
||||||
that can be used in 2 kB granularity by lseek(2) and
|
|
||||||
read(2), and possibly write(2) if not read-only.
|
|
||||||
E.g. a USB stick or a hard disk.
|
|
||||||
|
|
||||||
burn_os_stdio_capacity() estimates the emulated media space of stdio-drives.
|
burn_os_stdio_capacity() estimates the emulated media space of stdio-drives.
|
||||||
|
|
||||||
burn_os_open_track_src() opens a disk file in a way that allows best
|
|
||||||
throughput with file reading and/or SCSI write command
|
|
||||||
transmission.
|
|
||||||
|
|
||||||
burn_os_alloc_buffer() allocates a memory area that is suitable for file
|
|
||||||
descriptors issued by burn_os_open_track_src().
|
|
||||||
The buffer size may be rounded up for alignment
|
|
||||||
reasons.
|
|
||||||
|
|
||||||
burn_os_free_buffer() delete a buffer obtained by burn_os_alloc_buffer().
|
|
||||||
|
|
||||||
|
|
||||||
Porting hints are marked by the text "PORTING:".
|
Porting hints are marked by the text "PORTING:".
|
||||||
Send feedback to libburn-hackers@pykix.org .
|
Send feedback to libburn-hackers@pykix.org .
|
||||||
@ -104,20 +59,9 @@ 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 ------ */
|
||||||
|
|
||||||
|
|
||||||
#ifdef Libburn_read_o_direcT
|
|
||||||
# ifndef _GNU_SOURCE
|
|
||||||
# define _GNU_SOURCE
|
|
||||||
# endif
|
|
||||||
#endif /* Libburn_read_o_direcT */
|
|
||||||
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@ -136,9 +80,6 @@ Hint: You should also look into sg-freebsd-port.c, which is a younger and
|
|||||||
/* for ioctl(BLKGETSIZE) */
|
/* for ioctl(BLKGETSIZE) */
|
||||||
#include <linux/fs.h>
|
#include <linux/fs.h>
|
||||||
|
|
||||||
/* for mmap() */
|
|
||||||
#include <sys/mman.h>
|
|
||||||
|
|
||||||
|
|
||||||
#include <scsi/sg.h>
|
#include <scsi/sg.h>
|
||||||
/* Values within sg_io_hdr_t indicating success after ioctl(SG_IO) : */
|
/* Values within sg_io_hdr_t indicating success after ioctl(SG_IO) : */
|
||||||
@ -217,17 +158,9 @@ static char linux_ata_device_family[80] = {"/dev/hd%c"};
|
|||||||
static int linux_ata_enumerate_verbous = 0;
|
static int linux_ata_enumerate_verbous = 0;
|
||||||
|
|
||||||
|
|
||||||
/* 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_linux_retry_usleeP 100000
|
|
||||||
#define Libburn_sg_linux_retry_incR 100000
|
|
||||||
|
|
||||||
|
|
||||||
/** PORTING : ------ libburn portable headers and definitions ----- */
|
/** PORTING : ------ libburn portable headers and definitions ----- */
|
||||||
|
|
||||||
#include "libburn.h"
|
|
||||||
#include "transport.h"
|
#include "transport.h"
|
||||||
#include "drive.h"
|
#include "drive.h"
|
||||||
#include "sg.h"
|
#include "sg.h"
|
||||||
@ -256,25 +189,17 @@ static void enumerate_common(char *fname, int bus_no, int host_no,
|
|||||||
|
|
||||||
|
|
||||||
/* ts A60813 : storage objects are in libburn/init.c
|
/* ts A60813 : storage objects are in libburn/init.c
|
||||||
whether to use O_EXCL with open(2) of devices
|
wether to use O_EXCL with open(2) of devices
|
||||||
whether to use fcntl(,F_SETLK,) after open(2) of devices
|
wether to use fcntl(,F_SETLK,) after open(2) of devices
|
||||||
what device family to use : 0=default, 1=sr, 2=scd, (3=st), 4=sg
|
what device family to use : 0=default, 1=sr, 2=scd, (3=st), 4=sg
|
||||||
whether to use O_NOBLOCK with open(2) on devices
|
wether to use O_NOBLOCK with open(2) on devices
|
||||||
whether to take O_EXCL rejection as fatal error
|
wether to take O_EXCL rejection as fatal error */
|
||||||
*/
|
|
||||||
extern int burn_sg_open_o_excl;
|
extern int burn_sg_open_o_excl;
|
||||||
extern int burn_sg_fcntl_f_setlk;
|
extern int burn_sg_fcntl_f_setlk;
|
||||||
extern int burn_sg_use_family;
|
extern int burn_sg_use_family;
|
||||||
extern int burn_sg_open_o_nonblock;
|
extern int burn_sg_open_o_nonblock;
|
||||||
extern int burn_sg_open_abort_busy;
|
extern int burn_sg_open_abort_busy;
|
||||||
|
|
||||||
/* ts A91111 :
|
|
||||||
whether to log SCSI commands:
|
|
||||||
bit0= log in /tmp/libburn_sg_command_log
|
|
||||||
bit1= log to stderr
|
|
||||||
bit2= flush every line
|
|
||||||
*/
|
|
||||||
extern int burn_sg_log_scsi;
|
|
||||||
|
|
||||||
/* ts A60821
|
/* ts A60821
|
||||||
debug: for tracing calls which might use open drive fds
|
debug: for tracing calls which might use open drive fds
|
||||||
@ -545,7 +470,7 @@ static int sg_fcntl_lock(int *fd, char *fd_name, int l_type, int verbous)
|
|||||||
/* ts A60926 */
|
/* ts A60926 */
|
||||||
static int sg_open_drive_fd(char *fname, int scan_mode)
|
static int sg_open_drive_fd(char *fname, int scan_mode)
|
||||||
{
|
{
|
||||||
int open_mode = O_RDWR, fd, tries= 0;
|
int open_mode = O_RDWR, fd;
|
||||||
char msg[81];
|
char msg[81];
|
||||||
|
|
||||||
/* ts A70409 : DDLP-B */
|
/* ts A70409 : DDLP-B */
|
||||||
@ -577,8 +502,7 @@ static int sg_open_drive_fd(char *fname, int scan_mode)
|
|||||||
"libburn: experimental: O_EXCL= %d , O_NDELAY= %d\n",
|
"libburn: experimental: O_EXCL= %d , O_NDELAY= %d\n",
|
||||||
!!(open_mode&O_EXCL),!!(open_mode&O_NDELAY));
|
!!(open_mode&O_EXCL),!!(open_mode&O_NDELAY));
|
||||||
*/
|
*/
|
||||||
|
|
||||||
try_open:;
|
|
||||||
fd = open(fname, open_mode);
|
fd = open(fname, open_mode);
|
||||||
if (fd == -1) {
|
if (fd == -1) {
|
||||||
/* <<< debugging
|
/* <<< debugging
|
||||||
@ -587,17 +511,6 @@ try_open:;
|
|||||||
fname,errno);
|
fname,errno);
|
||||||
*/
|
*/
|
||||||
if (errno == EBUSY) {
|
if (errno == EBUSY) {
|
||||||
tries++;
|
|
||||||
|
|
||||||
/* <<< debugging
|
|
||||||
fprintf(stderr,
|
|
||||||
"\nlibburn_DEBUG: EBUSY , tries= %d\n", tries);
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (tries < 4) {
|
|
||||||
usleep(2000000);
|
|
||||||
goto try_open;
|
|
||||||
}
|
|
||||||
sg_handle_busy_device(fname, errno);
|
sg_handle_busy_device(fname, errno);
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
@ -731,6 +644,10 @@ failed:;
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#define Libburn_drive_new_deaL 1
|
||||||
|
|
||||||
|
#ifdef Libburn_drive_new_deaL
|
||||||
|
|
||||||
/* ts A80731 */
|
/* ts A80731 */
|
||||||
static int is_ata_drive(char *fname)
|
static int is_ata_drive(char *fname)
|
||||||
{
|
{
|
||||||
@ -876,7 +793,7 @@ static int is_scsi_drive(char *fname, int *bus_no, int *host_no,
|
|||||||
if (ret<=0) {
|
if (ret<=0) {
|
||||||
if (linux_sg_enumerate_debug)
|
if (linux_sg_enumerate_debug)
|
||||||
fprintf(stderr, "cannot lock siblings\n");
|
fprintf(stderr, "cannot lock siblings\n");
|
||||||
sg_handle_busy_device(fname, 0);
|
sg_handle_busy_device(fname, 0);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
/* the final occupation will be done in sg_grab() */
|
/* the final occupation will be done in sg_grab() */
|
||||||
@ -896,12 +813,23 @@ static int is_scsi_drive(char *fname, int *bus_no, int *host_no,
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif /* Libburn_drive_new_deaL */
|
||||||
|
|
||||||
/** Speciality of GNU/Linux: detect non-SCSI ATAPI (EIDE) which will from
|
|
||||||
|
/** Speciality of Linux: detect non-SCSI ATAPI (EIDE) which will from
|
||||||
then on used used via generic SCSI as is done with (emulated) SCSI drives */
|
then on used used via generic SCSI as is done with (emulated) SCSI drives */
|
||||||
static void ata_enumerate(void)
|
static void ata_enumerate(void)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
#ifdef Libburn_drive_new_deaL
|
||||||
|
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
#else
|
||||||
|
struct hd_driveid tm;
|
||||||
|
int fd;
|
||||||
|
#endif
|
||||||
|
|
||||||
int i;
|
int i;
|
||||||
char fname[10];
|
char fname[10];
|
||||||
|
|
||||||
@ -923,11 +851,57 @@ static void ata_enumerate(void)
|
|||||||
fprintf(stderr, "not in whitelist\n");
|
fprintf(stderr, "not in whitelist\n");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef Libburn_drive_new_deaL
|
||||||
|
|
||||||
ret = is_ata_drive(fname);
|
ret = is_ata_drive(fname);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
break;
|
break;
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
#else /* Libburn_drive_new_deaL */
|
||||||
|
|
||||||
|
fd = sg_open_drive_fd(fname, 1);
|
||||||
|
if (fd == -1) {
|
||||||
|
if (linux_ata_enumerate_verbous)
|
||||||
|
fprintf(stderr,"open failed, errno=%d '%s'\n",
|
||||||
|
errno, strerror(errno));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* found a drive */
|
||||||
|
ioctl(fd, HDIO_GET_IDENTITY, &tm);
|
||||||
|
|
||||||
|
/* not atapi */
|
||||||
|
if (!(tm.config & 0x8000) || (tm.config & 0x4000)) {
|
||||||
|
if (linux_ata_enumerate_verbous)
|
||||||
|
fprintf(stderr, "not marked as ATAPI\n");
|
||||||
|
sg_close_drive_fd(fname, -1, &fd, 0);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* if SG_IO fails on an atapi device, we should stop trying to
|
||||||
|
use hd* devices */
|
||||||
|
if (sgio_test(fd) == -1) {
|
||||||
|
if (linux_ata_enumerate_verbous)
|
||||||
|
fprintf(stderr,
|
||||||
|
"FATAL: sgio_test() failed: errno=%d '%s'\n",
|
||||||
|
errno, strerror(errno));
|
||||||
|
sg_close_drive_fd(fname, -1, &fd, 0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (sg_close_drive_fd(fname, -1, &fd, 1) <= 0) {
|
||||||
|
if (linux_ata_enumerate_verbous)
|
||||||
|
fprintf(stderr,
|
||||||
|
"cannot close properly, errno=%d '%s'\n",
|
||||||
|
errno, strerror(errno));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* Libburn_drive_new_deaL */
|
||||||
|
|
||||||
|
|
||||||
if (linux_ata_enumerate_verbous)
|
if (linux_ata_enumerate_verbous)
|
||||||
fprintf(stderr, "accepting as drive without SCSI address\n");
|
fprintf(stderr, "accepting as drive without SCSI address\n");
|
||||||
enumerate_common(fname, -1, -1, -1, -1, -1);
|
enumerate_common(fname, -1, -1, -1, -1, -1);
|
||||||
@ -938,6 +912,15 @@ static void ata_enumerate(void)
|
|||||||
/** Detects (probably emulated) SCSI drives */
|
/** Detects (probably emulated) SCSI drives */
|
||||||
static void sg_enumerate(void)
|
static void sg_enumerate(void)
|
||||||
{
|
{
|
||||||
|
#ifdef Libburn_drive_new_deaL
|
||||||
|
|
||||||
|
#else
|
||||||
|
struct sg_scsi_id sid;
|
||||||
|
int fd, sibling_fds[BURN_OS_SG_MAX_SIBLINGS], sibling_count= 0;
|
||||||
|
char sibling_fnames[BURN_OS_SG_MAX_SIBLINGS][BURN_OS_SG_MAX_NAMELEN];
|
||||||
|
int sid_ret = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
int i, ret;
|
int i, ret;
|
||||||
int bus_no= -1, host_no= -1, channel_no= -1, target_no= -1, lun_no= -1;
|
int bus_no= -1, host_no= -1, channel_no= -1, target_no= -1, lun_no= -1;
|
||||||
char fname[17];
|
char fname[17];
|
||||||
@ -967,6 +950,9 @@ static void sg_enumerate(void)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef Libburn_drive_new_deaL
|
||||||
|
|
||||||
ret = is_scsi_drive(fname, &bus_no, &host_no, &channel_no,
|
ret = is_scsi_drive(fname, &bus_no, &host_no, &channel_no,
|
||||||
&target_no, &lun_no);
|
&target_no, &lun_no);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
@ -979,10 +965,132 @@ static void sg_enumerate(void)
|
|||||||
enumerate_common(fname, bus_no, host_no, channel_no,
|
enumerate_common(fname, bus_no, host_no, channel_no,
|
||||||
target_no, lun_no);
|
target_no, lun_no);
|
||||||
|
|
||||||
|
#else /* Libburn_drive_new_deaL */
|
||||||
|
|
||||||
|
/* ts A60927 */
|
||||||
|
fd = sg_open_drive_fd(fname, 1);
|
||||||
|
if (fd == -1) {
|
||||||
|
if (linux_sg_enumerate_debug)
|
||||||
|
fprintf(stderr, "open failed, errno=%d '%s'\n",
|
||||||
|
errno, strerror(errno));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* found a drive */
|
||||||
|
sid_ret = ioctl(fd, SG_GET_SCSI_ID, &sid);
|
||||||
|
if (sid_ret == -1) {
|
||||||
|
sid.scsi_id = -1; /* mark SCSI address as invalid */
|
||||||
|
if(linux_sg_enumerate_debug)
|
||||||
|
fprintf(stderr,
|
||||||
|
"ioctl(SG_GET_SCSI_ID) failed, errno=%d '%s' , ",
|
||||||
|
errno, strerror(errno));
|
||||||
|
|
||||||
|
if (sgio_test(fd) == -1) {
|
||||||
|
if (linux_sg_enumerate_debug)
|
||||||
|
fprintf(stderr,
|
||||||
|
"FATAL: sgio_test() failed: errno=%d '%s'",
|
||||||
|
errno, strerror(errno));
|
||||||
|
|
||||||
|
sg_close_drive_fd(fname, -1, &fd, 0);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef CDROM_DRIVE_STATUS
|
||||||
|
/* ts A61211 : not widening old acceptance range */
|
||||||
|
if (strcmp(linux_sg_device_family,"/dev/sg%d") != 0) {
|
||||||
|
/* http://developer.osdl.org/dev/robustmutexes/
|
||||||
|
src/fusyn.hg/Documentation/ioctl/cdrom.txt */
|
||||||
|
sid_ret = ioctl(fd, CDROM_DRIVE_STATUS, 0);
|
||||||
|
if(linux_sg_enumerate_debug)
|
||||||
|
fprintf(stderr,
|
||||||
|
"ioctl(CDROM_DRIVE_STATUS) = %d , ",
|
||||||
|
sid_ret);
|
||||||
|
if (sid_ret != -1 && sid_ret != CDS_NO_INFO)
|
||||||
|
sid.scsi_type = TYPE_ROM;
|
||||||
|
else
|
||||||
|
sid_ret = -1;
|
||||||
|
}
|
||||||
|
#endif /* CDROM_DRIVE_STATUS */
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef SCSI_IOCTL_GET_BUS_NUMBER
|
||||||
|
/* Hearsay A61005 */
|
||||||
|
if (ioctl(fd, SCSI_IOCTL_GET_BUS_NUMBER, &bus_no) == -1)
|
||||||
|
bus_no = -1;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (sg_close_drive_fd(fname, -1, &fd,
|
||||||
|
sid.scsi_type == TYPE_ROM ) <= 0) {
|
||||||
|
if (linux_sg_enumerate_debug)
|
||||||
|
fprintf(stderr,
|
||||||
|
"cannot close properly, errno=%d '%s'\n",
|
||||||
|
errno, strerror(errno));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if ( (sid_ret == -1 || sid.scsi_type != TYPE_ROM)
|
||||||
|
&& !linux_sg_accept_any_type) {
|
||||||
|
if (linux_sg_enumerate_debug)
|
||||||
|
fprintf(stderr, "sid.scsi_type = %d (!= TYPE_ROM)\n",
|
||||||
|
sid.scsi_type);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sid_ret == -1 || sid.scsi_id < 0) {
|
||||||
|
/* ts A61211 : employ a more general ioctl */
|
||||||
|
ret = sg_obtain_scsi_adr(fname, &bus_no, &host_no,
|
||||||
|
&channel_no, &target_no, &lun_no);
|
||||||
|
if (ret>0) {
|
||||||
|
sid.host_no = host_no;
|
||||||
|
sid.channel = channel_no;
|
||||||
|
sid.scsi_id = target_no;
|
||||||
|
sid.lun = lun_no;
|
||||||
|
} else {
|
||||||
|
if (linux_sg_enumerate_debug)
|
||||||
|
fprintf(stderr,
|
||||||
|
"sg_obtain_scsi_adr() failed\n");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ts A60927 : trying to do locking with growisofs */
|
||||||
|
if(burn_sg_open_o_excl>1) {
|
||||||
|
ret = sg_open_scsi_siblings(
|
||||||
|
fname, -1, sibling_fds, sibling_fnames,
|
||||||
|
&sibling_count,
|
||||||
|
sid.host_no, sid.channel,
|
||||||
|
sid.scsi_id, sid.lun);
|
||||||
|
if (ret<=0) {
|
||||||
|
if (linux_sg_enumerate_debug)
|
||||||
|
fprintf(stderr, "cannot lock siblings\n");
|
||||||
|
sg_handle_busy_device(fname, 0);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
/* the final occupation will be done in sg_grab() */
|
||||||
|
sg_release_siblings(sibling_fds, sibling_fnames,
|
||||||
|
&sibling_count);
|
||||||
|
}
|
||||||
|
#ifdef SCSI_IOCTL_GET_BUS_NUMBER
|
||||||
|
if(bus_no == -1)
|
||||||
|
bus_no = 1000 * (sid.host_no + 1) + sid.channel;
|
||||||
|
#else
|
||||||
|
bus_no = sid.host_no;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (linux_sg_enumerate_debug)
|
||||||
|
fprintf(stderr, "accepting as SCSI %d,%d,%d,%d bus=%d\n",
|
||||||
|
sid.host_no, sid.channel, sid.scsi_id, sid.lun,
|
||||||
|
bus_no);
|
||||||
|
enumerate_common(fname, bus_no, sid.host_no, sid.channel,
|
||||||
|
sid.scsi_id, sid.lun);
|
||||||
|
#endif /* Libburn_drive_new_deaL */
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef Libburn_drive_new_deaL
|
||||||
|
|
||||||
|
|
||||||
/* ts A80805 : eventually produce the other official name of a device file */
|
/* ts A80805 : eventually produce the other official name of a device file */
|
||||||
static int fname_other_name(char *fname, char other_name[80], int flag)
|
static int fname_other_name(char *fname, char other_name[80], int flag)
|
||||||
@ -1182,6 +1290,8 @@ static int add_proc_info_drives(int flag)
|
|||||||
return 1 + count;
|
return 1 + count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif /* Libburn_drive_new_deaL */
|
||||||
|
|
||||||
|
|
||||||
/* ts A61115 */
|
/* ts A61115 */
|
||||||
/* ----------------------------------------------------------------------- */
|
/* ----------------------------------------------------------------------- */
|
||||||
@ -1215,7 +1325,7 @@ static void enumerate_common(char *fname, int bus_no, int host_no,
|
|||||||
|
|
||||||
/* PORTING: ------------------- non portable part --------------- */
|
/* PORTING: ------------------- non portable part --------------- */
|
||||||
|
|
||||||
/* Operating system adapter is GNU/Linux Generic SCSI (sg) */
|
/* Operating system adapter is Linux Generic SCSI (sg) */
|
||||||
/* Adapter specific handles and data */
|
/* Adapter specific handles and data */
|
||||||
out.fd = -1337;
|
out.fd = -1337;
|
||||||
out.sibling_count = 0;
|
out.sibling_count = 0;
|
||||||
@ -1241,63 +1351,8 @@ static void enumerate_common(char *fname, int bus_no, int host_no,
|
|||||||
/* ------------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------------ */
|
||||||
|
|
||||||
|
|
||||||
/** Returns the id string of the SCSI transport adapter and eventually
|
|
||||||
needed operating system facilities.
|
|
||||||
This call is usable even if sg_initialize() was not called yet. In that
|
|
||||||
case a preliminary constant message might be issued if detailed info is
|
|
||||||
not available yet.
|
|
||||||
@param msg returns id string
|
|
||||||
@param flag unused yet, submit 0
|
|
||||||
@return 1 = success, <=0 = failure
|
|
||||||
*/
|
|
||||||
int sg_id_string(char msg[1024], int flag)
|
|
||||||
{
|
|
||||||
strcpy(msg, "internal GNU/Linux SG_IO adapter sg-linux");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/** Performs global initialization of the SCSI transport adapter and eventually
|
|
||||||
needed operating system facilities. Checks for compatibility supporting
|
|
||||||
software components.
|
|
||||||
@param msg returns ids and/or error messages of eventual helpers
|
|
||||||
@param flag unused yet, submit 0
|
|
||||||
@return 1 = success, <=0 = failure
|
|
||||||
*/
|
|
||||||
int sg_initialize(char msg[1024], int flag)
|
|
||||||
{
|
|
||||||
return sg_id_string(msg, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/** Performs global finalization of the SCSI transport adapter and eventually
|
|
||||||
needed operating system facilities. Releases globally aquired resources.
|
|
||||||
@param flag unused yet, submit 0
|
|
||||||
@return 1 = success, <=0 = failure
|
|
||||||
*/
|
|
||||||
int sg_shutdown(int flag)
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/** Finalizes BURN_OS_TRANSPORT_DRIVE_ELEMENTS, the components of
|
|
||||||
struct burn_drive which are defined in os-*.h.
|
|
||||||
The eventual initialization of those components was made underneath
|
|
||||||
scsi_enumerate_drives().
|
|
||||||
This will be called when a burn_drive gets disposed.
|
|
||||||
@param d the drive to be finalized
|
|
||||||
@param flag unused yet, submit 0
|
|
||||||
@return 1 = success, <=0 = failure
|
|
||||||
*/
|
|
||||||
int sg_dispose_drive(struct burn_drive *d, int flag)
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/** PORTING:
|
/** PORTING:
|
||||||
In this GNU/Linux implementation, this function mirrors the enumeration
|
In this Linux implementation, this function mirrors the enumeration
|
||||||
done in sg_enumerate and ata_enumerate(). It would be better to base those
|
done in sg_enumerate and ata_enumerate(). It would be better to base those
|
||||||
functions on this sg_give_next_adr() but the situation is not inviting.
|
functions on this sg_give_next_adr() but the situation is not inviting.
|
||||||
*/
|
*/
|
||||||
@ -1394,7 +1449,7 @@ return_1_pre_proc:;
|
|||||||
libburn's list of drives.
|
libburn's list of drives.
|
||||||
*/
|
*/
|
||||||
/** PORTING:
|
/** PORTING:
|
||||||
If not stricken with an incompletely unified situation like in GNU/Linux
|
If not stricken with an incompletely unified situation like in Linux
|
||||||
one would rather implement this by a loop calling sg_give_next_adr().
|
one would rather implement this by a loop calling sg_give_next_adr().
|
||||||
If needed with your sg_give_next_adr() results, do a test for existence
|
If needed with your sg_give_next_adr() results, do a test for existence
|
||||||
and accessability. If burn activities are prone to external interference
|
and accessability. If burn activities are prone to external interference
|
||||||
@ -1408,18 +1463,27 @@ return_1_pre_proc:;
|
|||||||
/* ts A61115: replacing call to sg-implementation internals from drive.c */
|
/* ts A61115: replacing call to sg-implementation internals from drive.c */
|
||||||
int scsi_enumerate_drives(void)
|
int scsi_enumerate_drives(void)
|
||||||
{
|
{
|
||||||
int ret;
|
|
||||||
|
|
||||||
|
#ifdef Libburn_drive_new_deaL
|
||||||
|
int ret;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef Libburn_drive_new_deaL
|
||||||
/* Direct examination of eventually single whitelisted name */
|
/* Direct examination of eventually single whitelisted name */
|
||||||
ret = single_enumerate(0);
|
ret = single_enumerate(0);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return -1;
|
return -1;
|
||||||
if (ret > 0)
|
if (ret > 0)
|
||||||
return 1;
|
return 1;
|
||||||
|
#endif /* Libburn_drive_new_deaL */
|
||||||
|
|
||||||
sg_enumerate();
|
sg_enumerate();
|
||||||
ata_enumerate();
|
ata_enumerate();
|
||||||
|
|
||||||
|
#ifdef Libburn_drive_new_deaL
|
||||||
add_proc_info_drives(0);
|
add_proc_info_drives(0);
|
||||||
|
#endif /* Libburn_drive_new_deaL */
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1449,7 +1513,6 @@ int sg_drive_is_open(struct burn_drive * d)
|
|||||||
int sg_grab(struct burn_drive *d)
|
int sg_grab(struct burn_drive *d)
|
||||||
{
|
{
|
||||||
int fd, os_errno= 0, ret;
|
int fd, os_errno= 0, ret;
|
||||||
int max_tries = 3, tries = 0;
|
|
||||||
|
|
||||||
/* ts A60813 */
|
/* ts A60813 */
|
||||||
int open_mode = O_RDWR;
|
int open_mode = O_RDWR;
|
||||||
@ -1483,7 +1546,6 @@ int sg_grab(struct burn_drive *d)
|
|||||||
value -1 of open(2) war used. */
|
value -1 of open(2) war used. */
|
||||||
if(! burn_drive_is_open(d)) {
|
if(! burn_drive_is_open(d)) {
|
||||||
|
|
||||||
try_open:;
|
|
||||||
/* ts A60821
|
/* ts A60821
|
||||||
<<< debug: for tracing calls which might use open drive fds */
|
<<< debug: for tracing calls which might use open drive fds */
|
||||||
mmc_function_spy(NULL, "sg_grab ----------- opening");
|
mmc_function_spy(NULL, "sg_grab ----------- opening");
|
||||||
@ -1517,19 +1579,13 @@ try_open:;
|
|||||||
fcntl(fd, F_SETOWN, getpid());
|
fcntl(fd, F_SETOWN, getpid());
|
||||||
d->released = 0;
|
d->released = 0;
|
||||||
return 1;
|
return 1;
|
||||||
} else if (errno == EBUSY)
|
}
|
||||||
goto drive_is_in_use;
|
|
||||||
libdax_msgs_submit(libdax_messenger, d->global_index, 0x00020003,
|
libdax_msgs_submit(libdax_messenger, d->global_index, 0x00020003,
|
||||||
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
|
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
"Could not grab drive", os_errno, 0);
|
"Could not grab drive", os_errno, 0);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
drive_is_in_use:;
|
drive_is_in_use:;
|
||||||
tries++;
|
|
||||||
if (tries < max_tries) {
|
|
||||||
usleep(2000000);
|
|
||||||
goto try_open;
|
|
||||||
}
|
|
||||||
libdax_msgs_submit(libdax_messenger, d->global_index,
|
libdax_msgs_submit(libdax_messenger, d->global_index,
|
||||||
0x00020003,
|
0x00020003,
|
||||||
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
|
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
@ -1567,22 +1623,90 @@ int sg_release(struct burn_drive *d)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** ts A70518:
|
||||||
|
Debugging log facility. Controlled by existence of macros:
|
||||||
|
Libburn_log_sg_commandS enables logging to file
|
||||||
|
/tmp/libburn_sg_command_log
|
||||||
|
Libburn_fflush_log_sg_commandS enables fflush after each output line
|
||||||
|
Libburn_log_sg_command_stderR enables additional log to stderr
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
#define Libburn_log_sg_commandS 1
|
||||||
|
#define Libburn_fflush_log_sg_commandS 1
|
||||||
|
#define Libburn_log_sg_command_stderR 1
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef Libburn_log_sg_commandS
|
||||||
|
|
||||||
|
/** Logs command (before execution) */
|
||||||
|
static int sg_log_cmd(struct command *c, FILE *fp, int flag)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (fp != NULL) {
|
||||||
|
for(i = 0; i < 16 && i < c->oplen; i++)
|
||||||
|
fprintf(fp,"%2.2x ", c->opcode[i]);
|
||||||
|
fprintf(fp, "\n");
|
||||||
|
#ifdef Libburn_fflush_log_sg_commandS
|
||||||
|
fflush(fp);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
if (fp == stderr)
|
||||||
|
return 1;
|
||||||
|
#ifdef Libburn_log_sg_command_stderR
|
||||||
|
sg_log_cmd(c, stderr, flag);
|
||||||
|
#endif
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** 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) {
|
||||||
|
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
|
||||||
|
fprintf(fp,"%6d ms\n", s->duration);
|
||||||
|
#ifdef Libburn_fflush_log_sg_commandS
|
||||||
|
fflush(fp);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
if (fp == stderr)
|
||||||
|
return 1;
|
||||||
|
#ifdef Libburn_log_sg_command_stderR
|
||||||
|
sg_log_err(c, stderr, s, flag);
|
||||||
|
#endif
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* Libburn_log_sg_commandS */
|
||||||
|
|
||||||
|
|
||||||
/** Sends a SCSI command to the drive, receives reply and evaluates wether
|
/** Sends a SCSI command to the drive, receives reply and evaluates wether
|
||||||
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.
|
||||||
The callers get notified by c->error. An SCSI failure which leads not to
|
The callers get notified by c->error. An SCSI failure which leads not to
|
||||||
a retry shall be notified via scsi_notify_error().
|
a retry shall be notified via scsi_notify_error().
|
||||||
|
The Libburn_log_sg_commandS facility might be of help when problems with
|
||||||
|
a drive have to be examined. It shall stay disabled for normal use.
|
||||||
@return: 1 success , <=0 failure
|
@return: 1 success , <=0 failure
|
||||||
*/
|
*/
|
||||||
int sg_issue_command(struct burn_drive *d, struct command *c)
|
int sg_issue_command(struct burn_drive *d, struct command *c)
|
||||||
{
|
{
|
||||||
int done = 0, no_c_page = 0, i;
|
int done = 0, no_c_page = 0;
|
||||||
int err;
|
int err;
|
||||||
time_t start_time;
|
|
||||||
sg_io_hdr_t s;
|
sg_io_hdr_t s;
|
||||||
|
|
||||||
|
#ifdef Libburn_log_sg_commandS
|
||||||
/* ts A61030 */
|
/* ts A61030 */
|
||||||
static FILE *fp= NULL;
|
static FILE *fp= NULL;
|
||||||
|
#endif /* Libburn_log_sg_commandS */
|
||||||
|
|
||||||
/* <<< ts A60821
|
/* <<< ts A60821
|
||||||
debug: for tracing calls which might use open drive fds */
|
debug: for tracing calls which might use open drive fds */
|
||||||
@ -1591,16 +1715,15 @@ int sg_issue_command(struct burn_drive *d, struct command *c)
|
|||||||
d->fd,d->released);
|
d->fd,d->released);
|
||||||
mmc_function_spy(NULL, buf);
|
mmc_function_spy(NULL, buf);
|
||||||
|
|
||||||
|
#ifdef Libburn_log_sg_commandS
|
||||||
/* ts A61030 */
|
/* ts A61030 */
|
||||||
if (burn_sg_log_scsi & 1) {
|
if(fp==NULL) {
|
||||||
if (fp == NULL) {
|
fp= fopen("/tmp/libburn_sg_command_log","a");
|
||||||
fp= fopen("/tmp/libburn_sg_command_log", "a");
|
fprintf(fp,"\n-----------------------------------------\n");
|
||||||
fprintf(fp,
|
|
||||||
"\n-----------------------------------------\n");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (burn_sg_log_scsi & 3)
|
sg_log_cmd(c,fp,0);
|
||||||
scsi_log_cmd(c,fp,0);
|
#endif /* Libburn_log_sg_commandS */
|
||||||
|
|
||||||
|
|
||||||
/* ts A61010 : with no fd there is no chance to send an ioctl */
|
/* ts A61010 : with no fd there is no chance to send an ioctl */
|
||||||
if (d->fd < 0) {
|
if (d->fd < 0) {
|
||||||
@ -1613,13 +1736,6 @@ int sg_issue_command(struct burn_drive *d, struct command *c)
|
|||||||
|
|
||||||
s.interface_id = 'S';
|
s.interface_id = 'S';
|
||||||
|
|
||||||
#ifdef Libburn_sgio_as_growisofS
|
|
||||||
/* ??? ts A91112 : does this speed up USB ? (from growisofs)
|
|
||||||
--- did not help
|
|
||||||
*/
|
|
||||||
s.flags = SG_FLAG_DIRECT_IO;
|
|
||||||
#endif /* Libburn_sgio_as_growisofS */
|
|
||||||
|
|
||||||
if (c->dir == TO_DRIVE)
|
if (c->dir == TO_DRIVE)
|
||||||
s.dxfer_direction = SG_DXFER_TO_DEV;
|
s.dxfer_direction = SG_DXFER_TO_DEV;
|
||||||
else if (c->dir == FROM_DRIVE)
|
else if (c->dir == FROM_DRIVE)
|
||||||
@ -1668,8 +1784,7 @@ int sg_issue_command(struct burn_drive *d, struct command *c)
|
|||||||
}
|
}
|
||||||
s.usr_ptr = c;
|
s.usr_ptr = c;
|
||||||
|
|
||||||
start_time = time(NULL);
|
do {
|
||||||
for(i = 0; !done; i++) {
|
|
||||||
err = ioctl(d->fd, SG_IO, &s);
|
err = ioctl(d->fd, SG_IO, &s);
|
||||||
|
|
||||||
/* ts A61010 */
|
/* ts A61010 */
|
||||||
@ -1686,12 +1801,34 @@ int sg_issue_command(struct burn_drive *d, struct command *c)
|
|||||||
c->error = 1;
|
c->error = 1;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
done = scsi_eval_cmd_outcome(d, c, fp, s.sbp, s.sb_len_wr,
|
|
||||||
s.duration, start_time, s.timeout, i, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (s.host_status != Libburn_sg_host_oK ||
|
if (s.sb_len_wr) {
|
||||||
(s.driver_status != Libburn_sg_driver_oK && !c->error)) {
|
if (!c->retry) {
|
||||||
|
c->error = 1;
|
||||||
|
|
||||||
|
/* A61106: rather than : return 1 */
|
||||||
|
goto ex;
|
||||||
|
}
|
||||||
|
switch (scsi_error(d, s.sbp, s.sb_len_wr)) {
|
||||||
|
case RETRY:
|
||||||
|
done = 0;
|
||||||
|
break;
|
||||||
|
case FAIL:
|
||||||
|
done = 1;
|
||||||
|
c->error = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
done = 1;
|
||||||
|
}
|
||||||
|
} while (!done);
|
||||||
|
|
||||||
|
/* ts A61106 */
|
||||||
|
ex:;
|
||||||
|
if (c->error) {
|
||||||
|
scsi_notify_error(d, c, s.sbp, s.sb_len_wr, 0);
|
||||||
|
} else if (s.host_status != Libburn_sg_host_oK ||
|
||||||
|
s.driver_status != Libburn_sg_driver_oK) {
|
||||||
char msg[161];
|
char msg[161];
|
||||||
|
|
||||||
sprintf(msg,
|
sprintf(msg,
|
||||||
@ -1706,6 +1843,11 @@ int sg_issue_command(struct burn_drive *d, struct command *c)
|
|||||||
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH,
|
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
msg, 0, 0);
|
msg, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef Libburn_log_sg_commandS
|
||||||
|
sg_log_err(c, fp, &s, c->error != 0);
|
||||||
|
#endif /* Libburn_log_sg_commandS */
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1724,8 +1866,6 @@ int sg_obtain_scsi_adr(char *path, int *bus_no, int *host_no, int *channel_no,
|
|||||||
};
|
};
|
||||||
struct my_scsi_idlun idlun;
|
struct my_scsi_idlun idlun;
|
||||||
|
|
||||||
/* valgrind called idlun unitialized because it is blind for ioctl */
|
|
||||||
memset(&idlun, 0, sizeof(struct my_scsi_idlun));
|
|
||||||
|
|
||||||
l = strlen(linux_ata_device_family) - 2;
|
l = strlen(linux_ata_device_family) - 2;
|
||||||
if (l > 0 && strncmp(path, linux_ata_device_family, l) == 0
|
if (l > 0 && strncmp(path, linux_ata_device_family, l) == 0
|
||||||
@ -1801,24 +1941,6 @@ int sg_is_enumerable_adr(char *adr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ts B00115 */
|
|
||||||
/* Return 1 if the given path leads to a regular file or a device that can be
|
|
||||||
seeked, read, and possibly written with 2 kB granularity.
|
|
||||||
*/
|
|
||||||
int burn_os_is_2k_seekrw(char *path, int flag)
|
|
||||||
{
|
|
||||||
struct stat stbuf;
|
|
||||||
|
|
||||||
if (stat(path, &stbuf) == -1)
|
|
||||||
return 0;
|
|
||||||
if (S_ISREG(stbuf.st_mode))
|
|
||||||
return 1;
|
|
||||||
if (S_ISBLK(stbuf.st_mode))
|
|
||||||
return 1;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* ts A70909 */
|
/* ts A70909 */
|
||||||
/** Estimate the potential payload capacity of a file address.
|
/** Estimate the potential payload capacity of a file address.
|
||||||
@param path The address of the file to be examined. If it does not
|
@param path The address of the file to be examined. If it does not
|
||||||
@ -1870,86 +1992,9 @@ int burn_os_stdio_capacity(char *path, off_t *bytes)
|
|||||||
if (testpath[0]) {
|
if (testpath[0]) {
|
||||||
if (statvfs(testpath, &vfsbuf) == -1)
|
if (statvfs(testpath, &vfsbuf) == -1)
|
||||||
return -2;
|
return -2;
|
||||||
*bytes = add_size + ((off_t) vfsbuf.f_frsize) *
|
*bytes = add_size + ((off_t) vfsbuf.f_bsize) *
|
||||||
(off_t) vfsbuf.f_bavail;
|
(off_t) vfsbuf.f_bavail;
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ts A91122 : an interface to open(O_DIRECT) or similar OS tricks. */
|
|
||||||
|
|
||||||
#ifdef PROT_READ
|
|
||||||
#ifdef PROT_WRITE
|
|
||||||
#ifdef MAP_SHARED
|
|
||||||
#ifdef MAP_ANONYMOUS
|
|
||||||
#ifdef MAP_FAILED
|
|
||||||
#define Libburn_linux_do_mmaP 1
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef Libburn_read_o_direcT
|
|
||||||
#ifdef O_DIRECT
|
|
||||||
#define Libburn_linux_do_o_direcT 1
|
|
||||||
#endif
|
|
||||||
#endif /* Libburn_read_o_direcT */
|
|
||||||
|
|
||||||
|
|
||||||
int burn_os_open_track_src(char *path, int open_flags, int flag)
|
|
||||||
{
|
|
||||||
int fd;
|
|
||||||
|
|
||||||
#ifdef Libburn_linux_do_o_direcT
|
|
||||||
libdax_msgs_submit(libdax_messenger, -1, 0x00000002,
|
|
||||||
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH,
|
|
||||||
"Opening track source with O_DIRECT" , 0, 0);
|
|
||||||
fd = open(path, open_flags | O_DIRECT);
|
|
||||||
#else
|
|
||||||
fd = open(path, open_flags);
|
|
||||||
#endif
|
|
||||||
return fd;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void *burn_os_alloc_buffer(size_t amount, int flag)
|
|
||||||
{
|
|
||||||
void *buf = NULL;
|
|
||||||
|
|
||||||
#ifdef Libburn_linux_do_mmaP
|
|
||||||
|
|
||||||
/* >>> check whether size is suitable */;
|
|
||||||
|
|
||||||
libdax_msgs_submit(libdax_messenger, -1, 0x00000002,
|
|
||||||
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH,
|
|
||||||
"Allocating buffer via mmap()" , 0, 0);
|
|
||||||
buf = mmap(NULL, amount, PROT_READ | PROT_WRITE,
|
|
||||||
MAP_SHARED | MAP_ANONYMOUS, -1, (off_t) 0);
|
|
||||||
if (buf == MAP_FAILED)
|
|
||||||
buf = NULL;
|
|
||||||
else
|
|
||||||
memset(buf, 0, amount);
|
|
||||||
#else
|
|
||||||
buf = calloc(1, amount);
|
|
||||||
#endif /* ! Libburn_linux_do_mmaP */
|
|
||||||
|
|
||||||
return buf;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int burn_os_free_buffer(void *buffer, size_t amount, int flag)
|
|
||||||
{
|
|
||||||
int ret = 0;
|
|
||||||
|
|
||||||
if (buffer == NULL)
|
|
||||||
return 0;
|
|
||||||
#ifdef Libburn_linux_do_mmaP
|
|
||||||
ret = munmap(buffer, amount);
|
|
||||||
#else
|
|
||||||
free(buffer);
|
|
||||||
#endif
|
|
||||||
return (ret == 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
@ -1,861 +0,0 @@
|
|||||||
/* -*- 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;
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* >>> 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;
|
|
||||||
|
|
||||||
} /* end of retry-loop */
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
58
libburn/sg.c
58
libburn/sg.c
@ -1,71 +1,17 @@
|
|||||||
|
|
||||||
/* 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 - 2010 Thomas Schmitt <scdbackup@gmx.net>,
|
Copyright (C) 2006 Thomas Schmitt <scdbackup@gmx.net>, provided under GPL
|
||||||
provided under GPLv2+
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
#include "../config.h"
|
|
||||||
#undef HAVE_CONFIG_H
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef Libburn_use_sg_dummY
|
|
||||||
|
|
||||||
#include "sg-dummy.c"
|
|
||||||
|
|
||||||
#else
|
|
||||||
#ifdef Libburn_use_libcdiO
|
|
||||||
|
|
||||||
#include "sg-libcdio.c"
|
|
||||||
|
|
||||||
#else
|
|
||||||
#ifdef __FreeBSD__
|
#ifdef __FreeBSD__
|
||||||
|
|
||||||
#include "sg-freebsd.c"
|
#include "sg-freebsd.c"
|
||||||
|
|
||||||
#else
|
#else
|
||||||
#ifdef __FreeBSD_kernel__
|
|
||||||
|
|
||||||
#include "sg-freebsd.c"
|
|
||||||
|
|
||||||
#else
|
|
||||||
#ifdef __linux
|
|
||||||
|
|
||||||
#include "sg-linux.c"
|
#include "sg-linux.c"
|
||||||
|
|
||||||
#else
|
#endif
|
||||||
#ifdef __sun
|
|
||||||
|
|
||||||
#include "sg-solaris.c"
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
/* The dummy adapter formally fulfills the expectations of libburn towards
|
|
||||||
its SCSI command transport. It will show no drives and perform no SCSI
|
|
||||||
commands.
|
|
||||||
libburn will then be restricted to using its stdio pseudo drives.
|
|
||||||
*/
|
|
||||||
static int intentional_compiler_warning(void)
|
|
||||||
{
|
|
||||||
int INTENTIONAL_COMPILER_WARNING_;
|
|
||||||
int Cannot_recognize_GNU_Linux_nor_FreeBSD_;
|
|
||||||
int Have_to_use_dummy_MMC_transport_adapter_;
|
|
||||||
int This_libburn_will_not_be_able_to_operate_on_real_CD_drives;
|
|
||||||
int Have_to_use_dummy_MMC_transport_adapter;
|
|
||||||
int Cannot_recognize_GNU_Linux_nor_FreeBSD;
|
|
||||||
int INTENTIONAL_COMPILER_WARNING;
|
|
||||||
|
|
||||||
return(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
#include "sg-dummy.c"
|
|
||||||
|
|
||||||
#endif /* ! __sun */
|
|
||||||
#endif /* ! __linux */
|
|
||||||
#endif /* ! __FreeBSD_kernel__ */
|
|
||||||
#endif /* ! __FreeBSD__ */
|
|
||||||
#endif /* ! Libburn_use_libcdiO */
|
|
||||||
#endif /* ! Libburn_use_sg_dummY */
|
|
||||||
|
|
||||||
|
48
libburn/sg.h
48
libburn/sg.h
@ -1,8 +1,5 @@
|
|||||||
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||||
|
|
||||||
/* Copyright (C) 2009 Thomas Schmitt <scdbackup@gmx.net>, provided under GPLv2+
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __SG
|
#ifndef __SG
|
||||||
#define __SG
|
#define __SG
|
||||||
|
|
||||||
@ -34,51 +31,6 @@ int scsi_enumerate_drives(void);
|
|||||||
|
|
||||||
int sg_drive_is_open(struct burn_drive * d);
|
int sg_drive_is_open(struct burn_drive * d);
|
||||||
|
|
||||||
int burn_os_is_2k_seekrw(char *path, int flag);
|
|
||||||
|
|
||||||
int burn_os_stdio_capacity(char *path, off_t *bytes);
|
int burn_os_stdio_capacity(char *path, off_t *bytes);
|
||||||
|
|
||||||
/* ts A91227 */
|
|
||||||
/** Returns the id string of the SCSI transport adapter and eventually
|
|
||||||
needed operating system facilities.
|
|
||||||
This call is usable even if sg_initialize() was not called yet. In that
|
|
||||||
case a preliminary constant message might be issued if detailed info is
|
|
||||||
not available yet.
|
|
||||||
@param msg returns id string
|
|
||||||
@param flag unused yet, submit 0
|
|
||||||
@return 1 = success, <=0 = failure
|
|
||||||
*/
|
|
||||||
int sg_id_string(char msg[1024], int flag);
|
|
||||||
|
|
||||||
/* ts A91225 */
|
|
||||||
/** Performs global initialization of the SCSI transport adapter and eventually
|
|
||||||
needed operating system facilities. Checks for compatibility supporting
|
|
||||||
software components.
|
|
||||||
@param msg returns ids and/or error messages of eventual helpers
|
|
||||||
@param flag unused yet, submit 0
|
|
||||||
@return 1 = success, <=0 = failure
|
|
||||||
*/
|
|
||||||
int sg_initialize(char msg[1024], int flag);
|
|
||||||
|
|
||||||
/* ts A91227 */
|
|
||||||
/** Performs global finalization of the SCSI transport adapter and eventually
|
|
||||||
needed operating system facilities. Releases globally aquired resources.
|
|
||||||
@param flag unused yet, submit 0
|
|
||||||
@return 1 = success, <=0 = failure
|
|
||||||
*/
|
|
||||||
int sg_shutdown(int flag);
|
|
||||||
|
|
||||||
/* ts A91227 */
|
|
||||||
/** Finalizes BURN_OS_TRANSPORT_DRIVE_ELEMENTS, the components of
|
|
||||||
struct burn_drive which are defined in os-*.h.
|
|
||||||
The eventual initialization of those components was made underneath
|
|
||||||
scsi_enumerate_drives().
|
|
||||||
This will be called when a burn_drive gets disposed.
|
|
||||||
@param d the drive to be finalized
|
|
||||||
@param flag unused yet, submit 0
|
|
||||||
@return 1 = success, <=0 = failure
|
|
||||||
*/
|
|
||||||
int sg_dispose_drive(struct burn_drive *d, int flag);
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* __SG */
|
#endif /* __SG */
|
||||||
|
@ -1,15 +1,5 @@
|
|||||||
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||||
|
|
||||||
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
|
|
||||||
Copyright (c) 2006 - 2010 Thomas Schmitt <scdbackup@gmx.net>
|
|
||||||
Provided under GPL version 2 or later.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
#include "../config.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "libburn.h"
|
#include "libburn.h"
|
||||||
@ -63,15 +53,3 @@ int burn_source_cancel(struct burn_source *src)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ts B00922 */
|
|
||||||
int burn_source_read(struct burn_source *src, unsigned char *buffer, int size)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
if (src->read != NULL)
|
|
||||||
ret = src->read(src, buffer, size);
|
|
||||||
else
|
|
||||||
ret = src->read_xt(src, buffer, size);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
@ -7,6 +7,4 @@ struct burn_source *burn_source_new(void);
|
|||||||
|
|
||||||
int burn_source_cancel(struct burn_source *src);
|
int burn_source_cancel(struct burn_source *src);
|
||||||
|
|
||||||
int burn_source_read(struct burn_source *src, unsigned char *buffer, int size);
|
|
||||||
|
|
||||||
#endif /*__SOURCE*/
|
#endif /*__SOURCE*/
|
||||||
|
549
libburn/spc.c
549
libburn/spc.c
@ -1,16 +1,7 @@
|
|||||||
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||||
|
|
||||||
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
|
|
||||||
Copyright (c) 2006 - 2010 Thomas Schmitt <scdbackup@gmx.net>
|
|
||||||
Provided under GPL version 2 or later.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* scsi primary commands */
|
/* scsi primary commands */
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
#include "../config.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
@ -36,13 +27,10 @@
|
|||||||
#include "libdax_msgs.h"
|
#include "libdax_msgs.h"
|
||||||
extern struct libdax_msgs *libdax_messenger;
|
extern struct libdax_msgs *libdax_messenger;
|
||||||
|
|
||||||
/* ts A91111 :
|
/* ts A70910
|
||||||
whether to log SCSI commands:
|
debug: for tracing calls which might use open drive fds
|
||||||
bit0= log in /tmp/libburn_sg_command_log
|
or for catching SCSI usage of emulated drives. */
|
||||||
bit1= log to stderr
|
int mmc_function_spy(struct burn_drive *d, char * text);
|
||||||
bit2= flush every line
|
|
||||||
*/
|
|
||||||
extern int burn_sg_log_scsi;
|
|
||||||
|
|
||||||
|
|
||||||
/* spc command set */
|
/* spc command set */
|
||||||
@ -53,7 +41,8 @@ static unsigned char SPC_INQUIRY[] = { 0x12, 0, 0, 0, 36, 0 };
|
|||||||
static unsigned char SPC_PREVENT[] = { 0x1e, 0, 0, 0, 1, 0 };
|
static unsigned char SPC_PREVENT[] = { 0x1e, 0, 0, 0, 1, 0 };
|
||||||
static unsigned char SPC_ALLOW[] = { 0x1e, 0, 0, 0, 0, 0 };
|
static unsigned char SPC_ALLOW[] = { 0x1e, 0, 0, 0, 0, 0 };
|
||||||
static unsigned char SPC_MODE_SENSE[] = { 0x5a, 0, 0, 0, 0, 0, 0, 16, 0, 0 };
|
static unsigned char SPC_MODE_SENSE[] = { 0x5a, 0, 0, 0, 0, 0, 0, 16, 0, 0 };
|
||||||
static unsigned char SPC_MODE_SELECT[] = { 0x55, 16, 0, 0, 0, 0, 0, 0, 0, 0 };
|
static unsigned char SPC_MODE_SELECT[] =
|
||||||
|
{ 0x55, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||||
static unsigned char SPC_REQUEST_SENSE[] = { 0x03, 0, 0, 0, 18, 0 };
|
static unsigned char SPC_REQUEST_SENSE[] = { 0x03, 0, 0, 0, 18, 0 };
|
||||||
static unsigned char SPC_TEST_UNIT_READY[] = { 0x00, 0, 0, 0, 0, 0 };
|
static unsigned char SPC_TEST_UNIT_READY[] = { 0x00, 0, 0, 0, 0, 0 };
|
||||||
|
|
||||||
@ -75,30 +64,6 @@ 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;
|
||||||
@ -107,23 +72,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];
|
||||||
fprintf(stderr, "sense[0 - 2] = %2.2X %2.2X %2.2X",
|
*ascq= c.sense[13];
|
||||||
c.sense[0], c.sense[1], c.sense[2]);
|
return (c.sense[2] & 0xF) == 0;
|
||||||
*/
|
|
||||||
|
|
||||||
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;
|
||||||
@ -133,23 +98,25 @@ int spc_test_unit_ready(struct burn_drive *d)
|
|||||||
|
|
||||||
|
|
||||||
/* ts A70315 */
|
/* ts A70315 */
|
||||||
/** @param flag bit0=do not wait 0.1 seconds before first test unit ready
|
/** @param flag bit0=do not wait 0.1 seconds before first test unit ready */
|
||||||
bit1=do not issue success message
|
|
||||||
*/
|
|
||||||
/** Wait until the drive state becomes clear or until max_usec elapsed */
|
/** Wait until the drive state becomes clear or until max_usec elapsed */
|
||||||
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, clueless_start = 0;
|
int i, ret = 1, key = 0, asc = 0, ascq = 0;
|
||||||
static int clueless_timeout = 5 * 10;
|
char msg[160];
|
||||||
char msg[320];
|
|
||||||
unsigned char sense[14];
|
|
||||||
enum response resp;
|
|
||||||
|
|
||||||
if (!(flag & 1))
|
if (!(flag & 1))
|
||||||
usleep(100000);
|
usleep(100000);
|
||||||
for(i = !(flag & 1); i < max_sec * 10; i++) {
|
for(i = !(flag & 1); i < max_sec * 10; i++) {
|
||||||
ret = spc_test_unit_ready_r(d, &key, &asc, &ascq);
|
ret = spc_test_unit_ready_r(d, &key, &asc, &ascq);
|
||||||
|
|
||||||
|
/* <<<
|
||||||
|
fprintf(stderr,
|
||||||
|
"libburn_EXPERIMENTAL: i= %d ret= %d key= %X asc= %2.2X ascq= %2.2X\n",
|
||||||
|
i, ret, (unsigned) key, (unsigned) asc, (unsigned) ascq);
|
||||||
|
*/
|
||||||
|
|
||||||
if (ret > 0) /* ready */
|
if (ret > 0) /* ready */
|
||||||
break;
|
break;
|
||||||
if (key!=0x2 || asc!=0x4) {
|
if (key!=0x2 || asc!=0x4) {
|
||||||
@ -171,50 +138,25 @@ 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 */
|
|
||||||
sprintf(msg,
|
sprintf(msg,
|
||||||
"Asynchronous SCSI error on %s: ", cmd_text);
|
"Asynchromous SCSI error on %s: key=%X asc=%2.2Xh ascq=%2.2Xh",
|
||||||
sense[0] = 0x70; /* Fixed format sense data */
|
cmd_text, (unsigned) key, (unsigned) asc,
|
||||||
sense[2] = key;
|
(unsigned) ascq);
|
||||||
sense[12] = asc;
|
|
||||||
sense[13] = ascq;
|
|
||||||
resp = scsi_error_msg(d, sense, 14, msg + strlen(msg),
|
|
||||||
&key, &asc, &ascq);
|
|
||||||
libdax_msgs_submit(libdax_messenger, d->global_index,
|
libdax_msgs_submit(libdax_messenger, d->global_index,
|
||||||
0x0002014d,
|
0x0002014d,
|
||||||
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
|
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
msg, 0, 0);
|
msg, 0, 0);
|
||||||
d->cancel = 1;
|
d->cancel = 1;
|
||||||
break;
|
break;
|
||||||
} else if (ascq == 0x00) { /* CAUSE NOT REPORTABLE */
|
}
|
||||||
/* Might be a clueless system adapter */
|
|
||||||
if (clueless_start == 0)
|
|
||||||
clueless_start = i;
|
|
||||||
if (i - clueless_start > clueless_timeout) {
|
|
||||||
libdax_msgs_submit(libdax_messenger,
|
|
||||||
d->global_index,
|
|
||||||
0x00000002,
|
|
||||||
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH,
|
|
||||||
"Ended clueless NOT READY cycle",
|
|
||||||
0, 0);
|
|
||||||
ret = 1; /* medium not present = ok */
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else if (ascq == 0x02 || ascq == 0x03)
|
|
||||||
goto handle_error;
|
|
||||||
|
|
||||||
slumber:;
|
slumber:;
|
||||||
usleep(100000);
|
usleep(100000);
|
||||||
}
|
}
|
||||||
if (ret <= 0 || !(flag & 2)) {
|
|
||||||
sprintf(msg, "Async %s %s after %d.%d seconds",
|
sprintf(msg, "Async %s %s after %d.%d seconds",
|
||||||
cmd_text, (ret > 0 ? "succeeded" : "failed"),
|
cmd_text, (ret > 0 ? "succeeded" : "failed"), i / 10, i % 10);
|
||||||
i / 10, i % 10);
|
libdax_msgs_submit(libdax_messenger, d->global_index, 0x00020150,
|
||||||
libdax_msgs_submit(libdax_messenger, d->global_index,
|
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_LOW, msg, 0, 0);
|
||||||
0x00020150, LIBDAX_MSGS_SEV_DEBUG,
|
|
||||||
LIBDAX_MSGS_PRIO_LOW, msg, 0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (i < max_sec * 10)
|
if (i < max_sec * 10)
|
||||||
return (ret > 0);
|
return (ret > 0);
|
||||||
@ -274,7 +216,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;
|
||||||
@ -304,14 +246,14 @@ void spc_prevent(struct burn_drive *d)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
scsi_init_command(&c, SPC_PREVENT, sizeof(SPC_PREVENT));
|
scsi_init_command(&c, SPC_PREVENT, sizeof(SPC_PREVENT));
|
||||||
|
/*
|
||||||
|
memcpy(c.opcode, SPC_PREVENT, sizeof(SPC_PREVENT));
|
||||||
|
c.oplen = sizeof(SPC_PREVENT);
|
||||||
|
c.page = NULL;
|
||||||
|
*/
|
||||||
c.retry = 1;
|
c.retry = 1;
|
||||||
c.dir = NO_TRANSFER;
|
c.dir = NO_TRANSFER;
|
||||||
d->issue_command(d, &c);
|
d->issue_command(d, &c);
|
||||||
|
|
||||||
#ifdef Libburn_pioneer_dvr_216d_get_evenT
|
|
||||||
mmc_get_event(d);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void spc_allow(struct burn_drive *d)
|
void spc_allow(struct burn_drive *d)
|
||||||
@ -333,7 +275,7 @@ void spc_allow(struct burn_drive *d)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
ts A70518 - A90603 : Do not call with *alloc_len < 10
|
ts A70518 : Do not call with *alloc_len < 8
|
||||||
*/
|
*/
|
||||||
/** flag&1= do only inquire alloc_len */
|
/** flag&1= do only inquire alloc_len */
|
||||||
static int spc_sense_caps_al(struct burn_drive *d, int *alloc_len, int flag)
|
static int spc_sense_caps_al(struct burn_drive *d, int *alloc_len, int flag)
|
||||||
@ -345,19 +287,13 @@ static int spc_sense_caps_al(struct burn_drive *d, int *alloc_len, int flag)
|
|||||||
unsigned char *page;
|
unsigned char *page;
|
||||||
struct command c;
|
struct command c;
|
||||||
struct burn_speed_descriptor *sd;
|
struct burn_speed_descriptor *sd;
|
||||||
char msg[BURN_DRIVE_ADR_LEN + 160];
|
|
||||||
|
|
||||||
/* ts A61225 : 1 = report about post-MMC-1 speed descriptors */
|
/* ts A61225 : 1 = report about post-MMC-1 speed descriptors */
|
||||||
static int speed_debug = 0;
|
static int speed_debug = 0;
|
||||||
|
|
||||||
if (*alloc_len < 10)
|
if (*alloc_len < 8)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* ts A90602 : Clearing mdata before command execution */
|
|
||||||
m = d->mdata;
|
|
||||||
m->valid = 0;
|
|
||||||
burn_mdata_free_subs(m);
|
|
||||||
|
|
||||||
memset(&buf, 0, sizeof(buf));
|
memset(&buf, 0, sizeof(buf));
|
||||||
scsi_init_command(&c, SPC_MODE_SENSE, sizeof(SPC_MODE_SENSE));
|
scsi_init_command(&c, SPC_MODE_SENSE, sizeof(SPC_MODE_SENSE));
|
||||||
/*
|
/*
|
||||||
@ -376,11 +312,12 @@ static int spc_sense_caps_al(struct burn_drive *d, int *alloc_len, int flag)
|
|||||||
d->issue_command(d, &c);
|
d->issue_command(d, &c);
|
||||||
if (c.error) {
|
if (c.error) {
|
||||||
memset(&buf, 0, sizeof(buf));
|
memset(&buf, 0, sizeof(buf));
|
||||||
m->valid = -1;
|
d->mdata->valid = -1;
|
||||||
was_error = 1;
|
was_error = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
size = c.page->data[0] * 256 + c.page->data[1] + 2;
|
size = c.page->data[0] * 256 + c.page->data[1];
|
||||||
|
m = d->mdata;
|
||||||
page = c.page->data + 8;
|
page = c.page->data + 8;
|
||||||
|
|
||||||
/* ts A61225 :
|
/* ts A61225 :
|
||||||
@ -389,28 +326,18 @@ static int spc_sense_caps_al(struct burn_drive *d, int *alloc_len, int flag)
|
|||||||
in MMC-3 6.3.11 there are at least 28 bytes plus a variable length
|
in MMC-3 6.3.11 there are at least 28 bytes plus a variable length
|
||||||
set of speed descriptors. In MMC-5 E.11 it is declared "legacy".
|
set of speed descriptors. In MMC-5 E.11 it is declared "legacy".
|
||||||
*/
|
*/
|
||||||
/* ts A90603 :
|
|
||||||
SPC-1 8.3.3 enumerates mode page format bytes from 0 to n and
|
|
||||||
defines Page Length as (n-1).
|
|
||||||
*/
|
|
||||||
page_length = page[1];
|
page_length = page[1];
|
||||||
old_alloc_len = *alloc_len;
|
old_alloc_len = *alloc_len;
|
||||||
*alloc_len = page_length + 10;
|
*alloc_len = page_length + 8;
|
||||||
if (flag & 1)
|
if (flag & 1)
|
||||||
return !was_error;
|
return !was_error;
|
||||||
if (page_length + 10 > old_alloc_len)
|
if (page_length + 8 > old_alloc_len)
|
||||||
page_length = old_alloc_len - 10;
|
page_length = old_alloc_len - 8;
|
||||||
|
if (page_length < 22)
|
||||||
/* ts A90602 : 20 asserts page[21]. (see SPC-1 8.3.3) */
|
|
||||||
if (page_length < 20) {
|
|
||||||
m->valid = -1;
|
|
||||||
sprintf(msg, "MODE SENSE page 2A too short: %s : %d",
|
|
||||||
d->devname, page_length);
|
|
||||||
libdax_msgs_submit(libdax_messenger, d->global_index,
|
|
||||||
0x0002016e, LIBDAX_MSGS_SEV_DEBUG,
|
|
||||||
LIBDAX_MSGS_PRIO_LOW, msg, 0, 0);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
|
||||||
|
m->valid = 0;
|
||||||
|
burn_mdata_free_subs(m);
|
||||||
|
|
||||||
m->buffer_size = page[12] * 256 + page[13];
|
m->buffer_size = page[12] * 256 + page[13];
|
||||||
m->dvdram_read = page[2] & 32;
|
m->dvdram_read = page[2] & 32;
|
||||||
@ -441,13 +368,12 @@ static int spc_sense_caps_al(struct burn_drive *d, int *alloc_len, int flag)
|
|||||||
m->min_end_lba = 0x7fffffff;
|
m->min_end_lba = 0x7fffffff;
|
||||||
m->max_end_lba = 0;
|
m->max_end_lba = 0;
|
||||||
|
|
||||||
if (!was_error)
|
m->valid = 1;
|
||||||
m->valid = 1;
|
|
||||||
|
|
||||||
mmc_get_configuration(d);
|
mmc_get_configuration(d);
|
||||||
|
|
||||||
/* ts A61225 : end of MMC-1 , begin of MMC-3 */
|
/* ts A61225 : end of MMC-1 , begin of MMC-3 */
|
||||||
if (page_length < 30) /* no write speed descriptors ? */
|
if (page_length < 32) /* no write speed descriptors ? */
|
||||||
goto try_mmc_get_performance;
|
goto try_mmc_get_performance;
|
||||||
|
|
||||||
m->cur_write_speed = page[28] * 256 + page[29];
|
m->cur_write_speed = page[28] * 256 + page[29];
|
||||||
@ -471,12 +397,12 @@ static int spc_sense_caps_al(struct burn_drive *d, int *alloc_len, int flag)
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < num_write_speeds; i++) {
|
for (i = 0; i < num_write_speeds; i++) {
|
||||||
speed = page[32 + 4 * i + 2] * 256 + page[32 + 4 * i + 3];
|
speed = page[32 + 4*i + 2] * 256 + page[32 + 4*i + 3];
|
||||||
|
|
||||||
if (speed_debug)
|
if (speed_debug)
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"LIBBURN_DEBUG: write speed #%d = %d kB/s (rc %d)\n",
|
"LIBBURN_DEBUG: write speed #%d = %d kB/s (rc %d)\n",
|
||||||
i, speed, page[32 + 4 * i + 1] & 7);
|
i, speed, page[32 + 4*i +1] & 7);
|
||||||
|
|
||||||
/* ts A61226 */
|
/* ts A61226 */
|
||||||
ret = burn_speed_descriptor_new(&(d->mdata->speed_descriptors),
|
ret = burn_speed_descriptor_new(&(d->mdata->speed_descriptors),
|
||||||
@ -489,7 +415,7 @@ static int spc_sense_caps_al(struct burn_drive *d, int *alloc_len, int flag)
|
|||||||
strcpy(sd->profile_name,
|
strcpy(sd->profile_name,
|
||||||
d->current_profile_text);
|
d->current_profile_text);
|
||||||
}
|
}
|
||||||
sd->wrc = (( page[32 + 4 * i + 1] & 7 ) == 1 );
|
sd->wrc = (( page[32 + 4*i +1] & 7 ) == 1 );
|
||||||
sd->write_speed = speed;
|
sd->write_speed = speed;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -505,33 +431,20 @@ static int spc_sense_caps_al(struct burn_drive *d, int *alloc_len, int flag)
|
|||||||
m->min_write_speed, m->max_write_speed);
|
m->min_write_speed, m->max_write_speed);
|
||||||
|
|
||||||
try_mmc_get_performance:;
|
try_mmc_get_performance:;
|
||||||
if (m->cdrw_write || page_length >= 32) {
|
ret = mmc_get_write_performance(d);
|
||||||
/* ts A90823:
|
|
||||||
One has to avoid U3 enhanced memory sticks here. On my
|
|
||||||
SuSE 10.2 a SanDisk Cruzer 4GB stalls at the second occasion
|
|
||||||
of ACh GET PERFORMANCE. (The first one is obviously called
|
|
||||||
by the OS at plug time.)
|
|
||||||
This pseudo drive returns no write capabilities and a page
|
|
||||||
length of 28. MMC-3 describes page length 32. Regrettably
|
|
||||||
MMC-2 prescribes a page length of 26. Here i have to trust
|
|
||||||
m->cdrw_write to reliably indicate any MMC-2 burner.
|
|
||||||
*/
|
|
||||||
ret = mmc_get_write_performance(d);
|
|
||||||
if (ret > 0 && speed_debug)
|
|
||||||
fprintf(stderr,
|
|
||||||
"LIBBURN_DEBUG: ACh min_write_speed = %d , max_write_speed = %d\n",
|
|
||||||
m->min_write_speed, m->max_write_speed);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if (ret > 0 && speed_debug)
|
||||||
|
fprintf(stderr,
|
||||||
|
"LIBBURN_DEBUG: ACh min_write_speed = %d , max_write_speed = %d\n",
|
||||||
|
m->min_write_speed, m->max_write_speed);
|
||||||
return !was_error;
|
return !was_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void spc_sense_caps(struct burn_drive *d)
|
void spc_sense_caps(struct burn_drive *d)
|
||||||
{
|
{
|
||||||
int alloc_len, start_len = 30, ret;
|
int alloc_len, start_len = 22, ret;
|
||||||
|
|
||||||
mmc_start_if_needed(d, 1);
|
|
||||||
if (mmc_function_spy(d, "sense_caps") <= 0)
|
if (mmc_function_spy(d, "sense_caps") <= 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -556,7 +469,6 @@ void spc_sense_error_params(struct burn_drive *d)
|
|||||||
unsigned char *page;
|
unsigned char *page;
|
||||||
struct command c;
|
struct command c;
|
||||||
|
|
||||||
mmc_start_if_needed(d, 1);
|
|
||||||
if (mmc_function_spy(d, "sense_error_params") <= 0)
|
if (mmc_function_spy(d, "sense_error_params") <= 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -576,7 +488,7 @@ void spc_sense_error_params(struct burn_drive *d)
|
|||||||
c.dir = FROM_DRIVE;
|
c.dir = FROM_DRIVE;
|
||||||
d->issue_command(d, &c);
|
d->issue_command(d, &c);
|
||||||
|
|
||||||
size = c.page->data[0] * 256 + c.page->data[1] + 2;
|
size = c.page->data[0] * 256 + c.page->data[1];
|
||||||
m = d->mdata;
|
m = d->mdata;
|
||||||
page = c.page->data + 8;
|
page = c.page->data + 8;
|
||||||
d->params.retries = page[3];
|
d->params.retries = page[3];
|
||||||
@ -590,7 +502,6 @@ void spc_select_error_params(struct burn_drive *d,
|
|||||||
struct buffer buf;
|
struct buffer buf;
|
||||||
struct command c;
|
struct command c;
|
||||||
|
|
||||||
mmc_start_if_needed(d, 1);
|
|
||||||
if (mmc_function_spy(d, "select_error_params") <= 0)
|
if (mmc_function_spy(d, "select_error_params") <= 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -632,7 +543,6 @@ void spc_sense_write_params(struct burn_drive *d)
|
|||||||
unsigned char *page;
|
unsigned char *page;
|
||||||
struct command c;
|
struct command c;
|
||||||
|
|
||||||
mmc_start_if_needed(d, 1);
|
|
||||||
if (mmc_function_spy(d, "sense_write_params") <= 0)
|
if (mmc_function_spy(d, "sense_write_params") <= 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -659,7 +569,7 @@ void spc_sense_write_params(struct burn_drive *d)
|
|||||||
/* ts A71128 : do not interpret reply if error */
|
/* ts A71128 : do not interpret reply if error */
|
||||||
m = d->mdata;
|
m = d->mdata;
|
||||||
if (!c.error) {
|
if (!c.error) {
|
||||||
size = c.page->data[0] * 256 + c.page->data[1] + 2;
|
size = c.page->data[0] * 256 + c.page->data[1];
|
||||||
page = c.page->data + 8;
|
page = c.page->data + 8;
|
||||||
burn_print(1, "write page length 0x%x\n", page[1]);
|
burn_print(1, "write page length 0x%x\n", page[1]);
|
||||||
m->write_page_length = page[1];
|
m->write_page_length = page[1];
|
||||||
@ -696,9 +606,7 @@ void spc_select_write_params(struct burn_drive *d,
|
|||||||
{
|
{
|
||||||
struct buffer buf;
|
struct buffer buf;
|
||||||
struct command c;
|
struct command c;
|
||||||
int alloc_len;
|
|
||||||
|
|
||||||
mmc_start_if_needed(d, 1);
|
|
||||||
if (mmc_function_spy(d, "select_write_params") <= 0)
|
if (mmc_function_spy(d, "select_write_params") <= 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -712,33 +620,13 @@ void spc_select_write_params(struct burn_drive *d,
|
|||||||
o->block_type,spc_block_type(o->block_type));
|
o->block_type,spc_block_type(o->block_type));
|
||||||
*/
|
*/
|
||||||
|
|
||||||
alloc_len = 8 + 2 + d->mdata->write_page_length;
|
|
||||||
memset(&(buf.data), 0, alloc_len);
|
|
||||||
|
|
||||||
#ifdef Libburn_pioneer_dvr_216d_load_mode5
|
|
||||||
|
|
||||||
scsi_init_command(&c, SPC_MODE_SENSE, sizeof(SPC_MODE_SENSE));
|
|
||||||
c.dxfer_len = alloc_len;
|
|
||||||
c.opcode[7] = (alloc_len >> 8) & 0xff;
|
|
||||||
c.opcode[8] = alloc_len & 0xff;
|
|
||||||
c.retry = 1;
|
|
||||||
c.opcode[2] = 0x05;
|
|
||||||
c.page = &buf;
|
|
||||||
c.page->bytes = 0;
|
|
||||||
c.page->sectors = 0;
|
|
||||||
c.dir = FROM_DRIVE;
|
|
||||||
d->issue_command(d, &c);
|
|
||||||
|
|
||||||
if (c.error)
|
|
||||||
memset(&(buf.data), 0,
|
|
||||||
8 + 2 + d->mdata->write_page_length);
|
|
||||||
|
|
||||||
#endif /* Libburn_pioneer_dvr_216d_load_mode5 */
|
|
||||||
|
|
||||||
scsi_init_command(&c, SPC_MODE_SELECT, sizeof(SPC_MODE_SELECT));
|
scsi_init_command(&c, SPC_MODE_SELECT, sizeof(SPC_MODE_SELECT));
|
||||||
|
/*
|
||||||
|
memcpy(c.opcode, SPC_MODE_SELECT, sizeof(SPC_MODE_SELECT));
|
||||||
|
c.oplen = sizeof(SPC_MODE_SELECT);
|
||||||
|
*/
|
||||||
c.retry = 1;
|
c.retry = 1;
|
||||||
c.opcode[7] = (alloc_len >> 8) & 0xff;
|
c.opcode[8] = 8 + 2 + d->mdata->write_page_length;
|
||||||
c.opcode[8] = alloc_len & 0xff;
|
|
||||||
c.page = &buf;
|
c.page = &buf;
|
||||||
c.page->bytes = 0;
|
c.page->bytes = 0;
|
||||||
c.page->sectors = 0;
|
c.page->sectors = 0;
|
||||||
@ -746,7 +634,8 @@ void spc_select_write_params(struct burn_drive *d,
|
|||||||
/* ts A61007 : moved up to burn_disc_write() */
|
/* ts A61007 : moved up to burn_disc_write() */
|
||||||
/* a ssert(d->mdata->valid); */
|
/* a ssert(d->mdata->valid); */
|
||||||
|
|
||||||
c.page->bytes = alloc_len;
|
memset(c.page->data, 0, 8 + 2 + d->mdata->write_page_length);
|
||||||
|
c.page->bytes = 8 + 2 + d->mdata->write_page_length;
|
||||||
|
|
||||||
burn_print(12, "using write page length %d (valid %d)\n",
|
burn_print(12, "using write page length %d (valid %d)\n",
|
||||||
d->mdata->write_page_length, d->mdata->write_page_valid);
|
d->mdata->write_page_length, d->mdata->write_page_valid);
|
||||||
@ -783,7 +672,6 @@ void spc_probe_write_modes(struct burn_drive *d)
|
|||||||
int last_try = 0;
|
int last_try = 0;
|
||||||
struct command c;
|
struct command c;
|
||||||
|
|
||||||
mmc_start_if_needed(d, 1);
|
|
||||||
if (mmc_function_spy(d, "spc_probe_write_modes") <= 0)
|
if (mmc_function_spy(d, "spc_probe_write_modes") <= 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -801,8 +689,11 @@ void spc_probe_write_modes(struct burn_drive *d)
|
|||||||
try_block_type = useable_block_type;
|
try_block_type = useable_block_type;
|
||||||
last_try= 1;
|
last_try= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
scsi_init_command(&c, SPC_MODE_SELECT,sizeof(SPC_MODE_SELECT));
|
scsi_init_command(&c, SPC_MODE_SELECT,sizeof(SPC_MODE_SELECT));
|
||||||
|
/*
|
||||||
|
memcpy(c.opcode, SPC_MODE_SELECT, sizeof(SPC_MODE_SELECT));
|
||||||
|
c.oplen = sizeof(SPC_MODE_SELECT);
|
||||||
|
*/
|
||||||
c.retry = 1;
|
c.retry = 1;
|
||||||
c.opcode[8] = 8 + 2 + 0x32;
|
c.opcode[8] = 8 + 2 + 0x32;
|
||||||
c.page = &buf;
|
c.page = &buf;
|
||||||
@ -828,7 +719,10 @@ void spc_probe_write_modes(struct burn_drive *d)
|
|||||||
if (last_try)
|
if (last_try)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
spc_decode_sense(c.sense, 0, &key, &asc, &ascq);
|
key = c.sense[2];
|
||||||
|
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 {
|
||||||
@ -874,7 +768,6 @@ void spc_probe_write_modes(struct burn_drive *d)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ( ts A61229 : shouldn't this go to mmc.c too ?) */
|
/* ( ts A61229 : shouldn't this go to mmc.c too ?) */
|
||||||
@ -981,35 +874,19 @@ 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] = {
|
|
||||||
"(no specific error)",
|
|
||||||
"Recovered error",
|
|
||||||
"Drive not ready",
|
|
||||||
"Medium error",
|
|
||||||
"Drive error",
|
|
||||||
"Illegal request",
|
|
||||||
"Drive event",
|
|
||||||
"Data protected",
|
|
||||||
"Blank/Nonblank",
|
|
||||||
"Vendor specific code",
|
|
||||||
"Copy aborted",
|
|
||||||
"Command aborted",
|
|
||||||
"(obsolete error code)",
|
|
||||||
"Volume overflow",
|
|
||||||
"Miscompare",
|
|
||||||
"(reserved error code)",
|
|
||||||
};
|
|
||||||
|
|
||||||
msg= msg_data;
|
msg= msg_data;
|
||||||
*key= *asc= *ascq= -1;
|
*key= *asc= *ascq= -1;
|
||||||
|
|
||||||
ret = spc_decode_sense(sense, senselen, key, asc, ascq);
|
if (senselen<=0 || senselen>2)
|
||||||
if (ret <= 0)
|
*key = sense[2];
|
||||||
*key= *asc= *ascq= -1;
|
if (senselen<=0 || senselen>12)
|
||||||
|
*asc = sense[12];
|
||||||
|
if (senselen<=0 || senselen>13)
|
||||||
|
*ascq = sense[13];
|
||||||
|
|
||||||
sprintf(msg, "[%X %2.2X %2.2X] ", *key, *asc, *ascq);
|
sprintf(msg, "[%X %2.2X %2.2X] ", *key, *asc, *ascq);
|
||||||
msg= msg + strlen(msg);
|
msg= msg + strlen(msg);
|
||||||
|
|
||||||
burn_print(12, "CONDITION: 0x%x 0x%x 0x%x on %s %s\n",
|
burn_print(12, "CONDITION: 0x%x 0x%x 0x%x on %s %s\n",
|
||||||
@ -1017,32 +894,15 @@ 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 GO_ON;
|
return RETRY;
|
||||||
|
|
||||||
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;
|
|
||||||
case 0x08:
|
|
||||||
if (*key != 4)
|
|
||||||
break;
|
|
||||||
if (*ascq == 0)
|
|
||||||
sprintf(msg, "Logical unit communication failure");
|
|
||||||
else if (*ascq == 1)
|
|
||||||
sprintf(msg, "Logical unit communication timeout");
|
|
||||||
else if (*ascq == 2)
|
|
||||||
sprintf(msg, "Logical unit communication parity error");
|
|
||||||
else if (*ascq == 3)
|
|
||||||
sprintf(msg, "Logical unit communication crc error");
|
|
||||||
return RETRY;
|
return RETRY;
|
||||||
case 0x09:
|
case 0x09:
|
||||||
if (*key != 4)
|
if (*key != 4)
|
||||||
@ -1226,17 +1086,6 @@ 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:
|
|
||||||
if (*key != 3 || *ascq != 0)
|
|
||||||
break;
|
|
||||||
sprintf(msg, "Unable to recover Table-of-Content");
|
|
||||||
return FAIL;
|
|
||||||
case 0x63:
|
case 0x63:
|
||||||
if (*key != 5)
|
if (*key != 5)
|
||||||
break;
|
break;
|
||||||
@ -1273,24 +1122,10 @@ enum response scsi_error_msg(struct burn_drive *d, unsigned char *sense,
|
|||||||
else
|
else
|
||||||
break;
|
break;
|
||||||
return FAIL;
|
return FAIL;
|
||||||
case 0x73:
|
|
||||||
if (*key == 3 && *ascq == 0)
|
|
||||||
sprintf(msg, "CD control error");
|
|
||||||
else if (*key == 3 && *ascq == 2)
|
|
||||||
sprintf(msg, "Power calibration area is full");
|
|
||||||
else if (*key == 3 && *ascq == 3)
|
|
||||||
sprintf(msg, "Power calibration area error");
|
|
||||||
else if (*key == 3 && *ascq == 4)
|
|
||||||
sprintf(msg, "Program memory area update failure");
|
|
||||||
else if (*key == 3 && *ascq == 5)
|
|
||||||
sprintf(msg, "Program memory area is full");
|
|
||||||
else
|
|
||||||
break;
|
|
||||||
return FAIL;
|
|
||||||
}
|
}
|
||||||
sprintf(msg_data,
|
sprintf(msg_data,
|
||||||
"See MMC specs: Sense Key %X \"%s\", ASC %2.2X ASCQ %2.2X",
|
"Failure. See mmc3r10g.pdf: Sense Key %X ASC %2.2X ASCQ %2.2X",
|
||||||
*key & 0xf, key_def[(*key) & 0xf], *asc, *ascq);
|
*key, *asc, *ascq);
|
||||||
return FAIL;
|
return FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1324,14 +1159,10 @@ static char *scsi_command_name(unsigned int c, int flag)
|
|||||||
return "FORMAT UNIT";
|
return "FORMAT UNIT";
|
||||||
case 0x1b:
|
case 0x1b:
|
||||||
return "START/STOP UNIT";
|
return "START/STOP UNIT";
|
||||||
case 0x12:
|
|
||||||
return "INQUIRY";
|
|
||||||
case 0x1e:
|
case 0x1e:
|
||||||
return "PREVENT/ALLOW MEDIA REMOVAL";
|
return "PREVENT/ALLOW MEDIA REMOVAL";
|
||||||
case 0x23:
|
case 0x23:
|
||||||
return "READ FORMAT CAPACITIES";
|
return "READ FORMAT CAPACITIES";
|
||||||
case 0x25:
|
|
||||||
return "READ CAPACITY";
|
|
||||||
case 0x28:
|
case 0x28:
|
||||||
return "READ(10)";
|
return "READ(10)";
|
||||||
case 0x2a:
|
case 0x2a:
|
||||||
@ -1355,7 +1186,7 @@ static char *scsi_command_name(unsigned int c, int flag)
|
|||||||
case 0x55:
|
case 0x55:
|
||||||
return "MODE SELECT";
|
return "MODE SELECT";
|
||||||
case 0x5a:
|
case 0x5a:
|
||||||
return "MODE SENSE";
|
return "SEND OPC INFORMATION";
|
||||||
case 0x5b:
|
case 0x5b:
|
||||||
return "CLOSE TRACK/SESSION";
|
return "CLOSE TRACK/SESSION";
|
||||||
case 0x5c:
|
case 0x5c:
|
||||||
@ -1368,8 +1199,6 @@ static char *scsi_command_name(unsigned int c, int flag)
|
|||||||
return "WRITE(12)";
|
return "WRITE(12)";
|
||||||
case 0xac:
|
case 0xac:
|
||||||
return "GET PERFORMANCE";
|
return "GET PERFORMANCE";
|
||||||
case 0xad:
|
|
||||||
return "READ DISC STRUCTURE";
|
|
||||||
case 0xb6:
|
case 0xb6:
|
||||||
return "SET STREAMING";
|
return "SET STREAMING";
|
||||||
case 0xbb:
|
case 0xbb:
|
||||||
@ -1408,186 +1237,28 @@ 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ts A91106 */
|
|
||||||
/* @param flag bit0= do not show eventual data payload sent to the drive
|
|
||||||
(never with WRITE commands)
|
|
||||||
bit1= show write length and target LBA in decimal
|
|
||||||
*/
|
|
||||||
int scsi_show_cmd_text(struct command *c, void *fp_in, int flag)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
FILE *fp = fp_in;
|
|
||||||
|
|
||||||
fprintf(fp, "\n%s\n",
|
|
||||||
scsi_command_name((unsigned int) c->opcode[0], 0));
|
|
||||||
for(i = 0; i < 16 && i < c->oplen; i++)
|
|
||||||
fprintf(fp, "%2.2x ", c->opcode[i]);
|
|
||||||
if (i > 0)
|
|
||||||
fprintf(fp, "\n");
|
|
||||||
if (flag & 1)
|
|
||||||
return 1;
|
|
||||||
if (c->opcode[0] == 0x2A) { /* WRITE 10 */
|
|
||||||
if (flag & 2)
|
|
||||||
fprintf(fp, "%d -> %d\n",
|
|
||||||
(c->opcode[7] << 8) | c->opcode[8],
|
|
||||||
mmc_four_char_to_int(c->opcode + 2));
|
|
||||||
} else if (c->opcode[0] == 0xAA) { /* WRITE 12 */
|
|
||||||
if (flag & 2)
|
|
||||||
fprintf(fp, "%d -> %d\n",
|
|
||||||
mmc_four_char_to_int(c->opcode + 6),
|
|
||||||
mmc_four_char_to_int(c->opcode + 2));
|
|
||||||
} else if (c->dir == TO_DRIVE) {
|
|
||||||
fprintf(fp, "To drive: %db\n", c->page->bytes);
|
|
||||||
for (i = 0; i < c->page->bytes; i++)
|
|
||||||
fprintf(fp, "%2.2x%c", c->page->data[i],
|
|
||||||
((i % 20) == 19 ? '\n' : ' '));
|
|
||||||
if (i % 20)
|
|
||||||
fprintf(fp, "\n");
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ts A91106 */
|
|
||||||
int scsi_show_cmd_reply(struct command *c, void *fp_in, int flag)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
FILE *fp = fp_in;
|
|
||||||
|
|
||||||
if (c->dir != FROM_DRIVE)
|
|
||||||
return 2;
|
|
||||||
if (c->opcode[0] == 0x28 || c->opcode[0] == 0x3C ||
|
|
||||||
c->opcode[0] == 0xA8 || c->opcode[0] == 0xBE) {
|
|
||||||
/* READ commands */
|
|
||||||
/* >>> report amount of data */;
|
|
||||||
|
|
||||||
return 2;
|
|
||||||
}
|
|
||||||
fprintf(fp, "From drive: %db\n", c->dxfer_len);
|
|
||||||
for (i = 0; i < c->dxfer_len; i++)
|
|
||||||
fprintf(fp, "%2.2x%c", c->page->data[i],
|
|
||||||
((i % 20) == 19 ? '\n' : ' '));
|
|
||||||
if (i % 20)
|
|
||||||
fprintf(fp, "\n");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* ts A91218 (former sg_log_cmd ts A70518) */
|
|
||||||
/** Logs command (before execution) */
|
|
||||||
int scsi_log_cmd(struct command *c, void *fp_in, int flag)
|
|
||||||
{
|
|
||||||
FILE *fp = fp_in;
|
|
||||||
|
|
||||||
if (fp != NULL && (fp == stderr || (burn_sg_log_scsi & 1))) {
|
|
||||||
scsi_show_cmd_text(c, fp, 0);
|
|
||||||
if (burn_sg_log_scsi & 4)
|
|
||||||
fflush(fp);
|
|
||||||
}
|
|
||||||
if (fp == stderr || !(burn_sg_log_scsi & 2))
|
|
||||||
return 1;
|
|
||||||
scsi_log_cmd(c, stderr, flag);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* ts A91221 (former sg_log_err ts A91108) */
|
|
||||||
/** Logs outcome of a sg command.
|
|
||||||
@param flag bit0 causes an error message
|
|
||||||
bit1 do not print duration
|
|
||||||
*/
|
|
||||||
int scsi_log_err(struct command *c, void *fp_in, unsigned char sense[18],
|
|
||||||
int sense_len, int duration, int flag)
|
|
||||||
{
|
|
||||||
char durtxt[20];
|
|
||||||
FILE *fp = fp_in;
|
|
||||||
int key, asc, ascq, i, l;
|
|
||||||
|
|
||||||
if (fp != NULL && (fp == stderr || (burn_sg_log_scsi & 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;
|
|
||||||
if (!(flag & 2))
|
|
||||||
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",
|
|
||||||
(unsigned int) key, (unsigned int) asc,
|
|
||||||
(unsigned int) ascq, durtxt);
|
|
||||||
} else {
|
|
||||||
scsi_show_cmd_reply(c, fp, 0);
|
|
||||||
if (!(flag & 2))
|
|
||||||
fprintf(fp,"%6d ms\n", duration);
|
|
||||||
}
|
|
||||||
if (burn_sg_log_scsi & 4)
|
|
||||||
fflush(fp);
|
|
||||||
}
|
|
||||||
if (fp == stderr || !(burn_sg_log_scsi & 2))
|
|
||||||
return 1;
|
|
||||||
scsi_log_err(c, stderr, sense, sense_len, duration, flag);
|
|
||||||
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 (burn_sg_log_scsi & 3)
|
|
||||||
scsi_log_err(c, fp, sense, sense_len, duration,
|
|
||||||
(sense_len > 0) | (flag & 2));
|
|
||||||
if (sense_len <= 0)
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
@ -1,11 +1,5 @@
|
|||||||
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||||
|
|
||||||
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
|
|
||||||
Copyright (c) 2006 - 2010 Thomas Schmitt <scdbackup@gmx.net>
|
|
||||||
Provided under GPL version 2 or later.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef __SPC
|
#ifndef __SPC
|
||||||
#define __SPC
|
#define __SPC
|
||||||
|
|
||||||
@ -49,7 +43,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, GO_ON };
|
enum response { RETRY, FAIL };
|
||||||
enum response scsi_error(struct burn_drive *, unsigned char *, int);
|
enum response scsi_error(struct burn_drive *, unsigned char *, int);
|
||||||
|
|
||||||
/* ts A61122 */
|
/* ts A61122 */
|
||||||
@ -65,42 +59,4 @@ int scsi_notify_error(struct burn_drive *, struct command *c,
|
|||||||
/* ts A70519 */
|
/* ts A70519 */
|
||||||
int scsi_init_command(struct command *c, unsigned char *opcode, int oplen);
|
int scsi_init_command(struct command *c, unsigned char *opcode, int oplen);
|
||||||
|
|
||||||
/* ts A91106 */
|
|
||||||
int scsi_show_cmd_text(struct command *c, void *fp, int flag);
|
|
||||||
|
|
||||||
/* ts A91106 */
|
|
||||||
int scsi_show_cmd_reply(struct command *c, void *fp, int flag);
|
|
||||||
|
|
||||||
/* ts A91218 (former sg_log_cmd ts A70518) */
|
|
||||||
/** Logs command (before execution) */
|
|
||||||
int scsi_log_cmd(struct command *c, void *fp, int flag);
|
|
||||||
|
|
||||||
/* ts A91221 (former sg_log_err ts A91108) */
|
|
||||||
/** Logs outcome of a sg command. */
|
|
||||||
int scsi_log_err(struct command *c, void *fp, unsigned char sense[18],
|
|
||||||
int 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*/
|
||||||
|
@ -1,13 +1,4 @@
|
|||||||
|
|
||||||
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
|
|
||||||
Copyright (c) 2006 - 2011 Thomas Schmitt <scdbackup@gmx.net>
|
|
||||||
Provided under GPL version 2 or later.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
#include "../config.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* ts A61008 */
|
/* ts A61008 */
|
||||||
/* #include <a ssert.h> */
|
/* #include <a ssert.h> */
|
||||||
|
|
||||||
@ -170,8 +161,6 @@ struct burn_track *burn_track_create(void)
|
|||||||
/* ts A61031 */
|
/* ts A61031 */
|
||||||
t->open_ended = 0;
|
t->open_ended = 0;
|
||||||
t->track_data_done = 0;
|
t->track_data_done = 0;
|
||||||
/* ts B10103 */
|
|
||||||
t->end_on_premature_eoi = 0;
|
|
||||||
|
|
||||||
t->postgap = 0;
|
t->postgap = 0;
|
||||||
t->pregap1 = 0;
|
t->pregap1 = 0;
|
||||||
@ -292,23 +281,13 @@ void burn_track_define_data(struct burn_track *t, int offset, int tail,
|
|||||||
/* ts A61024 */
|
/* ts A61024 */
|
||||||
int burn_track_set_byte_swap(struct burn_track *t, int swap_source_bytes)
|
int burn_track_set_byte_swap(struct burn_track *t, int swap_source_bytes)
|
||||||
{
|
{
|
||||||
if (swap_source_bytes != 0 && swap_source_bytes != 1)
|
if(swap_source_bytes!=0 && swap_source_bytes!=1)
|
||||||
return 0;
|
return 0;
|
||||||
t->swap_source_bytes = swap_source_bytes;
|
t->swap_source_bytes = swap_source_bytes;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ts A90911 : API */
|
|
||||||
int burn_track_set_cdxa_conv(struct burn_track *t, int value)
|
|
||||||
{
|
|
||||||
if (value < 0 || value > 1)
|
|
||||||
return 0;
|
|
||||||
t->cdxa_conversion = value;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void burn_track_set_isrc(struct burn_track *t, char *country, char *owner,
|
void burn_track_set_isrc(struct burn_track *t, char *country, char *owner,
|
||||||
unsigned char year, unsigned int serial)
|
unsigned char year, unsigned int serial)
|
||||||
{
|
{
|
||||||
@ -379,11 +358,6 @@ int burn_track_get_sectors(struct burn_track *t)
|
|||||||
int sectors, seclen;
|
int sectors, seclen;
|
||||||
|
|
||||||
seclen = burn_sector_length(t->mode);
|
seclen = burn_sector_length(t->mode);
|
||||||
|
|
||||||
if (t->cdxa_conversion == 1)
|
|
||||||
/* ts A90911 : will read blocks of 2056 bytes and write 2048 */
|
|
||||||
seclen += 8;
|
|
||||||
|
|
||||||
if (t->source != NULL) /* ts A80808 : mending sigsegv */
|
if (t->source != NULL) /* ts A80808 : mending sigsegv */
|
||||||
size = t->offset + t->source->get_size(t->source) + t->tail;
|
size = t->offset + t->source->get_size(t->source) + t->tail;
|
||||||
else if(t->entry != NULL) {
|
else if(t->entry != NULL) {
|
||||||
|
@ -1,9 +1,3 @@
|
|||||||
|
|
||||||
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
|
|
||||||
Copyright (c) 2006 - 2011 Thomas Schmitt <scdbackup@gmx.net>
|
|
||||||
Provided under GPL version 2 or later.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef BURN__STRUCTURE_H
|
#ifndef BURN__STRUCTURE_H
|
||||||
#define BURN__STRUCTURE_H
|
#define BURN__STRUCTURE_H
|
||||||
|
|
||||||
@ -55,14 +49,6 @@ struct burn_track
|
|||||||
int open_ended;
|
int open_ended;
|
||||||
/** End of open ended track flag : offset+payload+tail are delivered */
|
/** End of open ended track flag : offset+payload+tail are delivered */
|
||||||
int track_data_done;
|
int track_data_done;
|
||||||
/* ts B10103 */
|
|
||||||
/** End track writing on premature End-of-input if source is of
|
|
||||||
defined length.
|
|
||||||
0= normal operation in case of eoi
|
|
||||||
1= be ready to end track writing on eoi
|
|
||||||
2= eoi was encountered with previously set value of 1
|
|
||||||
*/
|
|
||||||
int end_on_premature_eoi;
|
|
||||||
|
|
||||||
/** The audio/data mode for the entry. Derived from control and
|
/** The audio/data mode for the entry. Derived from control and
|
||||||
possibly from reading the track's first sector. */
|
possibly from reading the track's first sector. */
|
||||||
@ -78,10 +64,6 @@ struct burn_track
|
|||||||
/* ts A61024 */
|
/* ts A61024 */
|
||||||
/** Byte swapping on source data stream : 0=none , 1=pairwise */
|
/** Byte swapping on source data stream : 0=none , 1=pairwise */
|
||||||
int swap_source_bytes;
|
int swap_source_bytes;
|
||||||
|
|
||||||
/* ts A90910 : conversions from CD XA prepared input */
|
|
||||||
int cdxa_conversion; /* 0=none, 1=remove -xa1 headers (first 8 bytes)*/
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct burn_session
|
struct burn_session
|
||||||
|
@ -1,14 +1,5 @@
|
|||||||
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||||
|
|
||||||
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
|
|
||||||
Provided under GPL version 2 or later.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
#include "../config.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* ts A61008 */
|
/* ts A61008 */
|
||||||
/* #include <a ssert.h> */
|
/* #include <a ssert.h> */
|
||||||
|
|
||||||
@ -139,7 +130,7 @@ void toc_find_modes(struct burn_drive *d)
|
|||||||
} else {
|
} else {
|
||||||
|
|
||||||
t->mode = BURN_MODE1;
|
t->mode = BURN_MODE1;
|
||||||
/* ts A70519 : this does not work with GNU/Linux 2.4 USB because one cannot
|
/* ts A70519 : this does not work with Linux 2.4 USB because one cannot
|
||||||
predict the exact dxfer_size without knowing the sector type.
|
predict the exact dxfer_size without knowing the sector type.
|
||||||
mem.sectors = 1;
|
mem.sectors = 1;
|
||||||
d->read_sectors(d, lba, mem.sectors, &o, &mem);
|
d->read_sectors(d, lba, mem.sectors, &o, &mem);
|
||||||
|
@ -1,10 +1,5 @@
|
|||||||
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||||
|
|
||||||
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
|
|
||||||
Provided under GPL version 2 or later.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef __TOC_H
|
#ifndef __TOC_H
|
||||||
#define __TOC_H
|
#define __TOC_H
|
||||||
|
|
||||||
|
@ -1,11 +1,5 @@
|
|||||||
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||||
|
|
||||||
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
|
|
||||||
Copyright (c) 2006 - 2010 Thomas Schmitt <scdbackup@gmx.net>
|
|
||||||
Provided under GPL version 2 or later.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef __TRANSPORT
|
#ifndef __TRANSPORT
|
||||||
#define __TRANSPORT
|
#define __TRANSPORT
|
||||||
|
|
||||||
@ -46,9 +40,7 @@ struct buffer
|
|||||||
Added 4096 bytes reserve against possible buffer overflows.
|
Added 4096 bytes reserve against possible buffer overflows.
|
||||||
(Changed in sector.c buffer flush test from >= to > BUFFER_SIZE .
|
(Changed in sector.c buffer flush test from >= to > BUFFER_SIZE .
|
||||||
This can at most cause a 1 sector overlap. Sometimes an offset
|
This can at most cause a 1 sector overlap. Sometimes an offset
|
||||||
of 16 byte is applied to the output data (in some RAW mode). )
|
of 16 byte is applied to the output data (in some RAW mode). ) */
|
||||||
burn_write_opts.cdxa_conversion can imply an offset of 8 bytes.
|
|
||||||
*/
|
|
||||||
unsigned char data[BUFFER_SIZE + 4096];
|
unsigned char data[BUFFER_SIZE + 4096];
|
||||||
int sectors;
|
int sectors;
|
||||||
int bytes;
|
int bytes;
|
||||||
@ -169,11 +161,6 @@ struct burn_drive
|
|||||||
char current_profile_text[80];
|
char current_profile_text[80];
|
||||||
int current_is_cd_profile;
|
int current_is_cd_profile;
|
||||||
int current_is_supported_profile;
|
int current_is_supported_profile;
|
||||||
/* ts A90603 */
|
|
||||||
int current_is_guessed_profile;
|
|
||||||
/* ts A90815 */
|
|
||||||
unsigned char all_profiles[256];
|
|
||||||
int num_profiles;
|
|
||||||
|
|
||||||
/* ts A70128 : MMC-to-MMC feature info from 46h for DVD-RW.
|
/* ts A70128 : MMC-to-MMC feature info from 46h for DVD-RW.
|
||||||
Quite internal. Regard as opaque :)
|
Quite internal. Regard as opaque :)
|
||||||
@ -184,19 +171,6 @@ struct burn_drive
|
|||||||
/* Link Size item number 0 from feature 0021h descriptor */
|
/* Link Size item number 0 from feature 0021h descriptor */
|
||||||
int current_feat21h_link_size;
|
int current_feat21h_link_size;
|
||||||
|
|
||||||
/* Flags from feature 0023h for formatting BD mmc5r03c.pdf 5.3.13
|
|
||||||
Byte 4 BD-RE:
|
|
||||||
bit0= Cert format 30h sub-type 10b
|
|
||||||
bit1= QCert format 30h sub-type 11b
|
|
||||||
bit2= Expand format 01h
|
|
||||||
bit3= RENoSA format 31h
|
|
||||||
Byte 8 BD-R:
|
|
||||||
bit0= RRM format 32h sub-type 10b
|
|
||||||
*/
|
|
||||||
int current_feat23h_byte4;
|
|
||||||
int current_feat23h_byte8;
|
|
||||||
|
|
||||||
|
|
||||||
/* Flags from feature 002Fh feature descriptor mmc5r03c.pdf 5.3.25 :
|
/* Flags from feature 002Fh feature descriptor mmc5r03c.pdf 5.3.25 :
|
||||||
bit1= DVD-RW supported
|
bit1= DVD-RW supported
|
||||||
bit2= Test Write available
|
bit2= Test Write available
|
||||||
@ -218,25 +192,8 @@ struct burn_drive
|
|||||||
with BD-RE */
|
with BD-RE */
|
||||||
int do_stream_recording;
|
int do_stream_recording;
|
||||||
|
|
||||||
/* ts A90227 : the LBA where stream recording shall start.
|
|
||||||
Writing to lower LBA will be done without streaming.
|
|
||||||
*/
|
|
||||||
int stream_recording_start;
|
|
||||||
|
|
||||||
/* ts A61218 from 51h READ DISC INFORMATION */
|
/* ts A61218 from 51h READ DISC INFORMATION */
|
||||||
int last_lead_in;
|
|
||||||
int last_lead_out;
|
|
||||||
int num_opc_tables; /* ts A91104: -1= not yet known */
|
|
||||||
int bg_format_status; /* 0=needs format start, 1=needs format restart*/
|
int bg_format_status; /* 0=needs format start, 1=needs format restart*/
|
||||||
int disc_type; /* 0="CD-DA or CD-ROM", 0x10="CD-I", 0x20="CD-ROM XA" */
|
|
||||||
unsigned int disc_id; /* a "32 bit binary integer" */
|
|
||||||
char disc_bar_code[9];
|
|
||||||
int disc_app_code;
|
|
||||||
int disc_info_valid; /* bit0= disc_type , bit1= disc_id ,
|
|
||||||
bit2= disc_bar_code , bit3= disc_app_code
|
|
||||||
bit4= URU bit is set (= unrestricted use)
|
|
||||||
bit5= Erasable bit was set in reply
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* ts A70108 from 23h READ FORMAT CAPACITY mmc5r03c.pdf 6.24 */
|
/* ts A70108 from 23h READ FORMAT CAPACITY mmc5r03c.pdf 6.24 */
|
||||||
int format_descr_type; /* 1=unformatted, 2=formatted, 3=unclear */
|
int format_descr_type; /* 1=unformatted, 2=formatted, 3=unclear */
|
||||||
@ -266,9 +223,6 @@ struct burn_drive
|
|||||||
|
|
||||||
/* ts A70131 : from 51h READ DISC INFORMATION Number of Sessions (-1)*/
|
/* ts A70131 : from 51h READ DISC INFORMATION Number of Sessions (-1)*/
|
||||||
int complete_sessions;
|
int complete_sessions;
|
||||||
/* ts A90107 */
|
|
||||||
int state_of_last_session;
|
|
||||||
|
|
||||||
/* ts A70129 :
|
/* ts A70129 :
|
||||||
from 51h READ DISC INFORMATION Last Track Number in Last Session */
|
from 51h READ DISC INFORMATION Last Track Number in Last Session */
|
||||||
int last_track_no;
|
int last_track_no;
|
||||||
@ -281,9 +235,6 @@ struct burn_drive
|
|||||||
/* ts A70215 : if > 0 : first lba on media that is too high for write*/
|
/* ts A70215 : if > 0 : first lba on media that is too high for write*/
|
||||||
int media_lba_limit;
|
int media_lba_limit;
|
||||||
|
|
||||||
/* ts A81210 : Upper limit of readable data size,
|
|
||||||
0x7fffffff = unknown */
|
|
||||||
int media_read_capacity;
|
|
||||||
|
|
||||||
int toc_temp;
|
int toc_temp;
|
||||||
struct burn_disc *disc; /* disc structure */
|
struct burn_disc *disc; /* disc structure */
|
||||||
@ -312,8 +263,6 @@ struct burn_drive
|
|||||||
/* ts A70929 */
|
/* ts A70929 */
|
||||||
pid_t thread_pid;
|
pid_t thread_pid;
|
||||||
int thread_pid_valid;
|
int thread_pid_valid;
|
||||||
/* ts B00225 */
|
|
||||||
pthread_t thread_tid;
|
|
||||||
|
|
||||||
|
|
||||||
/* transport functions */
|
/* transport functions */
|
||||||
@ -339,11 +288,6 @@ struct burn_drive
|
|||||||
void (*eject) (struct burn_drive *);
|
void (*eject) (struct burn_drive *);
|
||||||
void (*load) (struct burn_drive *);
|
void (*load) (struct burn_drive *);
|
||||||
int (*start_unit) (struct burn_drive *);
|
int (*start_unit) (struct burn_drive *);
|
||||||
|
|
||||||
/* ts A90824 : Calming down noisy drives */
|
|
||||||
int (*stop_unit) (struct burn_drive *);
|
|
||||||
int is_stopped;
|
|
||||||
|
|
||||||
void (*read_disc_info) (struct burn_drive *);
|
void (*read_disc_info) (struct burn_drive *);
|
||||||
void (*read_sectors) (struct burn_drive *,
|
void (*read_sectors) (struct burn_drive *,
|
||||||
int start,
|
int start,
|
||||||
|
280
libburn/util.c
280
libburn/util.c
@ -1,20 +1,9 @@
|
|||||||
|
|
||||||
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
|
|
||||||
Copyright (c) 2006 - 2010 Thomas Schmitt <scdbackup@gmx.net>
|
|
||||||
Provided under GPL version 2 or later.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
#include "../config.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
/* ts A61008 */
|
/* ts A61008 */
|
||||||
/* #include <a ssert.h> */
|
/* #include <a ssert.h> */
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
/* ts A80914 : This is unneeded. Version info comes from libburn.h.
|
/* ts A80914 : This is unneeded. Version info comes from libburn.h.
|
||||||
#include "v ersion.h"
|
#include "v ersion.h"
|
||||||
@ -34,7 +23,7 @@ char *burn_strdup(char *s)
|
|||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
l = strlen(s) + 1;
|
l = strlen(s) + 1;
|
||||||
ret = calloc(1, l);
|
ret = malloc(l);
|
||||||
memcpy(ret, s, l);
|
memcpy(ret, s, l);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
@ -52,7 +41,7 @@ char *burn_strndup(char *s, int n)
|
|||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
l = strlen(s);
|
l = strlen(s);
|
||||||
ret = calloc(1, l < n ? l : n);
|
ret = malloc(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';
|
||||||
@ -67,268 +56,3 @@ void burn_version(int *major, int *minor, int *micro)
|
|||||||
*minor = burn_header_version_minor;
|
*minor = burn_header_version_minor;
|
||||||
*micro = burn_header_version_micro;
|
*micro = burn_header_version_micro;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
struct cd_mid_record {
|
|
||||||
char *manufacturer;
|
|
||||||
int m_li;
|
|
||||||
int s_li;
|
|
||||||
int f_li;
|
|
||||||
int m_lo;
|
|
||||||
int s_lo;
|
|
||||||
int f_lo;
|
|
||||||
char *other_brands;
|
|
||||||
};
|
|
||||||
typedef struct cd_mid_record cd_mid_record_t;
|
|
||||||
|
|
||||||
|
|
||||||
/* ts A90902 */
|
|
||||||
/** API
|
|
||||||
@param flag Bitfield for control purposes,
|
|
||||||
bit0= append "(aka %s)",other_brands to reply
|
|
||||||
*/
|
|
||||||
char *burn_guess_cd_manufacturer(int m_li, int s_li, int f_li,
|
|
||||||
int m_lo, int s_lo, int f_lo, int flag)
|
|
||||||
{
|
|
||||||
static cd_mid_record_t mid_list[]= {
|
|
||||||
{"SKC", 96, 40, 0, 0, 0, 0, ""},
|
|
||||||
{"Ritek Corp" , 96, 43, 30, 0, 0, 0, ""},
|
|
||||||
{"TDK / Ritek" , 97, 10, 0, 0, 0, 0, "TRAXDATA"},
|
|
||||||
{"TDK Corporation" , 97, 15, 0, 0, 0, 0, ""},
|
|
||||||
{"Ritek Corp" , 97, 15, 10, 0, 0, 0, "7-plus, Aopen, PONY, Power Source, TDK, TRAXDATA, HiCO, PHILIPS, Primdisc, Victor.JVC, OPTI STORAGE, Samsung"},
|
|
||||||
{"Mitsubishi Chemical Corporation" , 97, 15, 20, 0, 0, 0, ""},
|
|
||||||
{"Nan-Ya Plastics Corporation" , 97, 15, 30, 0, 0, 0, "Hatron, MMore, Acer, LITEON"},
|
|
||||||
{"Delphi" , 97, 15, 50, 0, 0, 0, ""},
|
|
||||||
{"Shenzhen SG&SAST" , 97, 16, 20, 0, 0, 0, ""},
|
|
||||||
{"Moser Baer India Limited" , 97, 17, 0, 0, 0, 0, "EMTEC, Intenso, YAKUMO, PLATINUM, Silver Circle"},
|
|
||||||
{"SKY media Manufacturing SA" , 97, 17, 10, 0, 0, 0, ""},
|
|
||||||
{"Wing" , 97, 18, 10, 0, 0, 0, ""},
|
|
||||||
{"DDT" , 97, 18, 20, 0, 0, 0, ""},
|
|
||||||
{"Daxon Technology Inc. / Acer" , 97, 22, 60, 0, 0, 0, "Maxmax, Diamond Data, BenQ, gold, SONY"},
|
|
||||||
{"Taiyo Yuden Company Limited" , 97, 24, 0, 0, 0, 0, "Maxell, FUJIFILM, SONY"},
|
|
||||||
{"Sony Corporation" , 97, 24, 10, 0, 0, 0, "LeadData, Imation"},
|
|
||||||
{"Computer Support Italcard s.r.l" , 97, 24, 20, 0, 0, 0, ""},
|
|
||||||
{"Unitech Japan Inc." , 97, 24, 30, 0, 0, 0, ""},
|
|
||||||
{"MPO, France" , 97, 25, 0, 0, 0, 0, "TDK"},
|
|
||||||
{"Hitachi Maxell Ltd." , 97, 25, 20, 0, 0, 0, ""},
|
|
||||||
{"Infodisc Technology Co,Ltd." , 97, 25, 30, 0, 0, 0, "MEMOREX, SPEEDA, Lead data"},
|
|
||||||
{"Xcitec" , 97, 25, 60, 0, 0, 0, ""},
|
|
||||||
{"Fornet International Pte Ltd" , 97, 26, 0, 0, 0, 0, "COMPUSA, Cdhouse"},
|
|
||||||
{"Postech Corporation" , 97, 26, 10, 0, 0, 0, "Mr.Platinum"},
|
|
||||||
{"SKC Co Ltd." , 97, 26, 20, 0, 0, 0, "Infinite"},
|
|
||||||
{"Fuji Photo Film Co,Ltd." , 97, 26, 40, 0, 0, 0, ""},
|
|
||||||
{"Lead Data Inc." , 97, 26, 50, 0, 0, 0, "SONY, Gigastorage, MIRAGE"},
|
|
||||||
{"CMC Magnetics Corporation" , 97, 26, 60, 0, 0, 0, "Daxon, Verbatim, Memorex, Bi-Winner, PLEXTOR, YAMAHA, Melody, Office DEPOT, Philips, eMARK, imation, HyperMedia, Samsung, Shintaro, Techworks"},
|
|
||||||
{"Ricoh Company Limited" , 97, 27, 0, 0, 0, 0, "Sony, Digital Storage, Csita"},
|
|
||||||
{"Plasmon Data Systems Ltd" , 97, 27, 10, 0, 0, 0, "Ritek, TDK, EMTEC, ALPHAPET, MANIA"},
|
|
||||||
{"Princo Corporation" , 97, 27, 20, 0, 0, 0, ""},
|
|
||||||
{"Pioneer" , 97, 27, 30, 0, 0, 0, ""},
|
|
||||||
{"Eastman Kodak Company" , 97, 27, 40, 0, 0, 0, ""},
|
|
||||||
{"Mitsui Chemicals Inc." , 97, 27, 50, 0, 0, 0, "MAM-A, TDK"},
|
|
||||||
{"Ricoh Company Limited" , 97, 27, 60, 0, 0, 0, "Ritek"},
|
|
||||||
{"Gigastorage Corporation" , 97, 28, 10, 0, 0, 0, "MaxMax, Nan-Ya"},
|
|
||||||
{"Multi Media Masters&Machinary SA" , 97, 28, 20, 0, 0, 0, "King, Mmirex"},
|
|
||||||
{"Ritek Corp" , 97, 31, 0, 0, 0, 0, "TDK"},
|
|
||||||
{"Grand Advance Technology Sdn. Bhd." , 97, 31, 30, 0, 0, 0, ""},
|
|
||||||
{"TDK Corporation" , 97, 32, 00, 0, 0, 0, ""},
|
|
||||||
{"Prodisc Technology Inc." , 97, 32, 10, 0, 0, 0, "Smartbuy, Mitsubishi, Digmaster, LG, Media Market"},
|
|
||||||
{"Mitsubishi Chemical Corporation" , 97, 34, 20, 0, 0, 0, "YAMAHA, Verbatim"},
|
|
||||||
{"Mitsui Chemicals Inc." , 97, 48, 50, 0, 0, 0, ""},
|
|
||||||
{"TDK Corporation" , 97, 49, 0, 0, 0, 0, ""},
|
|
||||||
{"", 0, 0, 0, 0, 0, 0, ""}
|
|
||||||
};
|
|
||||||
|
|
||||||
int i, f_li_0;
|
|
||||||
char buf[1024];
|
|
||||||
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);
|
|
||||||
for (i = 0; mid_list[i].manufacturer[0]; i++) {
|
|
||||||
if (m_li == mid_list[i].m_li &&
|
|
||||||
s_li == mid_list[i].s_li &&
|
|
||||||
(f_li_0 == mid_list[i].f_li || f_li == mid_list[i].f_li))
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (mid_list[i].manufacturer[0] == 0) {
|
|
||||||
sprintf(buf, "Unknown CD manufacturer. Please report code '%2.2dm%2.2ds%2.2df/%2.2dm%2.2ds%2.2df', the human readable brand, size, and speed to scdbackup@gmx.net.", m_li, s_li, f_li, m_lo, s_lo, f_lo);
|
|
||||||
result = strdup(buf);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Compose, allocate and copy result */
|
|
||||||
if ((flag & 1) && mid_list[i].other_brands[0]) {
|
|
||||||
sprintf(buf, "%s (aka %s)",
|
|
||||||
mid_list[i].manufacturer, mid_list[i].other_brands);
|
|
||||||
result = strdup(buf);
|
|
||||||
} else
|
|
||||||
result = strdup(mid_list[i].manufacturer);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* ts A90904 */
|
|
||||||
struct dvd_mid_record {
|
|
||||||
char *mc1;
|
|
||||||
char *mc2;
|
|
||||||
int mc1_sig_len;
|
|
||||||
char *manufacturer;
|
|
||||||
};
|
|
||||||
typedef struct dvd_mid_record dvd_mid_record_t;
|
|
||||||
|
|
||||||
/* ts A90904 */
|
|
||||||
char *burn_guess_manufacturer(int prf,
|
|
||||||
char *media_code1, char *media_code2, int flag)
|
|
||||||
{
|
|
||||||
int i, l = 0, m_li, s_li, f_li, m_lo, s_lo, f_lo;
|
|
||||||
char buf[1024];
|
|
||||||
char *result = NULL, *cpt;
|
|
||||||
|
|
||||||
/* Important Note: media_code1 and media_code2 are supposed to be
|
|
||||||
encoded by burn_util_make_printable_word().
|
|
||||||
Especially: ' ' -> '_' , {"_%/" unprintables -> %XY)
|
|
||||||
*/
|
|
||||||
static dvd_mid_record_t mid_list[]= {
|
|
||||||
{"AML", "", 8, "UML"},
|
|
||||||
{"BeAll", "", 5, "BeAll Developers, Inc."},
|
|
||||||
{"CMC", "", 3, "CMC Magnetics Corporation"},
|
|
||||||
{"DAXON", "", 5, "Daxon Technology Inc. / Acer"},
|
|
||||||
{"Daxon", "", 5, "Daxon Technology Inc. / Acer"},
|
|
||||||
{"FUJI", "", 4, "Fujifilm Holdings Corporation"},
|
|
||||||
{"INFODISC", "", 8, "New Star Digital Co., Ltd."},
|
|
||||||
{"INFOME", "", 6, "InfoMedia Inc."},
|
|
||||||
{"ISMMBD", "", 6, "Info Source Multi Media Ltd."},
|
|
||||||
{"JVC", "", 3, "JVC Limited"},
|
|
||||||
{"KIC01RG", "", 7, "AMC"},
|
|
||||||
{"LD", "", 8, "Lead Data Inc."},
|
|
||||||
{"LGE", "", 3, "LG Electronics"},
|
|
||||||
{"MAM", "", 8, "Mitsui Advanced Media, Inc. Europe"},
|
|
||||||
{"MAXELL", "", 6, "Hitachi Maxell Ltd."},
|
|
||||||
{"MBI", "", 3, "Moser Baer India Limited"},
|
|
||||||
{"MCC", "", 8, "Mitsubishi Chemical Corporation"},
|
|
||||||
{"MCI", "", 8, "Mitsui Chemicals Inc."},
|
|
||||||
{"MEI", "", 3, "Panasonic Corporation"},
|
|
||||||
{"MKM", "", 3, "Mitsubishi Kagaku Media Co."},
|
|
||||||
{"MMC", "", 8, "Mitsubishi Kagaku Media Co."},
|
|
||||||
{"MXL", "", 8, "Hitachi Maxell Ltd."},
|
|
||||||
{"NANYA", "", 5, "Nan-Ya Plastics Corporation"},
|
|
||||||
{"NSD", "", 8, "NESA International Inc."},
|
|
||||||
{"OPTODISC", "", 8, "Optodisc Technology Corporation"},
|
|
||||||
{"OTCBDR", "", 8, "Optodisc Technology Corporation"},
|
|
||||||
{"PHILIP", "", 8, "Moser Baer India Limited"},
|
|
||||||
{"PHILIPS", "", 8, "Philips"},
|
|
||||||
{"PRINCO", "", 6, "Princo Corporation"},
|
|
||||||
{"PRODISC", "", 7, "Prodisc Technology Inc."},
|
|
||||||
{"Prodisc", "", 7, "Prodisc Technology Inc."},
|
|
||||||
{"PVC", "", 3, "Pioneer"},
|
|
||||||
{"RICOHJPN", "", 8, "Ricoh Company Limited"},
|
|
||||||
{"RITEK", "", 5, "Ritek Corp"},
|
|
||||||
{"SONY", "", 4, "Sony Corporation"},
|
|
||||||
{"TDK", "", 3, "TDK Corporation"},
|
|
||||||
{"TT", "", 8, "TDK Corporation"},
|
|
||||||
{"TY", "", 8, "Taiyo Yuden Company Limited"},
|
|
||||||
{"TYG", "", 3, "Taiyo Yuden Company Limited"},
|
|
||||||
{"UTJR001", "", 7, "Unifino Inc."},
|
|
||||||
{"VERBAT", "", 5, "Mitsubishi Kagaku Media Co."},
|
|
||||||
{"YUDEN", "", 5, "Taiyo Yuden Company Limited"},
|
|
||||||
{"", "", 0, ""}
|
|
||||||
};
|
|
||||||
|
|
||||||
if (media_code2 != NULL &&
|
|
||||||
(prf == -1 || prf == 0x09 || prf == 0x0A)) {
|
|
||||||
if (strlen(media_code2) == 9 && media_code1[0] == '9' &&
|
|
||||||
media_code1[2] == 'm' && media_code1[5] == 's' &&
|
|
||||||
media_code1[8] == 'f' &&
|
|
||||||
strchr(media_code1, '%') == NULL) {
|
|
||||||
sscanf(media_code1, "%dm%ds%df", &m_li, &s_li, &f_li);
|
|
||||||
sscanf(media_code2, "%dm%ds%df", &m_lo, &s_lo, &f_lo);
|
|
||||||
if (m_li >= 96 && m_li <= 97 && m_lo > 0) {
|
|
||||||
result = burn_guess_cd_manufacturer(
|
|
||||||
m_li, s_li, f_li, m_lo, s_lo, f_lo, 0);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* DVD-R do not keep manufacturer id apart from media id.
|
|
||||||
Some manufacturers use a blank as separator which would now be '_'.
|
|
||||||
*/
|
|
||||||
cpt = strchr(media_code1, '_');
|
|
||||||
if (cpt != NULL && (prf == -1 || prf == 0x11 || prf == 0x13 ||
|
|
||||||
prf == 0x14 || prf == 0x15))
|
|
||||||
l = cpt - media_code1;
|
|
||||||
|
|
||||||
for (i = 0; mid_list[i].mc1[0]; i++) {
|
|
||||||
if (strncmp(mid_list[i].mc1, media_code1,
|
|
||||||
mid_list[i].mc1_sig_len) == 0)
|
|
||||||
break;
|
|
||||||
if (l > 0)
|
|
||||||
if (strncmp(mid_list[i].mc1, media_code1, l) == 0)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (mid_list[i].mc1[0] == 0) {
|
|
||||||
sprintf(buf, "Unknown DVD/BD manufacturer. Please report code '%s/%s', the human readable brand, size, and speed to scdbackup@gmx.net.",
|
|
||||||
media_code1, media_code2);
|
|
||||||
result = strdup(buf);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
result = strdup(mid_list[i].manufacturer);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* ts A90905 */
|
|
||||||
/* Make *text a single printable word */
|
|
||||||
/* IMPORTANT: text must be freeable memory !
|
|
||||||
@param flag bit0=escape '/' too
|
|
||||||
bit1=(overrides bit0) do not escape " _/"
|
|
||||||
*/
|
|
||||||
int burn_util_make_printable_word(char **text, int flag)
|
|
||||||
{
|
|
||||||
int i, esc_add = 0, ret;
|
|
||||||
char *wpt, *rpt, *new_text = NULL;
|
|
||||||
|
|
||||||
if (flag & 2)
|
|
||||||
flag &= ~1;
|
|
||||||
|
|
||||||
for (i = 0; (*text)[i]; i++) {
|
|
||||||
rpt = (*text) + i;
|
|
||||||
if (*rpt < 32 || *rpt > 126 || *rpt == 96 ||
|
|
||||||
((*rpt == '_' || *rpt == '%') && (!(flag & 2))) ||
|
|
||||||
(*rpt == '/' && (flag & 1)))
|
|
||||||
esc_add += 2;
|
|
||||||
}
|
|
||||||
if (esc_add) {
|
|
||||||
new_text = calloc(strlen(*text) + esc_add + 1, 1);
|
|
||||||
if (new_text == NULL) {
|
|
||||||
ret = -1;
|
|
||||||
goto ex;
|
|
||||||
}
|
|
||||||
wpt = new_text;
|
|
||||||
for (i = 0; (*text)[i]; i++) {
|
|
||||||
rpt = (*text) + i;
|
|
||||||
if (*rpt < 32 || *rpt > 126 || *rpt == 96 ||
|
|
||||||
((*rpt == '_' || *rpt == '%') && (!(flag & 2))) ||
|
|
||||||
(*rpt == '/' && (flag & 1))) {
|
|
||||||
sprintf(wpt, "%%%2.2X",
|
|
||||||
(unsigned int) *((unsigned char *) rpt));
|
|
||||||
wpt+= 3;
|
|
||||||
} else
|
|
||||||
*(wpt++) = *rpt;
|
|
||||||
}
|
|
||||||
*wpt = 0;
|
|
||||||
free(*text);
|
|
||||||
*text = new_text;
|
|
||||||
}
|
|
||||||
if (!(flag & 2))
|
|
||||||
for (i = 0; (*text)[i]; i++)
|
|
||||||
if ((*text)[i] == ' ')
|
|
||||||
(*text)[i] = '_';
|
|
||||||
ret = 1;
|
|
||||||
ex:
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
@ -5,7 +5,4 @@ char *burn_strdup(char *s);
|
|||||||
|
|
||||||
char *burn_strndup(char *s, int n);
|
char *burn_strndup(char *s, int n);
|
||||||
|
|
||||||
/* ts A90905 */
|
|
||||||
int burn_util_make_printable_word(char **text, int flag);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
509
libburn/write.c
509
libburn/write.c
@ -1,15 +1,5 @@
|
|||||||
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||||
|
|
||||||
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
|
|
||||||
Copyright (c) 2006 - 2011 Thomas Schmitt <scdbackup@gmx.net>
|
|
||||||
Provided under GPL version 2 or later.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
#include "../config.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
|
|
||||||
@ -43,8 +33,10 @@
|
|||||||
#include "libburn.h"
|
#include "libburn.h"
|
||||||
#include "drive.h"
|
#include "drive.h"
|
||||||
#include "transport.h"
|
#include "transport.h"
|
||||||
|
#include "crc.h"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
#include "init.h"
|
#include "init.h"
|
||||||
|
#include "lec.h"
|
||||||
#include "toc.h"
|
#include "toc.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "sg.h"
|
#include "sg.h"
|
||||||
@ -52,19 +44,11 @@
|
|||||||
#include "options.h"
|
#include "options.h"
|
||||||
#include "structure.h"
|
#include "structure.h"
|
||||||
#include "source.h"
|
#include "source.h"
|
||||||
#include "mmc.h"
|
|
||||||
#include "spc.h"
|
|
||||||
|
|
||||||
#include "libdax_msgs.h"
|
#include "libdax_msgs.h"
|
||||||
extern struct libdax_msgs *libdax_messenger;
|
extern struct libdax_msgs *libdax_messenger;
|
||||||
|
|
||||||
|
|
||||||
/* ts A91120 : <<< experimental */
|
|
||||||
#ifdef Libburn_mmap_write_buffeR
|
|
||||||
#include <sys/mman.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/* The maximum output size to be used with CD media. This is also curbed
|
/* The maximum output size to be used with CD media. This is also curbed
|
||||||
by BURN_OS_TRANSPORT_BUFFER_SIZE. The smaller number gets into effect.
|
by BURN_OS_TRANSPORT_BUFFER_SIZE. The smaller number gets into effect.
|
||||||
*/
|
*/
|
||||||
@ -385,9 +369,9 @@ struct cue_sheet *burn_create_toc_entries(struct burn_write_opts *o,
|
|||||||
runtime = nwa-150;
|
runtime = nwa-150;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
sheet = calloc(1, sizeof(struct cue_sheet));
|
sheet = malloc(sizeof(struct cue_sheet));
|
||||||
|
|
||||||
/* ts A61009 : react on failures of calloc(), add_cue_sheet()
|
/* ts A61009 : react on failures of malloc(), add_cue_sheet()
|
||||||
type_to_form() */
|
type_to_form() */
|
||||||
if (sheet == NULL) {
|
if (sheet == NULL) {
|
||||||
libdax_msgs_submit(libdax_messenger, -1, 0x00020111,
|
libdax_msgs_submit(libdax_messenger, -1, 0x00020111,
|
||||||
@ -786,18 +770,8 @@ int burn_write_track(struct burn_write_opts *o, struct burn_session *s,
|
|||||||
libdax_msgs_submit(libdax_messenger, d->global_index, 0x000002,
|
libdax_msgs_submit(libdax_messenger, d->global_index, 0x000002,
|
||||||
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_ZERO,
|
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_ZERO,
|
||||||
msg, 0, 0);
|
msg, 0, 0);
|
||||||
|
if (nwa > d->nwa)
|
||||||
/* ts A91003 */
|
d->nwa = nwa;
|
||||||
if (nwa < d->nwa) {
|
|
||||||
libdax_msgs_submit(libdax_messenger, d->global_index,
|
|
||||||
0x00020173,
|
|
||||||
LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH,
|
|
||||||
"Drive tells NWA smaller than last written address",
|
|
||||||
0, 0);
|
|
||||||
d->sync_cache(d);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
d->nwa = nwa;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -894,19 +868,8 @@ ex:;
|
|||||||
d->sync_cache(d);
|
d->sync_cache(d);
|
||||||
|
|
||||||
/* ts A61030 */
|
/* ts A61030 */
|
||||||
/* ts A91003 :
|
if (burn_write_close_track(o, s, tnum) <= 0)
|
||||||
At least in simulation mode this causes NWA=0 for the
|
ret = 0;
|
||||||
next track. cdrecord does not use CLOSE TRACK at all but
|
|
||||||
ends the tracks by SYNCHRONIZE CACHE alone.
|
|
||||||
*/
|
|
||||||
/* ts A91202 :
|
|
||||||
Peng Shao reports that his LG GH22LS30 issues an SCSI error
|
|
||||||
on CLOSE TRACK even in non-dummy mode. So i better give up
|
|
||||||
this gesture which seems not be needed by any drive.
|
|
||||||
if (!o->simulate)
|
|
||||||
if (burn_write_close_track(o, s, tnum) <= 0)
|
|
||||||
ret = 0;
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -921,8 +884,8 @@ int burn_disc_write_is_ok(struct burn_write_opts *o, struct burn_disc *disc,
|
|||||||
|
|
||||||
for (i = 0; i < disc->sessions; i++)
|
for (i = 0; i < disc->sessions; i++)
|
||||||
for (t = 0; t < disc->session[i]->tracks; t++)
|
for (t = 0; t < disc->session[i]->tracks; t++)
|
||||||
if (sector_headers_is_ok(
|
if (!sector_headers_is_ok(
|
||||||
o, disc->session[i]->track[t]->mode) != 1)
|
o, disc->session[i]->track[t]->mode))
|
||||||
goto bad_track_mode_found;
|
goto bad_track_mode_found;
|
||||||
return 1;
|
return 1;
|
||||||
bad_track_mode_found:;
|
bad_track_mode_found:;
|
||||||
@ -946,8 +909,6 @@ int burn_disc_init_write_status(struct burn_write_opts *o,
|
|||||||
|
|
||||||
d->cancel = 0;
|
d->cancel = 0;
|
||||||
|
|
||||||
#ifdef Libburn_reset_progress_asynC
|
|
||||||
/* <<< This is now done in async.c */
|
|
||||||
/* init progress before showing the state */
|
/* init progress before showing the state */
|
||||||
d->progress.session = 0;
|
d->progress.session = 0;
|
||||||
d->progress.sessions = disc->sessions;
|
d->progress.sessions = disc->sessions;
|
||||||
@ -962,7 +923,6 @@ int burn_disc_init_write_status(struct burn_write_opts *o,
|
|||||||
d->progress.sectors = 0;
|
d->progress.sectors = 0;
|
||||||
d->progress.sector = 0;
|
d->progress.sector = 0;
|
||||||
d->progress.track = 0;
|
d->progress.track = 0;
|
||||||
#endif /* Libburn_reset_progress_asynC */
|
|
||||||
|
|
||||||
/* ts A61023 */
|
/* ts A61023 */
|
||||||
d->progress.buffer_capacity = 0;
|
d->progress.buffer_capacity = 0;
|
||||||
@ -1045,10 +1005,8 @@ int burn_precheck_write(struct burn_write_opts *o, struct burn_disc *disc,
|
|||||||
} else if (d->drive_role == 3 ||
|
} else if (d->drive_role == 3 ||
|
||||||
d->current_profile == 0x11 || d->current_profile == 0x14 ||
|
d->current_profile == 0x11 || d->current_profile == 0x14 ||
|
||||||
d->current_profile == 0x15 ||
|
d->current_profile == 0x15 ||
|
||||||
d->current_profile == 0x1b || d->current_profile == 0x2b ||
|
d->current_profile == 0x1b || d->current_profile == 0x2b ) {
|
||||||
d->current_profile == 0x41) {
|
/* DVD-R* Sequential , DVD+R[/DL] , sequential stdio "drive" */
|
||||||
/* DVD-R* Sequential , DVD+R[/DL] , BD-R,
|
|
||||||
sequential stdio "drive" */
|
|
||||||
if (o->start_byte >= 0)
|
if (o->start_byte >= 0)
|
||||||
strcat(reasons, "write start address not supported, ");
|
strcat(reasons, "write start address not supported, ");
|
||||||
} else {
|
} else {
|
||||||
@ -1105,25 +1063,11 @@ int burn_disc_open_track_dvd_minus_r(struct burn_write_opts *o,
|
|||||||
/* ts A70214 : eventually adjust already expanded size of track */
|
/* ts A70214 : eventually adjust already expanded size of track */
|
||||||
burn_track_apply_fillup(s->track[tnum], d->media_capacity_remaining,1);
|
burn_track_apply_fillup(s->track[tnum], d->media_capacity_remaining,1);
|
||||||
|
|
||||||
#ifdef Libburn_pioneer_dvr_216d_with_opC
|
|
||||||
fprintf(stderr, "libburn_DEBUG: Libburn_pioneer_dvr_216d_with_opC : num_opc_tables = %d\n", d->num_opc_tables);
|
|
||||||
if (d->num_opc_tables <= 0 && !o->simulate) {
|
|
||||||
fprintf(stderr, "libburn_DEBUG: Libburn_pioneer_dvr_216d_with_opC : performing OPC\n");
|
|
||||||
d->perform_opc(d);
|
|
||||||
fprintf(stderr, "libburn_DEBUG: Libburn_pioneer_dvr_216d_with_opC : done\n");
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef Libburn_pioneer_dvr_216d_get_evenT
|
|
||||||
mmc_get_event(d);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (o->write_type == BURN_WRITE_SAO) { /* DAO */
|
if (o->write_type == BURN_WRITE_SAO) { /* DAO */
|
||||||
/* Round track size up to write chunk size and reserve track */
|
/* Round track size up to 32 KiB and reserve track */
|
||||||
size = ((off_t) burn_track_get_sectors(s->track[tnum]))
|
size = ((off_t) burn_track_get_sectors(s->track[tnum]))
|
||||||
* (off_t) 2048;
|
* (off_t) 2048;
|
||||||
if (size % o->obs)
|
size = (size + (off_t) 0x7fff) & ~((off_t) 0x7fff);
|
||||||
size += (off_t) (o->obs - (size % o->obs));
|
|
||||||
ret = d->reserve_track(d, size);
|
ret = d->reserve_track(d, size);
|
||||||
if (ret <= 0) {
|
if (ret <= 0) {
|
||||||
sprintf(msg, "Cannot reserve track of %.f bytes",
|
sprintf(msg, "Cannot reserve track of %.f bytes",
|
||||||
@ -1161,11 +1105,10 @@ int burn_disc_open_track_dvd_plus_r(struct burn_write_opts *o,
|
|||||||
|
|
||||||
if (o->write_type == BURN_WRITE_SAO &&
|
if (o->write_type == BURN_WRITE_SAO &&
|
||||||
! burn_track_is_open_ended(s->track[tnum])) {
|
! burn_track_is_open_ended(s->track[tnum])) {
|
||||||
/* Round track size up to write chunk size and reserve track */
|
/* Round track size up to 32 KiB and reserve track */
|
||||||
size = ((off_t) burn_track_get_sectors(s->track[tnum]))
|
size = ((off_t) burn_track_get_sectors(s->track[tnum]))
|
||||||
* (off_t) 2048;
|
* (off_t) 2048;
|
||||||
if (size % o->obs)
|
size = (size + (off_t) 0x7fff) & ~((off_t) 0x7fff);
|
||||||
size += (off_t) (o->obs - (size % o->obs));
|
|
||||||
ret = d->reserve_track(d, size);
|
ret = d->reserve_track(d, size);
|
||||||
if (ret <= 0) {
|
if (ret <= 0) {
|
||||||
sprintf(msg, "Cannot reserve track of %.f bytes",
|
sprintf(msg, "Cannot reserve track of %.f bytes",
|
||||||
@ -1210,29 +1153,19 @@ int burn_disc_close_track_dvd_minus_r(struct burn_write_opts *o,
|
|||||||
int burn_disc_finalize_dvd_plus_r(struct burn_write_opts *o)
|
int burn_disc_finalize_dvd_plus_r(struct burn_write_opts *o)
|
||||||
{
|
{
|
||||||
struct burn_drive *d = o->drive;
|
struct burn_drive *d = o->drive;
|
||||||
char msg[80];
|
|
||||||
|
|
||||||
sprintf(msg, "Finalizing %s ...",
|
|
||||||
d->current_profile_text);
|
|
||||||
libdax_msgs_submit(libdax_messenger, d->global_index,
|
libdax_msgs_submit(libdax_messenger, d->global_index,
|
||||||
0x00000002,
|
0x00000002,
|
||||||
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_ZERO,
|
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_ZERO,
|
||||||
msg, 0, 0);
|
"Finalizing DVD+R ...", 0, 0);
|
||||||
|
|
||||||
if(d->current_profile == 0x41) { /* BD-R */
|
/* CLOSE SESSION, 101b, Finalize with minimal radius */
|
||||||
/* CLOSE SESSION, 110b, Finalize Disc */
|
d->close_track_session(d, 2, 1); /* (2<<1)|1 = 5 */
|
||||||
d->close_track_session(d, 3, 0); /* (3<<1)|0 = 6 */
|
|
||||||
} else {
|
|
||||||
/* CLOSE SESSION, 101b, Finalize with minimal radius */
|
|
||||||
d->close_track_session(d, 2, 1); /* (2<<1)|1 = 5 */
|
|
||||||
}
|
|
||||||
|
|
||||||
sprintf(msg, "... finalizing %s done ",
|
|
||||||
d->current_profile_text);
|
|
||||||
libdax_msgs_submit(libdax_messenger, d->global_index,
|
libdax_msgs_submit(libdax_messenger, d->global_index,
|
||||||
0x00000002,
|
0x00000002,
|
||||||
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_ZERO,
|
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_ZERO,
|
||||||
msg, 0, 0);
|
"... finalizing DVD+R done ", 0, 0);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -1267,133 +1200,7 @@ int burn_disc_close_track_dvd_plus_r(struct burn_write_opts *o,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* <<<
|
/* ts A61218 - A70129 */
|
||||||
#define Libburn_simplified_dvd_chunk_transactioN 1
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef Libburn_simplified_dvd_chunk_transactioN
|
|
||||||
|
|
||||||
/* ts A91114 : EXPERIMENTAL, NOT COMPLETELY IMPLEMENTED
|
|
||||||
|
|
||||||
Simplified data transmission for DVD. libburn via GNU/Linux USB is 30 %
|
|
||||||
slower than growisofs or cdrecord when transmitting 32 KB chunks.
|
|
||||||
With 64 KB chunks it is 20% faster than the competitors.
|
|
||||||
No heavy CPU load is visible but there might be subtle race conditions in
|
|
||||||
the USB driver which work better with shorter time gaps between WRITE
|
|
||||||
commands.
|
|
||||||
|
|
||||||
Insight: It is actually about the interference of track source reading
|
|
||||||
with SCSI writing via USB. growisofs reads with O_DIRECT into a
|
|
||||||
mmap()ed buffer. When doing the same, libburn with 32 KB chunks
|
|
||||||
reaches similar write speed.
|
|
||||||
On the other hand, 64 KB chunks are 20% faster than that and
|
|
||||||
are not improved by reading O_DIRECT.
|
|
||||||
|
|
||||||
O_DIRECT is a property of the input fd of struct burn_source.
|
|
||||||
It can only be done with properly aligned memory and with aligned
|
|
||||||
read size. Alignment size is file system system specific.
|
|
||||||
System call
|
|
||||||
mmap(NULL, (size_t) buffer_size, PROT_READ | PROT_WRITE,
|
|
||||||
MAP_SHARED | MAP_ANONYMOUS, -1, (off_t) 0);
|
|
||||||
is supposed to allocate a properly aligned buffer.
|
|
||||||
64 KB is supposed to be a safe size.
|
|
||||||
Actually mmap() seems to be the main cause for a positive effect
|
|
||||||
of O_DIRECT.
|
|
||||||
|
|
||||||
This simplified transmission function did not bring visible benefit.
|
|
||||||
So for now it is not worth to teach it all applicable details of old
|
|
||||||
CD sector oriented transmission.
|
|
||||||
|
|
||||||
@return 1= ok, go on , 2= no input with track->open_ended = nothing written
|
|
||||||
<= 0 = error
|
|
||||||
*/
|
|
||||||
static int transact_dvd_chunk(struct burn_write_opts *opts,
|
|
||||||
struct burn_track *track)
|
|
||||||
{
|
|
||||||
int curr = 0, valid, err;
|
|
||||||
struct burn_drive *d = opts->drive;
|
|
||||||
struct buffer *out = d->buffer;
|
|
||||||
unsigned char *data = out->data;
|
|
||||||
|
|
||||||
#ifdef Libburn_log_in_and_out_streaM
|
|
||||||
/* ts A61031 */
|
|
||||||
static int tee_fd= -1;
|
|
||||||
if(tee_fd==-1)
|
|
||||||
tee_fd= open("/tmp/libburn_sg_readin",
|
|
||||||
O_WRONLY|O_CREAT|O_TRUNC,S_IRUSR|S_IWUSR);
|
|
||||||
#endif /* Libburn_log_in_and_out_streaM */
|
|
||||||
|
|
||||||
|
|
||||||
/* Read a chunk full of data */
|
|
||||||
|
|
||||||
/* ??? Do we have offset padding ? >>> First produce offset padding */;
|
|
||||||
|
|
||||||
/* <<<< */
|
|
||||||
if (0 && !track->eos) {
|
|
||||||
for (curr = 0; curr < opts->obs; curr += 2048) {
|
|
||||||
if (track->source->read != NULL)
|
|
||||||
valid = track->source->read(track->source,
|
|
||||||
data + curr, 2048);
|
|
||||||
else
|
|
||||||
valid = track->source->read_xt(track->source,
|
|
||||||
data + curr, 2048);
|
|
||||||
if (valid <= 0) {
|
|
||||||
track->eos = 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
track->sourcecount += valid;
|
|
||||||
|
|
||||||
#ifdef Libburn_log_in_and_out_streaM
|
|
||||||
if(tee_fd!=-1 && valid>0) {
|
|
||||||
write(tee_fd, data + curr, valid);
|
|
||||||
}
|
|
||||||
#endif /* Libburn_log_in_and_out_streaM */
|
|
||||||
|
|
||||||
}
|
|
||||||
} else if (!track->eos){
|
|
||||||
valid = track->source->read(track->source, data, opts->obs);
|
|
||||||
if (valid <= 0) {
|
|
||||||
track->eos = 1;
|
|
||||||
} else {
|
|
||||||
track->sourcecount += valid;
|
|
||||||
curr = valid;
|
|
||||||
|
|
||||||
#ifdef Libburn_log_in_and_out_streaM
|
|
||||||
if(tee_fd!=-1 && valid>0) {
|
|
||||||
write(tee_fd, data, valid);
|
|
||||||
}
|
|
||||||
#endif /* Libburn_log_in_and_out_streaM */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (curr == 0 && track->open_ended) {
|
|
||||||
|
|
||||||
/* >>> allow tail padding */;
|
|
||||||
|
|
||||||
return 2;
|
|
||||||
}
|
|
||||||
if (curr < opts->obs)
|
|
||||||
memset(data + curr , 0, opts->obs - curr);
|
|
||||||
|
|
||||||
/* Write chunk */
|
|
||||||
out->bytes = opts->obs;
|
|
||||||
out->sectors = out->bytes / 2048;
|
|
||||||
err = d->write(d, d->nwa, out);
|
|
||||||
if (err == BE_CANCELLED)
|
|
||||||
return 0;
|
|
||||||
track->writecount += out->bytes;
|
|
||||||
track->written_sectors += out->sectors;
|
|
||||||
d->progress.buffered_bytes += out->bytes;
|
|
||||||
d->nwa += out->sectors;
|
|
||||||
out->bytes = 0;
|
|
||||||
out->sectors = 0;
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* Libburn_simplified_dvd_chunk_transactioN */
|
|
||||||
|
|
||||||
|
|
||||||
/* ts A61218 - A81208 */
|
|
||||||
int burn_dvd_write_track(struct burn_write_opts *o,
|
int burn_dvd_write_track(struct burn_write_opts *o,
|
||||||
struct burn_session *s, int tnum, int is_last_track)
|
struct burn_session *s, int tnum, int is_last_track)
|
||||||
{
|
{
|
||||||
@ -1402,7 +1209,6 @@ int burn_dvd_write_track(struct burn_write_opts *o,
|
|||||||
struct buffer *out = d->buffer;
|
struct buffer *out = d->buffer;
|
||||||
int sectors;
|
int sectors;
|
||||||
int i, open_ended = 0, ret= 0, is_flushed = 0;
|
int i, open_ended = 0, ret= 0, is_flushed = 0;
|
||||||
int first_buf_cap = 0, further_cap = 0, buf_cap_step = 1024;
|
|
||||||
|
|
||||||
/* ts A70213 : eventually expand size of track to max */
|
/* ts A70213 : eventually expand size of track to max */
|
||||||
burn_track_apply_fillup(t, d->media_capacity_remaining, 0);
|
burn_track_apply_fillup(t, d->media_capacity_remaining, 0);
|
||||||
@ -1413,21 +1219,11 @@ int burn_dvd_write_track(struct burn_write_opts *o,
|
|||||||
ret = burn_disc_open_track_dvd_minus_r(o, s, tnum);
|
ret = burn_disc_open_track_dvd_minus_r(o, s, tnum);
|
||||||
if (ret <= 0)
|
if (ret <= 0)
|
||||||
goto ex;
|
goto ex;
|
||||||
/* Pioneer DVR-216D rev 1.09 hates multiple buffer inquiries
|
|
||||||
before the drive buffer is full.
|
|
||||||
*/
|
|
||||||
first_buf_cap = 0;
|
|
||||||
further_cap = -1;
|
|
||||||
} else if (d->current_profile == 0x1b || d->current_profile == 0x2b) {
|
} else if (d->current_profile == 0x1b || d->current_profile == 0x2b) {
|
||||||
/* DVD+R , DVD+R/DL */
|
/* DVD+R , DVD+R/DL */
|
||||||
ret = burn_disc_open_track_dvd_plus_r(o, s, tnum);
|
ret = burn_disc_open_track_dvd_plus_r(o, s, tnum);
|
||||||
if (ret <= 0)
|
if (ret <= 0)
|
||||||
goto ex;
|
goto ex;
|
||||||
} else if (d->current_profile == 0x41) {
|
|
||||||
/* BD-R SRM */
|
|
||||||
ret = burn_disc_open_track_dvd_plus_r(o, s, tnum);
|
|
||||||
if (ret <= 0)
|
|
||||||
goto ex;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sectors = burn_track_get_sectors(t);
|
sectors = burn_track_get_sectors(t);
|
||||||
@ -1453,30 +1249,12 @@ int burn_dvd_write_track(struct burn_write_opts *o,
|
|||||||
for (i = 0; open_ended || i < sectors; i++) {
|
for (i = 0; open_ended || i < sectors; i++) {
|
||||||
|
|
||||||
/* From time to time inquire drive buffer */
|
/* From time to time inquire drive buffer */
|
||||||
/* ts A91110: Eventually avoid to do this more than once
|
if ((i%256)==0)
|
||||||
before the drive buffer is full. See above DVD-
|
|
||||||
*/
|
|
||||||
if (i == first_buf_cap ||
|
|
||||||
((i % buf_cap_step) == 0 &&
|
|
||||||
(i >= further_cap || further_cap < 0))) {
|
|
||||||
d->read_buffer_capacity(d);
|
d->read_buffer_capacity(d);
|
||||||
if (further_cap < 0)
|
|
||||||
further_cap =
|
|
||||||
d->progress.buffer_capacity / 2048 + 128;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef Libburn_simplified_dvd_chunk_transactioN
|
|
||||||
|
|
||||||
ret = transact_dvd_chunk(o, t);
|
|
||||||
if (ret <= 0)
|
|
||||||
{ret = 0; goto ex;}
|
|
||||||
i += o->obs / 2048 - 1;
|
|
||||||
d->progress.sector += o->obs / 2048 - 1;
|
|
||||||
#else
|
|
||||||
/* transact a (CD sized) sector */
|
/* transact a (CD sized) sector */
|
||||||
if (!sector_data(o, t, 0))
|
if (!sector_data(o, t, 0))
|
||||||
{ ret = 0; goto ex; }
|
{ ret = 0; goto ex; }
|
||||||
#endif
|
|
||||||
|
|
||||||
if (open_ended) {
|
if (open_ended) {
|
||||||
d->progress.sectors = sectors = i;
|
d->progress.sectors = sectors = i;
|
||||||
@ -1514,12 +1292,6 @@ int burn_dvd_write_track(struct burn_write_opts *o,
|
|||||||
is_last_track);
|
is_last_track);
|
||||||
if (ret <= 0)
|
if (ret <= 0)
|
||||||
goto ex;
|
goto ex;
|
||||||
} else if (d->current_profile == 0x41) {
|
|
||||||
/* BD-R SRM */
|
|
||||||
ret = burn_disc_close_track_dvd_plus_r(o, s, tnum,
|
|
||||||
is_last_track);
|
|
||||||
if (ret <= 0)
|
|
||||||
goto ex;
|
|
||||||
}
|
}
|
||||||
ret = 1;
|
ret = 1;
|
||||||
ex:;
|
ex:;
|
||||||
@ -1600,70 +1372,10 @@ int burn_disc_close_session_dvd_minus_r(struct burn_write_opts *o,
|
|||||||
int burn_dvd_write_session(struct burn_write_opts *o,
|
int burn_dvd_write_session(struct burn_write_opts *o,
|
||||||
struct burn_session *s, int is_last_session)
|
struct burn_session *s, int is_last_session)
|
||||||
{
|
{
|
||||||
int i, ret, multi_mem;
|
int i,ret;
|
||||||
struct burn_drive *d = o->drive;
|
struct burn_drive *d = o->drive;
|
||||||
|
|
||||||
/* ts A90108 */
|
/* >>> open_session ? */
|
||||||
if (d->current_profile == 0x41 && d->status == BURN_DISC_APPENDABLE &&
|
|
||||||
d->state_of_last_session == 1) {
|
|
||||||
/* last session on BD-R is still open */;
|
|
||||||
|
|
||||||
/* BR-R were not closed by libburn-0.6.0.pl00 if o->multi==0.
|
|
||||||
This leads to an unreadable, but recoverable) media state.
|
|
||||||
Technically they are appendable although the last session
|
|
||||||
is not readable.
|
|
||||||
|
|
||||||
By default the open session gets closed here before the new
|
|
||||||
session is written. E.g. after writing a small dummy seesion
|
|
||||||
number 2 one can read session 1 and write session 3 which
|
|
||||||
points to data of session 1.
|
|
||||||
|
|
||||||
For the case that no media with 3 sessions is desired it is
|
|
||||||
possible to activate the following coarse single-session
|
|
||||||
closing code:
|
|
||||||
No new session will be written but calling programs will
|
|
||||||
report success. Quite misleading.
|
|
||||||
Activate only if really needed by
|
|
||||||
# define Libburn_bug_A90108_close_disC yes
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef Libburn_bug_A90108_close_disC
|
|
||||||
|
|
||||||
/* Close open session and media.
|
|
||||||
That was the goal of the failed run which led to the
|
|
||||||
unreadable (but recoverable) media state.
|
|
||||||
|
|
||||||
It is not easy to implement a general close function for
|
|
||||||
all media types. Therefore this pseudo write code is under
|
|
||||||
control of #ifdef.
|
|
||||||
*/
|
|
||||||
libdax_msgs_submit(libdax_messenger, d->global_index,
|
|
||||||
0x00020171,
|
|
||||||
LIBDAX_MSGS_SEV_NOTE, LIBDAX_MSGS_PRIO_HIGH,
|
|
||||||
"Closing BD-R with accidently open session",
|
|
||||||
0, 0);
|
|
||||||
d->close_track_session(d, 3, 0); /* CLOSE SESSION, 110b */
|
|
||||||
d->state_of_last_session = 3; /* mark as complete session */
|
|
||||||
d->status = BURN_DISC_FULL;
|
|
||||||
sleep(3); /* The caller might need time to arrange itself */
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
#else /* Libburn_bug_A90108_close_disC */
|
|
||||||
|
|
||||||
/* This is the default mode.
|
|
||||||
*/
|
|
||||||
libdax_msgs_submit(libdax_messenger, d->global_index,
|
|
||||||
0x00020170,
|
|
||||||
LIBDAX_MSGS_SEV_NOTE, LIBDAX_MSGS_PRIO_HIGH,
|
|
||||||
"Closing open session before writing new one",
|
|
||||||
0, 0);
|
|
||||||
d->close_track_session(d, 1, 0); /* CLOSE SESSION, 010b */
|
|
||||||
d->state_of_last_session = 3; /* mark as complete session */
|
|
||||||
|
|
||||||
#endif /* ! Libburn_bug_A90108_close_disC */
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < s->tracks; i++) {
|
for (i = 0; i < s->tracks; i++) {
|
||||||
ret = burn_dvd_write_track(o, s, i,
|
ret = burn_dvd_write_track(o, s, i,
|
||||||
@ -1674,11 +1386,7 @@ int burn_dvd_write_session(struct burn_write_opts *o,
|
|||||||
if (d->current_profile == 0x11 || d->current_profile == 0x14 ||
|
if (d->current_profile == 0x11 || d->current_profile == 0x14 ||
|
||||||
d->current_profile == 0x15) {
|
d->current_profile == 0x15) {
|
||||||
/* DVD-R , DVD-RW Sequential, DVD-R/DL Sequential */
|
/* DVD-R , DVD-RW Sequential, DVD-R/DL Sequential */
|
||||||
multi_mem = o->multi;
|
|
||||||
if (!is_last_session)
|
|
||||||
o->multi = 1;
|
|
||||||
ret = burn_disc_close_session_dvd_minus_r(o, s);
|
ret = burn_disc_close_session_dvd_minus_r(o, s);
|
||||||
o->multi = multi_mem;
|
|
||||||
if (ret <= 0)
|
if (ret <= 0)
|
||||||
return 0;
|
return 0;
|
||||||
} else if (d->current_profile == 0x12 || d->current_profile == 0x43) {
|
} else if (d->current_profile == 0x12 || d->current_profile == 0x43) {
|
||||||
@ -1700,8 +1408,6 @@ int burn_dvd_write_session(struct burn_write_opts *o,
|
|||||||
}
|
}
|
||||||
} else if (d->current_profile == 0x1b || d->current_profile == 0x2b) {
|
} else if (d->current_profile == 0x1b || d->current_profile == 0x2b) {
|
||||||
/* DVD+R , DVD+R/DL do each track as an own session */;
|
/* DVD+R , DVD+R/DL do each track as an own session */;
|
||||||
} else if (d->current_profile == 0x41) {
|
|
||||||
/* BD-R SRM do each track as an own session */;
|
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -1905,12 +1611,8 @@ int burn_dvd_write_sync(struct burn_write_opts *o,
|
|||||||
/* ??? padding needed ??? cowardly doing it for now */
|
/* ??? padding needed ??? cowardly doing it for now */
|
||||||
o->obs_pad = 1; /* fill-up track's last 32k buffer */
|
o->obs_pad = 1; /* fill-up track's last 32k buffer */
|
||||||
|
|
||||||
} else if (d->current_profile == 0x1b || d->current_profile == 0x2b ||
|
} else if (d->current_profile == 0x1b || d->current_profile == 0x2b) {
|
||||||
d->current_profile == 0x41) {
|
/* DVD+R , DVD+R/DL */
|
||||||
/* DVD+R , DVD+R/DL , BD-R SRM */
|
|
||||||
|
|
||||||
/* >>> ts A81208 : with BD-R set o->obs to 64 kB ? */
|
|
||||||
|
|
||||||
t = disc->session[0]->track[0];
|
t = disc->session[0]->track[0];
|
||||||
o_end = ( burn_track_is_open_ended(t) && !o->fill_up_media );
|
o_end = ( burn_track_is_open_ended(t) && !o->fill_up_media );
|
||||||
default_size = burn_track_get_default_size(t);
|
default_size = burn_track_get_default_size(t);
|
||||||
@ -1925,8 +1627,8 @@ int burn_dvd_write_sync(struct burn_write_opts *o,
|
|||||||
}
|
}
|
||||||
ret = burn_disc_setup_dvd_plus_r(o, disc);
|
ret = burn_disc_setup_dvd_plus_r(o, disc);
|
||||||
if (ret <= 0) {
|
if (ret <= 0) {
|
||||||
sprintf(msg, "Write preparation setup failed for %s",
|
sprintf(msg,
|
||||||
d->current_profile == 0x41 ? "BD-R" : "DVD+R");
|
"Write preparation setup failed for DVD+R");
|
||||||
libdax_msgs_submit(libdax_messenger, d->global_index,
|
libdax_msgs_submit(libdax_messenger, d->global_index,
|
||||||
0x00020121,
|
0x00020121,
|
||||||
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
|
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
@ -1935,46 +1637,6 @@ int burn_dvd_write_sync(struct burn_write_opts *o,
|
|||||||
}
|
}
|
||||||
/* ??? padding needed ??? cowardly doing it for now */
|
/* ??? padding needed ??? cowardly doing it for now */
|
||||||
o->obs_pad = 1; /* fill-up track's last 32k buffer */
|
o->obs_pad = 1; /* fill-up track's last 32k buffer */
|
||||||
if (d->do_stream_recording) {
|
|
||||||
if (d->current_profile == 0x41) /* BD-R */
|
|
||||||
o->obs = Libburn_bd_re_streamed_obS;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef Libburn_dvd_obs_default_64K
|
|
||||||
o->obs = 64 * 1024;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* <<< test only : Does this increase effective speed with USB ?
|
|
||||||
ts A90801 : 64kB: speed with 16x DVD-R is 12 rather than 8
|
|
||||||
128kB: glibc complains about double free
|
|
||||||
With BURN_OS_TRANSPORT_BUFFER_SIZE
|
|
||||||
enlarged to 128 MB, the first WRITE fails
|
|
||||||
with an i/o error.
|
|
||||||
o->obs = 64 * 1024;
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (o->dvd_obs_override >= 32 * 1024)
|
|
||||||
o->obs = o->dvd_obs_override;
|
|
||||||
|
|
||||||
if (o->obs > BUFFER_SIZE) {
|
|
||||||
sprintf(msg, "Chosen write chunk size %d exceeds system dependent buffer size", o->obs);
|
|
||||||
libdax_msgs_submit(libdax_messenger, d->global_index,
|
|
||||||
0x00000002, LIBDAX_MSGS_SEV_DEBUG,
|
|
||||||
LIBDAX_MSGS_PRIO_ZERO, msg, 0, 0);
|
|
||||||
o->obs = 32 * 1024; /* This size is required to work */
|
|
||||||
}
|
|
||||||
|
|
||||||
if (d->do_stream_recording &&
|
|
||||||
(d->current_profile == 0x43 || d->current_profile == 0x41) &&
|
|
||||||
o->obs < Libburn_bd_re_streamed_obS) {
|
|
||||||
/* LG GGW-H20 writes junk with stream recording and obs=32k */
|
|
||||||
sprintf(msg,
|
|
||||||
"Stream recording disabled because of small OS buffer");
|
|
||||||
libdax_msgs_submit(libdax_messenger, d->global_index,
|
|
||||||
0x00020176, LIBDAX_MSGS_SEV_NOTE,
|
|
||||||
LIBDAX_MSGS_PRIO_HIGH, msg, 0, 0);
|
|
||||||
d->do_stream_recording = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sprintf(msg, "dvd/bd Profile= %2.2Xh , obs= %d , obs_pad= %d",
|
sprintf(msg, "dvd/bd Profile= %2.2Xh , obs= %d , obs_pad= %d",
|
||||||
@ -2006,13 +1668,7 @@ ex:;
|
|||||||
burn_drive_mark_unready(d);
|
burn_drive_mark_unready(d);
|
||||||
burn_drive_inquire_media(d);
|
burn_drive_inquire_media(d);
|
||||||
|
|
||||||
if (d->current_profile == 0x41 && d->complete_sessions >= 300) {
|
d->busy = BURN_DRIVE_IDLE;
|
||||||
sprintf(msg, "Sequential BD-R media now contains %d sessions. It is likely to soon fail writing.", d->complete_sessions);
|
|
||||||
libdax_msgs_submit(libdax_messenger, d->global_index,
|
|
||||||
0x0002017b, LIBDAX_MSGS_SEV_WARNING,
|
|
||||||
LIBDAX_MSGS_PRIO_ZERO, msg, 0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
early_failure:;
|
early_failure:;
|
||||||
return 0;
|
return 0;
|
||||||
@ -2024,8 +1680,7 @@ int burn_stdio_open_write(struct burn_drive *d, off_t start_byte,
|
|||||||
int sector_size, int flag)
|
int sector_size, int flag)
|
||||||
{
|
{
|
||||||
|
|
||||||
/* We normally need _LARGEFILE64_SOURCE defined by the build system.
|
/* <<< We need _LARGEFILE64_SOURCE defined by the build system.
|
||||||
Nevertheless the system might use large address integers by default.
|
|
||||||
*/
|
*/
|
||||||
#ifndef O_LARGEFILE
|
#ifndef O_LARGEFILE
|
||||||
#define O_LARGEFILE 0
|
#define O_LARGEFILE 0
|
||||||
@ -2041,8 +1696,7 @@ int burn_stdio_open_write(struct burn_drive *d, off_t start_byte,
|
|||||||
if (fd >= 0)
|
if (fd >= 0)
|
||||||
fd = dup(fd); /* check validity and make closeable */
|
fd = dup(fd); /* check validity and make closeable */
|
||||||
else
|
else
|
||||||
fd = open(d->devname, mode,
|
fd = open(d->devname, mode, S_IRUSR | S_IWUSR);
|
||||||
S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
|
|
||||||
if (fd == -1) {
|
if (fd == -1) {
|
||||||
libdax_msgs_submit(libdax_messenger, d->global_index,
|
libdax_msgs_submit(libdax_messenger, d->global_index,
|
||||||
0x00020005,
|
0x00020005,
|
||||||
@ -2094,13 +1748,6 @@ int burn_stdio_read_source(struct burn_source *source, char *buf, int bufsize,
|
|||||||
int burn_stdio_write(int fd, char *buf, int count, struct burn_drive *d,
|
int burn_stdio_write(int fd, char *buf, int count, struct burn_drive *d,
|
||||||
int flag)
|
int flag)
|
||||||
{
|
{
|
||||||
if (d->cancel)
|
|
||||||
return 0;
|
|
||||||
/*
|
|
||||||
fprintf(stderr, "libburn_DEBUG: write(%d, %lX, %d)\n",
|
|
||||||
fd, (unsigned long) buf, count);
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (write(fd, buf, count) != count) {
|
if (write(fd, buf, count) != count) {
|
||||||
libdax_msgs_submit(libdax_messenger, d->global_index,
|
libdax_msgs_submit(libdax_messenger, d->global_index,
|
||||||
0x00020148,
|
0x00020148,
|
||||||
@ -2122,11 +1769,9 @@ int burn_stdio_mmc_write(struct burn_drive *d, int start, struct buffer *buf)
|
|||||||
if (d->cancel)
|
if (d->cancel)
|
||||||
return BE_CANCELLED;
|
return BE_CANCELLED;
|
||||||
if (d->stdio_fd < 0) {
|
if (d->stdio_fd < 0) {
|
||||||
libdax_msgs_submit(libdax_messenger, d->global_index,
|
|
||||||
0x0002017d,
|
/* >>> program error */;
|
||||||
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
|
|
||||||
"Invalid file descriptor with stdio pseudo-drive",
|
|
||||||
0, 0);
|
|
||||||
d->cancel = 1;
|
d->cancel = 1;
|
||||||
return BE_CANCELLED;
|
return BE_CANCELLED;
|
||||||
}
|
}
|
||||||
@ -2174,11 +1819,9 @@ int burn_stdio_mmc_dummy_write(struct burn_drive *d, int start,
|
|||||||
int burn_stdio_sync_cache(int fd, struct burn_drive *d, int flag)
|
int burn_stdio_sync_cache(int fd, struct burn_drive *d, int flag)
|
||||||
{
|
{
|
||||||
if (fd < 0) {
|
if (fd < 0) {
|
||||||
libdax_msgs_submit(libdax_messenger, d->global_index,
|
|
||||||
0x0002017d,
|
/* >>> program error */;
|
||||||
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
|
|
||||||
"Invalid file descriptor with stdio pseudo-drive",
|
|
||||||
0, 0);
|
|
||||||
d->cancel = 1;
|
d->cancel = 1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -2257,8 +1900,6 @@ int burn_stdio_write_track(struct burn_write_opts *o, struct burn_session *s,
|
|||||||
burn_disc_init_track_status(o, s, tnum, sectors);
|
burn_disc_init_track_status(o, s, tnum, sectors);
|
||||||
open_ended = burn_track_is_open_ended(t);
|
open_ended = burn_track_is_open_ended(t);
|
||||||
|
|
||||||
t->end_on_premature_eoi = (o->write_type == BURN_WRITE_TAO);
|
|
||||||
|
|
||||||
/* attach stdio emulators for mmc_*() functions */
|
/* attach stdio emulators for mmc_*() functions */
|
||||||
if (o->simulate)
|
if (o->simulate)
|
||||||
d->write = burn_stdio_mmc_dummy_write;
|
d->write = burn_stdio_mmc_dummy_write;
|
||||||
@ -2271,22 +1912,19 @@ int burn_stdio_write_track(struct burn_write_opts *o, struct burn_session *s,
|
|||||||
/* transact a (CD sized) sector */
|
/* transact a (CD sized) sector */
|
||||||
if (!sector_data(o, t, 0))
|
if (!sector_data(o, t, 0))
|
||||||
{ret= 0; goto ex;}
|
{ret= 0; goto ex;}
|
||||||
if (open_ended)
|
if (open_ended) {
|
||||||
d->progress.sectors = sectors = d->progress.sector;
|
d->progress.sectors = sectors = d->progress.sector;
|
||||||
if (open_ended || t->end_on_premature_eoi) {
|
|
||||||
if (burn_track_is_data_done(t))
|
if (burn_track_is_data_done(t))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
d->progress.sector++;
|
d->progress.sector++;
|
||||||
/* Flush to disk from time to time */
|
/* Flush to disk after each full MB */
|
||||||
if (d->progress.sector - prev_sync_sector >=
|
if (d->progress.sector - prev_sync_sector >= 512) {
|
||||||
o->stdio_fsync_size && o->stdio_fsync_size > 0) {
|
|
||||||
prev_sync_sector = d->progress.sector;
|
prev_sync_sector = d->progress.sector;
|
||||||
if (!o->simulate)
|
if (!o->simulate)
|
||||||
burn_stdio_sync_cache(d->stdio_fd, d, 1);
|
burn_stdio_sync_cache(d->stdio_fd, d, 1);
|
||||||
}
|
|
||||||
if ((d->progress.sector % 512) == 0)
|
|
||||||
burn_stdio_slowdown(d, &prev_time, 512 * 2, 0);
|
burn_stdio_slowdown(d, &prev_time, 512 * 2, 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Pad up buffer to next full o->obs (usually 32 kB) */
|
/* Pad up buffer to next full o->obs (usually 32 kB) */
|
||||||
@ -2300,8 +1938,6 @@ int burn_stdio_write_track(struct burn_write_opts *o, struct burn_session *s,
|
|||||||
ex:;
|
ex:;
|
||||||
if (d->cancel)
|
if (d->cancel)
|
||||||
burn_source_cancel(t->source);
|
burn_source_cancel(t->source);
|
||||||
if (t->end_on_premature_eoi == 2)
|
|
||||||
d->cancel = 1;
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2351,7 +1987,7 @@ ex:;
|
|||||||
/* update media state records */
|
/* update media state records */
|
||||||
burn_drive_mark_unready(d);
|
burn_drive_mark_unready(d);
|
||||||
|
|
||||||
/* <<< d->busy = BURN_DRIVE_IDLE; */
|
d->busy = BURN_DRIVE_IDLE;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2360,13 +1996,12 @@ void burn_disc_write_sync(struct burn_write_opts *o, struct burn_disc *disc)
|
|||||||
{
|
{
|
||||||
struct cue_sheet *sheet;
|
struct cue_sheet *sheet;
|
||||||
struct burn_drive *d = o->drive;
|
struct burn_drive *d = o->drive;
|
||||||
struct buffer *buffer_mem = o->drive->buffer;
|
struct buffer buf, *buffer_mem = o->drive->buffer;
|
||||||
struct burn_track *lt, *t;
|
struct burn_track *lt, *t;
|
||||||
int first = 1, i, ret, lba, nwa = 0, multi_mem;
|
int first = 1, i, ret, lba, nwa = 0;
|
||||||
off_t default_size;
|
off_t default_size;
|
||||||
char msg[80];
|
char msg[80];
|
||||||
|
|
||||||
|
|
||||||
/* ts A60924 : libburn/message.c gets obsoleted
|
/* ts A60924 : libburn/message.c gets obsoleted
|
||||||
burn_message_clear_queue();
|
burn_message_clear_queue();
|
||||||
*/
|
*/
|
||||||
@ -2374,41 +2009,11 @@ void burn_disc_write_sync(struct burn_write_opts *o, struct burn_disc *disc)
|
|||||||
/* ts A61224 */
|
/* ts A61224 */
|
||||||
burn_disc_init_write_status(o, disc); /* must be done very early */
|
burn_disc_init_write_status(o, disc); /* must be done very early */
|
||||||
|
|
||||||
/* ts A80412 , A90227 */
|
/* ts A80412 */
|
||||||
d->do_stream_recording = !!o->do_stream_recording;
|
d->do_stream_recording = o->do_stream_recording;
|
||||||
if (o->do_stream_recording >= 16)
|
|
||||||
d->stream_recording_start = o->do_stream_recording;
|
|
||||||
else
|
|
||||||
d->stream_recording_start = 0;
|
|
||||||
|
|
||||||
/* ts A91122 : Get buffer suitable for sources made by
|
|
||||||
burn_os_open_track_src() */
|
|
||||||
d->buffer = burn_os_alloc_buffer(sizeof(struct buffer), 0);
|
|
||||||
if (d->buffer == NULL)
|
|
||||||
goto fail_wo_sync;
|
|
||||||
|
|
||||||
/* >>> ts A90321
|
|
||||||
|
|
||||||
|
d->buffer = &buf;
|
||||||
memset(d->buffer, 0, sizeof(struct buffer));
|
memset(d->buffer, 0, sizeof(struct buffer));
|
||||||
|
|
||||||
fprintf(stderr, "libburn_DEBUG: d->buffer = %lX , size = %d\n",
|
|
||||||
(unsigned long) d->buffer, (int) sizeof(struct buffer));
|
|
||||||
|
|
||||||
calloc() seems not to have the desired effect. valgrind warns:
|
|
||||||
==18251== Syscall param write(buf) points to uninitialised byte(s)
|
|
||||||
==18251== at 0x5071DEB: (within /lib64/libpthread-2.5.so)
|
|
||||||
==18251== by 0x4723FA: burn_stdio_write (write.c:1850)
|
|
||||||
==18251== by 0x4725DC: burn_stdio_mmc_write (write.c:1894)
|
|
||||||
==18251== by 0x483B7A: get_sector (sector.c:229)
|
|
||||||
==18251== by 0x484F11: sector_data (sector.c:639)
|
|
||||||
==18251== by 0x4729FE: burn_stdio_write_track (write.c:2012)
|
|
||||||
==18251== by 0x472CF4: burn_stdio_write_sync (write.c:2072)
|
|
||||||
==18251== by 0x472E8D: burn_disc_write_sync (write.c:2125) <<< we are here
|
|
||||||
==18251== by 0x460254: write_disc_worker_func (async.c:514)
|
|
||||||
==18251== by 0x506B09D: start_thread (in /lib64/libpthread-2.5.so)
|
|
||||||
==18251== by 0x55484CC: clone (in /lib64/libc-2.5.so)
|
|
||||||
*/
|
|
||||||
|
|
||||||
d->rlba = -150;
|
d->rlba = -150;
|
||||||
d->toc_temp = 9;
|
d->toc_temp = 9;
|
||||||
|
|
||||||
@ -2427,7 +2032,7 @@ calloc() seems not to have the desired effect. valgrind warns:
|
|||||||
goto ex;
|
goto ex;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ts A70521 : GNU/Linux 2.4 USB audio fails with 64 kiB */
|
/* ts A70521 : Linux 2.4 USB audio fails with 64 kiB */
|
||||||
/* ts A80414 : might need 64 kiB for BD-RE streaming */
|
/* ts A80414 : might need 64 kiB for BD-RE streaming */
|
||||||
/* buffer flush trigger for sector.c:get_sector() */
|
/* buffer flush trigger for sector.c:get_sector() */
|
||||||
o->obs = Libburn_cd_obS;
|
o->obs = Libburn_cd_obS;
|
||||||
@ -2543,12 +2148,7 @@ return crap. so we send the command, then ignore the result.
|
|||||||
d->alba += 4500;
|
d->alba += 4500;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
multi_mem = o->multi;
|
if (!burn_write_session(o, disc->session[i]))
|
||||||
if(i < disc->sessions - 1)
|
|
||||||
o->multi = 1;
|
|
||||||
ret = burn_write_session(o, disc->session[i]);
|
|
||||||
o->multi = multi_mem;
|
|
||||||
if (!ret)
|
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
lt = disc->session[i]->track[disc->session[i]->tracks - 1];
|
lt = disc->session[i]->track[disc->session[i]->tracks - 1];
|
||||||
@ -2588,7 +2188,7 @@ return crap. so we send the command, then ignore the result.
|
|||||||
burn_drive_inquire_media(d);
|
burn_drive_inquire_media(d);
|
||||||
|
|
||||||
burn_print(1, "done\n");
|
burn_print(1, "done\n");
|
||||||
/* <<< d->busy = BURN_DRIVE_IDLE; */
|
d->busy = BURN_DRIVE_IDLE;
|
||||||
|
|
||||||
/* ts A61012 : This return was traditionally missing. I suspect this
|
/* ts A61012 : This return was traditionally missing. I suspect this
|
||||||
to have caused Cdrskin_eject() failures */
|
to have caused Cdrskin_eject() failures */
|
||||||
@ -2603,12 +2203,9 @@ fail_wo_sync:;
|
|||||||
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
|
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
"Burn run failed", 0, 0);
|
"Burn run failed", 0, 0);
|
||||||
d->cancel = 1;
|
d->cancel = 1;
|
||||||
/* <<< d->busy = BURN_DRIVE_IDLE; */
|
d->busy = BURN_DRIVE_IDLE;
|
||||||
ex:;
|
ex:;
|
||||||
d->do_stream_recording = 0;
|
d->do_stream_recording = 0;
|
||||||
if (d->buffer != NULL)
|
|
||||||
burn_os_free_buffer((char *) d->buffer,
|
|
||||||
sizeof(struct buffer), 0);
|
|
||||||
d->buffer = buffer_mem;
|
d->buffer = buffer_mem;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,5 @@
|
|||||||
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||||
|
|
||||||
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
|
|
||||||
Copyright (c) 2006 - 2010 Thomas Schmitt <scdbackup@gmx.net>
|
|
||||||
Provided under GPL version 2 or later.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef BURN__WRITE_H
|
#ifndef BURN__WRITE_H
|
||||||
#define BURN__WRITE_H
|
#define BURN__WRITE_H
|
||||||
|
|
||||||
|
@ -25,19 +25,18 @@
|
|||||||
#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 and libdax_audioxtr via libburn */
|
/* This build environment uses libdax_msgs 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)
|
||||||
{
|
{
|
||||||
|
158
test/libburner.c
158
test/libburner.c
@ -1,16 +1,16 @@
|
|||||||
|
|
||||||
/* test/libburner.c , API illustration of burning data or audio tracks to CD */
|
/* test/libburner.c , API illustration of burning data or audio tracks to CD */
|
||||||
/* Copyright (C) 2005 - 2010 Thomas Schmitt <scdbackup@gmx.net> */
|
/* Copyright (C) 2005 - 2007 Thomas Schmitt <scdbackup@gmx.net> */
|
||||||
/* Provided under GPL, see also "License and copyright aspects" at file end */
|
/* Provided under GPLv2,see also "License and copyright aspects" at file end */
|
||||||
|
|
||||||
|
|
||||||
/** Overview
|
/** Overview
|
||||||
|
|
||||||
libburner is a minimal demo application for the library libburn as provided
|
libburner is a minimal demo application for the library libburn as provided
|
||||||
on http://libburnia-project.org . It can list the available devices, can
|
on http://libburnia-project.org . It can list the available devices, can
|
||||||
blank a CD-RW or DVD-RW, can format DVD-RW and BD, can burn to CD-R,
|
blank a CD-RW or DVD-RW, can format DVD-RW and BD-RE, can burn to CD-R,
|
||||||
CD-RW, DVD-R, DVD+R, DVD+R/DL, DVD+RW, DVD-RW, DVD-RAM, BD-R, BD-RE.
|
CD-RW, DVD-R, DVD+R, DVD+R/DL, DVD+RW, DVD-RW, DVD-RAM, BD-RE.
|
||||||
Not supported yet: DVD-R/DL.
|
Not supported yet: DVD-R/DL, BD-R.
|
||||||
|
|
||||||
It's main purpose, nevertheless, is to show you how to use libburn and also
|
It's main purpose, nevertheless, is to show you how to use libburn and also
|
||||||
to serve the libburnia team as reference application. libburner.c does indeed
|
to serve the libburnia team as reference application. libburner.c does indeed
|
||||||
@ -20,53 +20,31 @@
|
|||||||
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("libburner : ", NULL, 0x0)
|
burn_set_signal_handling()
|
||||||
as it is done in main() at the end of this file.
|
as it is done in main() at the end of this file. Then you aquire a
|
||||||
Then you aquire a drive in an appropriate way conforming to the API. The twoi
|
drive in an appropriate way conforming to the API. The two main
|
||||||
main approaches are shown here in application functions:
|
approaches are shown here in application functions:
|
||||||
libburner_aquire_by_adr() demonstrates usage as of cdrecord traditions
|
libburner_aquire_by_adr() demonstrates usage as of cdrecord traditions
|
||||||
libburner_aquire_by_driveno() demonstrates a scan-and-choose approach
|
libburner_aquire_by_driveno() demonstrates a scan-and-choose approach
|
||||||
|
With that aquired drive you can blank a CD-RW
|
||||||
With that aquired drive you can blank a CD-RW or DVD-RW 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-RE to default size
|
||||||
libburner_format()
|
libburner_format_owrt()
|
||||||
With the aquired drive you can burn to CD, DVD, BD. See
|
With the aquired drive you can burn to CD or DVD
|
||||||
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()
|
||||||
|
|
||||||
Applications must use 64 bit off_t. E.g. by defining
|
|
||||||
#define _LARGEFILE_SOURCE
|
|
||||||
#define _FILE_OFFSET_BITS 64
|
|
||||||
or take special precautions to interface with the library by 64 bit integers
|
|
||||||
where libburn/libburn.h prescribes off_t.
|
|
||||||
This program gets fed with appropriate settings externally by libburn's
|
|
||||||
autotools generated build system.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
/** See this for the decisive API specs . libburn.h is The Original */
|
/** See this for the decisive API specs . libburn.h is The Original */
|
||||||
/* For using the installed header file : #include <libburn/libburn.h> */
|
/* For using the installed header file : #include <libburn/libburn.h> */
|
||||||
/* This program insists in the own headerfile. */
|
/* This program insists in the own headerfile. */
|
||||||
#include "../libburn/libburn.h"
|
#include "../libburn/libburn.h"
|
||||||
|
|
||||||
/* libburn works on Linux systems with kernel 2.4 or 2.6, FreeBSD, Solaris */
|
/* libburn is intended for Linux systems with kernel 2.4 or 2.6 for now */
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
@ -128,7 +106,7 @@ int libburner_aquire_drive(char *drive_adr, int *driveno)
|
|||||||
ret = libburner_aquire_by_adr(drive_adr);
|
ret = libburner_aquire_by_adr(drive_adr);
|
||||||
else
|
else
|
||||||
ret = libburner_aquire_by_driveno(driveno);
|
ret = libburner_aquire_by_driveno(driveno);
|
||||||
if (ret <= 0 || *driveno <= 0)
|
if (ret <= 0)
|
||||||
return ret;
|
return ret;
|
||||||
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);
|
||||||
@ -282,8 +260,7 @@ int libburner_aquire_by_driveno(int *driveno)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** Makes a previously used CD-RW or unformatted DVD-RW ready for thorough
|
/** Makes a previously used CD-RW ready for thorough re-usal.
|
||||||
re-usal.
|
|
||||||
|
|
||||||
To our knowledge it is hardly possible to abort an ongoing blank operation
|
To our knowledge it is hardly possible to abort an ongoing blank operation
|
||||||
because after start it is entirely handled by the drive.
|
because after start it is entirely handled by the drive.
|
||||||
@ -322,12 +299,9 @@ int libburner_blank_disc(struct burn_drive *drive, int blank_fast)
|
|||||||
"FATAL : Media is not of erasable type\n");
|
"FATAL : Media is not of erasable type\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
/* Switch to asynchronous signal handling for the time of waiting */
|
printf(
|
||||||
burn_set_signal_handling("libburner : ", NULL, 0x30);
|
"Beginning to %s-blank media.\n", (blank_fast?"fast":"full"));
|
||||||
|
|
||||||
printf("Beginning to %s-blank media.\n", (blank_fast?"fast":"full"));
|
|
||||||
burn_disc_erase(drive, blank_fast);
|
burn_disc_erase(drive, blank_fast);
|
||||||
|
|
||||||
sleep(1);
|
sleep(1);
|
||||||
while (burn_drive_get_status(drive, &p) != BURN_DRIVE_IDLE) {
|
while (burn_drive_get_status(drive, &p) != BURN_DRIVE_IDLE) {
|
||||||
if(p.sectors>0 && p.sector>=0) /* display 1 to 99 percent */
|
if(p.sectors>0 && p.sector>=0) /* display 1 to 99 percent */
|
||||||
@ -336,10 +310,6 @@ int libburner_blank_disc(struct burn_drive *drive, int blank_fast)
|
|||||||
printf("Blanking ( %.1f%% done )\n", percent);
|
printf("Blanking ( %.1f%% done )\n", percent);
|
||||||
sleep(1);
|
sleep(1);
|
||||||
}
|
}
|
||||||
if (burn_is_aborting(0) > 0)
|
|
||||||
return -1;
|
|
||||||
/* Back to synchronous handling */
|
|
||||||
burn_set_signal_handling("libburner : ", NULL, 0x0);
|
|
||||||
printf("Done\n");
|
printf("Done\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -352,35 +322,24 @@ int libburner_blank_disc(struct burn_drive *drive, int blank_fast)
|
|||||||
Formats unformatted BD-RE to default size. This will allocate some
|
Formats unformatted BD-RE to default size. This will allocate some
|
||||||
reserve space, test for bad blocks and make the media ready for writing.
|
reserve space, test for bad blocks and make the media ready for writing.
|
||||||
Expect a very long run time.
|
Expect a very long run time.
|
||||||
|
|
||||||
Formats unformatted blank BD-R to hold a default amount of spare blocks
|
|
||||||
for eventual mishaps during writing. If BD-R get written without being
|
|
||||||
formatted, then they get no such reserve and will burn at full speed.
|
|
||||||
*/
|
*/
|
||||||
int libburner_format(struct burn_drive *drive)
|
int libburner_format_owrt(struct burn_drive *drive)
|
||||||
{
|
{
|
||||||
struct burn_progress p;
|
struct burn_progress p;
|
||||||
double percent = 1.0;
|
double percent = 1.0;
|
||||||
int ret, status, num_formats, format_flag= 0;
|
int ret, status, num_formats, format_flag= 0;
|
||||||
off_t size = 0;
|
off_t size = 0;
|
||||||
unsigned dummy;
|
unsigned dummy;
|
||||||
enum burn_disc_status disc_state;
|
|
||||||
|
|
||||||
if (current_profile == 0x13) {
|
if (current_profile == 0x13) {
|
||||||
fprintf(stderr, "IDLE: DVD-RW media is already formatted\n");
|
fprintf(stderr, "IDLE: DVD-RW media is already formatted\n");
|
||||||
return 2;
|
return 2;
|
||||||
} else if (current_profile == 0x41 || current_profile == 0x43) {
|
} else if (current_profile == 0x43) {
|
||||||
disc_state = burn_disc_get_status(drive);
|
|
||||||
if (disc_state != BURN_DISC_BLANK && current_profile == 0x41) {
|
|
||||||
fprintf(stderr,
|
|
||||||
"FATAL: BD-R is not blank. Cannot format.\n");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
ret = burn_disc_get_formats(drive, &status, &size, &dummy,
|
ret = burn_disc_get_formats(drive, &status, &size, &dummy,
|
||||||
&num_formats);
|
&num_formats);
|
||||||
if (ret > 0 && status != BURN_FORMAT_IS_UNFORMATTED) {
|
if (ret > 0 && status == BURN_FORMAT_IS_FORMATTED) {
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"IDLE: BD media is already formatted\n");
|
"IDLE: BD-RE media is already formatted\n");
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
size = 0; /* does not really matter */
|
size = 0; /* does not really matter */
|
||||||
@ -389,10 +348,9 @@ int libburner_format(struct burn_drive *drive)
|
|||||||
size = 128 * 1024 * 1024;
|
size = 128 * 1024 * 1024;
|
||||||
format_flag = 1; /* write initial 128 MiB */
|
format_flag = 1; /* write initial 128 MiB */
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr, "FATAL: Can only format DVD-RW or BD\n");
|
fprintf(stderr, "FATAL: Can only format DVD-RW or BD-RE\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
burn_set_signal_handling("libburner : ", NULL, 0x30);
|
|
||||||
|
|
||||||
printf("Beginning to format media.\n");
|
printf("Beginning to format media.\n");
|
||||||
burn_disc_format(drive, size, format_flag);
|
burn_disc_format(drive, size, format_flag);
|
||||||
@ -405,9 +363,6 @@ int libburner_format(struct burn_drive *drive)
|
|||||||
printf("Formatting ( %.1f%% done )\n", percent);
|
printf("Formatting ( %.1f%% done )\n", percent);
|
||||||
sleep(1);
|
sleep(1);
|
||||||
}
|
}
|
||||||
if (burn_is_aborting(0) > 0)
|
|
||||||
return -1;
|
|
||||||
burn_set_signal_handling("libburner : ", NULL, 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)
|
||||||
@ -521,7 +476,7 @@ int libburner_payload(struct burn_drive *drive,
|
|||||||
/* Give up local reference to the data burn_source object */
|
/* Give up local reference to the data burn_source object */
|
||||||
burn_source_free(data_src);
|
burn_source_free(data_src);
|
||||||
|
|
||||||
} /* trackno loop end */
|
} /* trackno loop end */
|
||||||
|
|
||||||
/* Evaluate drive and media */
|
/* Evaluate drive and media */
|
||||||
disc_state = burn_disc_get_status(drive);
|
disc_state = burn_disc_get_status(drive);
|
||||||
@ -553,7 +508,6 @@ int libburner_payload(struct burn_drive *drive,
|
|||||||
fprintf(stderr, "Reasons given:\n%s\n", reasons);
|
fprintf(stderr, "Reasons given:\n%s\n", reasons);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
burn_set_signal_handling("libburner : ", NULL, 0x30);
|
|
||||||
|
|
||||||
printf("Burning starts. With e.g. 4x media expect up to a minute of zero progress.\n");
|
printf("Burning starts. With e.g. 4x media expect up to a minute of zero progress.\n");
|
||||||
start_time = time(0);
|
start_time = time(0);
|
||||||
@ -601,8 +555,6 @@ int libburner_payload(struct burn_drive *drive,
|
|||||||
}
|
}
|
||||||
burn_session_free(session);
|
burn_session_free(session);
|
||||||
burn_disc_free(target_disc);
|
burn_disc_free(target_disc);
|
||||||
if (burn_is_aborting(0) > 0)
|
|
||||||
return -1;
|
|
||||||
if (multi && current_profile != 0x1a && current_profile != 0x13 &&
|
if (multi && current_profile != 0x1a && current_profile != 0x13 &&
|
||||||
current_profile != 0x12 && current_profile != 0x43)
|
current_profile != 0x12 && current_profile != 0x43)
|
||||||
/* not with DVD+RW, formatted DVD-RW, DVD-RAM, BD-RE */
|
/* not with DVD+RW, formatted DVD-RW, DVD-RAM, BD-RE */
|
||||||
@ -662,8 +614,7 @@ int libburner_setup(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
strcpy(drive_adr, argv[i]);
|
strcpy(drive_adr, argv[i]);
|
||||||
}
|
}
|
||||||
} else if ((!strcmp(argv[i], "--format_overwrite")) ||
|
} else if (!strcmp(argv[i], "--format_overwrite")) {
|
||||||
(!strcmp(argv[i], "--format"))) {
|
|
||||||
do_blank = 101;
|
do_blank = 101;
|
||||||
|
|
||||||
} else if (!strcmp(argv[i], "--multi")) {
|
} else if (!strcmp(argv[i], "--multi")) {
|
||||||
@ -704,7 +655,8 @@ int libburner_setup(int argc, char **argv)
|
|||||||
if (print_help || insuffient_parameters ) {
|
if (print_help || insuffient_parameters ) {
|
||||||
printf("Usage: %s\n", argv[0]);
|
printf("Usage: %s\n", argv[0]);
|
||||||
printf(" [--drive <address>|<driveno>|\"-\"] [--audio]\n");
|
printf(" [--drive <address>|<driveno>|\"-\"] [--audio]\n");
|
||||||
printf(" [--blank_fast|--blank_full|--format] [--try_to_simulate]\n");
|
printf(" [--blank_fast|--blank_full|--format_overwrite]\n");
|
||||||
|
printf(" [--try_to_simulate]\n");
|
||||||
printf(" [--multi] [<one or more imagefiles>|\"-\"]\n");
|
printf(" [--multi] [<one or more imagefiles>|\"-\"]\n");
|
||||||
printf("Examples\n");
|
printf("Examples\n");
|
||||||
printf("A bus scan (needs rw-permissions to see a drive):\n");
|
printf("A bus scan (needs rw-permissions to see a drive):\n");
|
||||||
@ -717,8 +669,8 @@ int libburner_setup(int argc, char **argv)
|
|||||||
printf(" %s --drive /dev/hdc --blank_fast\n",argv[0]);
|
printf(" %s --drive /dev/hdc --blank_fast\n",argv[0]);
|
||||||
printf("Blank a used DVD-RW (is combinable with burning in one run):\n");
|
printf("Blank a used DVD-RW (is combinable with burning in one run):\n");
|
||||||
printf(" %s --drive /dev/hdc --blank_full\n",argv[0]);
|
printf(" %s --drive /dev/hdc --blank_full\n",argv[0]);
|
||||||
printf("Format a DVD-RW, BD-RE or BD-R:\n");
|
printf("Format a DVD-RW to avoid need for blanking before re-use:\n");
|
||||||
printf(" %s --drive /dev/hdc --format\n", argv[0]);
|
printf(" %s --drive /dev/hdc --format_overwrite\n", argv[0]);
|
||||||
printf("Burn two audio tracks (to CD only):\n");
|
printf("Burn two audio tracks (to CD only):\n");
|
||||||
printf(" lame --decode -t /path/to/track1.mp3 track1.cd\n");
|
printf(" lame --decode -t /path/to/track1.mp3 track1.cd\n");
|
||||||
printf(" test/dewav /path/to/track2.wav -o track2.cd\n");
|
printf(" test/dewav /path/to/track2.wav -o track2.cd\n");
|
||||||
@ -738,13 +690,6 @@ 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);
|
||||||
@ -761,9 +706,9 @@ int main(int argc, char **argv)
|
|||||||
/* Print messages of severity SORRY or more directly to stderr */
|
/* Print messages of severity SORRY or more directly to stderr */
|
||||||
burn_msgs_set_severities("NEVER", "SORRY", "libburner : ");
|
burn_msgs_set_severities("NEVER", "SORRY", "libburner : ");
|
||||||
|
|
||||||
/* Activate the synchronous signal handler which eventually will try to
|
/* Activate the default 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, 0x0);
|
burn_set_signal_handling("libburner : ", NULL, 0);
|
||||||
|
|
||||||
/** 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);
|
||||||
@ -775,7 +720,7 @@ int main(int argc, char **argv)
|
|||||||
{ ret = 0; goto release_drive; }
|
{ ret = 0; goto release_drive; }
|
||||||
if (do_blank) {
|
if (do_blank) {
|
||||||
if (do_blank > 100)
|
if (do_blank > 100)
|
||||||
ret = libburner_format(drive_list[driveno].drive);
|
ret = libburner_format_owrt(drive_list[driveno].drive);
|
||||||
else
|
else
|
||||||
ret = libburner_blank_disc(drive_list[driveno].drive,
|
ret = libburner_blank_disc(drive_list[driveno].drive,
|
||||||
do_blank == 1);
|
do_blank == 1);
|
||||||
@ -795,14 +740,10 @@ release_drive:;
|
|||||||
burn_drive_release(drive_list[driveno].drive, 0);
|
burn_drive_release(drive_list[driveno].drive, 0);
|
||||||
|
|
||||||
finish_libburn:;
|
finish_libburn:;
|
||||||
if (burn_is_aborting(0) > 0) {
|
|
||||||
burn_abort(4400, burn_abort_pacifier, "libburner : ");
|
|
||||||
fprintf(stderr,"\nlibburner run aborted\n");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
/* This app does not bother to know about exact scan state.
|
/* This app does not bother to know about exact scan state.
|
||||||
Better to accept a memory leak here. We are done anyway. */
|
Better to accept a memory leak here. We are done anyway. */
|
||||||
/* burn_drive_info_free(drive_list); */
|
/* burn_drive_info_free(drive_list); */
|
||||||
|
|
||||||
burn_finish();
|
burn_finish();
|
||||||
exit(ret);
|
exit(ret);
|
||||||
}
|
}
|
||||||
@ -815,6 +756,37 @@ Read. Try. Think. Play. Write yourself some code. Be free of my copyright.
|
|||||||
|
|
||||||
Be also invited to study the code of cdrskin/cdrskin.c et al.
|
Be also invited to study the code of cdrskin/cdrskin.c et al.
|
||||||
|
|
||||||
|
|
||||||
|
Clarification in my name and in the name of Mario Danic, copyright holder
|
||||||
|
on toplevel of libburnia. To be fully in effect after the remaining other
|
||||||
|
copyrighted code has been replaced by ours and by copyright-free contributions
|
||||||
|
of our friends:
|
||||||
|
|
||||||
|
We, the copyright holders, agree on the interpretation that
|
||||||
|
dynamical linking of our libraries constitutes "use of" and
|
||||||
|
not "derivation from" our work in the sense of GPL, provided
|
||||||
|
those libraries are compiled from our unaltered code.
|
||||||
|
|
||||||
|
Thus you may link our libraries dynamically with applications
|
||||||
|
which are not under GPL. You may distribute our libraries and
|
||||||
|
application tools in binary form, if you fulfill the usual
|
||||||
|
condition of GPL to offer a copy of the source code -altered
|
||||||
|
or unaltered- under GPL.
|
||||||
|
|
||||||
|
We ask you politely to use our work in open source spirit
|
||||||
|
and with the due reference to the entire open source community.
|
||||||
|
|
||||||
|
If there should really arise the case where above clarification
|
||||||
|
does not suffice to fulfill a clear and neat request in open source
|
||||||
|
spirit that would otherwise be declined for mere formal reasons,
|
||||||
|
only in that case we will duely consider to issue a special license
|
||||||
|
covering only that special case.
|
||||||
|
It is the open source idea of responsible freedom which will be
|
||||||
|
decisive and you will have to prove that you exhausted all own
|
||||||
|
means to qualify for GPL.
|
||||||
|
|
||||||
|
For now we are firmly committed to maintain one single license: GPL.
|
||||||
|
|
||||||
History:
|
History:
|
||||||
libburner is a compilation of my own contributions to test/burniso.c and
|
libburner is a compilation of my own contributions to test/burniso.c and
|
||||||
fresh code which replaced the remaining parts under copyright of
|
fresh code which replaced the remaining parts under copyright of
|
||||||
|
@ -1,134 +0,0 @@
|
|||||||
|
|
||||||
/*
|
|
||||||
cc -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS -g -o test/offst_source test/offst_source.c -lburn
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "../libburn/libburn.h"
|
|
||||||
|
|
||||||
/* Just everything from test/libburner.c */
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <ctype.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <time.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
|
|
||||||
|
|
||||||
static int create_original(struct burn_source **original, char *path, int flag)
|
|
||||||
{
|
|
||||||
printf("create_original: path='%s'\n", path);
|
|
||||||
*original = burn_file_source_new(path, NULL);
|
|
||||||
if (*original == NULL)
|
|
||||||
return 0;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int set_up_offst_sources(struct burn_source *original,
|
|
||||||
struct burn_source *offsetters[],
|
|
||||||
int count, int flag)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
off_t start = 3, size = 10, gap = 7;
|
|
||||||
|
|
||||||
for (i = 0; i < count; i++) {
|
|
||||||
offsetters[i] = burn_offst_source_new(original,
|
|
||||||
i > 0 ? offsetters[i - 1] : NULL,
|
|
||||||
start, size, 0);
|
|
||||||
if (offsetters[i] == NULL)
|
|
||||||
return 0;
|
|
||||||
printf("set_up_offst_sources: idx=%d, start=%d\n",
|
|
||||||
i, (int) start);
|
|
||||||
start += size + gap;
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int consume_source(struct burn_source *src, int flag)
|
|
||||||
{
|
|
||||||
int ret, count = 0;
|
|
||||||
unsigned char buf[1];
|
|
||||||
|
|
||||||
while (1) {
|
|
||||||
ret = src->read_xt(src, buf, 1);
|
|
||||||
if (ret < 0) {
|
|
||||||
printf("\n");
|
|
||||||
fprintf(stderr, "consume_source: count=%d, ret=%d\n",
|
|
||||||
count, ret);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
if (ret == 0)
|
|
||||||
break;
|
|
||||||
printf("%u ", buf[0]);
|
|
||||||
count++;
|
|
||||||
}
|
|
||||||
printf(" count=%d\n", count);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int consume_all_sources(struct burn_source *offsetters[],
|
|
||||||
int count, int flag)
|
|
||||||
{
|
|
||||||
int i, ret;
|
|
||||||
|
|
||||||
for (i = 0; i < count; i++) {
|
|
||||||
printf("consume_source: idx=%d\n", i);
|
|
||||||
ret = consume_source(offsetters[i], 0);
|
|
||||||
if (ret <= 0)
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int free_all_sources(struct burn_source *original,
|
|
||||||
struct burn_source *offsetters[],
|
|
||||||
int count, int flag)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < count; i++)
|
|
||||||
burn_source_free(offsetters[i]);
|
|
||||||
burn_source_free(original);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
char *path = "./COPYRIGHT";
|
|
||||||
struct burn_source *original = NULL, *offsetters[4];
|
|
||||||
|
|
||||||
if (argc > 1)
|
|
||||||
path = argv[1];
|
|
||||||
|
|
||||||
if (burn_initialize() == 0)
|
|
||||||
exit(1);
|
|
||||||
|
|
||||||
ret = create_original(&original, path, 0);
|
|
||||||
if (ret <= 0)
|
|
||||||
exit(2);
|
|
||||||
|
|
||||||
ret = set_up_offst_sources(original, offsetters, 4, 0);
|
|
||||||
if (ret <= 0)
|
|
||||||
exit(3);
|
|
||||||
|
|
||||||
ret = consume_all_sources(offsetters, 4, 0);
|
|
||||||
if (ret <= 0)
|
|
||||||
exit(4);
|
|
||||||
|
|
||||||
ret = free_all_sources(original, offsetters, 4, 0);
|
|
||||||
if (ret <= 0)
|
|
||||||
exit(5);
|
|
||||||
|
|
||||||
burn_finish();
|
|
||||||
exit(0);
|
|
||||||
}
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
|||||||
|
|
||||||
/* test/telltoc.c , API illustration of obtaining media status info */
|
/* test/telltoc.c , API illustration of obtaining media status info */
|
||||||
/* Copyright (C) 2006 - 2010 Thomas Schmitt <scdbackup@gmx.net>
|
/* Copyright (C) 2006 - 2007 Thomas Schmitt <scdbackup@gmx.net>
|
||||||
Provided under GPL */
|
Provided under GPL version 2 */
|
||||||
|
|
||||||
/** Overview
|
/** Overview
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user