Compare commits

..

4 Commits
1.4.4 ... 1.2.6

Author SHA1 Message Date
3c32cbcb71 Updated change log 2013-01-08 08:42:02 +00:00
5232c8010d Updated cdrskin tarball generator 2013-01-08 08:40:35 +00:00
27a8ea1c90 Made number transition to 1.2.6 2013-01-08 08:39:40 +00:00
97544934aa Branching for libburn release 1.2.6 2013-01-08 08:03:30 +00:00
76 changed files with 1947 additions and 9394 deletions

View File

@ -1,7 +1,7 @@
Derek Foreman <derek@signalmarketing.com> and Ben Jansens <xor@orodu.net>
Copyright (C) 2002-2006 Derek Foreman and Ben Jansens
Mario Danic <mario.danic@gmail.com>, Thomas Schmitt <scdbackup@gmx.net>
Copyright (C) 2006-2014 Mario Danic, Thomas Schmitt
Copyright (C) 2006-2011 Mario Danic, Thomas Schmitt
This program is free software; you can redistribute it and/or modify

105
ChangeLog
View File

@ -1,114 +1,17 @@
libburn-1.4.4.tar.gz Fri Jul 01 2016
===============================================================================
* Bug fix: Option drive_scsi_dev_family=sg did not convert /dev/sr* to /dev/sg*
* Bug fix: burn_make_input_sheet_v07t() falsly recognized double byte encoding.
Affected cdrskin option: cdtext_to_v07t=
* Bug fix: Double free at end of run if burn_write_opts_set_leadin_text() is
used. Affected cdrskin option: textfile=
* Bug fix: DVD book type of DVD+RW DL and DVD+R DL was reported wrong.
Thanks to Etienne Bergeron.
libburn-1.4.2.pl01.tar.gz Fri Jan 29 2016
===============================================================================
* Bug fix: cdrskin "failed to attach fifo" when burning from stdin.
Regression of 1.4.2, rev 5522.
libburn-1.4.2.tar.gz Sat Nov 28 2015
===============================================================================
* Bug fix: burn_disc_get_media_id() returned BD identifiers 2 chars too long
* Bug fix: burn_disc_get_multi_caps() returned 2048 bytes too many in
caps.start_range_high
* Bug fix: Media summary session count of blank and closed media was short by 1
* Bug fix: Endless loop if transport error occurs while waiting for drive ready
* New API calls burn_drive_get_serial_no() and burn_drive_get_media_sno()
* Result of a Coverity audit: 40+ code changes, but no easy-to-trigger bugs
libburn-1.4.0.tar.gz Sun May 17 2015
===============================================================================
* Bug fix: Double free with cdrskin -vvv.
Introduced with rev 5065, version 1.3.1
* Bug fix: Wrong read access to memory. Reported by valgrind of lian jianfei.
libburn-1.3.8.tar.gz Sat Jun 28 2014
===============================================================================
* Bug fix: Wrong stack usage caused SIGBUS on sparc when compiled by gcc -O2
* Bug fix: Minimum drive buffer fill was measured by cdrskin before the buffer
could get full
* Bug fix: A failed MMC BLANK command did not cause error indication by libburn
* Bug fix: A final fsync(2) was performed with stdio drives, even if not
desired
libburn-1.3.6.pl01.tar.gz Tue Mar 18 2013
===============================================================================
* Bug fix: CD TAO with multiple tracks could cause a buffer overrun
* Bug fix: Compilation warning for unsupported systems mutated into an error
libburn-1.3.6.tar.gz Tue Mar 04 2013
===============================================================================
* New system adapter for NetBSD
libburn-1.3.4.tar.gz Thu Dec 12 2013
===============================================================================
* Bug fix: Drive error reports were ignored during blanking and formatting
* Bug fix: Drive LG BH16NS40 stalls on inspection of unformatted DVD+RW
* New API call burn_disc_pretend_full_uncond()
libburn-1.3.2.tar.gz Wed Aug 07 2013
===============================================================================
* Bug fix: cdrskin -msinfo on DVD and BD reported
old session start = next writable address.
Regression introduced by version 1.2.8 (rev 4956).
* Bug fix: The signal handler aborted on SIGCONT, SIGTSTP, SIGTTIN, SIGTTOU
* New API call burn_make_input_sheet_v07t()
* API call burn_session_input_sheet_v07t(): read multiple blocks from same file
* New API calls burn_drive_extract_audio(), burn_drive_extract_audio_track()
* New cdrskin option textfile_to_v07t=
* New cdrskin options cdtext_to_textfile= and cdtext_to_v07t=
* New cdrskin options extract_audio_to= , extract_tracks= , extract_basename= ,
--extract_dap
* New cdrskin option --pacifier_with_newline
* Improved granularity of SCSI log time measurement, now with timestamp
* Optional "make doc" now demands doxygen 1.8.4
libburn-1.3.0.pl01.tar.gz Fri May 31 2013
===============================================================================
* Bug fix: cdrskin -msinfo on DVD and BD reported
old session start = next writable address.
Regression introduced by version 1.2.8.
libburn-1.3.0.tar.gz Fri May 17 2013
===============================================================================
* Bug fix: Full formatting of BD-RE used certification regardless of drive
capabilities
* Bug fix: DVD+R with damaged TOC were reported by -minfo with wrong end
address
libburn-1.2.8.tar.gz Mon Mar 18 2013
===============================================================================
* Bug fix: All CD tracks were reported with the sizes of the tracks in the
first session. Regression introduced with version 1.2.0 (rev 4552).
* Bug fix: On some drives the request for minimum speed yielded maximum speed
* New cdrskin option --list_speeds
* -toc and -minfo now report about tracks in the incomplete session
* New API call burn_disc_get_incomplete_sessions()
* New burn_toc_entry component .track_status_bits
libburn-1.2.6.tar.gz Tue Jan 08 2013
===============================================================================
* Bug fix: Speed setting had no effect on BD media
* New cdrskin option --no_load
* Bug fix: Speed setting had no effect on BD media
* New API call burn_read_audio()
* New API call burn_list_sev_texts()
libburn-1.2.4.tar.gz Fri Jul 20 2012
===============================================================================
* Bug fix: CD SAO sessions with data tracks started by an audio pause
* Bug fix: CD tracks were perceived 2 sectors too short.
Nice with TAO, bad with SAO.
* Bug fix: cdrskin SIGSEGV if track source was added when no drive was available
* New API call burn_write_opts_set_obs_pad(), ./configure --enable-dvd-obs-pad
* New cdrskin option --obs_pad
* Bug fix: CD SAO sessions with data tracks started by an audio pause
* Bug fix: CD tracks were perceived 2 sectors too short. Nice with TAO, bad with SAO.
* Bug fix: cdrskin SIGSEGV if track source was added when no drive was available
libburn-1.2.2.tar.gz Mon Apr 02 2012
===============================================================================

View File

@ -12,7 +12,7 @@ ACLOCAL_AMFLAGS = -I ./
# Build libraries
libburn_libburn_la_LDFLAGS = \
-version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE) $(LIBLDFLAGS)
-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)
@ -77,7 +77,7 @@ libinclude_HEADERS = \
libburn/libburn.h
install-exec-hook:
$(LIBBURNIA_LDCONFIG_CMD) "$(DESTDIR)$(libdir)" || echo 'NOTE: Explicit dynamic library configuration failed. If needed, configure manually for:' "$(DESTDIR)$(libdir)"
$(LIBBURNIA_LDCONFIG_CMD) "$(DESTDIR)$(libdir)" || echo 'NOTE: Explicite dynamic library configuration failed. If needed, configure manually for:' "$(DESTDIR)$(libdir)"
## ========================================================================= ##
@ -88,7 +88,8 @@ noinst_PROGRAMS = \
test/telltoc \
test/dewav \
test/fake_au \
test/poll
test/poll \
test/structest
bin_PROGRAMS = \
cdrskin/cdrskin
@ -113,10 +114,13 @@ test_fake_au_SOURCES = test/fake_au.c
test_poll_CPPFLAGS = -Ilibburn
test_poll_LDADD = $(libburn_libburn_la_OBJECTS) $(LIBBURN_EXTRALIBS)
test_poll_SOURCES = test/poll.c
test_structest_CPPFLAGS = -Ilibburn
test_structest_LDADD = $(libburn_libburn_la_OBJECTS) $(LIBBURN_EXTRALIBS)
test_structest_SOURCES = test/structest.c
## cdrskin construction site - ts A60816 - B60701
## cdrskin construction site - ts A60816 - B20720
cdrskin_cdrskin_CPPFLAGS = -Ilibburn
cdrskin_cdrskin_CFLAGS = -DCdrskin_libburn_1_4_4
cdrskin_cdrskin_CFLAGS = -DCdrskin_libburn_1_2_6
# cdrskin_cdrskin_LDADD = $(libburn_libburn_la_OBJECTS) $(LIBBURN_EXTRALIBS)
# ts A80123, change proposed by Simon Huggins to cause dynamic libburn linking
@ -171,7 +175,8 @@ uninstall-local:
# Indent source files
indent_files = \
$(libburn_libburn_la_SOURCES) \
$(test_poll_SOURCES)
$(test_poll_SOURCES) \
$(test_structest_SOURCES)
indent: $(indent_files)
@ -220,13 +225,11 @@ EXTRA_DIST = \
libburn/os-linux.h \
libburn/os-libcdio.h \
libburn/os-solaris.h \
libburn/os-netbsd.h \
libburn/sg-dummy.c \
libburn/sg-freebsd.c \
libburn/sg-linux.c \
libburn/sg-libcdio.c \
libburn/sg-solaris.c \
libburn/sg-netbsd.c \
COPYING \
NEWS \
ChangeLog \

134
README
View File

@ -6,12 +6,12 @@ This all is under GPL.
------------------------------------------------------------------------------
libburnia-project.org
By Mario Danic <mario.danic@gmail.com> and Thomas Schmitt <scdbackup@gmx.net>
Copyright (C) 2006-2016 Mario Danic, Thomas Schmitt
Copyright (C) 2006-2013 Mario Danic, Thomas Schmitt
Still containing parts of Libburn. By Derek Foreman <derek@signalmarketing.com>
and Ben Jansens <xor@orodu.net>
Copyright (C) 2002-2006 Derek Foreman and Ben Jansens
http://files.libburnia-project.org/releases/libburn-1.4.4.tar.gz
http://files.libburnia-project.org/releases/libburn-1.2.6.tar.gz
------------------------------------------------------------------------------
@ -19,14 +19,14 @@ Copyright (C) 2002-2006 Derek Foreman and Ben Jansens
From tarball
Obtain libburn-1.4.4.tar.gz, take it to a directory of your choice and do:
Obtain libburn-1.2.6.tar.gz, take it to a directory of your choice and do:
tar xzf libburn-1.4.4.tar.gz
cd libburn-1.4.4
tar xzf libburn-1.2.6.tar.gz
cd libburn-1.2.6
./configure --prefix=/usr
make
To make libburn accessible for running and application development,
To make libburn accessible for running resp. application development,
and to install the cdrecord compatibility binary cdrskin, do
(as Superuser):
@ -78,7 +78,7 @@ configure time by:
This may be combined with above --enable-track-src-odirect .
If it is desired that DVD DAO writing and stdio: writing get padded up to
a full write chunk of 32k or 64k, then use ./configure option:
a full write chunk of 32k resp. 64k, then use ./configure option:
--enable-dvd-obs-pad
Alternatively the transport of SCSI commands can be done via libcdio-0.83.
@ -137,13 +137,12 @@ These are libraries, language bindings, and middleware binaries which emulate
classical (and valuable) Linux tools.
Currently it is supported on GNU/Linux with kernels >= 2.4,
on FreeBSD with ATAPI/CAM enabled in the kernel (see man atapicam),
on OpenSolaris (tested with kernel 5.11),
on NetBSD (tested with 6.1.3).
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
or a live OS on CD or DVD, advise from a system person about the equivalent
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.
@ -174,8 +173,8 @@ The project components (list subject to growth, hopefully):
content.
- libisoburn is an add-on to libburn and libisofs which coordinates both and
also can grow ISO-9660 filesystem images on multi-session media
as well as on overwriteable media via the same API.
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.
It also contains the methods of command oriented application
xorriso and offers them via a C language API.
@ -355,7 +354,7 @@ Project history as far as known to me:
- 27th Apr 2008 libisofs-0.6.4 can now read data file content from images
and can map pieces of disk files onto image files. Image directory iteration
has been enhanced. Input data streams and extended information have been
exposed in the API to enable future development.
exposed in the API to allow future development.
- 29th Apr 2008 libisoburn-0.1.4 was made more efficient with reading of
image tree nodes. It now depends on libisofs-0.6.4 and libburn-0.4.4.
@ -369,8 +368,7 @@ Project history as far as known to me:
type with automatic media state recognition.
- 17th May 2008 an old bug with DVD-RAM and now with BD-RE is fixed by
libburn-0.4.8. So libisoburn can now perform emulation of multisession
on those media.
libburn-0.4.8 to allow libisoburn emulation of multisession on those media.
- 19th May 2008 libisoburn-0.1.6 brings better table-of-content emulation
on overwriteble media and disk files.
@ -395,8 +393,8 @@ Project history as far as known to me:
- 24th Aug 2008 libisoburn/xorriso-0.2.4 introduces a media readability check
with data retrieval option.
- 18th Sep 2008 libisofs-0.6.8 supports ISO 9660 Level 3 which can represent
very large data files in the image.
- 18th Sep 2008 libisofs-0.6.8 supports ISO 9660 Level 3 which allows very
large data files in the image.
- 20th Sep 2008 libisoburn/xorriso-0.2.6 takes into respect the new Level 3
capabilities of libisofs.
@ -414,7 +412,7 @@ Project history as far as known to me:
of an aborted burn run.
- 26th Nov 2008 libisofs-0.6.12 can produce a ISOLINUX isohybrid MBR on the fly
and can produce ISO images which resemble old mkisofs images.
and allows to produce ISO images which resemble old mkisofs images.
- 2nd Dec 2008 libisoburn-0.3.0. xorriso now is ready for exotic character
sets, for legacy FreeBSD systems which expect an outdated Rock Ridge
@ -426,7 +424,7 @@ Project history as far as known to me:
- 9th Dec 2008 Our project received a donation from Thomas Weber.
- 2nd Jan 2009 libburn-0.6.0 learned to format BD-R and write to either
- 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
@ -449,16 +447,15 @@ Project history as far as known to me:
- 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 was precondition
to lift the ban to build libburn on operating systems other than Linux
and FreeBSD.
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 implement compression to formats gzip and zisofs. External
filter processes can perform arbitrary data conversions like encryption.
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.
@ -483,10 +480,10 @@ Project history as far as known to me:
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 can be used to verify superblock
and directory tree before importing them.
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 learned to calm down a drive and to inquire its
- 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.
@ -520,7 +517,7 @@ Project history as far as known to me:
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 now offers performance tuning of output to DVD
- 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
@ -533,7 +530,7 @@ Project history as far as known to me:
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 can use
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
@ -555,8 +552,7 @@ Project history as far as known to me:
- 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 was needed to use GRUB boot images
for EFI.
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.
@ -610,11 +606,11 @@ Project history as far as known to me:
- 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 store untranslated ECMA-119 names (violating the specs).
libburn-1.0.0.pl00 is now willing to create stdio-drive files with
rw-permissions for all, if umask really asks for it. cdrskin now refuses
to burn if the foreseeable size exceeds media capacity
libisoburn-1.0.0.pl00 can now create an ISO 9660:1999 directory tree,
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.
@ -696,72 +692,6 @@ Project history as far as known to me:
programs. A proof of concept for a GUI frontend has been implemented:
xorriso-tcltk
- Mon Mar 18 2013 release 1.2.8:
Some rarely occuring bugs were fixed in libisofs and libburn. libburn's
handling of incomplete sessions has been improved. xorriso's mkisofs
emulation learned to set El Torito section id strings.
- Fri May 17 2013 release 1.3.0:
Several bugs were fixed in the libraries and in xorriso. The recently
introduced new boot preparation capabilities have been tested. New
boot preparation options for GRUB2 were added.
- Fri May 31 2013 patch release libburn-1.3.0.pl01:
cdrskin -msinfo on DVD and BD reported as old session start the same
number as the next writable address.
Regression introduced by version 1.2.8.
- Fri Aug 07 2013 release 1.3.2:
cdrskin has aquired the capability to copy audio tracks to .wav files.
It can extract CD-TEXT in a form that is readable for humans and for
cdrskin itself. Several small bugs were fixed in xorriso. Its capabilities
to serve frontend programs in dialog mode have been improved.
- Thu Dec 12 2013 release 1.3.4:
A long standing hidden bug was fixed, which affected inspection of
unformatted DVD+RW.
xorriso now by default puts EL Torito boot images to low block addresses.
It can report and set read speeds. Several rarely occuring bugs were fixed.
- Tue Mar 04 2014 release 1.3.6:
libburn learned to operate optical drives and media on NetBSD. libisofs got
a bug fix about HFS+ and enhancements about character set conversion.
Minor bugs were fixed in libisoburn. xorriso can now find files with names
which cannot be represented unchanged in ECMA-119, Joliet, or HFS+.
- Sat Jun 28 2014 release 1.3.8:
libburn got several bugs fixed. libisofs offers new API calls for inspection
of boot sectors in ISO 9660 filesystems. xorriso improved its support for
NetBSD, offers new features with command -find, and a command to extract
ISO 9660 file content onto standard output or into filter processes.
- Sun May 17 2015 release 1.4.0:
This release is mainly about bug fixes and a new feature of xorriso to
propose commands or as_mkisofs options which can reproduce the boot
equipment of the loaded ISO filesystem.
- Sat Nov 28 2015 release 1.4.2:
libburn got some bugs fixed and learned to inquire the drive serial number.
libisofs now sorts data file content by ECMA-119 file names for better
reproducability of ISO content. Rock Ridge filenames may be restricted to
lengths between 64 and 255 bytes. If needed, a qualified truncation happens.
xorriso now can replay boot settings when modifying ISO filesystems.
In order to avoid clogging of concurrent Linux SG_IO, xorriso got command
-modesty_on_drive to enable an old workaround from IDE master/slave days.
The source code underwent a scan by Coverity. About 150 code changes
resulted, but no easy-to-trigger bugs were found.
- Fri Jan 29 2016 patch release libburn-1.4.2.pl01:
cdrskin did not work with "-" (stdin) as input.
Regression introduced by version 1.4.2.
- Fri Jul 01 2016 release 1.4.4:
The capability to use Linux /dev/sg was revived in order to circumvent the
sr_mutex lock which hampers concurrent use of optical drives via SG_IO.
libisofs now can use appended partitions by El Torito, avoiding the need
for duplicate EFI System Partition images.
Several bugs have been fixed.
------------------------------------------------------------------------------

View File

@ -1,7 +1,7 @@
AC_DEFUN([LIBBURNIA_SET_FLAGS],
[
case $target_os in
freebsd* | netbsd*)
freebsd*)
LDFLAGS="$LDFLAGS -L/usr/local/lib"
CPPFLAGS="$CPPFLAGS -I/usr/local/include"
;;
@ -18,25 +18,21 @@ AC_DEFUN([TARGET_SHIZZLE],
LIBBURNIA_LDCONFIG_CMD="echo 'No ldconfig run performed. If needed, configure manually for:'"
case $target in
*-*-linux*)
case $target_os in
linux*)
ARCH=linux
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*)
kfreebsd*-gnu)
ARCH=freebsd
LIBBURN_ARCH_LIBS=-lcam
;;
*-solaris*)
ARCH=solaris
LIBBURN_ARCH_LIBS=-lvolmgt
;;
*)
ARCH=
LIBBURN_ARCH_LIBS=
@ -56,14 +52,12 @@ AC_DEFUN([LIBBURN_ASSERT_VERS_LIBS],
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 = xyes
if test x$vers_libs_test = xno
then
LIBLDFLAGS="-Wl,--version-script=libburn/libburn.ver"
LDFLAGS="$libburnia_save_LDFLAGS"
fi
LDFLAGS="$libburnia_save_LDFLAGS"
AC_SUBST(LIBLDFLAGS)
])
dnl LIBBURNIA_SET_PKGCONFIG determines the install directory for the *.pc file.
dnl Important: Must be performed _after_ TARGET_SHIZZLE
@ -115,37 +109,3 @@ dnl For debugging only
])
dnl LIBBURNIA_CHECK_ARCH_LIBS is by Thomas Schmitt, libburnia project
dnl It tests whether the OS dependent libraries are available.
dnl With libisoburn they are needed only for the case that indirect linking
dnl does not work. So it is worth a try to omit them.
dnl $1 = "mandatory" or "optional" define the action if test linking fails.
AC_DEFUN([LIBBURNIA_CHECK_ARCH_LIBS],
[
libburnia_save_LIBS="$LIBS"
if test "x$LIBBURN_ARCH_LIBS" = x
then
dummy=dummy
else
LIBS="$LIBS $LIBBURN_ARCH_LIBS"
AC_TRY_LINK([#include <stdio.h>], [printf("Hello\n");],
[archlibs_test="yes"], [archlibs_test="no"])
LIBS="$libburnia_save_LIBS"
if test x$archlibs_test = xno
then
if test x"$1" = xmandatory
then
echo >&2
echo "FATAL: Test linking with mandatory library options failed: $LIBBURN_ARCH_LIBS" >&2
echo >&2
(exit 1); exit 1;
else
echo "disabled linking with $LIBBURN_ARCH_LIBS (because not found)"
LIBBURN_ARCH_LIBS=""
fi
else
echo "enabled linking with $LIBBURN_ARCH_LIBS"
fi
fi
])

View File

@ -4,17 +4,17 @@
cdrskin. By Thomas Schmitt <scdbackup@gmx.net>
Integrated sub project of libburnia-project.org but also published via:
http://scdbackup.sourceforge.net/cdrskin_eng.html
http://scdbackup.sourceforge.net/cdrskin-1.4.4.tar.gz
http://scdbackup.sourceforge.net/cdrskin-1.2.6.tar.gz
Copyright (C) 2006-2016 Thomas Schmitt, provided under GPL version 2 or later.
Copyright (C) 2006-2013 Thomas Schmitt, provided under GPL version 2 or later.
------------------------------------------------------------------------------
cdrskin is a limited cdrecord compatibility wrapper which allows to use
most of the libburn features from the command line.
Currently it is fully supported on GNU/Linux with kernels >= 2.4, on FreeBSD,
on OpenSolaris, and on NetBSD.
Currently it is supported on GNU/Linux with kernels >= 2.4,
on FreeBSD and on OpenSolaris.
IDE drives under Linux 2.4. need kernel module ide-scsi.
ATA and SATA drives under FreeBSD need kernel module atapicam.
On other X/Open compliant systems there will only be emulated drives, but no
@ -26,10 +26,10 @@ By using this software you agree to the disclaimer at the end of this text
Compilation, First Glimpse, Installation
Obtain cdrskin-1.4.4.tar.gz, take it to a directory of your choice and do:
Obtain cdrskin-1.2.6.tar.gz, take it to a directory of your choice and do:
tar xzf cdrskin-1.4.4.tar.gz
cd cdrskin-1.4.4
tar xzf cdrskin-1.2.6.tar.gz
cd cdrskin-1.2.6
Within that directory execute:
@ -108,9 +108,8 @@ On Linux, 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 rw-permissions are to be set in /etc/devfs.rules.
On FreeBSD, device permissions are to be set in /etc/devfs.rules.
On Solaris, pfexec privileges may be restricted to "basic,sys_devices".
On NetBSD, rw-permission may be granted by chmod a+rw /dev/rcd?d.
See below "System Dependend Drive Permission Examples".
I strongly discourage to run cdrskin with setuid root or via sudo !
@ -192,11 +191,6 @@ See below "Audio CD" for specifications.
cdrskin -v dev=0,1,0 blank=fast -eject speed=48 -sao \
-audio -swab track0[1-5].cd /path/to/track6.wav
Extract audio tracks and CD-TEXT from CD into directory /home/me/my_cd:
mkdir /home/me/my_cd
cdrskin -v dev=/dev/sr0 extract_audio_to=/home/me/my_cd \
cdtext_to_v07t=/home/me/my_cd/cdtext.v07t
Restrictions
@ -428,9 +422,6 @@ It can also be enabled at configure time by
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
Add option
-use_libcdio
to your run of cdrskin/compile_cdrskin.sh .
You may get a (super fat) statically linked binary by :
cdrskin/compile_cdrskin.sh -static
@ -468,7 +459,7 @@ closing it immediately, waiting, and only then opening it for real:
System Dependend Drive Permission Examples
Accessing the optical drives requires privileges which usually are granted
only to the superuser. Linux, FreeBSD, Solaris, NetBSD, offer quite different
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
@ -479,9 +470,9 @@ 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 systems:
---------------
---------------------
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
@ -541,12 +532,6 @@ Then allow the group r-access to the drives
The last two commands have to be executed after each boot. I do not know
the relevant device configuration files yet.
----------
On NetBSD:
----------
Allow rw-access to the drives
chgrp floppy /dev/rcd[01]d
chmod g+rw /dev/rcd[01]d
------------------------------------------------------------------------------
Project aspects and legal stuff
@ -591,7 +576,7 @@ contributions in a due way.
Based on and sub project of:
libburnia-project.org
By Mario Danic <mario.danic@gmail.com> and Thomas Schmitt <scdbackup@gmx.net>
Copyright (C) 2006-2014 Mario Danic, Thomas Schmitt
Copyright (C) 2006-2013 Mario Danic, Thomas Schmitt
libburnia-project.org is inspired by and in other components still containing
parts of

View File

@ -18,7 +18,7 @@ set -x
# Both binaries are static in respect to libburn.
#
# The script is to be run in the directory above the toplevel
# directory of libburn (or cdrskin) development.
# directory of libburn resp. cdrskin development.
#
# The top level directory in the SVN snapshot is named
@ -38,7 +38,7 @@ original="./libburn_svn_release.tgz"
# My changes are in $changes , mainly in $changes/cdrskin
changes="./libburn-release"
skin_release="1.4.4"
skin_release="1.2.6"
patch_level=""
# patch_level=".pl00"
skin_rev="$skin_release""$patch_level"
@ -60,8 +60,7 @@ man_to_html_cmd="./cdrskin/convert_man_to_html.sh"
man_page_html="cdrskin/man_1_cdrskin.html"
# bintarget_dynamic="cdrskin_${skin_rev}-x86-suse9_0"
# bintarget_dynamic="cdrskin_${skin_rev}-amd64-suse10_2"
bintarget_dynamic="cdrskin_${skin_rev}-amd64-debian8_0"
bintarget_dynamic="cdrskin_${skin_rev}-amd64-suse10_2"
bintarget_static="$bintarget_dynamic"-static
if test -d "$changes"

View File

@ -18,7 +18,7 @@ set -x
# Both binaries are static in respect to libburn.
#
# The script is to be run in the directory above the toplevel
# directory of libburn (or cdrskin) development.
# directory of libburn resp. cdrskin development.
#
# The top level directory in the SVN snapshot is named
@ -38,7 +38,7 @@ original="./libburn_svn.tgz"
# My changes are in $changes , mainly in $changes/cdrskin
changes="./libburn-develop"
skin_release="1.4.5"
skin_release="1.2.7"
patch_level=""
skin_rev="$skin_release""$patch_level"
@ -58,8 +58,7 @@ compile_result="cdrskin/cdrskin"
man_to_html_cmd="./cdrskin/convert_man_to_html.sh"
man_page_html="cdrskin/man_1_cdrskin.html"
# bintarget_dynamic="cdrskin_${skin_rev}-amd64-suse10_2"
bintarget_dynamic="cdrskin_${skin_rev}-amd64-debian8_0"
bintarget_dynamic="cdrskin_${skin_rev}-amd64-suse10_2"
bintarget_static="$bintarget_dynamic"-static
if test -d "$changes"

View File

@ -118,7 +118,7 @@ int Cdrfifo_get_cdr_counters(struct CdrfifO *o,
int flag);
/** Inquire the eventually detected size of an eventual ISO-9660 file system
@return 0=no ISO size detected, 1=size_in_bytes is valid
@return 0=no ISO resp. size detected, 1=size_in_bytes is valid
*/
int Cdrfifo_get_iso_fs_size(struct CdrfifO *o, double *size_in_bytes,int flag);

View File

@ -2,7 +2,7 @@
.\" First parameter, NAME, should be all caps
.\" Second parameter, SECTION, should be 1-8, maybe w/ subsection
.\" other parameters are allowed: see man(7), man(1)
.TH CDRSKIN 1 "Version 1.4.4, Jul 01, 2016"
.TH CDRSKIN 1 "Version 1.2.6, Jan 08, 2013"
.\" Please adjust this date whenever revising the manpage.
.\"
.\" Some roff macros, for reference:
@ -37,7 +37,7 @@ Blanking of CD-RW and DVD-RW.
.br
Formatting of DVD-RW, DVD+RW, DVD-RAM, BD.
.br
Burning of data tracks or audio tracks with CD-TEXT to CD,
Burning of data or audio tracks to CD,
.br
either in versatile Track at Once mode (TAO)
.br
@ -55,8 +55,6 @@ on overwriteable DVD+RW, DVD-RW, DVD-RAM, BD-RE
.br
or on data file or block device.
.br
Extraction of audio tracks and CD-TEXT to hard disk files.
.br
Bus scan, burnfree, speed options, retrieving media info, padding, fifo.
.br
See section EXAMPLES at the end of this text.
@ -103,11 +101,11 @@ This information is also used by the operating systems' CD-ROM read drivers.
.PP
In general there are two types of tracks: data and audio. They differ in
sector size, throughput and readability via the systems' CD-ROM drivers
and 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
If not explicitly option -audio is given, then any track is burned as type
data, unless the track source is a file with suffix ".wav" or ".au" and has a
header part which identifies it as MS-WAVE or 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.
.PP
While audio tracks just contain a given time span of acoustic vibrations,
@ -128,10 +126,10 @@ the archivers afio and star. Not suitable seems GNU tar.
.br
In general there are two approaches for writing media:
.br
A permissive mode selected by option
A permissive mode depicted by option
.B -tao
which needs no predicted track size and can use
multi-session capabilities if offered by drive and medium.
which needs no predicted track size and allows to make use of
eventual multi-session capabilities.
.br
A more restrictive mode
.B -sao
@ -156,8 +154,8 @@ read-only. Closing is done automatically unless option
is given which keeps the media appendable.
.br
Write mode
-tao is able to use track sources of unpredictable length (like stdin) and
to write further sessions to appendable media.
-tao allows to use track sources of unpredictable length (like stdin) and
allows to write further sessions to appendable media.
-sao produces audio sessions with seamless tracks but needs predicted track
sizes and cannot append sessions to media.
.br
@ -185,8 +183,7 @@ Used DVD-RW get into blank sequential state by option
With DVD-R[W] two write modes may be available:
.br
Mode DAO has many restrictions. It does not work with
appendable media, cannot do -multi and writes 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
of recognizable size or the size has to be announced explicitly by options
.B tsize=
@ -203,8 +200,8 @@ The other mode, Incremental Streaming, is the default write mode if
it is available and if the restrictions of DAO would prevent the job.
Incremental Streaming may be selected explicitly by option
.B -tao
as it resembles much CD TAO by accepting track sources of
unpredicted length and being able to keep media appendable by option
as it resembles much CD TAO by allowing track sources of
unpredicted length and to keep media appendable by option
.B -multi . It does not work with DVD-R DL and minimally blanked DVD-RW.
The only restriction towards CD-R[W] is the lack of support for -audio tracks.
Multiple tracks per session are permissible.
@ -215,7 +212,7 @@ with DVD+R[/DL] or BD-R.
.br
Quite deliberately write mode -sao insists in the tradition of a predicted
track size and blank media, whereas -tao writes the tracks open ended and
can be applied to appendable media.
allows appendable media.
.br
BD-R may be formatted before first use to enable the Defect Management which
might catch and repair some bad spots at the expense of slow speed
@ -238,7 +235,7 @@ of option
.B --grow_overwriteable_iso .
Without this option or without an ISO-9660 filesystem image present
on media, -toc does not return information about the media content and
media get treated as blank regardless whether they hold data or not.
media get treated as blank regardless wether they hold data or not.
.br
Currently there is no difference between -sao and -tao. If ever, then -tao
will be the mode which preserves the current behavior.
@ -320,7 +317,7 @@ redirected to stderr and the stream data of a burn run will appear on stdout.
.br
Not good for terminals ! Redirect it.
.br
Pseudo-drives support -dummy. Their reply with --tell_media_space can be utopic.
Pseudo-drives allow -dummy. Their reply with --tell_media_space can be utopic.
-dummy burn runs touch the file but do not modify its data content.
.br
Note: --allow_emulated_drives is restricted to stdio:/dev/null if cdrskin
@ -361,7 +358,7 @@ Announces that the subsequent tracks are to be burned as audio.
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
-swab. Unless marked explicitly by option -data, input files with suffix
".wav" are examined whether 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
audio track. Same is done for suffix ".au" and SUN Audio.
.br
@ -427,7 +424,7 @@ Format a DVD-RW to "Restricted Overwrite". The user should bring some patience.
.TP
format_overwrite_quickest
Like format_overwrite without creating a 128 MiB trailblazer session.
Leads to "intermediate" state which only supports sequential write
Leads to "intermediate" state which only allows sequential write
beginning from address 0.
The "intermediate" state ends after the first session of writing data.
.TP
@ -446,7 +443,7 @@ format_defectmgt
Format DVD-RAM or BD to reserve the default amount of spare blocks for
defect management.
.br
The following format_defectmgt_* enable the user to submit wishes which
The following format_defectmgt_* allow to submit user wishes which
nevertheless have to match one of the available formats. These formats are
offered by the drive after examining the media.
.TP
@ -482,7 +479,7 @@ Unformatted blank BD-R will be left unformatted.
format_defectmgt_payload_<size>
Format DVD-RAM or BD. The text after "format_defectmgt_payload_" gives a
number of bytes, eventually with suffixes "s", "k", "m". The largest number
of spare blocks will be chosen which enables at least the given payload size.
of spare blocks will be chosen which allows at least the given payload size.
.TP
format_by_index_<number>
Format DVD-RW, DVD+RW, DVD-RAM or BD.
@ -833,7 +830,7 @@ This mode also applies pro-forma to overwriteable media
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
to appendable media which already hold data. With unformatted DVD-R[W] it is
the only mode which can keep media appendable by option -multi.
the only mode which allows -multi.
.br
Mode -tao is not usable for minimally blanked DVD-RW and for DVD-R DL.
.TP
@ -928,9 +925,9 @@ startup files. Level 3 is for debugging and useful mainly in conjunction with
somebody who had a look into the program sourcecode.
.TP
.BI \-V
Enable logging of SCSI commands to stderr. This is helpful for expert
examination of the interaction between libburn and the drive.
The commands are specified in SCSI-3 standards SPC, SBC, MMC.
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
Wait until input data is available at stdin or EOF occurs at stdin.
@ -997,25 +994,6 @@ the default.
This setting applies only to CD SAO writing. It overrides the track number
settings caused by options cuefile= or input_sheet_v07t=.
.TP
.BI cdtext_to_textfile= path
Extract the CD-TEXT packs from the lead-in of an audio CD and write them to
the file with the given path. If CD-TEXT can be retrieved, then this file
will be suitable for option textfile=.
.br
Not all drives can read CD-TEXT and not all audio CDs bear CD-TEXT.
It is not considered an error if no CD-TEXT is available.
.TP
.BI cdtext_to_v07t= path
Extract the CD-TEXT packs from the lead-in of an audio CD and write them
as human readable Sony Input Sheet Version 0.7T to the file with the
given path. If CD-TEXT can be retrieved, then this file
will be suitable for option input_sheet_v07t=.
.br
If the given path is "-", then the result is printed to standard output.
.br
Not all drives can read CD-TEXT and not all audio CDs bear CD-TEXT.
It is not considered an error if no CD-TEXT is available.
.TP
.BI \--demand_a_drive
Exit with a nonzero value if no drive can be found during a bus scan.
.TP
@ -1071,6 +1049,7 @@ media dependend transaction size. With DVD-RAM, BD-RE, DVD+RW this is 2k, with
overwriteable DVD-RW it is 32k.
.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. With most write types, tracks get padded up to the next multiple
of this write size (see option --obs_pad).
@ -1078,32 +1057,6 @@ A number of 64 KB may improve throughput with systems
which show latency problems. The default depends on media type, option
stream_recording=, and on compile time options.
.TP
.BI extract_audio_to= directory_path
Extract tracks from an audio CD as separate WAVE audio files into the
given directory.
This directory has to already exist, but none of the track files may exist.
This option will rather fail than overwrite an existing file.
.br
By default all tracks of the CD are extracted to files with names
trackNN.wav, where NN is the track number from 01 to at most 99.
.TP
.BI extract_basename= name
Set a filename which shall be used by extract_audio_to= instead of the default
name "track".
.TP
.BI --extract_dap
Enable Digital Audio Play flaw obscuring mechanisms
like audio data mute and interpolate.
.TP
.BI extract_tracks= number[,number[,...]]
Set a list of track numbers to define which tracks shall be extracted
by extract_audio_to=.
If no extract_tracks= is given, then all audio tracks get extracted.
It is permissible to have more than one extract_tracks= option in order
to split a long list into shorter pieces.
.br
The lowest permissible track number is 1, the highest is 99.
.TP
.BI fallback_program= command
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
@ -1187,15 +1140,7 @@ growisofs -dvd-compat is roughly equivalent to cdrskin without option -multi.
.BI input_sheet_v07t= path
Read CD-TEXT definitions from a Sony Input Sheet version 0.7T. Up to eight
or seven such sheets can be read by multiple input_sheet_v07t= options.
Each will define one CD-TEXT language block.
.br
The first line of a sheet file decides whether more than one sheet
may be defined by the file. If it is
.br
Input Sheet Version = 0.7T
.br
then each further line with that text switches to the next sheet for the next block.
If it is not, then all definitions apply to a single block.
Each will define a CD-TEXT language block.
.br
The information in such a sheet is given by text lines of the following form:
.br
@ -1298,27 +1243,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
option which ends by "=". The list is ended by an empty line.
.TP
.BI \--list_speeds
Put out a list of speed values as reported by the output drive with
the loaded medium. This does not necessarily mean that the medium is writable
or that these speeds are actually achievable. Especially the
lists reported with empty drive or with ROM media obviously advertise
speeds for other media.
.br
It is not mandatory to use speed values out of the listed range.
The drive is supposed to choose a safe speed that is as near to the desired
speed as possible.
.br
At the end of the list, "Write speed L" and "Write speed H"
are the best guesses for lower and upper speed limit.
"Write speed l" and "Write speed h" may appear only with CD
and eventually override the list of other speed offers.
.br
Only if the drive reports contradicting speed information there will appear
"Write speed 0" or "Write speed-1", which tell the outcome of speed selection
by options speed=0 or speed=-1, if it deviates from "Write speed L"
or "Write speed H", respectively.
.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 ...".
@ -1332,11 +1256,6 @@ which usually lack a motorized tray loader.
Only if used as first command line argument this option prevents reading and
interpretation of eventual startup files. See section FILES below.
.TP
.BI \--pacifier_with_newline
Adds a newline character to each pacifier line that would elsewise be
overwritten by the next pacifier line. Such lines are emitted during a
run of writing, formatting, or blanking if option -v is given.
.TP
.BI \--prodvd_cli_compatible
Activates behavior modifications with some DVD situations which bring cdrskin
nearer to the behavior of cdrecord-ProDVD:
@ -1373,8 +1292,8 @@ source cannot deliver a size prediction and no tsize= was specified and an
exact track size prediction is demanded by the write mode.
.br
This was the fallback from bad old times when cdrskin was unable to burn
in mode -tao . It came back with minimally blanked DVD-RW, which cannot do
Incremental Streaming (-tao), and with explicitly selected write mode -sao
in mode -tao . It came back with minimally blanked DVD-RW which allow no
Incremental Streaming (-tao) resp. with explicitly selected write mode -sao
for best DVD-ROM compatibility.
.br
If the track source delivers less bytes than announced then the missing ones
@ -1384,7 +1303,7 @@ will be filled with zeros.
Prepare a recording session, do not perform it but rather inquire the
maximum number of 2048 byte data blocks which may be written in
the current state of media with the prepared setup. So this option disables
recording of data. It does not disable blanking, though, and will measure space
recording of data. It does allow blanking, though, and will measure space
afterwards.
.br
It is not mandatory to give track sources but their nature may influence
@ -1399,17 +1318,6 @@ is possible with the given options.
This option redirects to stderr all message output except its own result
string and eventual output of -msinfo.
.TP
.BI textfile_to_v07t= path
Read a CD-TEXT pack file (e.g. cdtext.dat from a run with -v -v -toc)
and print its content in the human readable format that is described
with option input_sheet_v07t=.
.br
The program run ends immediately thereafter.
No drive scan will happen and no drive will be acquired.
.br
To avoid the cdrskin start message in the output, run:
cdrskin textfile_to_v07t=cdtext.dat | grep -v '^cdrskin'
.TP
.BI --two_channel
Indicate for subsequent tracks that they were mastered with two channels.
.TP
@ -1419,52 +1327,6 @@ or BD-RE byte_offset must be aligned to 2 kiB blocks, but better is 32 kiB.
With DVD-RW 32 kiB alignment is mandatory.
.br
Other media are not suitable for this option yet.
.TP
.BI modesty_on_drive= <mode>[:parameter=<value>[:parameter=<value>...]]
Mode 1 keeps the program from trying to write to the burner drive while its
buffer is in danger to be filled by more than parameter "max_percent".
If this filling is exceeded then the program will wait until the filling
is at most the value of parameter "min_percent".
.br
Percentages are permissible in the range of 25 to 100.
.br
This can ease the load on operating system and drive controller and thus help
with achieving better input bandwidth if disk and burner are not on independent
controllers (like hda and hdb). Unsufficient input bandwidth is indicated by
output "(fifo xy%)" of option -v if xy is lower than 90 for some time.
modesty_on_drive= might hamper output bandwidth and cause buffer underruns.
.br
A new use case is to work around the poor simultaneous performance of multiple
burn runs on Linux kernel 3.16 and alike. Here it is not about giving the
hard disk enough time to fill the fifo, but about keeping ioctl(SG_IO) from
blocking for a longer time and thus blocking all other burn runs.
.br
To have max_percent larger than the burner's best actual
buffer fill has the same effect as min_percent==max_percent. Some burners
do not use their full buffer with all media types. Watch output "[buf xy%]"
of option -v to get an impression of the actual buffer usage. Some burners
are not suitable because they report buffer fill with granularity too large
in size or time, or because they go to full speed only when their buffer is
full.
.br
If a write attempt is delayed, the program will wait for a number of
microseconds which is given by parameter "min_usec" before inquiring the buffer
again. iIf more retries occur, this waiting time between inquiries increases
up to the value of parameter "max_usec".
.br
If the delay lasts longer than the number of seconds given by parameter
"timeout_sec", then mode 1 is set 0 and normal burning goes on.
.br
Mode 0 disables this feature. Mode -1 keeps it unchanged. Default is:
.br
0:min_percent=65:max_percent=95:timeout_sec=120:
min_usec=10000:max_usec=100000
.br
The defaults of cdrskin are good for IDE problems. With concurrent Linux SG_IO
problems on modern hardware, higher min_percent and lower usec might yield
better buffer fills while still avoiding the problem:
.br
min_percent=90:max_percent=95:min_usec=5000:max_usec=25000
.PP
Alphabetical list of options which are only intended for very special
situations and not for normal use:
@ -1527,13 +1389,13 @@ fcntl(2).
.TP
.BI \--drive_not_o_excl
Linux specific: Do not ask the operating system to prevent opening busy drives.
Whether this leads to senseful behavior depends on operating system and kernel.
Wether this leads to senseful behavior depends on operating system and kernel.
.TP
.BI drive_scsi_dev_family= sr | scd | sg
Linux specific: Select a SCSI device file family to be scanned for by
options --devices, --device_links and -scanbus.
Normally this is /dev/sgN on kernel versions < 2.6 and /dev/srN
on kernels >= 2.6 . This option explicitly overrides that default
on kernels >= 2.6 . This option allows to explicitly override that default
in order to meet other programs at a common device file for each drive.
On kernel 2.4 families sr and scd will find no drives.
.br
@ -1544,7 +1406,7 @@ Linux specific:
Try to exclusively reserve device files /dev/srN, /dev/scdM, /dev/sgK of drives.
This would be helpful to protect against collisions with program growisofs.
Regrettably on Linux kernel 2.4 with ide-scsi emulation this seems not to
work. Whether it becomes helpful with new Linux systems has to be evaluated.
work. Wether it becomes helpful with new Linux systems has to be evaluated.
.TP
.BI \--fifo_disable
Disable fifo despite any fs=.
@ -1579,6 +1441,30 @@ Try to ignore any signals rather than to abort the program. This is not a
very good idea. You might end up waiting a very long time for cdrskin
to finish.
.TP
.BI modesty_on_drive= <mode>[:min_percent=<num>][:max_percent=<num>]
Mode 1 keeps the program from trying to write to the burner drive while its
buffer is in danger to be filled by more than max_percent. If this filling is
exceeded then the program will wait until the filling is at most min_percent.
.br
This can ease the load on operating system and drive controller and thus help
with achieving better input bandwidth if disk and burner are not on independent
controllers (like hda and hdb). Unsufficient input bandwidth is indicated by
output "(fifo xy%)" of option -v if xy is lower than 90 for some time.
modesty_on_drive= might hamper output bandwidth and cause buffer underruns.
.br
To have max_percent larger than the burner's best actual
buffer fill has the same effect as min_percent==max_percent. Some burners
do not use their full buffer with all media types. Watch output "[buf xy%]"
of option -v to get an impression of the actual buffer usage. Some burners
are not suitable because they report buffer fill with granularity too large
in size or time.
.br
Mode 0 disables this feature. Mode -1 keeps it unchanged. Default is:
.br
modesty_on_drive=0:min_percent=65:max_percent=95
.br
Percentages are permissible in the range of 25 to 100.
.TP
.BI \--no_abort_handler
On signals exit even if the drive is in busy state. This is not a very good
idea. You might end up with a stuck drive that refuses to hand out the media.
@ -1625,7 +1511,7 @@ This setting affects only CD SAO write runs.
.BI sao_pregap= off|number
Define whether a pre-gap shall be written before the track and how many
sectors this pre-gap shall have. A pre-gap is written in the range of track
index 0 and contains zeros. No bytes from the track source
index 0 and contains zeros resp. silence. No bytes from the track source
will be read for writing the pre-gap.
.br
This setting affects only CD SAO write runs.
@ -1670,7 +1556,7 @@ cdrskin -v dev=/dev/sr0 blank=deformat_sequential
.br
cdrskin -v dev=/dev/hdc speed=12 fs=8m \\
.br
blank=as_needed -eject padsize=300k my_image.iso
blank=as_needed -eject padsize=300k my_image.iso
.SS
.B Write compressed afio archive on-the-fly (not possible with minimally blanked DVD-RW or DVD-R DL):
.br
@ -1678,7 +1564,7 @@ find . | afio -oZ - | \\
.br
cdrskin -v dev=0,1,0 fs=32m speed=8 \\
.br
blank=as_needed padsize=300k -
blank=as_needed padsize=300k -
.SS
.B Write multi-session to the same CD, DVD-R[W], DVD+R[/DL], or BD-R:
.br
@ -1700,25 +1586,16 @@ mkisofs ... -C "$c_values" ...
.br
x=$(cdrskin dev=/dev/sr0 -multi \\
.br
--tell_media_space 2>/dev/null)
--tell_media_space 2>/dev/null)
.br
echo "Available: $x blocks of 2048 data bytes"
.SS
.B Write audio tracks and CD-TEXT to CD:
.B Write audio tracks to CD:
.br
cdrskin -v dev=ATA:1,0,0 speed=48 -sao \\
.br
input_sheet_v07t=cdtext.v07t \\
track1.wav track2.au -audio -swab track3.raw
.br
track1.wav track2.au -audio -swab track3.raw
.SS
.B Extract audio tracks and CD-TEXT from CD into directory /home/me/my_cd:
.br
mkdir /home/me/my_cd
.br
cdrskin -v dev=/dev/sr0 extract_audio_to=/home/me/my_cd \\
.br
cdtext_to_v07t=/home/me/my_cd/cdtext.v07t
.SH FILES
.SS
Startup files:

File diff suppressed because it is too large Load Diff

View File

@ -39,8 +39,8 @@ About any CD, DVD, or BD recorder produced in the recent ten years.
<BR>
<A HREF="http://libburnia-project.org">libburn</A>
supports recorders which are compliant to standards MMC-1 for CD and
MMC-5 for DVD or BD. Linux, FreeBSD, Solaris, and NetBSD can communicate
with drives connected via SCSI, PATA (aka IDE, ATA), USB, or SATA.
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>
</P>
@ -49,14 +49,12 @@ with drives connected via SCSI, PATA (aka IDE, ATA), USB, or SATA.
<DL>
<DT>Linux with kernel 2.4 or higher (and libc, of course) :</DT>
<DD>With kernel 2.4 an ATA drive has to be under ide-scsi emulation.</DD>
<DD>With kernel 2.6 or higher the drive should not be under ide-scsi.</DD>
<DD>With kernel 2.6 the drive should not be under ide-scsi.</DD>
<DT>or FreeBSD (with libc, of course) :</DT>
<DD>ATA and SATA drives need atapicam running.</DD>
<DD>libcam has to be installed.</DD>
<DT>or Solaris (with libc, of course) :</DT>
<DD>Tested on kernel 5.11, hopefully suitable for older ones too.</DD>
<DT>or NetBSD (with libc, of course) :</DT>
<DD>Tested on 6.1.2 and 6.1.3</DD>
<DT>libpthread</DT>
<DD>is supposed to be a standard system component.</DD>
</DL>
@ -67,7 +65,7 @@ with drives connected via SCSI, PATA (aka IDE, ATA), USB, or SATA.
GPL software included:<BR>
</H2>
<DL>
<DT>libburn-1.4.4</DT>
<DT>libburn-1.2.6</DT>
<DD>(founded by Derek Foreman and Ben Jansens,
developed and maintained since August 2006 by
Thomas Schmitt from team of libburnia-project.org)
@ -78,7 +76,7 @@ Thomas Schmitt from team of libburnia-project.org)
<P>
This program system has been tested on Intel/AMD with Linux, FreeBSD,
OpenSolaris, and NetBSD based operating systems.<BR>
and OpenSolaris based operating systems.<BR>
Ports to other usable systems are appreciated. Reports are welcome.
</P>
@ -109,10 +107,10 @@ DVD-R DL, which both support no -multi.
<DD>#<KBD>&nbsp;cdrskin -scanbus</KBD></DD>
<DD>#<KBD>&nbsp;cdrskin dev=ATA -scanbus</KBD></DD>
<DD>#<KBD>&nbsp;cdrskin --devices</KBD></DD>
<DT>Being superuser avoids permission problems with /dev/srN and /dev/hdX .
<DT>Being superuser avoids permission problems with /dev/srN resp. /dev/hdX .
</DT>
<DT>Ordinary users should then get granted access to the /dev files
as listed by option --devices. Linux, FreeBSD, and NetBSD demand rw-permission.
as listed by option --devices. Linux and FreeBSD demand rw-permission.
On Solaris it is r-permission and privileges "basic,sys_devices".</DT>
<DT>&nbsp;</DT>
@ -202,13 +200,13 @@ Standalone ISO 9660 multi-session CD/DVD/BD tool
<P>
<DL>
<DT>Download as source code (see README):</DT>
<DD><A HREF="cdrskin-1.4.4.tar.gz">cdrskin-1.4.4.tar.gz</A>
(1050 KB).
<DD><A HREF="cdrskin-1.2.6.tar.gz">cdrskin-1.2.6.tar.gz</A>
(940 KB).
</DD>
<DD><A HREF="cdrskin-1.4.4.tar.gz.sig">cdrskin-1.4.4.tar.gz.sig</A></DD>
<DD><A HREF="cdrskin-1.2.6.tar.gz.sig">cdrskin-1.2.6.tar.gz.sig</A></DD>
<DD>
(detached GPG signature for verification by
<KBD>gpg --verify cdrskin-1.4.4.tar.gz.sig cdrskin-1.4.4.tar.gz</KBD>
<KBD>gpg --verify cdrskin-1.2.6.tar.gz.sig cdrskin-1.2.6.tar.gz</KBD>
<BR>
after <KBD>gpg --keyserver keys.gnupg.net --recv-keys ABC0A854</KBD>).
</DD>
@ -247,8 +245,8 @@ cdrskin_0.4.2.pl00-x86-suse9_0-static.tar.gz</A>, (310 KB), -static compiled,
</DL>
<DL><DT>Contact:</DT>
<DD>Thomas Schmitt, <A HREF="mailto:scdbackup@gmx.net">scdbackup@gmx.net</A></DD>
<DD>GNU xorriso mailing list, where cdrskin and libburn are on topic, too:
<A HREF="mailto:bug-xorriso@gnu.org">bug-xorriso@gnu.org</A></DD>
<DD>libburn development mailing list,
<A HREF="mailto:libburn-hackers@pykix.org">libburn-hackers@pykix.org</A></DD>
</DL>
<DL><DT>License:</DT>
<DD><A HREF="COPYING_cdrskin">GPL</A>, an <A HREF="http://www.opensource.org/">Open Source</A> approved license</DD>
@ -259,60 +257,49 @@ cdrskin_0.4.2.pl00-x86-suse9_0-static.tar.gz</A>, (310 KB), -static compiled,
<HR>
<P>
Enhancements towards previous stable version cdrskin-1.4.2:
Enhancements towards previous stable version cdrskin-1.2.4:
<UL>
<LI>none</LI>
<LI>New option --no_load</LI>
<!--
<LI>none</LI>
-->
</UL>
Bug fixes towards cdrskin-1.4.2.pl01:
Bug fixes towards cdrskin-1.2.4:
<UL>
<LI>Option drive_scsi_dev_family=sg did not convert /dev/sr* to /dev/sg*</LI>
<LI>Option cdtext_to_v07t= falsly recognized double byte encoding.</LI>
<LI>
Option textfile= caused a double free at end of the cdrskin run.
</LI>
<LI>DVD book type of DVD+RW DL and DVD+R DL was reported wrong. Thanks to Etienne Bergeron.</LI>
<LI>Speed setting had no effect on BD media</LI>
<!--
<LI>none</LI>
-->
</UL>
Bug fixes towards cdrskin-1.4.2 (without .pl01):
<UL>
<LI>"failed to attach fifo" when trying to burn from stdin. Regression of 1.4.2.</LI>
</UL>
<HR>
<P>
<DL>
<DT><H3>Development snapshot, version 1.4.5 :</H3></DT>
<DD>Enhancements towards current stable version 1.4.4:
<DT><H3>Development snapshot, version 1.2.7 :</H3></DT>
<DD>Enhancements towards current stable version 1.2.6:
<UL>
<LI>none yet</LI>
<!--
<LI>none yet</LI>
-->
</UL>
</DD>
<DD>Bug fixes towards cdrskin-1.4.4:
<DD>Bug fixes towards cdrskin-1.2.6:
<UL>
<LI>none yet</LI>
<!--
<LI>none yet</LI>
-->
</UL>
</DD>
<DD>&nbsp;</DD>
<DD><A HREF="README_cdrskin_devel">README 1.4.5</A>
<DD><A HREF="cdrskin__help_devel">cdrskin-1.4.5 --help</A></DD>
<DD><A HREF="cdrskin_help_devel">cdrskin-1.4.5 -help</A></DD>
<DD><A HREF="man_1_cdrskin_devel.html">man cdrskin (as of 1.4.5)</A></DD>
<DD><A HREF="README_cdrskin_devel">README 1.2.7</A>
<DD><A HREF="cdrskin__help_devel">cdrskin-1.2.7 --help</A></DD>
<DD><A HREF="cdrskin_help_devel">cdrskin-1.2.7 -help</A></DD>
<DD><A HREF="man_1_cdrskin_devel.html">man cdrskin (as of 1.2.7)</A></DD>
<DD>&nbsp;</DD>
<DT>Maintainers of cdrskin unstable packages please use SVN of
<A HREF="http://libburnia-project.org"> libburnia-project.org</A></DT>
@ -327,13 +314,13 @@ vanilla tools like make and gcc are needed.</DD>
</DD>
<DD>&nbsp;</DD>
<DT>The following download is intended for adventurous end users or
admins with full system sovereignty.</DT>
admins with full system souvereignty.</DT>
<DD>Source (./bootstrap is already applied, build tested, for more see
<A HREF="README_cdrskin_devel">upcoming README</A> ):
</DD>
<DD>
<A HREF="cdrskin-1.4.5.tar.gz">cdrskin-1.4.5.tar.gz</A>
(1050 KB).
<A HREF="cdrskin-1.2.7.tar.gz">cdrskin-1.2.7.tar.gz</A>
(940 KB).
</DD>
<!-- This is not offered any more since spring 2008
@ -483,7 +470,7 @@ cdrecord but not vice versa.
<BR>
<BR>
I was a long time user of cdrecord and it worked fine for me.
Especially i do appreciate its write mode -tao which can pipe arbitrary
Especially i do appreciate its write mode -tao which allows to pipe arbitrary
data on CD and CD-RW via stdin. cdrecord is reliable, versatile and well
maintained. So for me - there would be no problem with using it for
burning CDs.
@ -529,15 +516,11 @@ and by <A HREF="http://sourceforge.net">sourceforge.net</A><BR>
<A href="http://sourceforge.net">
<IMG src="sflogo-88-1.png" BORDER="0" ALT="SourceForge Logo"></A>
<!-- on sourceforge use : <IMG src="http://sourceforge.net/sflogo.php?group_id=16010" width="88" height="31" border="0" alt="SourceForge Logo"></A> -->
<!--
<P>
Enjoying a FreeBSD shell account with the opportunity to
build and install cdrskin at<BR>
<A HREF="http://www.en.free-shells.com.ar">free-shells.com.ar</A>
</P>
-->
</FONT></CENTER>
<HR>
<DL>

View File

@ -1 +1 @@
#define Cdrskin_timestamP "2016.07.01.110001"
#define Cdrskin_timestamP "2013.01.08.090001"

File diff suppressed because it is too large Load Diff

View File

@ -1,14 +1,14 @@
#!/bin/sh
# compile_cdrskin.sh
# Copyright 2005 - 2016 Thomas Schmitt, scdbackup@gmx.net, GPL v2 or later
# to be executed within ./libburn-* or./cdrskin-*
# Copyright 2005 - 2013 Thomas Schmitt, scdbackup@gmx.net, GPL v2 or later
# to be executed within ./libburn-* resp ./cdrskin-*
debug_opts="-O2"
def_opts=
largefile_opts="-D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE=1"
fifo_opts=""
libvers="-DCdrskin_libburn_1_4_4"
libvers="-DCdrskin_libburn_1_2_6"
# To be used if Makefile.am uses libburn_libburn_la_CFLAGS
# burn="libburn/libburn_libburn_la-"
@ -41,15 +41,15 @@ do
elif test "$i" = "-compile_dewav"
then
compile_dewav=1
elif test "$i" = "-libburn_1_4_4"
elif test "$i" = "-libburn_1_2_6"
then
libvers="-DCdrskin_libburn_1_4_4"
libvers="-DCdrskin_libburn_1_2_6"
libdax_audioxtr_o="$burn"libdax_audioxtr.o
libdax_msgs_o="$burn"libdax_msgs.o
cleanup_src_or_obj="$burn"cleanup.o
elif test "$i" = "-libburn_svn"
then
libvers="-DCdrskin_libburn_1_4_5"
libvers="-DCdrskin_libburn_1_2_7"
libdax_audioxtr_o="$burn"libdax_audioxtr.o
libdax_msgs_o="$burn"libdax_msgs.o
cleanup_src_or_obj="$burn"cleanup.o
@ -99,7 +99,7 @@ do
echo "Options:"
echo " -compile_cdrfifo compile program cdrskin/cdrfifo."
echo " -compile_dewav compile program test/dewav without libburn."
echo " -libburn_1_4_4 set macro to match libburn-1.4.4"
echo " -libburn_1_2_6 set macro to match libburn-1.2.6"
echo " -libburn_svn set macro to match current libburn-SVN."
echo " -dvd_obs_64k 64 KB default size for DVD/BD writing."
echo " -use_libcdio link with -lcdio because libburn uses it."

View File

@ -1,7 +1,7 @@
#!/bin/sh
#
# convert_man_to_html.sh - ts A61214 , B50802
# convert_man_to_html.sh - ts A61214
#
# Generates a HTML version of man page cdrskin.1
#
@ -38,25 +38,24 @@ then
sed \
-e 's/<meta name="generator" content="groff -Thtml, see www.gnu.org">/<meta name="generator" content="groff -Thtml, via man -H, via cdrskin\/convert_man_to_html.sh">/' \
-e 's/<meta name="Content-Style" content="text\/css">/<meta name="Content-Style" content="text\/css"><META NAME="description" CONTENT="man page of cdrskin"><META NAME="keywords" CONTENT="man cdrskin, manual, cdrskin, CD-RW, CD-R, DVD-R, DVD-RW, DVD+R, DVD+RW, BD-R, BD-RE, burning, cdrecord, compatible"><META NAME="robots" CONTENT="follow">/' \
-e 's/<meta name="Content-Style" content="text\/css">/<meta name="Content-Style" content="text\/css"><META NAME="description" CONTENT="man page of cdrskin"><META NAME="keywords" CONTENT="man cdrskin, manual, cdrskin, CD, CD-RW, CD-R, burning, cdrecord, compatible"><META NAME="robots" CONTENT="follow">/' \
-e 's/<title>CDRSKIN<\/title>/<title>man 1 cdrskin<\/title>/' \
-e 's/<h1 align=center>CDRSKIN<\/h1>/<h1 align=center>man 1 cdrskin<\/h1>/' \
-e 's/<body>/<body BGCOLOR="#F5DEB3" TEXT=#000000 LINK=#0000A0 VLINK=#800000>/' \
-e 's/<b>Overview of features:<\/b>/<b>Overview of features:<\/b><BR>/' \
-e 's/<b>General information paragraphs:<\/b>/<b>General information paragraphs:<\/b><BR>/' \
-e 's/<b>Track recording model:<\/b>/\&nbsp;<BR><b>Track recording model:<\/b><BR>/' \
-e 's/<b>Overview of features:<\/b>/\&nbsp;<BR><b>Overview of features:<\/b>/' \
-e 's/<b>General information paragraphs:<\/b>/\&nbsp;<BR><b>General information paragraphs:<\/b>/' \
-e 's/<b>Track recording model:<\/b>/\&nbsp;<BR><b>Track recording model:<\/b>/' \
-e 's/^In general there are two types of tracks: data and audio./\&nbsp;<BR>In general there are two types of tracks: data and audio./' \
-e 's/^While audio tracks just contain a given/\&nbsp;<BR>While audio tracks just contain a given/' \
-e 's/<b>Write mode selection:<\/b>/<b>Write mode selection:<\/b><BR>/' \
-e 's/<b>Recordable CD Media:<\/b>/<b>Recordable CD Media:<\/b><BR>/' \
-e 's/<b>Overwriteable DVD or BD Media:<\/b>/<b>Overwriteable DVD or BD Media:<\/b><BR>/' \
-e 's/<b>Sequentially Recordable DVD or BD Media:<\/b>/<b>Sequentially Recordable DVD or BD Media:<\/b><BR>/' \
-e 's/<b>Write mode selection:<\/b>/\&nbsp;<BR><b>Write mode selection:<\/b>/' \
-e 's/<b>Recordable CD Media:<\/b>/\&nbsp;<BR><b>Recordable CD Media:<\/b>/' \
-e 's/<b>Overwriteable DVD Media:<\/b>/\&nbsp;<BR><b>Overwriteable DVD Media:<\/b>/' \
-e 's/<b>Sequentially Recordable DVD Media:<\/b>/\&nbsp;<BR><b>Sequentially Recordable DVD Media:<\/b>/' \
-e 's/^The write modes for DVD+R/\&nbsp;<BR>The write modes for DVD+R/' \
-e 's/<b>Drive preparation and addressing:<\/b>/<b>Drive preparation and addressing:<\/b><BR>/' \
-e 's/<b>Drive preparation and addressing:<\/b>/\&nbsp;<BR><b>Drive preparation and addressing:<\/b>/' \
-e 's/^If you only got one CD capable drive/\&nbsp;<BR>If you only got one CD capable drive/' \
-e 's/<b>Emulated drives:<\/b>/<b>Emulated drives:<\/b><BR>/' \
-e 's/for normal use: <b><br>/for normal use: <b><br><BR>/' \
-e 's/original cdrecord by Joerg Schilling:<\/p>/original cdrecord by Joerg Schilling:<\/p><BR>/' \
-e 's/<b>Emulated drives:<\/b>/\&nbsp;<BR><b>Emulated drives:<\/b>/' \
-e 's/^Alphabetical list of options/\&nbsp;<BR>Alphabetical list of options/' \
-e 's/<\/body>/<BR><HR><FONT SIZE=-1><CENTER>(HTML generated from '"$manpage"'.1 on '"$(date)"' by '$(basename "$0")' )<\/CENTER><\/FONT><\/body>/' \
-e 's/See section FILES/See section <A HREF="#FILES">FILES<\/A>/' \
-e 's/See section EXAMPLES/See section <A HREF="#EXAMPLES">EXAMPLES<\/A>/' \
@ -71,10 +70,8 @@ then
else
# export BROWSER='cp "%s" '"$raw_html"
export BROWSER=$(pwd)/'cdrskin/unite_html_b_line "%s" '"$raw_html"
export BROWSER='cp "%s" '"$raw_html"
man -H "$manpage"
# cp "$raw_html" /tmp/x.html
"$0" -work_as_filter "$raw_html"
rm "$raw_html"
rm "$man_dir"/man1

View File

@ -1,7 +1,7 @@
#!/bin/sh
# Create version timestamp cdrskin/cdrskin_timestamp.h
# to be executed within ./libburn-* or ./cdrskin-*
# to be executed within ./libburn-* resp ./cdrskin-*
timestamp="$(date -u '+%Y.%m.%d.%H%M%S')"
echo "Version timestamp : $timestamp"

View File

@ -1,124 +0,0 @@
/*
( cd cdrskin ; cc -g -Wall -o unite_html_b_line unite_html_b_line.c )
*/
/*
Specialized converter for the output of man -H,
which unites lines where the line end is between <b> and </b>.
Copyright 2015 Thomas Schmitt, <scdbackup@gmx.net>
Provided under GPL version 2 or later.
*/
#ifdef HAVE_CONFIG_H
#include "../config.h"
#endif
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <errno.h>
int unite_lines(char *buffer, int *b_open, int *b_state, int flag)
{
char *cpt;
int last_was_nl= 0;
for(cpt= buffer; *cpt != 0; cpt++) {
if(*b_open) {
if(*b_state == 0 && *cpt == '<') {
*b_state= 1;
} else if(*b_state == 1) {
if(*cpt == '/')
*b_state= 2;
else
*b_state= 0;
} else if(*b_state == 2) {
if(*cpt == 'b' || *cpt == 'B')
*b_state= 3;
else
*b_state= 0;
} else if(*b_state == 3) {
if(*cpt == '>')
*b_open= 0;
*b_state= 0;
}
} else {
if(*b_state == 0 && *cpt == '<') {
*b_state= 1;
} else if(*b_state == 1) {
if(*cpt == 'b' || *cpt == 'B')
*b_state= 2;
else
*b_state= 0;
} else if(*b_state == 2) {
if(*cpt == '>')
*b_open= 1;
*b_state= 0;
}
}
last_was_nl= (*cpt == '\n');
}
if(*b_open && last_was_nl) {
/* replace newline */
*(cpt - 1)= ' ';
}
return(1);
}
int main(int argc, char **argv)
{
FILE *fpin, *fpout;
char buffer[4096], *respt;
int ret, b_open= 0, b_state= 0;
if(argc != 3) {
fprintf(stderr, "usage: %s input_path output_path\n", argv[0]);
return(1);
}
if(strcmp(argv[1], "-") == 0) {
fpin= stdin;
} else {
fpin= fopen(argv[1], "rb");
if(fpin == 0) {
fprintf(stderr, "Error with input file '%s' : %s\n",
argv[1], strerror(errno));
return(2);
}
}
if(strcmp(argv[2], "-") == 0) {
fpout= stdout;
} else {
fpout= fopen(argv[2], "wb");
if(fpout == 0) {
fprintf(stderr, "Error with output file '%s' : %s\n",
argv[2], strerror(errno));
return(3);
}
}
while(1) {
respt= fgets(buffer, sizeof(buffer), fpin);
if(respt == NULL)
break;
ret= unite_lines(buffer, &b_open, &b_state, 0);
if(ret <= 0)
break;
ret= fputs(buffer, fpout);
if(ret < 0) {
fprintf(stderr, "Error writing to output file '%s' : %s\n",
argv[2], strerror(errno));
return(4);
}
}
if(fpin != stdin)
fclose(fpin);
if(fpout != stdout)
fclose(stdout);
return(0);
}

View File

@ -23,6 +23,11 @@ About libburn API for burning CD, DVD, and BD: http://api.libburnia-project.org
--------------------------------------------------------------------------
For yet unsupported media types see the advice to use dvd+rw-tools at
the end of this text.
--------------------------------------------------------------------------
About the command line options of cdrskin:
They are described in detail in [http://scdbackup.sourceforge.net/man_1_cdrskin_devel.html#OPTIONS section OPTIONS] of
@ -56,7 +61,7 @@ Some are of general user interest, though:
--------------------------------------------------------------------------
--devices can be used by the sysadmin to scan the system for possible drives
--devices allows the sysadmin to scan the system for possible drives
and displays their detected properties.
The drives are listed one per line, with fields:
libburn-drive-number, sysadmin-device-file, permissions, vendor, type
@ -167,7 +172,7 @@ media with a single session and track on it. blank= invalidates ISO images.
--------------------------------------------------------------------------
assert_write_lba=<lba> ensures that the start block address which
assert_write_lba=<lba> allows to ensure that the start block address which
was used with the formatter program (e.g. mkisofs -C) matches the start block
address which will be used by the upcoming burn.
@ -215,7 +220,7 @@ With a very fat fs=# buffer (128 MB for 12x CD is not unrealistic) this
can cause a big delay until burning finally starts and takes its due time.
fifo_start_at=<num> makes cdrskin start burning after the given number of bytes
is read rather than waiting for the FIFO to be completely full or the data
is read rather than waiting for the FIFO to be completely full resp. the data
stream to end. It risks a few drive buffer underruns at the beginning of burn
- but modern drives stand this.

View File

@ -1,4 +1,4 @@
AC_INIT([libburn], [1.4.4], [http://libburnia-project.org])
AC_INIT([libburn], [1.2.6], [http://libburnia-project.org])
AC_PREREQ([2.50])
dnl AC_CONFIG_HEADER([config.h])
@ -99,15 +99,6 @@ dnl 1.2.0 = libburn.so.4.73.0
dnl 1.2.2 = libburn.so.4.75.0
dnl 1.2.4 = libburn.so.4.77.0
dnl 1.2.6 = libburn.so.4.79.0
dnl 1.2.8 = libburn.so.4.81.0
dnl 1.3.0 = libburn.so.4.83.0
dnl 1.3.2 = libburn.so.4.85.0
dnl 1.3.4 = libburn.so.4.87.0
dnl 1.3.6 = libburn.so.4.89.0
dnl 1.3.8 = libburn.so.4.91.0
dnl 1.4.0 = libburn.so.4.93.0
dnl 1.4.2 = libburn.so.4.95.0
dnl 1.4.4 = libburn.so.4.97.0
dnl
dnl So LT_CURRENT, LT_REVISION and LT_AGE get set directly here.
dnl SONAME of the emerging library is LT_CURRENT - LT_AGE.
@ -132,8 +123,8 @@ dnl If BURN_*_VERSION changes, be sure to change AC_INIT above to match.
dnl
dnl As said: Only copies. Original in libburn/libburn.h : burn_header_version_*
BURN_MAJOR_VERSION=1
BURN_MINOR_VERSION=4
BURN_MICRO_VERSION=4
BURN_MINOR_VERSION=2
BURN_MICRO_VERSION=6
BURN_VERSION=$BURN_MAJOR_VERSION.$BURN_MINOR_VERSION.$BURN_MICRO_VERSION
AC_SUBST(BURN_MAJOR_VERSION)
@ -144,14 +135,14 @@ AC_SUBST(BURN_VERSION)
dnl Libtool versioning
LT_RELEASE=$BURN_MAJOR_VERSION.$BURN_MINOR_VERSION.$BURN_MICRO_VERSION
dnl
dnl This is the release version libburn-1.4.4
dnl This is the release version libburn-1.2.6
dnl ### This is the development version after above release version
dnl LT_CURRENT++, LT_AGE++ has not yet happened.
dnl ### LT_CURRENT++, LT_AGE++ has happened meanwhile.
dnl
dnl SONAME = 101 - 97 = 4 . Linux library name = libburn.so.4.97.0
LT_CURRENT=101
LT_AGE=97
dnl SONAME = 83 - 79 = 4 . Linux library name = libburn.so.4.79.0
LT_CURRENT=83
LT_AGE=79
LT_REVISION=0
LT_CURRENT_MINUS_AGE=`expr $LT_CURRENT - $LT_AGE`
@ -187,7 +178,7 @@ fi
AC_PROG_LIBTOOL
AC_SUBST(LIBTOOL_DEPS)
dnl LIBTOOL="$LIBTOOL --silent"
LIBTOOL="$LIBTOOL --silent"
AC_PROG_INSTALL
@ -228,27 +219,27 @@ 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 writing, default=no],
[ --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"
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"
echo "disabled write size default 64 KB on DVD and BD"
fi
CFLAGS="$LIBBURN_DVD_OBS_64K $CFLAGS"
dnl ts B20413
AC_ARG_ENABLE(dvd-obs-pad,
[ --enable-dvd-obs-pad pad DVD DAO sessions to 32 or 64 KB, default=no],
[ --enable-dvd-obs-pad pad DVD DAO sessions to 32 resp. 64 KB, default=no],
, enable_dvd_obs_pad=no)
if test x$enable_dvd_obs_pad = xyes; then
LIBBURN_DVD_OBS_PAD="-DLibburn_dvd_always_obs_paD"
echo "enabled padding of DVD DAO sessions to 32 or 64 KB"
echo "enabled padding of DVD DAO sessions to 32 resp. 64 KB"
else
LIBBURN_DVD_OBS_64K=
echo "disabled padding of DVD DAO sessions to 32 or 64 KB"
echo "disabled padding of DVD DAO sessions to 32 resp. 64 KB"
fi
CFLAGS="$LIBBURN_DVD_OBS_PAD $CFLAGS"
@ -318,9 +309,6 @@ else
echo "disabled strict symbol encapsulation"
fi
# Check for system dependent mandatory libraries (LIBBURN_ARCH_LIBS)
LIBBURNIA_CHECK_ARCH_LIBS(mandatory)
AC_ARG_ENABLE(ldconfig-at-install,
[ --enable-ldconfig-at-install On GNU/Linux run ldconfig, default=yes],
, ldconfig_at_install=yes)
@ -347,7 +335,7 @@ if test x$enable_debug != xyes; then
CFLAGS="-DNDEBUG $CFLAGS"
else
if test x$GCC = xyes; then
CFLAGS="-g -pedantic -Wall -Wextra -Wno-unused-parameter -Wno-char-subscripts $CFLAGS"
CFLAGS="-g -pedantic -Wall -Wextra -Wno-unused-parameter $CFLAGS"
fi
CFLAGS="-DDEBUG $CFLAGS"
fi

View File

@ -195,7 +195,7 @@ as it is limited to 64 kB - 2.)
If a text of a track (pack types 0x80 to 0x85 and 0x8e) repeats identically
for the next track, then it may be represented by a TAB character (ASCII 9)
for single byte texts, and two TAB characters for double byte texts.
for single byte texts, resp. two TAB characters for double byte texts.
(This should be used because 256 * 12 bytes is few space for 99 tracks.)
The two binary bytes of pack type 0x87 are written to the first 0x87 pack of
@ -403,7 +403,7 @@ Byte :Value Meaning
-------------------------------------------------------------------------------
Overview of libburn API calls for CD-TEXT (see libburn/libburn.h for details):
libburn can retrieve the array of text packs from a CD:
libburn can retrieve the set of text packs from a CD:
int burn_disc_get_leadin_text(struct burn_drive *d,
unsigned char **text_packs, int *num_packs,
@ -418,7 +418,7 @@ This set may be attached as array of readily formatted text packs by:
unsigned char *text_packs,
int num_packs, int flag);
The array of text packs may be read from a file by
The array may be read from a file by
int burn_cdtext_from_packfile(char *path, unsigned char **text_packs,
int *num_packs, int flag);
@ -453,12 +453,6 @@ There is a reader for Sony Input Sheet Version 0.7T:
int burn_session_input_sheet_v07t(struct burn_session *session,
char *path, int block, int flag);
and a writer which converts an array of text packs to such a Sony Input Sheet:
int burn_make_input_sheet_v07t(unsigned char *text_packs, int num_packs,
int start_tno, int track_count,
char **result, int *char_code, int flag);
CD-TEXT can be read from a CDRWIN cue sheet file which defines the tracks
of a session
@ -572,8 +566,7 @@ libburn peculiarties:
libburn may read files of the described format by
burn_session_input_sheet_v07t()
after the burn_session has been establiched and all burn_track objects have
been added. It can convert an array of CD-TEXT packs into this format by
burn_make_input_sheet_v07t()
been added.
The following purpose specifiers accept byte values of the form 0xXY.
Text Code , Language Code , Genre Code , Text Data Copy Protection
@ -600,7 +593,7 @@ as empty test. (Normally empty content is ignored.)
Example cdrskin run with three tracks:
$ cdrskin dev=/dev/sr0 -v input_sheet_v07t=NIGHTCATS.TXT \
-audio -swab track_source_1 track_source_2 track_source_3
-audio track_source_1 track_source_2 track_source_3
----------------------------------------------------------
Content of file NIGHTCATS.TXT :

View File

@ -10,9 +10,9 @@ optical discs. This page is about its capability to handle optical media.
For now this means CD-R, CD-RW, DVD-RAM, DVD+RW, DVD+R, DVD+R/DL, DVD-RW,
DVD-R, DVD-R/DL, BD-R, BD-RE.
Our scope is currently Linux 2.4 and 2.6, FreeBSD, OpenSolaris, or NetBSD.
For ports to other systems we would need : login on a development machine or
an OS that is installable on an AMD 64-bit PC, advise from a system person
Our scope is currently Linux 2.4 and 2.6, or FreeBSD, or Solaris . For ports
to other systems we would need : login on a development machine resp.
an OS ithat is installable on an AMD 64-bit PC, advise from a system person
about the equivalent of Linux sg or FreeBSD CAM, volunteers for testing of
realistic use cases.
@ -52,7 +52,7 @@ and execute
- make
To make the libraries accessible for running and developing applications
To make the libraries accessible for running resp. developing applications
- make install

View File

@ -618,7 +618,7 @@ BG Format 3 indicates fully formatted media.
DVD-RW reaches this state either by Format Type 00h (or 10h) with maximum
size given as Number Of Blocks, or by writing sequentially until the disc is
completely full into an intermediate session opened by format 15h or 13h.
completely full into an intermediate session opened by format 15h resp. 13h.
(mmc5r03c.pdf, 6.5 FORMAT UNIT, 6.5.4.2.1, 6.5.4.2.10, 6.5.4.2.8)
A fully formatted DVD-RW can be recognized by 23h READ FORMAT CAPACITIES. The
Descriptor Type of the Current/Maximum Capacity Descriptor is 10b ("Formatted
@ -647,7 +647,7 @@ In the reply, BG Format 0 indicates unformatted media (or unsuitable media).
(mmc5r03c.pdf 6.22.3.1.13)
Formatting has to be started by command 04h FORMAT UNIT, Format Type 26h.
Different from other format types, 26h is allowed to send a fantasy size of
Different from other format types, 26h allows to send a fantasy size of
0xffffffff blocks and does not require the caller to know the exact maximum
size offered with that format.
(mmc5r03c.pdf, 6.5 FORMAT UNIT, 6.5.4.2.14 Format Type = 26h)
@ -744,7 +744,7 @@ Elsewise the media is in Intermediate state. See below.
A partly formatted DVD-RW can be recognized by 23h READ FORMAT CAPACITIES. The
Descriptor Type of the Current/Maximum Capacity Descriptor is 10b ("Formatted
Media") and the Number Of Blocks with formats 00h, 10h or 15h is larger than the
currently formatted size, or more than 0 blocks are offered with Format
currently formatted size, resp. more than 0 blocks are offered with Format
Types 13h or 11h.
(mmc5r03c.pdf, 6.24.3.2.1, 6.24.3.3)
@ -753,7 +753,7 @@ be unnecessary to do any further formatting.
But in order to make the DVD-RW surely accept its maximum number of bytes,
partial formatting may be expanded by command 04h FORMAT UNIT, Format Type 13h,
which is supposed to be offered by the drive in this state. This brings the
session again into Intermediate state and thus enables expansion by sequential
session again into Intermediate state and thus allows expansion by sequential
writing. As with Format Type 15h it is ok to set Number Of Blocks to 0, so that
no fixed size formatting work is done and writing can begin soon after.
(mmc5r03c.pdf, 6.5.4.2.8 Format Type = 13h)
@ -803,8 +803,8 @@ Two format types are relevant for DVD-RAM : 00h and 01h.
00h offers the default size format and usually a maximum payload size format.
Even with that maximum size payload there is hardware defect management.
(mmc5r03c.pdf 6.5.4.2.1.2)
01h can convert payload capacity into spare blocks for defect managment.
There is no way to increase payload capacity by format 01h.
01h allows to convert payload capacity into spare blocks for defect
managment. There is no way to increase payload capacity by format 01h.
(mmc5r03c.pdf 6.5.4.2.2.1)
With BD-RE there are three format types : 00h, 30h and 31h.
@ -978,10 +978,10 @@ DVD-RW Sequential Recording 0014h
DVD-R/DL Sequential Recording 0015h (can only do single-session)
There are two approaches for writing to sequential DVD-R[W]: DAO and
Incremental. Not all media and drives offer Incremental which can do
Incremental. Not all media and drives offer Incremental which allows
multi-session as with CD media and does not demand a predicted track size.
DAO seems to be the older method. It can only write one single session and
track, and it demands an exactly predicted track size.
DAO seems to be the older method. It allows only one single session and
track and it demands an exactly predicted track size.
- About overwriteable, blank, appendable and finalized DVD-R[W] media
- Incremental writing
@ -1025,7 +1025,7 @@ brings back this feature.
-------------------------------------------------------------------------------
Incremental writing :
Incremental writing can produce multi-session DVDs. It is indicated
Incremental writing allows to produce multi-session DVDs. It is indicated
by feature 0021h being marked current in the reply of 46h GET CONFIGURATION.
growisofs inquires 0021h by setting Starting Feature Number to 0x21 and
Allocation Length to 16 in order to get only this one. The feature descriptor
@ -1042,8 +1042,8 @@ which are returned by ACh.
growisofs fetches a mode page 05h template by MODE SENSE and inserts its own
parameters. It sets Multi-session to 11b, unless dvd_compat is nonzero.
libburn composes its mode page 05h from zero and enables the application
to control Multi-Session.
libburn composes its mode page 05h from zero and allows control of
Multi-Session by the application.
BUFE Buffer Underrun protection 0=off, 1=on
LS_V Link size valid 1=true
Test Write -dummy mode for writing 0=off, 1=on
@ -1456,7 +1456,7 @@ eventually RRM) chosen by the format sub-type:
10b = (RRM)
(mmc5r03c.pdf 6.5.4.2.1.6)
Format type 32h uses the same sub-types but can allocate non-default
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.

View File

@ -280,7 +280,7 @@ There are two classes of device specific suffixes:
If a lockfile does not exist and cannot be created then this shall not keep
a program from working on a device. But if a lockfile exists and if permissions
or locking state do not allow to obtain a lock of the appropirate type, then
this shall prevent any opening of device file in question and shall cause
this shall prevent any opening of device file in question resp. shall cause
immediate close(2) of an already opened device file.
The vulnerable programs shall not start their operation before they locked a
@ -346,7 +346,7 @@ which keeps it from being the solution to all known legitimate use cases.
The attempt has failed to compose a waterproof locking mechanism from means of
POSIX, FHS and from hardly documented Linux open(O_EXCL) on device files.
The resulting mechanisms would need about 1000 lines of code and still do
not close all gaps and cover the well motivated use cases.
not close all gaps resp. cover the well motivated use cases.
This attempt you see above: DDLP-A and DDLP-B.

File diff suppressed because it is too large Load Diff

View File

@ -190,7 +190,7 @@ Via libburn these manufacturer and media ids can be retrieved by API call
burn_disc_get_media_id() as a single printable word product_id and as two
printable words media_code1, media_code2. The latter can be translated into
a manufacturer company name by API call burn_guess_manufacturer().
(Both calls work for CD, too. burn_disc_get_media_id() eventually calls
(Both calls work for CD, too. burn_get_media_product_id() eventually calls
burn_disc_read_atip().)
@ -1036,9 +1036,6 @@ MEI T02 Panasonic Corporation 1-4X HTL 12cm [Blu]
MEI 00V001 MATSUSHITA EI 2X [Hij]
MEI 00V002 MATSUSHITA EI 4X [Hij]
"Millenniata Inc."
MILLENMR MR1 Verbatim M-DISC 4x 25 GB (user reported)
"Mitsubishi Kagaku Media Co."
MKM 001 MKM 6X [Hij]
MKM 003 MKM 8X [Hij]
@ -1189,7 +1186,7 @@ TYG11 TAIYO YUDEN DVD-R DL 8x
TYG-BD Y01 TAIYO YUDEN Co., Ltd. 1-2X LTH [Blu]
TYG-BD Y03 TAIYO YUDEN Co., Ltd. 1-4X LTH [Blu]
"UmeDisc Limited"
"UmeDisc Ltd. HK"
UMEDISC DL1 Elite DVD+R DL [User report feb 2012]
"Unifino Inc."

View File

@ -1,7 +1,7 @@
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
Copyright (c) 2006 - 2014 Thomas Schmitt <scdbackup@gmx.net>
Copyright (c) 2006 - 2012 Thomas Schmitt <scdbackup@gmx.net>
Provided under GPL version 2 or later.
*/
@ -98,14 +98,6 @@ struct fifo_opts
int flag;
};
union w_list_data
{
struct scan_opts scan;
struct erase_opts erase;
struct format_opts format;
struct write_opts write;
struct fifo_opts fifo;
};
struct w_list
{
@ -117,7 +109,14 @@ struct w_list
struct w_list *next;
union w_list_data u;
union w_list_data
{
struct scan_opts scan;
struct erase_opts erase;
struct format_opts format;
struct write_opts write;
struct fifo_opts fifo;
} u;
};
static struct w_list *workers = NULL;
@ -134,7 +133,7 @@ static struct w_list *find_worker(struct burn_drive *d)
}
static void add_worker(int w_type, struct burn_drive *d,
WorkerFunc f, union w_list_data *data)
WorkerFunc f, void *data)
{
struct w_list *a;
struct w_list *tmp;
@ -147,11 +146,7 @@ static void add_worker(int w_type, struct burn_drive *d,
a = calloc(1, sizeof(struct w_list));
a->w_type = w_type;
a->drive = d;
a->u = *data;
/*
memcpy(&(a->u), data, sizeof(union w_list_data));
*/
a->u = *(union w_list_data *)data;
/* insert at front of the list */
a->next = workers;
@ -258,7 +253,7 @@ static void reset_progress(struct burn_drive *d, int sessions, int tracks,
int burn_drive_scan(struct burn_drive_info *drives[], unsigned int *n_drives)
{
union w_list_data o;
struct scan_opts o;
int ret = 0;
/* ts A61006 : moved up from burn_drive_scan_sync , former Assert */
@ -297,9 +292,9 @@ drive_is_active:;
*drives = NULL;
*n_drives = 0;
o.scan.drives = drives;
o.scan.n_drives = n_drives;
o.scan.done = 0;
o.drives = drives;
o.n_drives = n_drives;
o.done = 0;
add_worker(Burnworker_type_scaN, NULL,
(WorkerFunc) scan_worker_func, &o);
} else if (workers->u.scan.done) {
@ -351,14 +346,14 @@ static void *erase_worker_func(struct w_list *w)
void burn_disc_erase(struct burn_drive *drive, int fast)
{
union w_list_data o;
struct erase_opts o;
/* ts A61006 */
/* a ssert(drive); */
/* a ssert(!SCAN_GOING()); */
/* a ssert(!find_worker(drive)); */
if(drive == NULL) {
if((drive == NULL)) {
libdax_msgs_submit(libdax_messenger, -1,
0x00020104,
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
@ -413,8 +408,8 @@ void burn_disc_erase(struct burn_drive *drive, int fast)
return;
}
o.erase.drive = drive;
o.erase.fast = fast;
o.drive = drive;
o.fast = fast;
add_worker(Burnworker_type_erasE, drive,
(WorkerFunc) erase_worker_func, &o);
}
@ -452,7 +447,7 @@ static void *format_worker_func(struct w_list *w)
/* ts A61230 */
void burn_disc_format(struct burn_drive *drive, off_t size, int flag)
{
union w_list_data o;
struct format_opts o;
int ok = 0, ret;
char msg[40];
@ -540,9 +535,9 @@ void burn_disc_format(struct burn_drive *drive, off_t size, int flag)
drive->cancel = 1;
return;
}
o.format.drive = drive;
o.format.size = size;
o.format.flag = flag;
o.drive = drive;
o.size = size;
o.flag = flag;
add_worker(Burnworker_type_formaT, drive,
(WorkerFunc) format_worker_func, &o);
}
@ -594,7 +589,7 @@ static void *write_disc_worker_func(struct w_list *w)
void burn_disc_write(struct burn_write_opts *opts, struct burn_disc *disc)
{
union w_list_data o;
struct write_opts o;
char *reasons= NULL;
struct burn_drive *d;
int mvalid;
@ -648,7 +643,8 @@ void burn_disc_write(struct burn_write_opts *opts, struct burn_disc *disc)
if (d->drive_role == 1) {
mvalid = 0;
if (d->mdata != NULL)
mvalid = 1;
if (d->mdata->valid > 0)
mvalid = 1;
if (!mvalid) {
libdax_msgs_submit(libdax_messenger,
d->global_index, 0x00020113,
@ -688,9 +684,9 @@ void burn_disc_write(struct burn_write_opts *opts, struct burn_disc *disc)
d->cancel = 0; /* End of the return = failure area */
o.write.drive = d;
o.write.opts = opts;
o.write.disc = disc;
o.drive = d;
o.opts = opts;
o.disc = disc;
opts->refcount++;
@ -736,7 +732,7 @@ static void *fifo_worker_func(struct w_list *w)
int burn_fifo_start(struct burn_source *source, int flag)
{
union w_list_data o;
struct fifo_opts o;
struct burn_source_fifo *fs = source->data;
fs->is_started = -1;
@ -749,8 +745,8 @@ int burn_fifo_start(struct burn_source *source, int flag)
return -1;
}
o.fifo.source = source;
o.fifo.flag = flag;
o.source = source;
o.flag = flag;
add_worker(Burnworker_type_fifO, NULL,
(WorkerFunc) fifo_worker_func, &o);
fs->is_started = 1;

View File

@ -1,5 +1,5 @@
/* Copyright (c) 2011 - 2016 Thomas Schmitt <scdbackup@gmx.net>
/* Copyright (c) 2011 Thomas Schmitt <scdbackup@gmx.net>
Provided under GPL version 2 or later.
*/
@ -615,65 +615,17 @@ static int v07t_cdtext_to_track(struct burn_track *track, int block,
}
static int v07t_apply_to_session(struct burn_session *session, int block,
int char_codes[8], int copyrights[8], int languages[8],
int session_attr_seen[16], int track_attr_seen[16],
int genre_code, char *genre_text, int flag)
{
int i, ret, length;
char *line = NULL;
BURN_ALLOC_MEM(line, char, 4096);
for (i= 0x80; i <= 0x8e; i++) {
if (i > 0x85 && i != 0x8e)
continue;
if (session_attr_seen[i - 0x80] || !track_attr_seen[i - 0x80])
continue;
ret = v07t_cdtext_to_session(session, block, "",
char_codes + block, i, NULL, 0);
if (ret <= 0)
goto ex;
}
if (genre_code >= 0 && genre_text[0]) {
line[0] = (genre_code >> 8) & 0xff;
line[1] = genre_code & 0xff;
strcpy(line + 2, genre_text);
length = 2 + strlen(line + 2) + 1;
ret = burn_session_set_cdtext(session, block, 0, "GENRE",
(unsigned char *) line, length, 0);
if (ret <= 0)
goto ex;
}
ret = burn_session_set_cdtext_par(session, char_codes, copyrights,
languages, 0);
if (ret <= 0)
goto ex;
for (i = 0; i < 8; i++)
char_codes[i] = copyrights[i] = languages[i]= -1;
for (i = 0; i < 16; i++)
session_attr_seen[i] = track_attr_seen[i] = 0;
genre_text[0] = 0;
ret = 1;
ex:
BURN_FREE_MEM(line);
return ret;
}
/* ts B11215 API */
/* @param flag bit0= permission to read multiple blocks from the same sheet
bit1= do not attach CATALOG to session or ISRC to track for
/* @param flag bit1= do not attach CATALOG to session or ISRC to track for
writing to Q sub-channel
*/
int burn_session_input_sheet_v07t(struct burn_session *session,
char *path, int block, int flag)
{
int ret = 0, num_tracks, char_codes[8], copyrights[8], languages[8], i;
int genre_code = -1, track_offset = 1, pack_type, tno, tnum;
int genre_code = -1, track_offset = 1, length, pack_type, tno, tnum;
int session_attr_seen[16], track_attr_seen[16];
int int0x00 = 0x00, int0x01 = 0x01;
int additional_blocks = -1, line_count = 0, enable_multi_block = 0;
struct stat stbuf;
FILE *fp = NULL;
char *line = NULL, *eq_pos, *payload, *genre_text = NULL, track_txt[3];
@ -726,7 +678,6 @@ cannot_open:;
burn_printify(msg), 0, 0);
ret = 0; goto ex;
}
line_count++;
if (strlen(line) == 0)
continue;
eq_pos = strchr(line, '=');
@ -871,31 +822,6 @@ cannot_open:;
burn_printify(msg), 0, 0);
ret = 0; goto ex;
}
if (flag & 1)
if (line_count == 1)
enable_multi_block = 1;
if (enable_multi_block) {
if (additional_blocks >= 0) {
if (block == 7) {
libdax_msgs_submit(
libdax_messenger, -1, 0x000201a0,
LIBDAX_MSGS_SEV_WARNING, LIBDAX_MSGS_PRIO_HIGH,
"Maximum number of CD-TEXT blocks exceeded",
0, 0);
break;
}
ret = v07t_apply_to_session(
session, block, char_codes,
copyrights, languages,
session_attr_seen,
track_attr_seen,
genre_code, genre_text, 0);
if (ret <= 0)
goto ex;
block++;
}
additional_blocks++;
}
} else if (strcmp(line, "Remarks") == 0) {
;
@ -1053,16 +979,33 @@ bad_track_no:;
ret = 0; goto ex;
}
}
ret = v07t_apply_to_session(session, block,
char_codes, copyrights, languages,
session_attr_seen, track_attr_seen,
genre_code, genre_text, 0);
for (i= 0x80; i <= 0x8e; i++) {
if (i > 0x85 && i != 0x8e)
continue;
if (session_attr_seen[i - 0x80] || !track_attr_seen[i - 0x80])
continue;
ret = v07t_cdtext_to_session(session, block, "",
char_codes + block, i, NULL, 0);
if (ret <= 0)
goto ex;
}
if (genre_code >= 0 && genre_text[0]) {
line[0] = (genre_code >> 8) & 0xff;
line[1] = genre_code & 0xff;
strcpy(line + 2, genre_text);
length = 2 + strlen(line + 2) + 1;
ret = burn_session_set_cdtext(session, block, 0, "GENRE",
(unsigned char *) line, length, 0);
if (ret <= 0)
goto ex;
}
ret = burn_session_set_cdtext_par(session, char_codes, copyrights,
languages, 0);
if (ret <= 0)
goto ex;
ret = 1;
if (additional_blocks > 0)
ret += additional_blocks;;
ex:;
if(fp != NULL)
fclose(fp);
@ -1085,7 +1028,6 @@ int burn_cdtext_from_packfile(char *path, unsigned char **text_packs,
BURN_ALLOC_MEM(msg, char, 4096);
*text_packs = NULL;
if (stat(path, &stbuf) == -1) {
cannot_open:;
sprintf(msg, "Cannot open CD-TEXT pack file '%.4000s'", path);
@ -1137,14 +1079,7 @@ cannot_read:;
path);
libdax_msgs_submit(libdax_messenger, -1, 0x0002018b,
LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH,
burn_printify(msg), 0, 0);
ret = 0; goto ex;
} if (*num_packs <= 0) {
strcpy(msg,
"CD-Text pack file contains no complete text pack");
libdax_msgs_submit(libdax_messenger, -1, 0x000201aa,
LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH,
burn_printify(msg), 0, 0);
burn_printify(msg), errno, 0);
ret = 0; goto ex;
}
@ -1174,564 +1109,3 @@ ex:;
}
/* --------------------------------- make_v07t -------------------------- */
static int search_pack(unsigned char *text_packs, int num_packs,
int start_no, int pack_type, int block,
unsigned char **found_pack, int *found_no, int flag)
{
int i;
for (i = start_no; i < num_packs; i++) {
if (pack_type >= 0)
if (text_packs[i * 18] != pack_type)
continue;
if (block >= 0)
if (((text_packs[i * 18 + 3] >> 4) & 7) != block)
continue;
*found_pack = text_packs + i * 18;
*found_no = i;
return 1;
}
*found_pack = NULL;
*found_no = num_packs;
return 0;
}
static void write_v07t_line(char **respt, char *spec, char *value, int vlen,
int *result_len, int flag)
{
int len;
if (vlen == -1)
vlen = strlen(value);
len = strlen(spec);
if (len < 19)
len = 19;
len += 3 + vlen + 1;
if(flag & 1) {
*result_len += len;
return;
}
sprintf(*respt, "%-19s = ", spec);
if (vlen > 0)
memcpy(*respt + strlen(*respt), value, vlen);
(*respt)[len - 1] = '\n';
(*respt)[len] = 0;
*respt+= len;
}
/*
@return -1 error
0 no pack of block,pack_type found
1 packs found, delimiter is single 0-byte
2 packs found, delimiter is double 0-byte
*/
static int collect_payload(unsigned char *text_packs, int num_packs,
int pack_type, int block,
unsigned char **payload, int *payload_count,
int flag)
{
unsigned char *pack;
int pack_no, ret, double_byte = 0;
*payload_count = 0;
for (pack_no = 0; ; pack_no++) {
ret = search_pack(text_packs, num_packs, pack_no, pack_type,
block, &pack, &pack_no, 0);
if (ret <= 0)
break;
*payload_count += 12;
}
if (*payload_count == 0)
return 0;
*payload = burn_alloc_mem(*payload_count + 1, 1, 0);
if (*payload == NULL)
return -1;
*payload_count = 0;
for (pack_no = 0; ; pack_no++) {
ret = search_pack(text_packs, num_packs, pack_no, pack_type,
block, &pack, &pack_no, 0);
if (ret <= 0)
break;
memcpy(*payload + *payload_count, pack + 4, 12);
*payload_count += 12;
if (pack[3] & 128)
double_byte = 1;
}
(*payload)[*payload_count] = 0;
return 1 + double_byte;
}
/*
@param flag bit0= use double 0 as delimiter
*/
static int is_payload_text_end(unsigned char *payload, int payload_count,
int i, int flag)
{
if (i >= payload_count)
return 1;
if (payload[i])
return 0;
if (!(flag & 1))
return 1;
if (i + 1 >= payload_count)
return 1;
if (payload[i + 1] == 0)
return 1;
return 0;
}
/*
@param flag Bitfield for control purposes.
bit0= use double 0 as delimiter
bit1= replace TAB resp. TAB TAB by text of previous tno
*/
static int pick_payload_text(unsigned char *payload, int payload_count,
int tno,
unsigned char **text_start, int *text_len,
int flag)
{
int i, skipped = 0, end_found = 0;
again:;
if (tno <= 0) {
*text_start = payload;
*text_len = 0;
for (i = 0; i < payload_count; i += 1 + (flag & 1)) {
end_found = is_payload_text_end(payload, payload_count,
i, flag & 1);
if (end_found) {
*text_len = i;
break;
}
}
return 1;
}
*text_start = NULL;
*text_len = 0;
for (i = 0; i < payload_count; i += 1 + (flag & 1)) {
end_found = is_payload_text_end(payload, payload_count,
i, flag & 1);
if (end_found) {
skipped++;
if (skipped == tno) {
*text_start = payload + (i + 1 + (flag & 1));
} else if (skipped == tno + 1) {
*text_len = i - (*text_start - payload);
goto found;
}
}
}
if (*text_start == NULL)
return 0;
*text_len = payload_count - (*text_start - payload);
found:;
if (flag & 2) {
/* If TAB resp. TAB TAB, then look back */
if (flag & 1) {
if (*text_len == 2) {
if ((*text_start)[0] == '\t' &&
(*text_start)[1] == '\t') {
skipped = 0;
tno--;
goto again;
}
}
} else if (*text_len == 1) {
if ((*text_start)[0] == '\t') {
skipped = 0;
tno--;
goto again;
}
}
}
return 1;
}
static int write_v07t_textline(unsigned char *text_packs, int num_packs,
int pack_type, int block,
int tno, int first_tno, char *spec,
char **respt, int *result_len, int flag)
{
unsigned char *payload = NULL, *text_start;
int ret, payload_count = 0, text_len, tab_flag = 0;
char msg[80];
if ((pack_type >= 0x80 && pack_type <= 0x85) || pack_type == 0x8e)
tab_flag = 2;
ret = collect_payload(text_packs, num_packs, pack_type, block,
&payload, &payload_count, 0);
if(ret > 0) {
ret = pick_payload_text(payload, payload_count, tno,
&text_start, &text_len,
(ret == 2) | tab_flag);
if (ret > 0) {
if (tno > 0 && strcmp(spec, "ISRC") == 0)
sprintf(msg, "%s %-2.2d",
spec, tno + first_tno - 1);
else if (tno > 0)
sprintf(msg, "Track %-2.2d %s",
tno + first_tno - 1, spec);
else
strcpy(msg, spec);
write_v07t_line(respt, msg,
(char *) text_start, text_len,
result_len, flag & 1);
ret = 1;
}
}
BURN_FREE_MEM(payload);
return ret;
}
static int report_track(unsigned char *text_packs, int num_packs,
int block, int tno, int first_tno,
char **respt, int *result_len, int flag)
{
int ret, i;
static char *track_specs[6] = {
"Title", "Artist", "Songwriter", "Composer",
"Arranger", "Message"
};
for (i = 0; i < 6; i++) {
ret = write_v07t_textline(text_packs, num_packs, 0x80 + i,
block, tno, first_tno,
track_specs[i], respt, result_len,
flag & 1);
if (ret < 0)
return -1;
}
ret = write_v07t_textline(text_packs, num_packs, 0x8e, block,
tno, first_tno,
"ISRC", respt, result_len, flag & 1);
if (ret < 0)
return -1;
return 1;
}
/*
@param flag Bitfield for control purposes.
bit0= Do not store text in result but only determine
the minimum size for the result array.
It is permissible to submit result == NULL.
Submit the already occupied size as result_size.
@return > 0 tells the number of valid text bytes in result resp.
with flag bit0 the prediction of that number.
This does not include the trailing 0-byte.
= 0 indicates that the block is not present
< 0 indicates failure.
*/
static int report_block(unsigned char *text_packs, int num_packs,
int block, int first_tno, int last_tno, int char_code,
char *result, int result_size, int flag)
{
char *respt = NULL;
unsigned char *pack, *payload = NULL;
int result_len = 0, pack_no, ret, i, lang, payload_count = 0, genre;
char msg[80];
static char *languages[] = {
BURN_CDTEXT_LANGUAGES_0X00,
BURN_CDTEXT_FILLER,
BURN_CDTEXT_LANGUAGES_0X45
};
static char *volume_specs[7] = {
"Album Title", "Artist Name", "Songwriter", "Composer",
"Arranger", "Album Message", "Catalog Number",
};
static char *genres[BURN_CDTEXT_NUM_GENRES] = {
BURN_CDTEXT_GENRE_LIST
};
/* Search for any pack of the block. But do not accept 0x8f as first.*/
ret = search_pack(text_packs, num_packs, 0, -1, block,
&pack, &pack_no, 0);
if (ret <= 0)
return 0;
if (pack[0] == 0x8f)
return 0;
if (flag & 1) {
result_len = result_size;
} else {
respt = result + result_size;
}
write_v07t_line(&respt, "Input Sheet Version", "0.7T", -1, &result_len,
flag & 1);
sprintf(msg, "Libburn report of CD-TEXT Block %d", block);
write_v07t_line(&respt, "Remarks ", msg, -1, &result_len,
flag & 1);
write_v07t_line(&respt, "Text Code ",
char_code == 0 ? "8859" : char_code == 0x01 ? "ASCII" : "MS-JIS",
-1, &result_len, flag & 1);
pack_no = 0;
for (i = 0; i < 3; i++) {
ret = search_pack(text_packs, num_packs, pack_no, 0x8f, -1,
&pack, &pack_no, 0);
if (ret <= 0) {
libdax_msgs_submit(libdax_messenger, -1, 0x0002019f,
LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH,
"No third CD-TEXT pack 0x8f found. No language code defined",
0, 0);
goto failure;
}
pack_no++;
}
lang = pack[8 + block];
if (lang > 127) {
sprintf(msg, "CD-TEXT with unknown language code %2.2x",
(unsigned int) lang);
libdax_msgs_submit(libdax_messenger, -1, 0x0002019f,
LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH,
msg, 0, 0);
goto failure;
}
write_v07t_line(&respt, "Language Code", languages[lang], -1,
&result_len, flag & 1);
for (i = 0; i < 7; i++) {
ret = write_v07t_textline(text_packs, num_packs, 0x80 + i,
block, 0, 0, volume_specs[i],
&respt, &result_len,
flag & 1);
if (ret < 0)
goto failure;
}
ret = collect_payload(text_packs, num_packs, 0x87, block,
&payload, &payload_count, 0);
if(ret > 0) {
genre = (payload[0] << 8) | payload[1];
if (genre < BURN_CDTEXT_NUM_GENRES)
strcpy(msg, genres[genre]);
else
sprintf(msg, "0x%-4.4x", (unsigned int) genre);
write_v07t_line(&respt, "Genre Code", msg,
-1, &result_len, flag & 1);
write_v07t_line(&respt, "Genre Information",
(char *) payload + 2,
-1, &result_len, flag & 1);
BURN_FREE_MEM(payload); payload = NULL;
}
ret = collect_payload(text_packs, num_packs, 0x8d, block,
&payload, &payload_count, 0);
if(ret > 0) {
write_v07t_line(&respt, "Closed Information", (char *) payload,
-1, &result_len, flag & 1);
BURN_FREE_MEM(payload); payload = NULL;
}
ret = write_v07t_textline(text_packs, num_packs, 0x8e, block, 0, 0,
"UPC / EAN", &respt, &result_len, flag & 1);
if (ret < 0)
goto failure;
ret = search_pack(text_packs, num_packs, 0, 0x8f, -1,
&pack, &pack_no, 0);
if (ret < 0)
goto failure;
if (pack[7] == 0x00)
strcpy(msg, "OFF");
else if (pack[7] == 0x03)
strcpy(msg, "ON");
else
sprintf(msg, "0x%2.2x", (unsigned int) pack[7]);
write_v07t_line(&respt, "Text Data Copy Protection", msg,
-1, &result_len, flag & 1);
sprintf(msg, "%d", first_tno);
write_v07t_line(&respt, "First Track Number", msg,
-1, &result_len, flag & 1);
sprintf(msg, "%d", last_tno);
write_v07t_line(&respt, "Last Track Number", msg,
-1, &result_len, flag & 1);
for (i = 0; i < last_tno - first_tno + 1; i++) {
ret = report_track(text_packs, num_packs, block,
i + 1, first_tno,
&respt, &result_len, flag & 1);
if (ret < 0)
goto failure;
}
if (flag & 1)
return result_len;
return respt - result;
failure:;
BURN_FREE_MEM(payload);
return -1;
}
/*
@param result A byte buffer of sufficient size.
It will be filled by the text for the v07t sheet file
plus a trailing 0-byte. (Be aware that double-byte
characters might contain 0-bytes, too.)
@param result_size The number of bytes in result.
To be determined by a run with flag bit0 set.
@param flag Bitfield for control purposes.
bit0= Do not store text in result but only determine
the minimum size for the result array.
It is permissible to submit result == NULL and
result_size == 0.
@return > 0 tells the number of valid text bytes in result resp.
with flag bit0 the prediction of that number.
This does not include the trailing 0-byte.
<= 0 indicates failure.
*/
static int burn_make_v07t(unsigned char *text_packs, int num_packs,
int first_tno, int track_count,
char *result, int result_size,
int *char_code, int flag)
{
int pack_no = 0, ret, block, last_tno = 0;
unsigned char *pack;
char msg[80];
/* >>> ??? Verify checksums ? */;
/* Check character code, reject unknown ones */
ret = search_pack(text_packs, num_packs, 0, 0x8f, -1,
&pack, &pack_no, 0);
if (ret <= 0) {
libdax_msgs_submit(libdax_messenger, -1, 0x0002019f,
LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH,
"No CD-TEXT pack 0x8f found. No character code defined",
0, 0);
return 0;
}
*char_code = pack[4];
if (*char_code != 0x00 && *char_code != 0x01 && *char_code != 0x80) {
sprintf(msg, "CD-TEXT with unknown character code %2.2x",
(unsigned int) *char_code);
libdax_msgs_submit(libdax_messenger, -1, 0x0002019f,
LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH,
msg, 0, 0);
return 0;
}
/* Obtain first_tno and last_tno from type 0x8f if present. */
if (first_tno <= 0) {
if (pack[5] > 0 && pack[5] + pack[6] < 100 &&
pack[5] <= pack[6]) {
first_tno = pack[5];
last_tno = pack[6];
} else {
sprintf(msg,
"CD-TEXT with illegal track range %d to %d",
(int) pack[5], (int) pack[6]);
libdax_msgs_submit(libdax_messenger, -1, 0x0002019f,
LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH,
msg, 0, 0);
return 0;
}
}
if (last_tno <= 0) {
if (track_count > 0) {
last_tno = first_tno + track_count - 1;
} else {
last_tno = 99;
}
}
/* Report content */
result_size = 0;
for (block = 0; block < 8; block++) {
/* Obtain character code, reject unknown ones */
ret = search_pack(text_packs, num_packs, 0, 0x8f, block,
&pack, &pack_no, 0);
if (ret > 0)
*char_code = pack[4];
if (*char_code != 0x00 && *char_code != 0x01 &&
*char_code != 0x80) {
sprintf(msg,
"CD-TEXT block %d with unknown character code %2.2x",
block, (unsigned int) *char_code);
libdax_msgs_submit(libdax_messenger, -1, 0x0002019f,
LIBDAX_MSGS_SEV_FAILURE,
LIBDAX_MSGS_PRIO_HIGH, msg, 0, 0);
return 0;
}
ret = report_block(text_packs, num_packs, block,
first_tno, last_tno, *char_code,
result, result_size, flag & 1);
if (ret < 0)
return ret;
if (ret == 0)
continue;
result_size = ret;
}
return result_size;
}
/* Convert an array of CD-TEXT packs into the text format of
Sony CD-TEXT Input Sheet Version 0.7T .
@param text_packs Array of bytes which form CD-TEXT packs of 18 bytes
each. For a description of the format of the array,
see file doc/cdtext.txt.
No header of 4 bytes must be prepended which would
tell the number of pack bytes + 2.
This parameter may be NULL if the currently attached
array of packs shall be removed.
@param num_packs The number of 18 byte packs in text_packs.
@param start_tno The start number of track counting, if known from
CD table-of-content or orther sources.
Submit 0 to enable the attempt to read it and the
track_count from pack type 0x8f.
@param track_count The number of tracks, if known from CD table-of-content
or orther sources.
@param result Will return the buffer with Sheet text.
Dispose by free() when no longer needed.
It will be filled by the text for the v07t sheet file
plus a trailing 0-byte. (Be aware that double-byte
characters might contain 0-bytes, too.)
Each CD-TEXT language block starts by the line
"Input Sheet Version = 0.7T"
and a "Remarks" line that tells the block number.
@param char_code Returns the character code of the pack array:
0x00 = ISO-8859-1
0x01 = 7 bit ASCII
0x80 = MS-JIS (japanese Kanji, double byte characters)
The presence of a code value that is not in this list
will cause this function to fail.
@param flag Bitfield for control purposes. Unused yet. Submit 0.
@return > 0 tells the number of valid text bytes in result.
This does not include the trailing 0-byte.
<= 0 indicates failure.
*/
int burn_make_input_sheet_v07t(unsigned char *text_packs, int num_packs,
int start_tno, int track_count,
char **result, int *char_code, int flag)
{
int ret, result_size = 0;
ret = burn_make_v07t(text_packs, num_packs, start_tno, track_count,
NULL, 0, char_code, 1);
if (ret <= 0)
return ret;
result_size = ret + 1;
*result = burn_alloc_mem(result_size, 1, 0);
if (*result == NULL)
return -1;
ret = burn_make_v07t(text_packs, num_packs, start_tno, track_count,
*result, result_size, char_code, 0);
if (ret <= 0) {
free(*result);
return ret;
}
return result_size - 1;
}

View File

@ -133,27 +133,15 @@ static void Cleanup_handler_generic(int signum)
}
static char *Cleanup_signo_to_name(int signo)
{
int i;
for(i= 0; i < signal_list_count; i++)
if(signal_list[i] == signo)
return(signal_name_list[i]);
return("");
}
int Cleanup_set_handlers(void *handle, Cleanup_app_handler_T handler, int flag)
/*
bit0= set to default handlers
bit1= set to ignore
bit2= set cleanup_perform_app_handler_first
bit3= set SIGABRT to handler (makes sense with bits 0 or 1)
bit8= set SIGPIPE to SIGIGN
*/
{
int i,j,max_sig= -1,min_sig= 0x7fffffff;
char *sig_name;
sighandler_t sig_handler;
cleanup_msg[0]= 0;
@ -184,17 +172,8 @@ int Cleanup_set_handlers(void *handle, Cleanup_app_handler_T handler, int flag)
if(i==non_signal_list[j])
break;
if(j>=non_signal_list_count) {
/* Avoid to use particular SIG macros which might not be defined.
If they are defined, then their names are in the name list.
*/
if(flag & (8 | 256))
sig_name= Cleanup_signo_to_name(i);
else
sig_name= "";
if((flag & 8) && strcmp(sig_name, "SIGABRT") == 0)
if(i==SIGABRT && (flag&8))
signal(i,Cleanup_handler_generic);
else if((flag & 256) && strcmp(sig_name, "SIGPIPE") == 0)
signal(i, SIG_IGN);
else
signal(i,sig_handler);
}

View File

@ -50,9 +50,7 @@ static int ddlpa_debug_mode = 1;
#ifndef O_LARGEFILE
#define O_LARGEFILE 0
#endif
#ifndef O_BINARY
#define O_BINARY 0
#endif
/* ----------------------- private -------------------- */
@ -175,7 +173,7 @@ static int ddlpa_occupy(struct ddlpa_lock *o, char *path, int *fd,
int ret, o_flags, o_rw, l_type;
char *o_rwtext;
o_flags = o->o_flags | O_NDELAY | O_BINARY;
o_flags = o->o_flags | O_NDELAY;
if(!no_o_excl)
o_flags |= O_EXCL;
o_rw = (o_flags) & (O_RDONLY | O_WRONLY | O_RDWR);
@ -218,7 +216,7 @@ static int ddlpa_occupy(struct ddlpa_lock *o, char *path, int *fd,
static int ddlpa_obtain_scsi_adr(struct ddlpa_lock *o, char *path,
int *bus, int *host, int *channel, int *id, int *lun)
{
int fd, ret, open_mode = O_RDONLY | O_NDELAY | O_BINARY;
int fd, ret, open_mode = O_RDONLY | O_NDELAY;
struct my_scsi_idlun {
int x;
int host_unique_id;
@ -552,8 +550,7 @@ usage:;
} else {
/*
This substitutes for:
fd = open(my_path,
O_RDWR | O_EXCL | O_LARGEFILE | O_BINARY);
fd = open(my_path, O_RDWR | O_EXCL | O_LARGEFILE);
*/

View File

@ -1,7 +1,7 @@
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
Copyright (c) 2006 - 2014 Thomas Schmitt <scdbackup@gmx.net>
Copyright (c) 2006 - 2012 Thomas Schmitt <scdbackup@gmx.net>
Provided under GPL version 2 or later.
*/
@ -26,12 +26,6 @@
#include <pthread.h>
#include <errno.h>
#include <fcntl.h>
/* ts B41126 : O_BINARY is needed for Cygwin but undefined elsewhere */
#ifndef O_BINARY
#define O_BINARY 0
#endif
#include "libburn.h"
#include "init.h"
#include "drive.h"
@ -83,16 +77,9 @@ int burn_setup_drive(struct burn_drive *d, char *fname)
d->released = 1;
d->stdio_fd = -1;
d->status = BURN_DISC_UNREADY;
d->erasable = 0;
d->current_profile = -1;
d->do_stream_recording = 0;
d->stream_recording_start= 0;
d->role_5_nwa = 0;
d->features = NULL;
d->drive_serial_number = NULL;
d->drive_serial_number_len = -1;
d->media_serial_number = NULL;
d->media_serial_number_len = -1;
return 1;
}
@ -117,11 +104,6 @@ void burn_drive_free_subs(struct burn_drive *d)
if (d->stdio_fd >= 0)
close (d->stdio_fd);
d->stdio_fd = -1;
burn_feature_descr_free(&(d->features), 0);
BURN_FREE_MEM(d->drive_serial_number);
BURN_FREE_MEM(d->media_serial_number);
d->drive_serial_number = d->media_serial_number = NULL;
d->drive_serial_number_len = d->media_serial_number_len = 0;
sg_dispose_drive(d, 0);
}
@ -279,10 +261,55 @@ int burn_drive_inquire_media(struct burn_drive *d)
/* ts A71128 : run read_disc_info() for any recognizeable profile */
if (d->current_profile > 0 || d->current_is_guessed_profile ||
(d->mdata->p2a_valid > 0 &&
(d->mdata->cdr_write || d->mdata->cdrw_write ||
d->mdata->dvdr_write || d->mdata->dvdram_write)) ) {
d->mdata->cdr_write || d->mdata->cdrw_write ||
d->mdata->dvdr_write || d->mdata->dvdram_write) {
#define Libburn_knows_correct_state_after_loaD 1
#ifdef Libburn_knows_correct_state_after_loaD
d->read_disc_info(d);
#else
/* ts A61227 : This repeated read_disc_info seems
to be obsoleted by above d->getcaps(d).
*/
/* ts A60908 */
/* Trying to stabilize the disc status after eventual load
without closing and re-opening the drive */
/* This seems to work for burn_disc_erasable() .
Speed values on RIP-14 and LITE-ON 48125S are stable
and false, nevertheless. */
int was_equal = 0, must_equal = 3, max_loop = 20;
int loop_count, old_speed = -1234567890, new_speed= -987654321;
int old_erasable = -1234567890, new_erasable = -987654321;
fprintf(stderr,"LIBBURN_DEBUG: read_disc_info()\n");
for (loop_count = 0; loop_count < max_loop; loop_count++){
old_speed = new_speed;
old_erasable = new_erasable;
d->read_disc_info(d);
if(d->status == BURN_DISC_UNSUITABLE)
break;
new_speed = burn_drive_get_write_speed(d);
new_erasable = burn_disc_erasable(d);
if (new_speed == old_speed &&
new_erasable == old_erasable) {
was_equal++;
if (was_equal >= must_equal)
break;
} else
was_equal = 0;
/*
if (loop_count >= 1 && was_equal == 0)
*/
fprintf(stderr,"LIBBURN_DEBUG: %d : speed %d:%d erasable %d:%d\n",
loop_count,old_speed,new_speed,old_erasable,new_erasable);
usleep(100000);
}
#endif /* ! Libburn_knows_correct_state_after_loaD */
} else {
if (d->current_profile == -1 || d->current_is_cd_profile)
d->read_toc(d);
@ -363,7 +390,7 @@ static int burn_drive__is_rdwr(char *fname, int *stat_ret,
if (S_ISREG(stbuf.st_mode))
read_size = stbuf.st_size;
else if (is_rdwr)
ret = burn_os_stdio_capacity(fname, 0, &read_size);
ret = burn_os_stdio_capacity(fname, &read_size);
if (ret <= 0 ||
read_size / (off_t) 2048 >= (off_t) 0x7ffffff0)
read_size = (off_t) 0x7ffffff0 * (off_t) 2048;
@ -397,8 +424,6 @@ fprintf(stderr, "LIBBURN_DEBUG: burn_drive__is_rdwr: getfl_ret = %lX , O_RDWR =
}
/* flag bit0= ( not needed yet: grab even if it is already grabbed )
*/
int burn_drive_grab_stdio(struct burn_drive *d, int flag)
{
int stat_ret = -1, is_rdwr, ret;
@ -419,9 +444,8 @@ int burn_drive_grab_stdio(struct burn_drive *d, int flag)
/* despite its name : last valid address, not size */
d->media_read_capacity =
read_size / 2048 - !(read_size % 2048);
d->mr_capacity_trusted = 1;
if ((stat_ret == -1 || is_rdwr) && d->devname[0]) {
ret = burn_os_stdio_capacity(d->devname, 0, &size);
ret = burn_os_stdio_capacity(d->devname, &size);
if (ret > 0)
burn_drive_set_media_capacity_remaining(d,
size);
@ -513,10 +537,6 @@ int burn_drive_grab(struct burn_drive *d, int le)
{ret = 0; goto ex;}
ex:;
if (d->cancel || burn_is_aborting(0)) {
d->unlock(d);
d->release(d);
}
d->silent_on_scsi_error = sose;
d->busy = BURN_DRIVE_IDLE;
burn_grab_restore_sig_action(signal_action_mem, 0);
@ -550,7 +570,6 @@ struct burn_drive *burn_drive_register(struct burn_drive *d)
d->toc_entry = NULL;
d->disc = NULL;
d->erasable = 0;
d->write_opts = NULL;
#ifdef Libburn_ticket_62_re_register_is_possiblE
/* ts A60904 : ticket 62, contribution by elmom */
@ -619,7 +638,7 @@ struct burn_drive *burn_drive_finish_enum(struct burn_drive *d)
t->released = 1;
} else {
/* ts A90602 */
d->mdata->p2a_valid = -1;
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,
@ -656,10 +675,6 @@ int burn_drive_mark_unready(struct burn_drive *d, int flag)
free(d->toc_entry);
d->toc_entry = NULL;
d->toc_entries = 0;
if (d->write_opts != NULL) {
burn_write_opts_free(d->write_opts);
d->write_opts = NULL;
}
if (d->disc != NULL) {
burn_disc_free(d->disc);
d->disc = NULL;
@ -713,14 +728,6 @@ int burn_drive_release_fl(struct burn_drive *d, int flag)
}
d->needs_sync_cache = 0; /* just to be sure */
if (d->drive_serial_number != NULL)
BURN_FREE_MEM(d->drive_serial_number);
if (d->media_serial_number != NULL)
BURN_FREE_MEM(d->media_serial_number);
d->drive_serial_number = d->media_serial_number = NULL;
d->drive_serial_number_len = d->media_serial_number_len = 0;
d->released = 1;
/* ts A61125 : outsourced model aspects */
@ -837,7 +844,7 @@ void burn_wait_all(void)
void burn_disc_erase_sync(struct burn_drive *d, int fast)
{
int ret, was_error = 0;
int ret;
if (d->drive_role == 5) { /* Random access write-only drive */
ret = truncate(d->devname, (off_t) 0);
@ -891,16 +898,12 @@ void burn_disc_erase_sync(struct burn_drive *d, int fast)
ret = d->get_erase_progress(d);
if (ret == -2 || ret > 0)
break;
if (ret == -3)
was_error = 1;
sleep(1);
}
while (1) {
ret = d->get_erase_progress(d);
if(ret == -2)
break;
if (ret == -3)
was_error = 1;
if (ret >= 0)
d->progress.sector = ret;
sleep(1);
@ -915,8 +918,6 @@ void burn_disc_erase_sync(struct burn_drive *d, int fast)
if (d->drive_role == 1)
burn_drive_inquire_media(d);
d->busy = BURN_DRIVE_IDLE;
if (was_error)
d->cancel = 1;
}
/*
@ -926,7 +927,6 @@ void burn_disc_erase_sync(struct burn_drive *d, int fast)
void burn_disc_format_sync(struct burn_drive *d, off_t size, int flag)
{
int ret, buf_secs, err, i, stages = 1, pbase, pfill, pseudo_sector;
int was_error = 0;
off_t num_bufs;
char msg[80];
struct buffer *buf = NULL, *buf_mem = d->buffer;
@ -971,16 +971,12 @@ void burn_disc_format_sync(struct burn_drive *d, off_t size, int flag)
ret = d->get_erase_progress(d);
if (ret == -2 || ret > 0)
break;
if (ret == -3)
was_error = 1;
sleep(1);
}
while (1) {
pseudo_sector = d->get_erase_progress(d);
if(pseudo_sector == -2)
break;
if (pseudo_sector == -3)
was_error = 1;
if (pseudo_sector >= 0)
d->progress.sector = pseudo_sector / stages;
sleep(1);
@ -1044,8 +1040,6 @@ ex:;
d->progress.sector = 0x10000;
d->busy = BURN_DRIVE_IDLE;
d->buffer = buf_mem;
if (was_error)
d->cancel = 1;
BURN_FREE_MEM(buf);
}
@ -1176,29 +1170,30 @@ void burn_drive_cancel(struct burn_drive *d)
}
static void strip_spaces(char *str, size_t len)
static void strip_spaces(char *str)
{
char *tmp, *tmp2;
char *tmp;
/* Remove trailing blanks */
for (tmp = str + len - 1; tmp >= str && (isspace(*tmp) || !*tmp); tmp--)
*tmp = 0;
/* Condense remaining blank intervals to single blanks */
for (tmp = str; tmp < str + len - 1 && *tmp; tmp++) {
tmp = str + strlen(str) - 1;
while (isspace(*tmp))
*(tmp--) = '\0';
tmp = str;
while (*tmp) {
if (isspace(*tmp) && isspace(*(tmp + 1))) {
for (tmp2 = tmp + 1; tmp2 < str + len && *tmp2; tmp2++)
char *tmp2;
for (tmp2 = tmp + 1; *tmp2; ++tmp2)
*(tmp2 - 1) = *tmp2;
*(tmp2 - 1) = '\0';
tmp--; /* try same first blank again */
}
} else
++tmp;
}
}
static int drive_getcaps(struct burn_drive *d, struct burn_drive_info *out)
{
struct burn_scsi_inquiry_data *id;
int i, profile;
struct burn_feature_descr *feat;
/* ts A61007 : now prevented in enumerate_common() */
#if 0
@ -1206,61 +1201,31 @@ static int drive_getcaps(struct burn_drive *d, struct burn_drive_info *out)
a ssert(d->mdata);
#endif
if(d->idata->valid <= 0)
if(d->idata->valid <= 0 || d->mdata->valid <= 0)
return 0;
id = (struct burn_scsi_inquiry_data *)d->idata;
memcpy(out->vendor, id->vendor, sizeof(id->vendor));
strip_spaces(out->vendor, sizeof(id->vendor));
strip_spaces(out->vendor);
memcpy(out->product, id->product, sizeof(id->product));
strip_spaces(out->product, sizeof(id->product));
strip_spaces(out->product);
memcpy(out->revision, id->revision, sizeof(id->revision));
strip_spaces(out->revision, sizeof(id->revision));
strip_spaces(out->revision);
strncpy(out->location, d->devname, 16);
out->location[16] = '\0';
if (d->mdata->p2a_valid > 0) {
out->buffer_size = d->mdata->buffer_size;
out->read_dvdram = !!d->mdata->dvdram_read;
out->read_dvdr = !!d->mdata->dvdr_read;
out->read_dvdrom = !!d->mdata->dvdrom_read;
out->read_cdr = !!d->mdata->cdr_read;
out->read_cdrw = !!d->mdata->cdrw_read;
out->write_dvdram = !!d->mdata->dvdram_write;
out->write_dvdr = !!d->mdata->dvdr_write;
out->write_cdr = !!d->mdata->cdr_write;
out->write_cdrw = !!d->mdata->cdrw_write;
out->write_simulate = !!d->mdata->simulate;
out->c2_errors = !!d->mdata->c2_pointers;
} else {
out->buffer_size = out->read_dvdram = out->read_dvdr = 0;
out->read_dvdrom = out->read_cdr = out->read_cdrw = 0;
out->write_dvdram = out->write_dvdr = out->write_cdr = 0;
out->write_cdrw = out->write_simulate = out->c2_errors = 0;
for (i = 0; i < d->num_profiles; i++) {
profile = (d->all_profiles[i * 4] << 8) |
d->all_profiles[i * 4 + 1];
if (profile == 0x09)
out->write_cdr = out->read_cdr = 1;
else if (profile == 0x0a)
out->write_cdrw = out->read_cdrw = 1;
else if (profile == 0x10)
out->read_dvdrom = 1;
else if (profile == 0x11)
out->write_dvdr = out->read_dvdr = 1;
else if (profile == 0x12)
out->write_dvdram = out->read_dvdram = 1;
}
/* Test Write bit of CD TAO, CD Mastering, DVD-R/-RW Write */
for (i = 0x002D; i <= 0x002F; i++)
if (burn_drive_has_feature(d, i, &feat, 0))
if (feat->data_lenght > 0)
out->write_simulate |=
!!(feat->data[0] & 4);
}
out->buffer_size = d->mdata->buffer_size;
out->read_dvdram = !!d->mdata->dvdram_read;
out->read_dvdr = !!d->mdata->dvdr_read;
out->read_dvdrom = !!d->mdata->dvdrom_read;
out->read_cdr = !!d->mdata->cdr_read;
out->read_cdrw = !!d->mdata->cdrw_read;
out->write_dvdram = !!d->mdata->dvdram_write;
out->write_dvdr = !!d->mdata->dvdr_write;
out->write_cdr = !!d->mdata->cdr_write;
out->write_cdrw = !!d->mdata->cdrw_write;
out->write_simulate = !!d->mdata->simulate;
out->c2_errors = !!d->mdata->c2_pointers;
out->drive = d;
#ifdef Libburn_dummy_probe_write_modeS
@ -1579,17 +1544,23 @@ void burn_sectors_to_msf(int sectors, int *m, int *s, int *f)
int burn_drive_get_read_speed(struct burn_drive *d)
{
if(d->mdata->valid <= 0)
return 0;
return d->mdata->max_read_speed;
}
int burn_drive_get_write_speed(struct burn_drive *d)
{
if(d->mdata->valid <= 0)
return 0;
return d->mdata->max_write_speed;
}
/* ts A61021 : New API function */
int burn_drive_get_min_write_speed(struct burn_drive *d)
{
if(d->mdata->valid <= 0)
return 0;
return d->mdata->min_write_speed;
}
@ -1661,17 +1632,17 @@ static int burn_role_by_access(char *fname, int flag)
#endif
int fd;
fd = open(fname, O_RDWR | O_LARGEFILE | O_BINARY);
fd = open(fname, O_RDWR | O_LARGEFILE);
if (fd != -1) {
close(fd);
return 2;
}
fd = open(fname, O_RDONLY | O_LARGEFILE | O_BINARY);
fd = open(fname, O_RDONLY | O_LARGEFILE);
if (fd != -1) {
close(fd);
return 4;
}
fd = open(fname, O_WRONLY | O_LARGEFILE | O_BINARY);
fd = open(fname, O_WRONLY | O_LARGEFILE);
if (fd != -1) {
close(fd);
return 5;
@ -1698,7 +1669,7 @@ int burn_drive_grab_dummy(struct burn_drive_info *drive_infos[], char *fname)
is_rdwr = burn_drive__is_rdwr(fname, &stat_ret, &stbuf,
&read_size, 1 | 2);
if (stat_ret == -1 || is_rdwr) {
ret = burn_os_stdio_capacity(fname, 0, &size);
ret = burn_os_stdio_capacity(fname, &size);
if (ret == -1) {
libdax_msgs_submit(libdax_messenger, -1,
0x00020009,
@ -1783,12 +1754,10 @@ int burn_drive_grab_dummy(struct burn_drive_info *drive_infos[], char *fname)
strcpy(d->current_profile_text,"stdio file");
d->current_is_cd_profile = 0;
d->current_is_supported_profile = 1;
if (read_size >= 0) {
if (read_size >= 0)
/* despite its name : last valid address, not size */
d->media_read_capacity =
read_size / 2048 - !(read_size % 2048);
d->mr_capacity_trusted = 1;
}
burn_drive_set_media_capacity_remaining(d, size);
} else
d->current_profile = 0; /* Drives return this if empty */
@ -1883,10 +1852,8 @@ int burn_drive_scan_and_grab(struct burn_drive_info *drive_infos[], char* adr,
*/
ret = burn_drive_grab(drive_infos[0]->drive, load);
if (ret != 1) {
burn_drive_forget(drive_infos[0]->drive, 0);
if (ret != 1)
return -1;
}
return 1;
}
@ -1900,15 +1867,14 @@ int burn_drive_adr_debug_msg(char *fmt, char *arg)
int ret;
char *msg = NULL, *msgpt;
BURN_ALLOC_MEM(msg, char, 4096);
msgpt = msg;
if(arg != NULL)
sprintf(msg, fmt, arg);
else
msgpt = fmt;
if(libdax_messenger == NULL)
return 0;
if(arg != NULL) {
BURN_ALLOC_MEM(msg, char, 4096);
msgpt = msg;
sprintf(msg, fmt, arg);
} else {
msgpt = fmt;
}
ret = libdax_msgs_submit(libdax_messenger, -1, 0x00000002,
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_ZERO,
msgpt, 0, 0);
@ -2157,7 +2123,7 @@ int burn_drive_convert_scsi_adr(int bus_no, int host_no, int channel_no,
ret = 0;
ex:;
if (first == 0)
sg_give_next_adr(&enm, fname, fname_size, -1);
sg_give_next_adr(&enm, fname, sizeof(fname), -1);
BURN_FREE_MEM(fname);
BURN_FREE_MEM(msg);
return ret;
@ -2510,13 +2476,6 @@ int burn_disc_pretend_full(struct burn_drive *d)
return 1;
}
/* ts B31110 API function */
int burn_disc_pretend_full_uncond(struct burn_drive *d)
{
d->status = BURN_DISC_FULL;
return 1;
}
/* ts A61021: new API function */
int burn_disc_read_atip(struct burn_drive *d)
{
@ -2531,8 +2490,7 @@ int burn_disc_read_atip(struct burn_drive *d)
if(d->drive_role != 1)
return 0;
if ((d->current_profile == -1 || d->current_is_cd_profile)
&& ((d->mdata->p2a_valid > 0 && d->mdata->cdrw_write) ||
d->current_profile != 0x08)) {
&& (d->mdata->cdrw_write || d->current_profile != 0x08)) {
d->read_atip(d);
/* >>> some control of success would be nice :) */
} else {
@ -2616,8 +2574,7 @@ int burn_disc_get_msc1(struct burn_drive *d, int *start)
off_t burn_disc_available_space(struct burn_drive *d,
struct burn_write_opts *o)
{
int lba, nwa, ret;
off_t bytes, start_byte = 0;
int lba, nwa;
if (burn_drive_is_released(d))
return 0;
@ -2626,15 +2583,9 @@ off_t burn_disc_available_space(struct burn_drive *d,
if (d->drive_role == 0)
return 0;
if (d->drive_role != 1) {
if (o != NULL)
start_byte = o->start_byte;
ret = burn_os_stdio_capacity(d->devname, start_byte, &bytes);
if (ret != 1)
bytes = d->media_capacity_remaining;
if (bytes <= 0)
bytes = (off_t) (512 * 1024 * 1024 - 1) * (off_t) 2048;
if (bytes != d->media_capacity_remaining)
burn_drive_set_media_capacity_remaining(d, bytes);
if (d->media_capacity_remaining <= 0)
burn_drive_set_media_capacity_remaining(d,
(off_t) (512 * 1024 * 1024 - 1) * (off_t) 2048);
} else {
if (o != NULL)
d->send_write_parameters(d, NULL, -1, o);
@ -2768,6 +2719,8 @@ int burn_speed_descriptor_copy(struct burn_speed_descriptor *from,
/* ts A61226 : free dynamically allocated sub data of struct scsi_mode_data */
int burn_mdata_free_subs(struct scsi_mode_data *m)
{
if(!m->valid)
return 0;
burn_speed_descriptor_destroy(&(m->speed_descriptors), 1);
return 1;
}
@ -2781,6 +2734,8 @@ int burn_drive_get_speedlist(struct burn_drive *d,
struct burn_speed_descriptor *sd, *csd = NULL;
(*speed_list) = NULL;
if(d->mdata->valid <= 0)
return 0;
for (sd = d->mdata->speed_descriptors; sd != NULL; sd = sd->next) {
ret = burn_speed_descriptor_new(&csd, NULL, csd, 0);
if (ret <= 0)
@ -2804,6 +2759,8 @@ int burn_drive_get_best_speed(struct burn_drive *d, int speed_goal,
if (speed_goal < 0)
best_speed = 2000000000;
*best_descr = NULL;
if(d->mdata->valid <= 0)
return 0;
for (sd = d->mdata->speed_descriptors; sd != NULL; sd = sd->next) {
if (flag & 1)
speed = sd->read_speed;
@ -2883,9 +2840,9 @@ int burn_disc_get_multi_caps(struct burn_drive *d, enum burn_write_types wt,
/* stdio file drive : random access read-write */
o->start_adr = 1;
size = d->media_capacity_remaining;
burn_os_stdio_capacity(d->devname, 0, &size);
burn_os_stdio_capacity(d->devname, &size);
burn_drive_set_media_capacity_remaining(d, size);
o->start_range_high = d->media_capacity_remaining - 2048;
o->start_range_high = d->media_capacity_remaining;
o->start_alignment = 2048; /* imposting a drive, not a file */
o->might_do_sao = 4;
o->might_do_tao = 2;
@ -2895,12 +2852,12 @@ int burn_disc_get_multi_caps(struct burn_drive *d, enum burn_write_types wt,
/* stdio file drive : random access write-only */
o->start_adr = 1;
size = d->media_capacity_remaining;
burn_os_stdio_capacity(d->devname, 0, &size);
burn_os_stdio_capacity(d->devname, &size);
burn_drive_set_media_capacity_remaining(d, size);
/* >>> start_range_low = file size rounded to 2048 */;
o->start_range_high = d->media_capacity_remaining - 2048;
o->start_range_high = d->media_capacity_remaining;
o->start_alignment = 2048; /* imposting a drive, not a file */
if (s == BURN_DISC_APPENDABLE) {
if (wt == BURN_WRITE_SAO || wt == BURN_WRITE_RAW)
@ -2947,8 +2904,7 @@ int burn_disc_get_multi_caps(struct burn_drive *d, enum burn_write_types wt,
o->multi_session = o->multi_track = 0;
else if(wt == BURN_WRITE_NONE || wt == BURN_WRITE_SAO ||
wt == BURN_WRITE_TAO)
o->might_simulate = !!(d->mdata->p2a_valid > 0 &&
d->mdata->simulate);
o->might_simulate = !!d->mdata->simulate;
} else if (d->current_profile == 0x11 || d->current_profile == 0x14 ||
d->current_profile == 0x15) {
/* DVD-R , sequential DVD-RW , DVD-R/DL Sequential */
@ -2981,7 +2937,7 @@ int burn_disc_get_multi_caps(struct burn_drive *d, enum burn_write_types wt,
&num_formats);
if (ret == 1) {
if (status == BURN_FORMAT_IS_FORMATTED)
o->start_range_high = size - 2048;
o->start_range_high = size;
if (d->current_profile == 0x13) {
o->start_alignment = 32 * 1024;
for (i = 0; i < num_formats; i++) {
@ -3325,8 +3281,7 @@ int burn_drive_set_media_capacity_remaining(struct burn_drive *d, off_t value)
/* ts A81215 : API */
int burn_get_read_capacity(struct burn_drive *d, int *capacity, int flag)
{
*capacity = d->media_read_capacity +
(d->media_read_capacity != 0x7fffffff);
*capacity = d->media_read_capacity + 1;
return (d->media_read_capacity != 0x7fffffff);
}
@ -3434,146 +3389,3 @@ int burn_disc_get_leadin_text(struct burn_drive *d,
return ret;
}
/* ts B31023 API */
/* Inquire for DVD-RW failure of TAO
*/
int burn_drive_was_feat21_failure(struct burn_drive *d)
{
return !!d->was_feat21h_failure;
}
/* ts B40106 */
int burn_feature_descr_new(struct burn_feature_descr **new,
unsigned char *descr, int descr_len, int flag)
{
struct burn_feature_descr *o;
*new = NULL;
if (descr_len < 4)
return 0;
(*new) = o = calloc(1, sizeof(struct burn_feature_descr));
if (o == NULL)
return -1;
o->feature_code = (descr[0] << 8) | descr[1];
o->flags = descr[2];
if (descr[3] > descr_len - 4)
o->data_lenght = 0;
else
o->data_lenght = descr[3];
o->data = NULL;
o->next = NULL;
if (o->data_lenght > 0) {
o->data = calloc(1, o->data_lenght);
if (o->data == NULL) {
burn_feature_descr_free(new, 0);
return -1;
}
memcpy(o->data, descr + 4, o->data_lenght);
}
return 1;
}
/* ts B40106 */
int burn_feature_descr_free(struct burn_feature_descr **descr, int flag)
{
struct burn_feature_descr *o, *next;
if (*descr == NULL)
return 0;
for (o = *descr; o != NULL; o = next) {
next = o->next;
if (o->data != NULL)
free(o->data);
free((char *) o);
}
*descr = NULL;
return 1;
}
/* ts B40107 */
int burn_drive_has_feature(struct burn_drive *d, int feature_code,
struct burn_feature_descr **descr, int flag)
{
struct burn_feature_descr *o;
for (o = d->features; o != NULL; o = o->next) {
if (o->feature_code == feature_code) {
if (descr != NULL)
*descr = o;
return 1;
}
}
return 0;
}
/* ts B51016 API */
int burn_drive_get_serial_no(struct burn_drive *d, char **sno, int *sno_len)
{
int ret;
if (*sno != NULL)
BURN_FREE_MEM(*sno);
if (d->drive_serial_number_len > 0)
*sno_len = d->drive_serial_number_len;
else
*sno_len = 0;
BURN_ALLOC_MEM(*sno, char, *sno_len + 1);
if (d->drive_serial_number_len > 0)
memcpy(*sno, d->drive_serial_number, *sno_len);
(*sno)[*sno_len] = 0;
ret = 1;
ex:
return ret;
}
/* ts B51016 API */
int burn_drive_get_media_sno(struct burn_drive *d, char **sno, int *sno_len)
{
int ret;
#ifdef Libburn_enable_scsi_cmd_ABh
struct burn_feature_descr *feat;
#endif
if (*sno != NULL)
BURN_FREE_MEM(*sno);
*sno = NULL;
if (d->media_serial_number_len == -1) {
#ifdef Libburn_enable_scsi_cmd_ABh
if (burn_drive_has_feature(d, 0x109, &feat, 0))
#ifndef Libburn_enable_scsi_cmd_ABh_pretend_currenT
if (feat->flags & 1) /* current */
#endif
spc_read_media_serial_number(d);
#else
;
#endif /* ! Libburn_enable_scsi_cmd_ABh */
}
if (d->media_serial_number_len > 0)
*sno_len = d->media_serial_number_len;
else
*sno_len = 0;
BURN_ALLOC_MEM(*sno, char, *sno_len + 1);
if (*sno_len > 0)
memcpy(*sno, d->media_serial_number, *sno_len);
(*sno)[*sno_len] = 0;
ret = 1;
ex:
return ret;
}

View File

@ -1,7 +1,7 @@
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
Copyright (c) 2006 - 2014 Thomas Schmitt <scdbackup@gmx.net>
Copyright (c) 2006 - 2011 Thomas Schmitt <scdbackup@gmx.net>
Provided under GPL version 2 or later.
*/
@ -19,7 +19,6 @@ struct command;
struct mempage;
struct scsi_mode_data;
struct burn_speed_descriptor;
struct burn_feature_descr;
#define LEAD_IN 1
#define GAP 2
@ -156,18 +155,4 @@ int burn_abort_5(int patience,
/* Send a default mode page 05 to CD and DVD-R-oids */
int burn_drive_send_default_page_05(struct burn_drive *d, int flag);
/* ts B40106 */
int burn_feature_descr_new(struct burn_feature_descr **new,
unsigned char *descr, int descr_len, int flag);
/* ts B40106 */
int burn_feature_descr_free(struct burn_feature_descr **new, int flag);
/* ts B40107 */
int burn_drive_has_feature(struct burn_drive *d, int feature_code,
struct burn_feature_descr **descr, int flag);
int burn_drive_grab_stdio(struct burn_drive *d, int flag);
#endif /* __DRIVE */

View File

@ -30,7 +30,7 @@
-------------------------------------------------------------------------
RSPC , P- and Q-Parity
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
@ -80,7 +80,7 @@
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 reduces the arithmetic task to table lookups, additions
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.
@ -245,7 +245,7 @@ static unsigned char gflog[256] = {
#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] and gfpow[44-1]. I blame this on the more
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

View File

@ -1,7 +1,7 @@
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
Copyright (c) 2006 - 2014 Thomas Schmitt <scdbackup@gmx.net>
Copyright (c) 2006 - 2010 Thomas Schmitt <scdbackup@gmx.net>
Provided under GPL version 2 or later.
*/
@ -22,17 +22,11 @@
#include <time.h>
#include <pthread.h>
/* ts B41126 : O_BINARY is needed for Cygwin but undefined elsewhere */
#ifndef O_BINARY
#define O_BINARY 0
#endif
#include "source.h"
#include "libburn.h"
#include "file.h"
#include "async.h"
#include "init.h"
#include "util.h"
#include "libdax_msgs.h"
extern struct libdax_msgs *libdax_messenger;
@ -126,11 +120,11 @@ struct burn_source *burn_file_source_new(const char *path, const char *subpath)
if (!path)
return NULL;
fd1 = open(path, O_RDONLY | O_BINARY);
fd1 = open(path, O_RDONLY);
if (fd1 == -1)
return NULL;
if (subpath != NULL) {
fd2 = open(subpath, O_RDONLY | O_BINARY);
fd2 = open(subpath, O_RDONLY);
if (fd2 == -1) {
close(fd1);
return NULL;
@ -925,159 +919,3 @@ struct burn_source *burn_offst_source_new(
return src;
}
/* -------------------- WAVE file extractor ------------------- */
/* ts B30522 */
/* API
@param flag Bitfield for control purposes:
bit0= Report about progress by UPDATE message
bit3= Enable DAP : "flaw obscuring mechanisms like
audio data mute and interpolate"
*/
int burn_drive_extract_audio(struct burn_drive *drive,
int start_sector, int sector_count,
char *target_path, int flag)
{
int fd = -1, ret, todo, sector_no, val, min, sec, fr;
int sectors_done= 0;
off_t data_size, data_count = 0;
time_t last_pacified = 0, now;
char *msg = NULL, *buf = NULL;
BURN_ALLOC_MEM(msg, char, 4096);
BURN_ALLOC_MEM(buf, char, 24 * 2352);
fd = open(target_path, O_WRONLY | O_CREAT | O_BINARY,
S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
if (fd == -1) {
sprintf(msg, "Cannot open disk file for writing: %.4000s",
target_path);
libdax_msgs_submit(libdax_messenger, -1, 0x000201a1,
LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH,
msg, errno, 0);
ret = 0; goto ex;
}
/* WAV header */
strcpy(buf, "RIFF");
val = 4 + 8 + 16 + 8 + sector_count * 2352; /* ChunkSize */
burn_int_to_lsb(val, buf + 4);
strcpy(buf + 8, "WAVE");
strcpy(buf + 12, "fmt ");
burn_int_to_lsb(16, buf + 16); /* Subchunk1Size */
buf[20] = 1; /* AudioFormat */
buf[21] = 0;
buf[22] = 2; /* NumChannels */
buf[23] = 0;
burn_int_to_lsb(44100, buf + 24); /* SampleRate */
burn_int_to_lsb(176400, buf + 28); /* ByteRate */
buf[32] = 4; /* BlockAlign */
buf[33] = 0;
buf[34] = 16; /* BitsPerSample */
buf[35] = 0;
strcpy(buf + 36, "data");
burn_int_to_lsb(sector_count * 2352, buf + 40); /* Subchunk2Size */
ret = write(fd, buf, 44);
if (ret == -1)
goto write_error;
/* Audio data */
todo = sector_count;
sector_no = start_sector;
while (todo > 0) {
if (todo > 24)
data_size = 24 * 2352;
else
data_size = todo * 2352;
ret = burn_read_audio(drive, sector_no, buf, data_size,
&data_count, flag & 8);
if (ret <= 0) {
sprintf(msg, "Failure to read audio sectors");
libdax_msgs_submit(libdax_messenger, -1, 0x000201a4,
LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH,
msg, 0, 0);
goto ex;
}
ret = write(fd, buf, data_count);
if (ret == -1) {
write_error:;
sprintf(msg,
"Error while writing to disk file: %.4000s",
target_path);
libdax_msgs_submit(libdax_messenger, -1, 0x000201a2,
LIBDAX_MSGS_SEV_FAILURE,
LIBDAX_MSGS_PRIO_HIGH,
msg, errno, 0);
ret = 0; goto ex;
}
todo -= data_count / 2352;
sectors_done += data_count / 2352;
sector_no += data_count / 2352;
if ((flag & 1) && (now = time(NULL)) - last_pacified >= 1) {
last_pacified = now;
burn_lba_to_msf(sectors_done, &min, &sec, &fr);
sprintf(msg,
"Minutes:seconds of audio data read: %2d:%2.2d (%6.2f MB)",
min, sec,
((double) sectors_done) * 2352.0 / 1048576.0);
libdax_msgs_submit(libdax_messenger, -1, 0x000201a3,
LIBDAX_MSGS_SEV_UPDATE,
LIBDAX_MSGS_PRIO_HIGH,
msg, 0, 1);
}
}
if ((flag & 1)) {
burn_lba_to_msf(sectors_done, &min, &sec, &fr);
sprintf(msg,
"Minutes:seconds of audio data read: %2d:%2.2d (%6.2f MB)",
min, sec, ((double) sectors_done) * 2352.0 / 1048576.0);
libdax_msgs_submit(libdax_messenger, -1, 0x000201a3,
LIBDAX_MSGS_SEV_UPDATE,
LIBDAX_MSGS_PRIO_HIGH,
msg, 0, 0);
}
ret = 1;
ex:;
BURN_FREE_MEM(buf);
BURN_FREE_MEM(msg);
if (fd != -1)
close(fd);
return ret;
}
/* ts B30522 */
/* API
@param flag Bitfield for control purposes:
bit0= Report about progress by UPDATE message
bit3= Enable DAP : "flaw obscuring mechanisms like
audio data mute and interpolate"
*/
int burn_drive_extract_audio_track(struct burn_drive *drive,
struct burn_track *track,
char *target_path, int flag)
{
int ret;
struct burn_toc_entry toc_entry;
burn_track_get_entry(track, &toc_entry);
if (!(toc_entry.extensions_valid & 1)) {
/* Can only happen if burn_disc_cd_toc_extensions() is skipped
in mmc_read_toc_al().
*/
libdax_msgs_submit(libdax_messenger, -1, 0x00000004,
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
"Internal libburn error: Outdated burn_toc_entry format encountered",
errno, 0);
return -1;
}
ret = burn_drive_extract_audio(drive, toc_entry.start_lba,
toc_entry.track_blocks,
target_path, flag & (1 | 8));
return ret;
}

View File

@ -1,7 +1,7 @@
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
Copyright (c) 2006 - 2013 Thomas Schmitt <scdbackup@gmx.net>
Copyright (c) 2006 - 2012 Thomas Schmitt <scdbackup@gmx.net>
Provided under GPL version 2 or later.
*/
@ -31,7 +31,6 @@
#include "libburn.h"
#include "drive.h"
#include "transport.h"
#include "util.h"
/* ts A60825 : The storage location for back_hacks.h variables. */
#define BURN_BACK_HACKS_INIT 1
@ -44,9 +43,6 @@ struct libdax_msgs *libdax_messenger= NULL;
int burn_running = 0;
double lib_start_time;
/* ts A60813 : GNU/Linux: whether to use O_EXCL on open() of device files
ts B00212 : FreeBSD: whether to use flock(LOCK_EX) after open()
*/
@ -140,8 +136,6 @@ int burn_initialize(void)
if (burn_running)
return 1;
lib_start_time = burn_get_time(0);
burn_support_untested_profiles = 0;
ret = burn_msgs_initialize();
if (ret <= 0)
@ -549,7 +543,7 @@ void burn_set_signal_handling(void *handle, burn_abort_handler_t handler,
if(burn_builtin_signal_action == 0)
burn_builtin_signal_action = 1;
Cleanup_set_handlers(handle, (Cleanup_app_handler_T) handler,
(mode & 15) | 4 | (mode & 256));
(mode & 15) | 4);
burn_global_signal_handle = handle;
burn_global_signal_handler = handler;
}

View File

@ -1,17 +1,10 @@
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
Copyright (c) 2006 - 2013 Thomas Schmitt <scdbackup@gmx.net>
Provided under GPL version 2 or later.
*/
#ifndef BURN__INIT_H
#define BURN__INIT_H
extern int burn_running;
extern double lib_start_time;
/** Indicator for burn_drive_get_status() wether a signal hit parts of the
thread team.
0= all works well ,

View File

@ -1,7 +1,7 @@
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
Copyright (c) 2006 - 2016 Thomas Schmitt <scdbackup@gmx.net>
Copyright (c) 2006 - 2013 Thomas Schmitt <scdbackup@gmx.net>
Provided under GPL version 2 or later.
This is the official API definition of libburn.
@ -343,6 +343,7 @@ enum burn_drive_status
"session", "point", "pmin", ...
Do not rely on the current size of a burn_toc_entry.
ts A70201 : DVD extension, see below
*/
struct burn_toc_entry
{
@ -371,8 +372,6 @@ struct burn_toc_entry
older elements in this structure:
bit0= DVD extension is valid @since 0.3.2
@since 0.5.2 : DVD extensions are made valid for CD too
bit1= LRA extension is valid @since 0.7.2
bit2= Track status bits extension is valid @since 1.2.8
*/
unsigned char extensions_valid;
@ -394,36 +393,17 @@ struct burn_toc_entry
This would mean profiles: 0x11, 0x15, 0x13, 0x14, 0x51, 0x41, 0x42
*/
int last_recorded_address;
/* ts B30112 : Track status bits extension. extensions_valid:bit2 */
/* @since 1.2.8 */
/* Names as of READ TRACK INFORMATION, MMC-5 6.27.3 :
bit0 - bit3 = Track Mode
bit4 = Copy
bit5 = Damage
bit6 - bit7 = LJRS
bit8 - bit11 = Data Mode
bit12 = FP
bit13 = Packet/Inc
bit14 = Blank
bit15 = RT
bit16 = NWA_V
bit17 = LRA_V
*/
int track_status_bits;
};
/** Data source interface for tracks.
This allows you to use arbitrary program code as provider of track input
data.
This allows to use arbitrary program code as provider of track input data.
Objects compliant to this interface are either provided by the application
or by API calls of libburn: burn_fd_source_new() , burn_file_source_new(),
and burn_fifo_source_new().
The API calls may use any file object as data source. Consider to feed
The API calls allow to use any file object as data source. Consider to feed
an eventual custom data stream asynchronously into a pipe(2) and to let
libburn handle the rest.
In this case the following rule applies:
@ -500,7 +480,7 @@ struct burn_source {
/** Get the size of the source's data. Return 0 means unpredictable
size. If application provided (*get_size) might return 0, then
size. If application provided (*get_size) allows return 0, then
the application MUST provide a fully functional (*set_size).
*/
off_t (*get_size)(struct burn_source *);
@ -595,11 +575,6 @@ struct burn_drive_info
to inquire a device file address. ^^^^^ ALWAYS ^^^^^^^*/
char location[17];
/* NOTE: The capability to write particular media types is also
announced by their profile number being in the list returned
by burn_drive_get_all_profile(). This is the only way to
inquire types DVD-RW, DVD+R, DVD+R DL, DVD+RW, BD-R, BD-RE.
*/
/** Can the drive read DVD-RAM discs */
unsigned int read_dvdram:1;
/** Can the drive read DVD-R discs */
@ -623,13 +598,11 @@ struct burn_drive_info
/** Can the drive simulate a write */
unsigned int write_simulate:1;
/** DEPRECATED: Can the drive report C2 errors */
/** Can the drive report C2 errors */
unsigned int c2_errors:1;
/** DEPRECATED: The size of the drive's buffer (in kilobytes) */
/** The size of the drive's buffer (in kilobytes) */
int buffer_size;
/**
* The supported block types in tao mode.
* They should be tested with the desired block type.
@ -721,11 +694,7 @@ struct burn_progress {
struct burn_speed_descriptor {
/** Where this info comes from :
0 = misc
1 = mode page 2Ah
2 = ACh GET PERFORMANCE Type 03h
3 = ACh GET PERFORMANCE Type 00h Data Type 10h (read speed)
*/
0 = misc , 1 = mode page 2Ah , 2 = ACh GET PERFORMANCE */
int source;
/** The media type that was current at the time of report
@ -822,7 +791,7 @@ int burn_abort_pacifier(void *handle, int patience, int elapsed);
void burn_set_verbosity(int level);
/* ts A91111 */
/** Enable or disable logging of SCSI commands.
/** Enable resp. disable logging of SCSI commands.
This call can be made at any time - even before burn_initialize().
It is in effect for all active drives and currently not very thread
safe for multiple drives.
@ -954,7 +923,7 @@ void burn_allow_untested_profiles(int yes);
Use with driveno 0 only.
@param adr The device file address of the desired drive. Either once
obtained by burn_drive_d_get_adr() or composed skillfully by
application or its user. E.g. "/dev/sr0".
application resp. its user. E.g. "/dev/sr0".
Consider to preprocess it by burn_drive_convert_fs_adr().
@param load Nonzero to make the drive attempt to load a disc (close its
tray door, etc).
@ -1016,7 +985,7 @@ int burn_drive_scan(struct burn_drive_info *drive_infos[],
function is called, and the amount of automatically provided
drive shutdown :
0= drive must be ungrabbed and BURN_DRIVE_IDLE
1= try to release drive even if in state BURN_DRIVE_GRABBING
1= try to release drive resp. accept BURN_DRIVE_GRABBING
Use these two only. Further values are to be defined.
@return 1 on success, 2 if drive was already forgotten,
0 if not permissible, <0 on other failures,
@ -1179,7 +1148,7 @@ int burn_drive_probe_cd_write_modes(struct burn_drive_info *drive_info);
@param d The drive to influence.
@param flag Bitfield for control purposes
bit0= become alert (else start snoozing)
This is not mandatory for further drive operations
This is not mandatory to allow further drive operations
@return 1= success , 0= drive role not suitable for calming
@since 0.7.0
*/
@ -1189,7 +1158,7 @@ int burn_drive_snooze(struct burn_drive *d, int flag);
/** Re-assess drive and media status. This should be done after a drive
underwent a status change and shall be further used without intermediate
burn_drive_release(), burn_drive_grab(). E.g. after blanking or burning.
@param d The already grabbed drive to re-assess.
@param drive The already grabbed drive to re-assess.
@param flag Unused yet. Submit 0.
@return 1 success , <= 0 could not determine drive and media state
@since 1.1.8
@ -1249,59 +1218,6 @@ int burn_disc_pretend_blank(struct burn_drive *drive);
int burn_disc_pretend_full(struct burn_drive *drive);
/* ts B31110 */
/** WARNING: This overrides the safety measures against unsuitable media.
Sets the drive status to BURN_DISC_FULL unconditionally.
@since 1.3.4
*/
int burn_disc_pretend_full_uncond(struct burn_drive *drive);
/* ts B51016 */
/** Returns the Drive Serial Number as of MMC feature 108h.
@param d The drive to inquire.
@param sno Returns the bytes of the serial number. A trailing 0-byte
is appended for convenience. MMC specifies ASCII 0x20 to
0x7h as possible byte values. But given drive firmware
habits there is no warranty that *sno contains no other
byte values.
Submit *sno as NULL or pointing to free()-able memory.
Apply free() to *sno when no longer needed.
@param sno_len Returns the number of valid bytes in returned *sno,
not counting the appended trailing 0.
@return 1= success (but maybe *sno_len is 0), <= 0 severe failure
@since 1.4.2
*/
int burn_drive_get_serial_no(struct burn_drive *d, char **sno, int *sno_len);
/* ts B51016 */
/** Returns the Media Serial Number as of MMC feature 109h and command ABh
READ MEDIA SERIAL NUMBER.
Note: This call will return an empty result unless the macro
Libburn_enable_scsi_cmd_ABh
is defined at compile time.
This is because the command READ MEDIA SERIAL NUMBER demands
superuser authority on Linux, because no medium with serial number
could be tested yet, and because this command made one of the test
drives unusable until power cycle when it was executed despite
feature 109h was not announced as "current".
@param d The drive to inquire.
@param sno Returns the bytes of the serial number. A trailing 0-byte
is appended for convenience. There is no warranty that
*sno contains only non-zero printable bytes.
Submit *sno as NULL or pointing to free()-able memory.
Apply free() to *sno when no longer needed.
@param sno_len Returns the number of valid bytes in returned *sno,
not counting the appended trailing 0.
@return 1= success (but maybe *sno_len is 0), <= 0 severe failure
@since 1.4.2
*/
int burn_drive_get_media_sno(struct burn_drive *d, char **sno, int *sno_len);
/* ts A61021 */
/** Reads ATIP information from inserted media. To be obtained via
burn_drive_get_write_speed(), burn_drive_get_min_write_speed(),
@ -1337,8 +1253,8 @@ int burn_drive_get_start_end_lba(struct burn_drive *drive,
burn_drive_get_start_end_lba(d, &start_lba, &end_lba, 0),
burn_lba_to_msf(start_lba, &m_li, &s_li, &f_li) and
burn_lba_to_msf(end_lba, &m_lo, &s_lo, &f_lo).
@param m_li "minute" part of ATIP lead-in or start_lba
@param s_li "second" of lead-in or start_lba
@param m_li "minute" part of ATIP lead-in resp. start_lba
@param s_li "second" of lead-in resp. start_lba
@param f_li "frame" of lead-in
@param m_lo "minute" part of ATIP lead-out
@param s_lo "second" of lead-out
@ -1469,7 +1385,7 @@ int burn_disc_track_lba_nwa(struct burn_drive *d, struct burn_write_opts *o,
/* ts B10525 */
/** Tells whether a previous attempt to determine the Next Writeable Address
of the upcomming track reveiled that the READ TRACK INFORMATION Damage Bit
is set for this track and that no valid writable address is available.
is set for this track, resp. that no valid writable address is available.
See MMC-5 6.27.3.7 Damage Bit, 6.27.3.11 NWA_V (NWA valid)
@param d The drive to query.
@param flag Bitfield for control purposes (unused yet, submit 0)
@ -1524,7 +1440,7 @@ int burn_disc_get_msc1(struct burn_drive *d, int *start_lba);
grabbed and BURN_DRIVE_IDLE. If not, then one will only get a canned value
from the most recent automatic inquiry (e.g. during last drive grabbing).
An eventual start address from burn_write_opts_set_start_byte() will be
taken into respect with the capacity estimation. Negative results get
subtracted from the obtained capacity estimation. Negative results get
defaulted to 0.
If the drive is actually a file in a large filesystem or a large block
device, then the capacity is curbed to a maximum of 0x7ffffff0 blocks
@ -1576,7 +1492,7 @@ int burn_disc_get_profile(struct burn_drive *d, int *pno, char name[80]);
/** Obtain product id and standards defined media codes.
The product id is a printable string which is supposed to be the same
for identical media but should vary with non-identical media. Some media
cannot provide such an id at all.
do not allow to obtain such an id at all.
The pair (profile_number, product_id) should be the best id to identify
media with identical product specifications.
The reply parameters media_code1 and media_code2 can be used with
@ -1609,7 +1525,7 @@ int burn_disc_get_media_id(struct burn_drive *d,
/** Guess the name of a manufacturer by profile number, manufacturer code
and media code. The profile number can be obtained by
burn_disc_get_profile(), the other two parameters can be obtained as
media_code1 and media_code2 by burn_disc_get_media_id().
media_code1 and media_code2 by burn_get_media_product_id().
@param profile_no Profile number (submit -1 if not known)
@param manuf_code Manufacturer code from media (e.g. "RICOHJPN")
@param media_code Media ID code from media (e.g. "W11")
@ -1691,7 +1607,7 @@ void burn_disc_erase(struct burn_drive *drive, int fast);
/** Format media for use with libburn. This currently applies to DVD-RW
in state "Sequential Recording" (profile 0014h) which get formatted to
state "Restricted Overwrite" (profile 0013h). DVD+RW can be "de-iced"
by setting bit4 of flag. DVD-RAM and BD-RE may get formatted initially
by setting bit2 of flag. DVD-RAM and BD-RE may get formatted initially
or re-formatted to adjust their Defect Managment.
This function usually returns while the drive is still in the process
of formatting. The formatting is done, when burn_drive_get_status()
@ -1879,18 +1795,6 @@ void burn_drive_cancel(struct burn_drive *drive);
int burn_drive_wrote_well(struct burn_drive *d);
/* ts B31023 */
/** Inquire whether a write error occured which is suspected to have happened
due to a false report about DVD-RW capability to be written in write type
BURN_WRITE_TAO.
@param d The drive to inquire.
@return 1= it seems that BURN_WRITE_TAO on DVD-RW caused error,
0= it does not seem so
@since 1.3.4
*/
int burn_drive_was_feat21_failure(struct burn_drive *d);
/** Convert a minute-second-frame (MSF) value to sector count
@param m Minute component
@param s Second component
@ -2051,10 +1955,9 @@ int burn_session_set_start_tno(struct burn_session *session, int tno,
int flag);
/* ts B20108 */
/** Inquire the CD track start number, as set by default or by
/** Inquire the CD track start number, as set by default ot by
burn_session_set_start_tno().
@param session The session to be inquired
@param flag Bitfield for control purposes. Unused yet. Submit 0.
@return > 0 is the currently set CD track start number
<= 0 indicates failure
@since 1.2.0
@ -2162,11 +2065,12 @@ int burn_session_set_cdtext_par(struct burn_session *s,
""
/* ts B11206 */
/** Obtain the current settings as of burn_session_set_cdtext_par()
/** Obtain the current settings as of burn_session_set_cdtext_par() resp.
by default.
@param s Session which to inquire
@param char_codes Will return Character Codes for block 0 to 7
@param copyrights Will return Copyright bytes for block 0 to 7
@param block_languages Will return Language Codes for block 0 to 7
@param languages Will return Language Codes for block 0 to 7
@param flag Bitfiled for control purposes. Unused yet. Submit 0.
@return <=0 failure, reply invalid, > 0 success, reply valid
@since 1.2.0
@ -2215,7 +2119,7 @@ int burn_session_get_cdtext_par(struct burn_session *s,
Pack type 0x8d contains ISO-8859-1 cleartext which is
not to be shown by commercial audio CD players.
Pack type 0x8e is ASCII cleartext with UPC/EAN code.
@param length Number of bytes in payload. Including terminating
@pram length Number of bytes in payload. Including terminating
0-bytes.
@param flag Bitfield for control purposes.
bit0= payload contains double byte characters
@ -2264,7 +2168,7 @@ int burn_session_set_cdtext(struct burn_session *s, int block,
If no text attribute is attached for pack type and
block, then payload is returned as NULL. The return
value will not indicate error in this case.
@param length Will return the number of bytes pointed to by payload.
@pram length Will return the number of bytes pointed to by payload.
Including terminating 0-bytes.
@param flag Bitfield for control purposes. Unused yet. Submit 0.
@return 1 single byte char, 2 double byte char, <=0 error
@ -2285,24 +2189,15 @@ int burn_session_get_cdtext(struct burn_session *s, int block,
The media catalog number from purpose specifier "UPC / EAN" gets into
effect only if burn_write_opts_set_has_mediacatalog() is set to 0.
The format of a v07t sheet file is documented in doc/cdtext.txt.
@param session Session where to attach CD-TEXT attributes
@param s Session where to attach CD-TEXT attributes
@param path Local filesystem address of the sheet file which
shall be read and interpreted.
@param block Number of the language block in which the attributes
shall appear. Possible values: 0 to 7.
@param flag Bitfield for control purposes.
bit0= Permission to read multiple blocks from the
given sheet file. Each block is supposed to begin
by a line "Input Sheet Version = 0.7T". Therefore
this permission is only valid if the input file
begins by such a line.
@since 1.3.2
bit1= Do not use media catalog string of session or ISRC
strings of tracks for writing to Q sub-channel.
@since 1.2.0
@return > 0 indicates success and the number of interpreted
blocks (1 if not flag bit0 is set).
<= 0 indicates failure
@return > 0 indicates success , <= 0 is failure
@since 1.2.0
*/
int burn_session_input_sheet_v07t(struct burn_session *session,
@ -2311,8 +2206,7 @@ int burn_session_input_sheet_v07t(struct burn_session *session,
/* ts B11210 */
/** Produce an array of CD-TEXT packs that could be submitted to
burn_write_opts_set_leadin_text(), or stored as *.cdt file,
or submitted to burn_make_input_sheet_v07t().
burn_write_opts_set_leadin_text() or stored as *.cdt file.
For a description of the format of the array, see file doc/cdtext.txt.
The input data stem from burn_session_set_cdtext_par(),
burn_session_set_cdtext(), and burn_track_set_cdtext().
@ -2337,49 +2231,6 @@ int burn_cdtext_from_session(struct burn_session *s,
int flag);
/* ts B30519 */
/** Convert an array of CD-TEXT packs into the text format of
Sony CD-TEXT Input Sheet Version 0.7T .
@param text_packs Array of bytes which form CD-TEXT packs of 18 bytes
each. For a description of the format of the array,
see file doc/cdtext.txt.
No header of 4 bytes must be prepended which would
tell the number of pack bytes + 2.
This parameter may be NULL if the currently attached
array of packs shall be removed.
@param num_packs The number of 18 byte packs in text_packs.
@param start_tno The start number of track counting, if known from
CD table-of-content or other sources.
Submit 0 to enable the attempt to read it and the
track_count from pack type 0x8f.
@param track_count The number of tracks, if known from CD table-of-content
or orther sources.
@param result Will return the buffer with Sheet text.
Dispose by free() when no longer needed.
It will be filled by the text for the v07t sheet file
plus a trailing 0-byte. (Be aware that double-byte
characters might contain 0-bytes, too.)
Each CD-TEXT language block starts by the line
"Input Sheet Version = 0.7T"
and a "Remarks" line that tells the block number.
@param char_code Returns the character code of the pack array:
0x00 = ISO-8859-1
0x01 = 7 bit ASCII
0x80 = MS-JIS (japanese Kanji, double byte characters)
The presence of a code value that is not in this list
will cause this function to fail.
@param flag Bitfield for control purposes. Unused yet. Submit 0.
@return > 0 tells the number of valid text bytes in result.
This does not include the trailing 0-byte.
<= 0 indicates failure.
@since 1.3.2
*/
int burn_make_input_sheet_v07t(unsigned char *text_packs, int num_packs,
int start_tno, int track_count,
char **result, int *char_code, int flag);
/* ts B11206 */
/** Remove all CD-TEXT attributes of the given block from the session.
They were attached by burn_session_set_cdtext().
@ -2450,7 +2301,7 @@ void burn_track_define_data(struct burn_track *t, int offset, int tail,
0x8e = "UPC_ISRC"
@param payload 0-terminated cleartext. If double byte characters
are used, then two 0-bytes terminate the cleartext.
@param length Number of bytes in payload. Including terminating
@pram length Number of bytes in payload. Including terminating
0-bytes.
@param flag Bitfield for control purposes.
bit0= payload contains double byte characters
@ -2475,7 +2326,7 @@ int burn_track_set_cdtext(struct burn_track *t, int block,
If no text attribute is attached for pack type and
block, then payload is returned as NULL. The return
value will not indicate error in this case.
@param length Will return the number of bytes pointed to by payload.
@pram length Will return the number of bytes pointed to by payload.
Including terminating 0-bytes.
@param flag Bitfield for control purposes. Unused yet. Submit 0.
@return 1=single byte char , 2= double byte char , <=0 error
@ -2582,7 +2433,7 @@ int burn_track_clear_indice(struct burn_track *t, int flag);
/* ts B20110 */
/** Define whether a pre-gap shall be written before the track and how many
sectors this pre-gap shall have. A pre-gap is written in the range of track
index 0 and contains zeros (audio silence). No bytes from the track source
index 0 and contains zeros resp. silence. No bytes from the track source
will be read for writing the pre-gap.
This setting affects only CD SAO write runs.
The first track automatically gets a pre-gap of at least 150 sectors. Its
@ -2899,7 +2750,7 @@ void burn_fifo_next_interval(struct burn_source *fifo, int *interval_min_fill);
data have arrived or until it becomes clear that this will not happen.
The call may be repeated with increased bufsize. It will always yield
the bytes beginning from the first one in the fifo.
@param fifo The fifo object to start and to inquire
@param fifo The fifo object to inquire resp. start
@param buf Pointer to memory of at least bufsize bytes where to
deliver the peeked data.
@param bufsize Number of bytes to peek from the start of the fifo data
@ -2938,7 +2789,7 @@ int burn_fifo_fill(struct burn_source *fifo, int fill, int flag);
int burn_track_set_size(struct burn_track *t, off_t size);
/** Tells how many sectors a track will have on disc, or already has on
/** Tells how many sectors a track will have on disc, resp. already has on
disc. This includes offset, payload, tail, and post-gap, but not pre-gap.
The result is NOT RELIABLE with tracks of undefined length
*/
@ -2958,8 +2809,7 @@ int burn_track_get_counters(struct burn_track *t,
/** Sets drive read and write speed
Note: "k" is 1000, not 1024.
1xCD = 176.4 k/s, 1xDVD = 1385 k/s, 1xBD = 4496 k/s.
Note: "k" is 1000, not 1024. 1xCD = 176.4 k/s, 1xDVD = 1385 k/s.
Fractional speeds should be rounded up. Like 4xCD = 706.
@param d The drive to set speed for
@param read Read speed in k/s (0 is max, -1 is min).
@ -2987,9 +2837,7 @@ void burn_drive_set_speed(struct burn_drive *d, int read, int write);
To have max_percent larger than the burner's best reported buffer fill has
the same effect as min_percent==max_percent. Some burners do not report
their full buffer with all media types. Some are not suitable because
they report their buffer fill with delay. Some do not go to full speed
unless their buffer is full.
they report their buffer fill with delay.
@param d The drive to control
@param enable 0= disable , 1= enable waiting , (-1 = do not change setting)
@param min_usec Shortest possible sleeping period (given in micro seconds)
@ -3036,7 +2884,7 @@ int burn_write_opts_set_write_type(struct burn_write_opts *opts,
made, i.e. immediately before burn_disc_write().
@param opts The nearly complete write opts to change
@param disc The already composed session and track model
@param reasons This text string collects reasons for decision or failure
@param reasons This text string collects reasons for decision resp. failure
@param flag Bitfield for control purposes:
bit0= do not choose type but check the one that is already set
bit1= do not issue error messages via burn_msgs queue
@ -3134,29 +2982,6 @@ void burn_write_opts_set_has_mediacatalog(struct burn_write_opts *opts,
*/
void burn_write_opts_set_multi(struct burn_write_opts *opts, int multi);
/* ts B31024 */
/** Set the severity to be used with write error messages which are potentially
caused by not using write type BURN_WRITE_SAO on fast blanked DVD-RW.
Normally the call burn_write_opts_auto_write_type() can prevent such
errors by looking for MMC feature 21h "Incremental Streaming Writable"
which anounnces the capability for BURN_WRITE_TAO and multi session.
Regrettable many drives announce feature 21h even if they only can do
BURN_WRITE_SAO. This mistake becomes obvious by an early write error.
If you plan to call burn_drive_was_feat21_failure() and to repeat the
burn attempt with BURN_WRITE_SAO, then set the severity of the error
message low enough, so that the application does not see reason to abort.
@param opts The option object to be manipulated
@param severity Severity as with burn_msgs_set_severities().
"ALL" or empty text means the default severity that
is attributed to other kinds of write errors.
*/
void burn_write_opts_set_fail21h_sev(struct burn_write_opts *opts,
char *severity);
/* ts B11204 */
/** Submit an array of CD-TEXT packs which shall be written to the Lead-in
of a SAO write run on CD.
@ -3184,8 +3009,8 @@ int burn_write_opts_set_leadin_text(struct burn_write_opts *opts,
/* ts A61222 */
/** Sets a start address for writing to media and write modes which are able
to choose this address at all (for now: DVD+RW, DVD-RAM, formatted DVD-RW).
/** Sets a start address for writing to media and write modes which allow to
choose this address at all (for now: DVD+RW, DVD-RAM, formatted DVD-RW).
now). The address is given in bytes. If it is not -1 then a write run
will fail if choice of start address is not supported or if the block
alignment of the address is not suitable for media and write mode.
@ -3273,10 +3098,7 @@ void burn_write_opts_set_obs_pad(struct burn_write_opts *opts, int pad);
from being clogged with lots of pending data for slow devices.
@param opts The write opts to change
@param rythm Number of 2KB output blocks after which fsync(2) is
performed.
-1 means no fsync()
0 means default
1 means fsync() only at end, @since 1.3.8 (noop before 1.3.8)
performed. -1 means no fsync(), 0 means default,
elsewise the value must be >= 32.
Default is currently 8192 = 16 MB.
@since 0.7.4
@ -3447,7 +3269,7 @@ int burn_drive_free_speedlist(struct burn_speed_descriptor **speed_list);
*/
struct burn_multi_caps {
/* Multi-session capability can keep the media appendable after
/* Multi-session capability allows to keep the media appendable after
writing a session. It also guarantees that the drive will be able
to predict and use the appropriate Next Writeable Address to place
the next session on the media without overwriting the existing ones.
@ -3460,7 +3282,7 @@ struct burn_multi_caps {
*/
int multi_session;
/* Multi-track capability can write more than one track source
/* Multi-track capability allows to write more than one track source
during a single session. The written tracks can later be found in
libburn's TOC model with their start addresses and sizes.
1= multiple tracks per session are allowed
@ -3468,7 +3290,7 @@ struct burn_multi_caps {
*/
int multi_track;
/* Start-address capability can set a non-zero address with
/* Start-address capability allows to set a non-zero address with
burn_write_opts_set_start_byte(). Eventually this has to respect
.start_alignment and .start_range_low, .start_range_high in this
structure.
@ -3565,12 +3387,8 @@ void burn_track_get_entry(struct burn_track *t, struct burn_toc_entry *entry);
void burn_session_get_leadout_entry(struct burn_session *s,
struct burn_toc_entry *entry);
/** Gets an array of all complete sessions for the disc
/** Gets an array of all the sessions for the disc
THIS IS NO LONGER VALID AFTER YOU ADD OR REMOVE A SESSION
The result array contains *num + burn_disc_get_incomplete_sessions()
elements. All above *num are incomplete sessions.
Typically there is at most one incomplete session with one empty track.
DVD+R and BD-R seem support more than one track with even readable data.
@param d Disc to get session array for
@param num Returns the number of sessions in the array
@return array of sessions
@ -3578,17 +3396,6 @@ void burn_session_get_leadout_entry(struct burn_session *s,
struct burn_session **burn_disc_get_sessions(struct burn_disc *d,
int *num);
/* ts B30112 */
/* @since 1.2.8 */
/** Obtains the number of incomplete sessions which are recorded in the
result array of burn_disc_get_sessions() after the complete sessions.
See above.
@param d Disc object to inquire
@return Number of incomplete sessions
*/
int burn_disc_get_incomplete_sessions(struct burn_disc *d);
int burn_disc_get_sectors(struct burn_disc *d);
/** Gets an array of all the tracks for a session
@ -3643,8 +3450,8 @@ void burn_version(int *major, int *minor, int *micro);
*/
#define burn_header_version_major 1
#define burn_header_version_minor 4
#define burn_header_version_micro 4
#define burn_header_version_minor 2
#define burn_header_version_micro 6
/** Note:
Above version numbers are also recorded in configure.ac because libtool
wants them as parameters at build time.
@ -3680,7 +3487,7 @@ At runtime (via *_is_compatible()):
Vreixo Formoso advises to compare the application's
requirements of library revisions with the runtime
library. This is to enable runtime libraries which are
library. This is to allow runtime libraries which are
young enough for the application but too old for
the lib*.h files seen at compile time.
@ -3827,7 +3634,7 @@ typedef int (*burn_abort_handler_t)(void *handle, int signum, int flag);
Depending on mode it may cancel all drive operations, wait for all drives
to become idle, exit(1). It may also prepare function
burn_drive_get_status() for waiting and performing exit(1).
Parameter handle may be NULL or a text that shall be used as prefix for
If parameter handle may be NULL or a text that shall be used as prefix for
pacifier messages of burn_abort_pacifier(). Other than with an application
provided handler, the prefix char array does not have to be kept existing
until the eventual signal event.
@ -3865,23 +3672,18 @@ typedef int (*burn_abort_handler_t)(void *handle, int signum, int flag);
0 Same as 1 (for pre-0.7.8 backward compatibility)
@since 0.7.8
1 Catch the control thread in abort handler, call
burn_abort() with a patience value > 0 and
finally exit(1). Does not always work with FreeBSD.
2 Call burn_abort() with patience -1 and return from
handler. When the control thread calls
burn_drive_get_status(), then call burn_abort()
with patience 1 instead, and finally exit(1).
burn_abort(>0) and finally exit(1).
Does not always work with FreeBSD.
3 Call burn_abort() with patience -1, return from handler.
It is duty of the application to detect a pending abort
condition by calling burn_is_aborting() and to wait for
all drives to become idle. E.g. by calling burn_abort()
with patience >0.
4 Like 3, but without calling burn_abort() with -1. Only
the indicator of burn_is_aborting() gets set.
bit8: @since 1.3.2
try to ignore SIGPIPE (regardless of bit0 - bit3)
2 Call burn_abort(-1) and return from handler. When the
control thread calls burn_drive_get_status(), then do
burn_abort(>0) instead, and finally exit(1).
Does not always work with FreeBSD.
3 Call burn_abort(-1), return from handler. It is duty of
the application to detect a pending abort condition
by calling burn_is_aborting() and to wait for all
drives to become idle. E.g. by calling burn_abort(>0).
4 Like 3, but without calling burn_abort(-1). Only the
indicator of burn_is_aborting() gets set.
@since 0.2.6
*/
void burn_set_signal_handling(void *handle, burn_abort_handler_t handler,
@ -3935,7 +3737,7 @@ int burn_random_access_write(struct burn_drive *d, off_t byte_address,
/* ts A81215 */
/** Inquire the maximum amount of readable data.
It is supposed that all LBAs in the range from 0 to capacity - 1
It is supposed that all LBAs in the range from 0 to media_read_acpacity-1
can be read via burn_read_data() although some of them may never have been
recorded. If tracks are recognizable then it is better to only read
LBAs which are part of some track.
@ -3965,7 +3767,6 @@ int burn_get_read_capacity(struct burn_drive *d, int *capacity, int flag);
@param data_size The amount of data to be read. This does not have to
be aligned to any block size.
@param data_count The amount of data actually read (interesting on error)
The counted bytes are supposed to be valid.
@param flag Bitfield for control purposes:
bit0= - reserved -
bit1= do not submit error message if read error
@ -3982,9 +3783,6 @@ int burn_get_read_capacity(struct burn_drive *d, int *capacity, int flag);
(Useful to try the last two blocks of a CD
track which might be non-data because of TAO.)
@since 1.2.6
bit5= issue messages with severity DEBUG if they would
be suppressed by bit1.
@since 1.4.0
@return 1=sucessful , <=0 an error occured
with bit3: -2= permission denied error
@since 0.4.0
@ -4029,9 +3827,6 @@ int burn_read_data(struct burn_drive *d, off_t byte_address,
event message. Do not retry reading in this case.
(Useful to try the last two blocks of a CD
track which might be non-audio because of TAO.)
bit5= issue messages with severity DEBUG if they would
be suppressed by bit1.
@since 1.4.0
@return 1=sucessful , <=0 an error occured
with bit3: -2= permission denied error
@since 1.2.6
@ -4040,49 +3835,6 @@ int burn_read_audio(struct burn_drive *d, int sector_no,
char data[], off_t data_size, off_t *data_count, int flag);
/* ts B30522 */
/** Extract an interval of audio sectors from CD and store it as a WAVE
audio file on hard disk.
@param drive The drive from which to read.
@param start_sector The logical block address of the first audio sector
which shall be read.
@param sector_count The number of audio sectors to be read.
Each sector consists of 2352 bytes.
@param target_path The address of the file where to store the extracted
audio data. Will be opened O_WRONLY | O_CREAT.
The file name should have suffix ".wav".
@param flag Bitfield for control purposes:
bit0= Report about progress by UPDATE messages
bit3= Enable DAP : "flaw obscuring mechanisms like
audio data mute and interpolate"
@since 1.3.2
*/
int burn_drive_extract_audio(struct burn_drive *drive,
int start_sector, int sector_count,
char *target_path, int flag);
/* ts B30522 */
/** Extract all audio sectors of a track from CD and store them as a WAVE
audio file on hard disk.
@param drive The drive from which to read.
@param track The track which shall be extracted.
@param target_path The address of the file where to store the extracted
audio data. Will be opened O_WRONLY | O_CREAT.
The file name should have suffix ".wav".
@param flag Bitfield for control purposes:
bit0= Report about progress by UPDATE messages
bit3= Enable DAP : "flaw obscuring mechanisms like
audio data mute and interpolate"
@since 1.3.2
*/
int burn_drive_extract_audio_track(struct burn_drive *drive,
struct burn_track *track,
char *target_path, int flag);
/* ts A70904 */
/** Inquire whether the drive object is a real MMC drive or a pseudo-drive
created by a stdio: address.
@ -4105,22 +3857,21 @@ int burn_drive_get_drive_role(struct burn_drive *d);
and drive role 5 "random access write-only".
By default a random access file assumes drive role 2 "read-write"
regardless whether it is actually readable or writeable.
If enabled, random-access file objects which recognizably permit no
writing will be classified as role 4 and those which permit no reading
If enabled, random-access file objects which recognizably allow no
writing will be classified as role 4 and those which allow no reading
will get role 5.
Candidates are drive addresses of the form stdio:/dev/fd/# , where # is
the integer number of an open file descriptor. If this descriptor was
opened read-only or write-only, then it gets role 4 or role 5,
respectively.
opened read-only resp. write-only, then it gets role 4 resp. role 5.
Other paths may get tested by an attempt to open them for read-write
(role 2) or read-only (role 4) or write-only (role 5). See bit1.
(role 2) resp. read-only (role 4) resp. write-only (role 5). See bit1.
@param allowed Bitfield for control purposes:
bit0= Enable roles 4 and 5 for drives which get
aquired after this call
bit1= with bit0:
Test whether the file can be opened for
read-write, read-only, or write-only.
Classify as roles 2, 4, 5.
read-write resp. read-only resp. write-only.
Classify as roles 2 resp. 4 resp. 5.
bit2= with bit0 and bit1:
Classify files which cannot be opened at all
as role 0 : useless dummy.
@ -4152,7 +3903,7 @@ void burn_allow_drive_role_4(int allowed);
The string must be shorter than BURN_DRIVE_ADR_LEN.
@param drive_role2 Role as burn_drive_get_drive_role() would attribute
to adr2 if it was a drive. Use value 2 for checking track
sources or pseudo-drive addresses without "stdio:".
sources resp. pseudo-drive addresses without "stdio:".
Use 1 for checking drive addresses including those with
prefix "stdio:".
@return 1= adr2 leads to d1 , 0= adr2 seems not to lead to d1,
@ -4242,7 +3993,7 @@ int libdax_audioxtr_read(struct libdax_audioxtr *xtr,
/** Try to obtain a file descriptor which will deliver extracted data
to normal calls of read(2). This may fail because the format is
unsuitable for that, but WAVE (.wav) is ok. If this call succeeds the xtr
unsuitable for that, but ".wav" is ok. If this call succeeds the xtr
object will have forgotten its file descriptor and libdax_audioxtr_read()
will return a usage error. One may use *fd after libdax_audioxtr_destroy()
and will have to close it via close(2) when done with it.
@ -4291,18 +4042,12 @@ BURN_END_DECLS
/* ts A91112 */
/* Do not probe CD modes but declare only data and audio modes supported.
For other modes or real probing one has to call
For other modes resp. real probing one has to call
burn_drive_probe_cd_write_modes().
*/
#define Libburn_dummy_probe_write_modeS 1
/* ts B30112 */
/* Handle DVD+R with reserved tracks in incomplete first session
by loading info about the incomplete session into struct burn_disc
*/
#define Libburn_disc_with_incomplete_sessioN 1
/* Early experimental:
Do not define Libburn_develop_quality_scaN unless you want to work
@ -4319,12 +4064,5 @@ int burn_nec_optiarc_rep_err_rate(struct burn_drive *d,
#endif /* Libburn_develop_quality_scaN */
/* Linux 3.16 problems with ABh Read Media Serial Number:
- as normal user lets ioctl(SG_IO) return -1 and errno = EFAULT
- as superuser renders LG BH16NS40 unusable until power cycle
#de fine Libburn_enable_scsi_cmd_ABh yes
#de fine Libburn_enable_scsi_cmd_ABh_pretend_currenT yes
*/
#endif /*LIBBURN_H*/

View File

@ -19,7 +19,6 @@ burn_disc_get_bd_spare_info;
burn_disc_get_cd_info;
burn_disc_get_format_descr;
burn_disc_get_formats;
burn_disc_get_incomplete_sessions;
burn_disc_get_leadin_text;
burn_disc_get_media_id;
burn_disc_get_msc1;
@ -32,7 +31,6 @@ burn_disc_get_status;
burn_disc_next_track_is_damaged;
burn_disc_pretend_blank;
burn_disc_pretend_full;
burn_disc_pretend_full_uncond;
burn_disc_read;
burn_disc_read_atip;
burn_disc_remove_session;
@ -45,18 +43,14 @@ burn_drive_convert_fs_adr;
burn_drive_convert_scsi_adr;
burn_drive_d_get_adr;
burn_drive_equals_adr;
burn_drive_extract_audio;
burn_drive_extract_audio_track;
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_media_sno;
burn_drive_get_min_write_speed;
burn_drive_get_read_speed;
burn_drive_get_serial_no;
burn_drive_get_speedlist;
burn_drive_get_start_end_lba;
burn_drive_get_status;
@ -76,7 +70,6 @@ burn_drive_set_buffer_waiting;
burn_drive_set_speed;
burn_drive_set_stream_recording;
burn_drive_snooze;
burn_drive_was_feat21_failure;
burn_drive_wrote_well;
burn_fd_source_new;
burn_fifo_fill;
@ -95,7 +88,6 @@ burn_is_aborting;
burn_lba_to_msf;
burn_list_sev_texts;
burn_lookup_device_link;
burn_make_input_sheet_v07t;
burn_msf_to_lba;
burn_msf_to_sectors;
burn_msgs_obtain;
@ -179,7 +171,6 @@ burn_write_opts_free;
burn_write_opts_get_drive;
burn_write_opts_new;
burn_write_opts_set_dvd_obs;
burn_write_opts_set_fail21h_sev;
burn_write_opts_set_fillup;
burn_write_opts_set_force;
burn_write_opts_set_format;

View File

@ -17,10 +17,6 @@
#include <stdlib.h>
#include <errno.h>
/* ts B41126 : O_BINARY is needed for Cygwin but undefined elsewhere */
#ifndef O_BINARY
#define O_BINARY 0
#endif
#include "libdax_msgs.h"
extern struct libdax_msgs *libdax_messenger;
@ -94,7 +90,7 @@ static int libdax_audioxtr_open(struct libdax_audioxtr *o, int flag)
if(strcmp(o->path,"-")==0)
o->fd= 0;
else
o->fd= open(o->path, O_RDONLY | O_BINARY);
o->fd= open(o->path, O_RDONLY);
if(o->fd<0) {
sprintf(msg,"Cannot open audio source file : %s",o->path);
libdax_msgs_submit(libdax_messenger,-1,0x00020200,
@ -208,6 +204,10 @@ static int libdax_audioxtr_identify_au(struct libdax_audioxtr *o, int flag)
sprintf(o->fmt_info,
".au , num_channels=%d , sample_rate=%d , bits_per_sample=%d",
o->num_channels,o->sample_rate,o->bits_per_sample);
/* <<< for testing only */;
return(1);
return(o->bits_per_sample>0); /* Audio format must be linear PCM */
}

View File

@ -1,7 +1,7 @@
/* libdax_msgs
Message handling facility of libdax.
Copyright (C) 2006 - 2016 Thomas Schmitt <scdbackup@gmx.net>,
Copyright (C) 2006 - 2010 Thomas Schmitt <scdbackup@gmx.net>,
provided under GPL version 2 or later.
*/
@ -34,13 +34,14 @@ static int libdax_msgs_item_new(struct libdax_msgs_item **item,
int ret;
struct libdax_msgs_item *o;
struct timeval tv;
struct timezone tz;
(*item)= o=
(struct libdax_msgs_item *) calloc(1, sizeof(struct libdax_msgs_item));
if(o==NULL)
return(-1);
o->timestamp= 0.0;
ret= gettimeofday(&tv, NULL);
ret= gettimeofday(&tv,&tz);
if(ret==0)
o->timestamp= tv.tv_sec+0.000001*tv.tv_usec;
o->process_id= getpid();
@ -326,11 +327,6 @@ int libdax_msgs__sev_to_text(int severity, char **severity_name,
}
/*
@param flag Bitfield for control purposes
bit0= If direct output to stderr:
CarriageReturn rather than LineFeed
*/
int libdax_msgs_submit(struct libdax_msgs *m, int origin, int error_code,
int severity, int priority, char *msg_text,
int os_errno, int flag)
@ -349,8 +345,7 @@ int libdax_msgs_submit(struct libdax_msgs *m, int origin, int error_code,
if(ret>0)
sprintf(sev_text,"%s : ",sev_name);
fprintf(stderr, "%s%s%s%c", m->print_id, sev_text, textpt,
(flag & 1) ? '\r' : '\n');
fprintf(stderr,"%s%s%s\n",m->print_id,sev_text,textpt);
if(os_errno!=0) {
ret= libdax_msgs_lock(m,0);
if(ret<=0)

View File

@ -302,9 +302,7 @@ int libdax_msgs_refer(struct libdax_msgs **pt, struct libdax_msgs *o, int flag);
@param priority The LIBDAX_MSGS_PRIO_* number of the event.
@param msg_text Printable and human readable message text.
@param os_errno Eventual error code from operating system (0 if none)
@param flag Bitfield for control purposes
bit0= If direct output to stderr:
CarriageReturn rather than LineFeed
@param flag Bitfield for control purposes (unused yet, submit 0)
@return 1 on success, 0 on rejection, <0 for severe errors
*/
int libdax_msgs_submit(struct libdax_msgs *m, int origin, int error_code,
@ -520,7 +518,7 @@ Range "scdbackup" : 0x00020000 to 0x0002ffff
0x0002014a (SORRY,HIGH) = Cannot read desired amount of data
0x0002014b (SORRY,HIGH) = Drive is already registered resp. scanned
0x0002014c (FATAL,HIGH) = Emulated drive caught in SCSI function
0x0002014d (SORRY,HIGH) = Asynchronous SCSI error
0x0002014d (SORRY,HIGH) = Asynchromous SCSI error
0x0002014f (SORRY,HIGH) = Timeout with asynchronous SCSI command
0x00020150 (DEBUG,LOW) = Reporting asynchronous waiting time
0x00020151 (FAILURE,HIGH) = Read attempt on write-only drive
@ -599,19 +597,6 @@ Range "scdbackup" : 0x00020000 to 0x0002ffff
0x0002019b (SORRY,HIGH) = CD track number exceeds range of 1 to 99
0x0002019c (SORRY,HIGH) = Session has no defined tracks
0x0002019d (SORRY,HIGH) = Audio read size not properly aligned
0x0002019e (NOTE,HIGH) = Drive does not support media certification
0x0002019f (FAILURE,HIGH) = CD-TEXT binary pack array faulty
0x000201a0 (WARNING,HIGH) = Maximum number of CD-TEXT blocks exceeded
0x000201a1 (FAILURE,HIGH) = Cannot open disk file for writing
0x000201a2 (FAILURE,HIGH) = Error while writing to disk file
0x000201a3 (UPDATE,HIGH) = Progress message of burn_drive_extract_audio()
0x000201a4 (FAILURE,HIGH) = Failure to read audio sectors
0x000201a5 (FAILURE,HIGH) = Asynchronous SCSI error
0x000201a6 (FATAL,HIGH) = Lost connection to drive
0x000201a7 (FAILURE,HIGH) = SCSI command yielded host problem
0x000201a8 (FAILURE,HIGH) = SCSI command yielded driver problem
0x000201a9 (FAILURE,HIGH) = Implausible length from GET CONFIGURATION
0x000201aa (FAILURE,HIGH) = No CD-TEXT packs in file
libdax_audioxtr:

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,7 @@
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
Copyright (c) 2006 - 2014 Thomas Schmitt <scdbackup@gmx.net>
Copyright (c) 2006 - 2010 Thomas Schmitt <scdbackup@gmx.net>
Provided under GPL version 2 or later.
*/
@ -127,9 +127,6 @@ int mmc_get_phys_format_info(struct burn_drive *d, int *disk_category,
int mmc_get_leadin_text(struct burn_drive *d,
unsigned char **text_packs, int *num_packs, int flag);
/* ts B40107 */
int mmc_get_performance(struct burn_drive *d, int descr_type, int flag);
#ifdef Libburn_develop_quality_scaN
/* B21108 ts */

View File

@ -20,7 +20,6 @@
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "libdax_msgs.h"
extern struct libdax_msgs *libdax_messenger;
@ -44,8 +43,7 @@ struct burn_write_opts *burn_write_opts_new(struct burn_drive *drive)
opts->toc_entry = NULL;
opts->toc_entries = 0;
opts->simulate = 0;
opts->underrun_proof = drive->mdata->p2a_valid > 0 &&
drive->mdata->underrun_proof;
opts->underrun_proof = drive->mdata->underrun_proof;
opts->perform_opc = 1;
opts->obs = -1;
@ -80,35 +78,6 @@ void burn_write_opts_free(struct burn_write_opts *opts)
free(opts);
}
int burn_write_opts_clone(struct burn_write_opts *from,
struct burn_write_opts **to, int flag)
{
if (*to != NULL)
burn_write_opts_free(*to);
if (from == NULL)
return 1;
*to = calloc(1, sizeof(struct burn_write_opts));
if (*to == NULL) {
out_of_mem:;
libdax_msgs_submit(libdax_messenger, -1, 0x00000003,
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
"Out of virtual memory", 0, 0);
return -1;
}
memcpy(*to, from, sizeof(struct burn_write_opts));
(*to)->text_packs = NULL;
(*to)->num_text_packs = 0;
if (from->text_packs != NULL && from->num_text_packs > 0) {
(*to)->text_packs = calloc(1, from->num_text_packs * 18);
if ((*to)->text_packs == NULL)
goto out_of_mem;
memcpy((*to)->text_packs, from->text_packs,
from->num_text_packs * 18);
}
(*to)->refcount= 1;
return 1;
}
struct burn_read_opts *burn_read_opts_new(struct burn_drive *drive)
{
struct burn_read_opts *opts;
@ -183,6 +152,17 @@ void burn_write_opts_set_format(struct burn_write_opts *opts, int format)
int burn_write_opts_set_simulate(struct burn_write_opts *opts, int sim)
{
/* <<< ts A70529 :
One cannot predict the ability to simulate from page 05h
information alone. This check is now done later in
function burn_write_opts_auto_write_type().
if (opts->drive->mdata->simulate) {
opts->simulate = sim;
return 1;
}
return 0;
*/
opts->simulate = !!sim;
return 1;
}
@ -190,8 +170,9 @@ int burn_write_opts_set_simulate(struct burn_write_opts *opts, int sim)
int burn_write_opts_set_underrun_proof(struct burn_write_opts *opts,
int underrun_proof)
{
if (opts->drive->mdata->p2a_valid <= 0 ||
opts->drive->mdata->underrun_proof) {
if (opts->drive->mdata->valid <= 0)
return 0;
if (opts->drive->mdata->underrun_proof) {
opts->underrun_proof = underrun_proof;
return 1;
}
@ -223,21 +204,6 @@ void burn_write_opts_set_multi(struct burn_write_opts *opts, int multi)
}
/* ts B31024 */
/* API */
void burn_write_opts_set_fail21h_sev(struct burn_write_opts *opts,
char *severity)
{
int ret, sevno;
ret = libdax_msgs__text_to_sev(severity, &sevno, 0);
if (ret <= 0)
opts->feat21h_fail_sev = 0;
else
opts->feat21h_fail_sev = sevno;
}
/* ts B11204 */
/* @param flag bit0=do not verify checksums
bit1= repair mismatching checksums
@ -288,12 +254,10 @@ int burn_write_opts_set_leadin_text(struct burn_write_opts *opts,
if (num_packs > 0) {
memcpy(pack_buffer, text_packs, num_packs * 18);
opts->text_packs = pack_buffer;
pack_buffer = NULL;
}
opts->num_text_packs = num_packs;
ret = 1;
ex:;
BURN_FREE_MEM(pack_buffer);
return ret;
}
@ -534,11 +498,9 @@ void burn_write_opts_set_obs_pad(struct burn_write_opts *opts, int pad)
void burn_write_opts_set_stdio_fsync(struct burn_write_opts *opts, int rythm)
{
if (rythm == -1)
opts->stdio_fsync_size = -1; /* never */
opts->stdio_fsync_size = 0;
else if (rythm == 0)
opts->stdio_fsync_size = Libburn_stdio_fsync_limiT;
else if (rythm == 1)
opts->stdio_fsync_size = 0; /* only at end of writing */
else if (rythm >= 32)
opts->stdio_fsync_size = rythm;
}

View File

@ -1,6 +1,6 @@
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
Copyright (c) 2006 - 2013 Thomas Schmitt <scdbackup@gmx.net>
Copyright (c) 2006 - 2012 Thomas Schmitt <scdbackup@gmx.net>
Provided under GPL version 2 or later.
*/
@ -46,7 +46,7 @@ struct burn_write_opts
2 indicates burn_write_opts_set_obs_pad(,1)
*/
/* ts A61222 : Start address for media which offer a choice */
/* ts A61222 : Start address for media which allow a choice */
off_t start_byte;
/* ts A70213 : Wether to fill up the available space on media */
@ -81,19 +81,9 @@ struct burn_write_opts
unsigned char mediacatalog[13];
/** Session format */
int format;
/* internal use only */
unsigned char control;
/* Whether to keep medium appendable */
unsigned char multi;
/* ts B31024 */
/* The severity to be attributed to error messages about failed
write attempt with blank DVD-RW, possibly due to falsely reported
feature 21h Incremental Streaming Writable
*/
int feat21h_fail_sev;
};
/* Default value for burn_write_opts.stdio_flush_size
@ -142,16 +132,11 @@ struct burn_read_opts
/* ts B21119 */
/* >>> Needs API access */
/** Whether to set DAP bit which allows the drive to apply
/** Whether to set DAP bit which allows drive to apply
"flaw obscuring mechanisms like audio data mute and interpolate"
*/
unsigned int dap_bit;
};
int burn_write_opts_clone(struct burn_write_opts *from,
struct burn_write_opts **to, int flag);
#endif /* BURN__OPTIONS_H */

View File

@ -5,8 +5,7 @@
Unknown POSIX like systems
with the dummy MMC transport adapter sg-dummy.c
Copyright (C) 2009 - 2013 Thomas Schmitt <scdbackup@gmx.net>
Provided under GPLv2+
Copyright (C) 2009 Thomas Schmitt <scdbackup@gmx.net>, provided under GPLv2+
*/
@ -17,16 +16,18 @@
#define BURN_OS_SIGNAL_MACRO_LIST \
SIGHUP, SIGINT, SIGQUIT, SIGILL, SIGABRT, \
SIGFPE, SIGSEGV, SIGPIPE, SIGALRM, SIGTERM, \
SIGUSR1, SIGUSR2, SIGXCPU
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"
"SIGUSR1", "SIGUSR2", "SIGXCPU", "SIGTSTP", "SIGTTIN", \
"SIGTTOU"
/* The number of above list items */
#define BURN_OS_SIGNAL_COUNT 13
#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
@ -54,12 +55,11 @@
/** The combined list of all signals which shall not be caught.
*/
#define BURN_OS_NON_SIGNAL_MACRO_LIST \
SIGKILL, SIGCHLD, SIGSTOP, SIGTSTP, SIGCONT, SIGTTIN, SIGTTOU \
BURN_OS_SIG_WINCH BURN_OS_SIG_URG
SIGKILL, SIGCHLD, SIGSTOP BURN_OS_SIG_WINCH BURN_OS_SIG_URG
/* The number of above list items */
#define BURN_OS_NON_SIGNAL_COUNT \
( 7 + BURN_OS_SIG_WINCH_CNT + BURN_OS_SIG_URG_CNT )
( 3 + BURN_OS_SIG_WINCH_CNT + BURN_OS_SIG_URG_CNT )
/* The maximum size for a (SCSI) i/o transaction */

View File

@ -4,8 +4,8 @@
by os.h in case of compilation for
FreeBSD with CAM
Copyright (C) 2006 - 2013 Thomas Schmitt <scdbackup@gmx.net>,
Provided under GPLv2+
Copyright (C) 2006 - 2010 Thomas Schmitt <scdbackup@gmx.net>,
provided under GPLv2+
*/
/** List of all signals which shall be caught by signal handlers and trigger
@ -15,25 +15,29 @@
#define BURN_OS_SIGNAL_MACRO_LIST \
SIGHUP, SIGINT, SIGQUIT, SIGILL, SIGABRT, \
SIGFPE, SIGSEGV, SIGPIPE, SIGALRM, SIGTERM, \
SIGUSR1, SIGUSR2, SIGXCPU, SIGBUS, SIGPROF, \
SIGSYS, SIGTRAP, SIGVTALRM, SIGXCPU, SIGXFSZ
SIGUSR1, SIGUSR2, SIGXCPU, SIGTSTP, SIGTTIN, \
SIGTTOU, \
SIGBUS, SIGPROF, SIGSYS, SIGTRAP, \
SIGVTALRM, SIGXCPU, SIGXFSZ
/* 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", "SIGBUS", "SIGPROF", \
"SIGSYS", "SIGTRAP", "SIGVTALRM", "SIGXCPU", "SIGXFSZ"
"SIGUSR1", "SIGUSR2", "SIGXCPU", "SIGTSTP", "SIGTTIN", \
"SIGTTOU", \
"SIGBUS", "SIGPROF", "SIGSYS", "SIGTRAP", \
"SIGVTALRM", "SIGXCPU", "SIGXFSZ"
/* The number of above list items */
#define BURN_OS_SIGNAL_COUNT 20
#define BURN_OS_SIGNAL_COUNT 23
/** To list all signals which shall surely not be caught */
#define BURN_OS_NON_SIGNAL_MACRO_LIST \
SIGKILL, SIGCHLD, SIGSTOP, SIGTSTP, SIGCONT, SIGTTIN, SIGTTOU, SIGURG, SIGWINCH
SIGKILL, SIGCHLD, SIGSTOP, SIGURG, SIGWINCH
/* The number of above list items */
#define BURN_OS_NON_SIGNAL_COUNT 9
#define BURN_OS_NON_SIGNAL_COUNT 5
/* The maximum size for a (SCSI) i/o transaction */

View File

@ -5,8 +5,7 @@
Unknown X/Open-like systems
with GNU libcdio MMC transport adapter sg-libcdio.c
Copyright (C) 2009 - 2013 Thomas Schmitt <scdbackup@gmx.net>
Provided under GPLv2+
Copyright (C) 2009 Thomas Schmitt <scdbackup@gmx.net>, provided under GPLv2+
*/
@ -17,16 +16,18 @@
#define BURN_OS_SIGNAL_MACRO_LIST \
SIGHUP, SIGINT, SIGQUIT, SIGILL, SIGABRT, \
SIGFPE, SIGSEGV, SIGPIPE, SIGALRM, SIGTERM, \
SIGUSR1, SIGUSR2, SIGXCPU
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"
"SIGUSR1", "SIGUSR2", "SIGXCPU", "SIGTSTP", "SIGTTIN", \
"SIGTTOU"
/* The number of above list items */
#define BURN_OS_SIGNAL_COUNT 13
#define BURN_OS_SIGNAL_COUNT 16
/** The list of all signals which shall surely not be caught.
@ -55,12 +56,11 @@
/** The combined list of all signals which shall not be caught.
*/
#define BURN_OS_NON_SIGNAL_MACRO_LIST \
SIGKILL, SIGCHLD, SIGSTOP, SIGTSTP, SIGCONT, SIGTTIN, SIGTTOU \
BURN_OS_SIG_WINCH BURN_OS_SIG_URG
SIGKILL, SIGCHLD, SIGSTOP BURN_OS_SIG_WINCH BURN_OS_SIG_URG
/* The number of above list items */
#define BURN_OS_NON_SIGNAL_COUNT \
( 7 + BURN_OS_SIG_WINCH_CNT + BURN_OS_SIG_URG_CNT )
( 3 + BURN_OS_SIG_WINCH_CNT + BURN_OS_SIG_URG_CNT )
/* The maximum size for a (SCSI) i/o transaction */

View File

@ -4,7 +4,7 @@
by os.h in case of compilation for
Linux kernels 2.4 and 2.6, GNU/Linux SCSI Generic (sg)
Copyright (C) 2006 - 2013 Thomas Schmitt <scdbackup@gmx.net>
Copyright (C) 2006 - 2010 Thomas Schmitt <scdbackup@gmx.net>
Provided under GPL version 2 or later.
*/
@ -16,27 +16,29 @@
#define BURN_OS_SIGNAL_MACRO_LIST \
SIGHUP, SIGINT, SIGQUIT, SIGILL, SIGABRT, \
SIGFPE, SIGSEGV, SIGPIPE, SIGALRM, SIGTERM, \
SIGUSR1, SIGUSR2, SIGXCPU, SIGBUS, SIGPOLL, \
SIGPROF, SIGSYS, SIGTRAP, SIGVTALRM, SIGXCPU, \
SIGXFSZ
SIGUSR1, SIGUSR2, SIGXCPU, SIGTSTP, SIGTTIN, \
SIGTTOU, \
SIGBUS, SIGPOLL, SIGPROF, SIGSYS, SIGTRAP, \
SIGVTALRM, SIGXCPU, SIGXFSZ
/* 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", "SIGBUS", "SIGPOLL", \
"SIGPROF", "SIGSYS", "SIGTRAP", "SIGVTALRM", "SIGXCPU", \
"SIGXFSZ"
"SIGUSR1", "SIGUSR2", "SIGXCPU", "SIGTSTP", "SIGTTIN", \
"SIGTTOU", \
"SIGBUS", "SIGPOLL", "SIGPROF", "SIGSYS", "SIGTRAP", \
"SIGVTALRM", "SIGXCPU", "SIGXFSZ"
/* The number of above list items */
#define BURN_OS_SIGNAL_COUNT 21
#define BURN_OS_SIGNAL_COUNT 24
/** To list all signals which shall surely not be caught */
#define BURN_OS_NON_SIGNAL_MACRO_LIST \
SIGKILL, SIGCHLD, SIGSTOP, SIGTSTP, SIGCONT, SIGURG, SIGWINCH, SIGTTIN, SIGTTOU
SIGKILL, SIGCHLD, SIGSTOP, SIGURG, SIGWINCH
/* The number of above list items */
#define BURN_OS_NON_SIGNAL_COUNT 9
#define BURN_OS_NON_SIGNAL_COUNT 5
/* The maximum size for a (SCSI) i/o transaction */

View File

@ -1,71 +0,0 @@
/* os-netbsd.h
Operating system specific libburn definitions and declarations. Included
by os.h in case of compilation for
NetBSD 6
with MMC transport adapter sg-netbsd.c
>>> for OpenBSD too ?
Copyright (C) 2010 - 2014 Thomas Schmitt <scdbackup@gmx.net>
provided under GPLv2+
Derived 2014 from libburn/os-solaris.c
*/
/** 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, SIGTRAP, \
SIGABRT, SIGEMT, SIGFPE, SIGBUS, SIGSEGV, \
SIGSYS, SIGPIPE, SIGALRM, SIGTERM, SIGXCPU, \
SIGXFSZ, SIGVTALRM, SIGPROF, SIGUSR1, SIGUSR2
/* Once as text 1:1 list of strings for messages and interpreters */
#define BURN_OS_SIGNAL_NAME_LIST \
"SIGHUP", "SIGINT", "SIGQUIT", "SIGILL", "SIGTRAP", \
"SIGABRT", "SIGEMT", "SIGFPE", "SIGBUS", "SIGSEGV", \
"SIGSYS", "SIGPIPE", "SIGALRM", "SIGTERM", "SIGXCPU", \
"SIGXFSZ", "SIGVTALRM", "SIGPROF", "SIGUSR1", "SIGUSR2"
/* The number of above list items */
#define BURN_OS_SIGNAL_COUNT 20
/** To list all signals which shall surely not be caught */
#define BURN_OS_NON_SIGNAL_MACRO_LIST \
SIGKILL, SIGURG, SIGSTOP, SIGTSTP, SIGCONT, \
SIGCHLD, SIGTTIN, SIGTTOU, SIGIO, SIGWINCH, \
SIGINFO, SIGPWR
/* The number of above list items */
#define BURN_OS_NON_SIGNAL_COUNT 12
/* 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.
*/
/* >>> ??? Does it do 64 kB ? */
#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 cdno;
};
#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;

View File

@ -5,8 +5,7 @@
Solaris based systems, e.g. SunOS 5.11
with Solaris uscsi MMC transport adapter sg-solaris.c
Copyright (C) 2010 - 2013 Thomas Schmitt <scdbackup@gmx.net>
provided under GPLv2+
Copyright (C) 2010 Thomas Schmitt <scdbackup@gmx.net>, provided under GPLv2+
*/
@ -17,23 +16,25 @@
#define BURN_OS_SIGNAL_MACRO_LIST \
SIGHUP, SIGINT, SIGQUIT, SIGILL, SIGABRT, \
SIGFPE, SIGSEGV, SIGPIPE, SIGALRM, SIGTERM, \
SIGUSR1, SIGUSR2, SIGXCPU
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"
"SIGUSR1", "SIGUSR2", "SIGXCPU", "SIGTSTP", "SIGTTIN", \
"SIGTTOU"
/* The number of above list items */
#define BURN_OS_SIGNAL_COUNT 13
#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, SIGTSTP, SIGCONT, SIGTTIN, SIGTTOU, SIGURG, SIGWINCH
SIGKILL, SIGCHLD, SIGSTOP, SIGURG, SIGWINCH
/* The number of above list items */
#define BURN_OS_NON_SIGNAL_COUNT 9
#define BURN_OS_NON_SIGNAL_COUNT 5
/* The maximum size for a (SCSI) i/o transaction */

View File

@ -3,8 +3,7 @@
Operating system specific libburn definitions and declarations.
The macros defined here are used by libburn modules in order to
avoid own system dependent case distinctions.
Copyright (C) 2009 - 2014 Thomas Schmitt <scdbackup@gmx.net>,
provided under GPLv2+
Copyright (C) 2009 Thomas Schmitt <scdbackup@gmx.net>, provided under GPLv2+
*/
#ifndef BURN_OS_H_INCLUDED
@ -15,12 +14,6 @@
*/
/* <<< Until it is known whether this adapter would work on OpenBSD too */
#ifdef __NetBSD__
#define Libburn_use_sg_netbsD
#endif
#ifdef Libburn_use_sg_dummY
@ -36,15 +29,6 @@
#include "os-libcdio.h"
#else
#ifdef Libburn_use_sg_netbsD
/* To become: # ifdef __NetBSD__ */
/* -------------------------- NetBSD with SCIOCCOMMAND --------------------- */
#include "os-netbsd.h"
#else
#ifdef __FreeBSD__
@ -88,7 +72,6 @@
#endif /* ! __linux */
#endif /* ! __FreeBSD__kernel__ */
#endif /* ! __FreeBSD__ */
#endif /* ! Libburn_use_sg_netbsD */
#endif /* ! Libburn_use_libcdiO */
#endif /* ! Libburn_use_sg_dummY */

View File

@ -1,7 +1,7 @@
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
Copyright (c) 2006 - 2014 Thomas Schmitt <scdbackup@gmx.net>
Copyright (c) 2006 - 2012 Thomas Schmitt <scdbackup@gmx.net>
Provided under GPL version 2 or later.
*/
@ -22,11 +22,6 @@
#include <fcntl.h>
#include <errno.h>
/* ts B41126 : O_BINARY is needed for Cygwin but undefined elsewhere */
#ifndef O_BINARY
#define O_BINARY 0
#endif
#include "sector.h"
#include "libburn.h"
#include "drive.h"
@ -314,33 +309,8 @@ static void flipq(unsigned char *sub)
*/
/** @param flag bit1= be silent on failure
bit5= report failure with severity DEBUG
*/
static int burn_stdio_seek(int fd, off_t byte_address, struct burn_drive *d,
int flag)
{
char msg[80];
if (lseek(fd, byte_address, SEEK_SET) != -1)
return 1;
if (!(flag & 2)) {
sprintf(msg, "Cannot address start byte %.f",
(double) byte_address);
libdax_msgs_submit(libdax_messenger,
d->global_index, 0x00020147,
(flag & 32) ?
LIBDAX_MSGS_SEV_DEBUG : LIBDAX_MSGS_SEV_SORRY,
LIBDAX_MSGS_PRIO_HIGH, msg, errno, 0);
}
return 0;
}
/* ts A70904 */
/** @param flag bit0= be silent on data shortage
bit5= report data shortage with severity DEBUG
*/
/** @param flag bit0=be silent on data shortage */
int burn_stdio_read(int fd, char *buf, int bufsize, struct burn_drive *d,
int flag)
{
@ -355,9 +325,7 @@ int burn_stdio_read(int fd, char *buf, int bufsize, struct burn_drive *d,
if(todo > 0 && !(flag & 1)) {
libdax_msgs_submit(libdax_messenger, d->global_index,
0x0002014a,
(flag & 32) ?
LIBDAX_MSGS_SEV_DEBUG : LIBDAX_MSGS_SEV_SORRY,
LIBDAX_MSGS_PRIO_HIGH,
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
"Cannot read desired amount of data", errno, 0);
}
if (count < 0)
@ -366,82 +334,11 @@ int burn_stdio_read(int fd, char *buf, int bufsize, struct burn_drive *d,
}
/* With DVD and BD media, the minimum ECC entity is read instead of single
blocks.
@param flag see burn_read_data() in libburn.h
*/
static int retry_mmc_read(struct burn_drive *d, int chunksize, int sose_mem,
int start, char **wpt, off_t *data_count,
int flag)
{
int i, err, todo;
int retry_at, retry_size;
retry_at = start;
retry_size = chunksize;
todo = chunksize;
retry_size = 16; /* DVD ECC block size */
if (d->current_is_cd_profile) {
retry_size = 1; /* CD block size */
} else if (d->current_profile >= 0x40 && d->current_profile <= 0x43) {
retry_size = 32; /* BD cluster size */
}
for (i = 0; todo > 0; i++) {
if (flag & 2)
d->silent_on_scsi_error = 1;
else if (flag & 32)
d->silent_on_scsi_error = 3;
retry_at = start + i * retry_size;
if (retry_size > todo)
retry_size = todo;
err = d->read_10(d, retry_at, retry_size, d->buffer);
if (flag & (2 | 32))
d->silent_on_scsi_error = sose_mem;
if (err == BE_CANCELLED)
return 0;
memcpy(*wpt, d->buffer->data, retry_size * 2048);
*wpt += retry_size * 2048;
*data_count += retry_size * 2048;
todo -= retry_size;
}
return 1;
}
/* @param flag see burn_read_data() in libburn.h
*/
static int retry_stdio_read(struct burn_drive *d, int fd, int chunksize,
int start, char **wpt, off_t *data_count,
int flag)
{
int i, ret, to_read, todo;
ret = burn_stdio_seek(fd, ((off_t) start) * 2048, d, flag & 2);
if (ret <= 0)
return ret;
todo = chunksize * 2048;
for (i = 0; todo > 0; i += 2048) {
to_read = todo;
if (to_read > 2048)
to_read = 2048;
ret = burn_stdio_read(fd, (char *) d->buffer->data, to_read,
d, 1);
if (ret <= 0)
return 0;
memcpy(*wpt, d->buffer->data, to_read);
*wpt += to_read;
*data_count += to_read;
todo -= to_read;
}
return 1;
}
/* ts A70812 : API function */
int burn_read_data(struct burn_drive *d, off_t byte_address,
char data[], off_t data_size, off_t *data_count, int flag)
{
int alignment = 2048, start, upto, chunksize = 1, err, cpy_size;
int alignment = 2048, start, upto, chunksize = 1, err, cpy_size, i;
int sose_mem = 0, fd = -1, ret;
char msg[81], *wpt;
struct buffer *buf = NULL, *buffer_mem = d->buffer;
@ -500,9 +397,9 @@ int burn_read_data(struct burn_drive *d, off_t byte_address,
(int) (byte_address / 2048 + !!(byte_address % 2048)),
d->media_read_capacity);
libdax_msgs_submit(libdax_messenger, d->global_index,
0x00020172, (flag & 32) ?
LIBDAX_MSGS_SEV_DEBUG : LIBDAX_MSGS_SEV_SORRY,
LIBDAX_MSGS_PRIO_HIGH, msg, 0, 0);
0x00020172,
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
msg, 0, 0);
}
{ret = 0; goto ex;}
}
@ -526,8 +423,7 @@ int burn_read_data(struct burn_drive *d, off_t byte_address,
fd = d->stdio_fd;
if (fd < 0)
d->stdio_fd = fd =
open(d->devname,
O_RDONLY | O_LARGEFILE | O_BINARY);
open(d->devname, O_RDONLY | O_LARGEFILE);
if (fd == -1) {
if (errno == EACCES && (flag & 2)) {
if (!(flag & 8))
@ -537,23 +433,29 @@ int burn_read_data(struct burn_drive *d, off_t byte_address,
LIBDAX_MSGS_PRIO_HIGH,
"Failed to open device (a pseudo-drive) for reading",
errno, 0);
} else if (errno != ENOENT || !(flag & 2))
} else if (errno!= ENOENT || !(flag & 2))
libdax_msgs_submit(libdax_messenger,
d->global_index, 0x00020005,
(flag & 32) && errno == ENOENT ?
LIBDAX_MSGS_SEV_DEBUG :
LIBDAX_MSGS_SEV_SORRY,
LIBDAX_MSGS_PRIO_HIGH,
d->global_index, 0x00020005,
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
"Failed to open device (a pseudo-drive) for reading",
errno, 0);
errno, 0);
ret = 0;
if (errno == EACCES && (flag & 8))
ret= -2;
goto ex;
}
ret = burn_stdio_seek(fd, byte_address, d, flag & (2 | 32));
if (ret <= 0)
goto ex;
if (lseek(fd, byte_address, SEEK_SET) == -1) {
if (!(flag & 2)) {
sprintf(msg, "Cannot address start byte %.f",
(double) byte_address);
libdax_msgs_submit(libdax_messenger,
d->global_index,
0x00020147,
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
msg, errno, 0);
}
ret = 0; goto ex;
}
}
d->busy = BURN_DRIVE_READING_SYNC;
@ -573,8 +475,6 @@ int burn_read_data(struct burn_drive *d, off_t byte_address,
cpy_size = data_size - *data_count;
if (flag & 2)
d->silent_on_scsi_error = 1;
else if (flag & 32)
d->silent_on_scsi_error = 3;
if (flag & 16) {
d->had_particular_error &= ~1;
if (!d->silent_on_scsi_error)
@ -584,36 +484,51 @@ int burn_read_data(struct burn_drive *d, off_t byte_address,
err = d->read_10(d, start, chunksize, d->buffer);
} else {
ret = burn_stdio_read(fd, (char *) d->buffer->data,
cpy_size, d,
(flag & 32) | !!(flag & 2));
cpy_size, d, !!(flag & 2));
err = 0;
if (ret <= 0)
err = BE_CANCELLED;
}
if (flag & (2 | 16 | 32))
if (flag & (2 | 16))
d->silent_on_scsi_error = sose_mem;
if (err == BE_CANCELLED) {
if ((flag & 16) && (d->had_particular_error & 1))
{ret = -3; goto ex;}
/* Retry: with CD read by single blocks
with other media: retry in full chunks
*/
if(flag & 4)
goto bad_read;
if (d->drive_role == 1) {
ret = retry_mmc_read(d, chunksize, sose_mem,
start, &wpt, data_count, flag);
} else {
ret = retry_stdio_read(d, fd, chunksize,
start, &wpt, data_count, flag);
/* Try to read a smaller part of the chunk */
if(!(flag & 4))
for (i = 0; i < chunksize - 1; i++) {
if (flag & 2)
d->silent_on_scsi_error = 1;
if (d->drive_role == 1) {
err = d->read_10(d, start + i, 1,
d->buffer);
} else {
ret = burn_stdio_read(fd,
(char *) d->buffer->data,
2048, d, 1);
if (ret <= 0)
err = BE_CANCELLED;
}
if (flag & 2)
d->silent_on_scsi_error = sose_mem;
if (err == BE_CANCELLED)
break;
memcpy(wpt, d->buffer->data, 2048);
wpt += 2048;
*data_count += 2048;
}
if (ret <= 0)
goto bad_read;
} else {
memcpy(wpt, d->buffer->data, cpy_size);
wpt += cpy_size;
*data_count += cpy_size;
if (!(flag & 2))
libdax_msgs_submit(libdax_messenger,
d->global_index,
0x00020000,
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH,
"burn_read_data() returns 0",
0, 0);
ret = 0; goto ex;
}
memcpy(wpt, d->buffer->data, cpy_size);
wpt += cpy_size;
*data_count += cpy_size;
}
ret = 1;
@ -622,14 +537,6 @@ ex:;
d->buffer = buffer_mem;
d->busy = BURN_DRIVE_IDLE;
return ret;
bad_read:;
if (!(flag & 2))
libdax_msgs_submit(libdax_messenger, d->global_index,
0x00020000,
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH,
"burn_read_data() returns 0", 0, 0);
ret = 0; goto ex;
}
@ -692,8 +599,6 @@ int burn_read_audio(struct burn_drive *d, int sector_no,
cpy_size = chunksize * alignment;
if (flag & 2)
d->silent_on_scsi_error = 1;
else if (flag & 32)
d->silent_on_scsi_error = 3;
if (flag & 16) {
d->had_particular_error &= ~1;
if (!d->silent_on_scsi_error)
@ -701,7 +606,7 @@ int burn_read_audio(struct burn_drive *d, int sector_no,
}
err = d->read_cd(d, start, chunksize, 1, 0x10, NULL, d->buffer,
(flag & 8) >> 3);
if (flag & (2 | 16 | 32))
if (flag & (2 | 16))
d->silent_on_scsi_error = sose_mem;
if (err == BE_CANCELLED) {
if ((flag & 16) && (d->had_particular_error & 1))
@ -710,11 +615,9 @@ int burn_read_audio(struct burn_drive *d, int sector_no,
for (i = 0; i < chunksize - 1; i++) {
if (flag & 2)
d->silent_on_scsi_error = 1;
else if (flag & 32)
d->silent_on_scsi_error = 3;
err = d->read_cd(d, start + i, 1, 1, 0x10,
NULL, d->buffer, (flag & 8) >> 3);
if (flag & (2 | 32))
if (flag & 2)
d->silent_on_scsi_error = sose_mem;
if (err == BE_CANCELLED)
break;

View File

@ -1,7 +1,7 @@
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
Copyright (c) 2006 - 2015 Thomas Schmitt <scdbackup@gmx.net>
Copyright (c) 2006 - 2011 Thomas Schmitt <scdbackup@gmx.net>
Provided under GPL version 2 or later.
*/
@ -40,10 +40,6 @@ extern struct libdax_msgs *libdax_messenger;
#include <fcntl.h>
#endif /* Libburn_log_in_and_out_streaM */
/* ts B41126 : O_BINARY is needed for Cygwin but undefined elsewhere */
#ifndef O_BINARY
#define O_BINARY 0
#endif
/*static unsigned char isrc[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";*/
@ -113,8 +109,7 @@ static void get_bytes(struct burn_track *track, int count, unsigned char *data)
static int tee_fd= -1;
if(tee_fd==-1)
tee_fd= open("/tmp/libburn_sg_readin",
O_WRONLY | O_CREAT | O_TRUNC | O_BINARY,
S_IRUSR | S_IWUSR);
O_WRONLY|O_CREAT|O_TRUNC,S_IRUSR|S_IWUSR);
#endif /* Libburn_log_in_and_out_streaM */
@ -353,7 +348,7 @@ static int convert_data(struct burn_write_opts *o, struct burn_track *track,
/* ts A61010 */
/* a ssert(outlen >= inlen); */
if (outlen < inlen || outlen < 0 || inlen < 0)
if (outlen < inlen)
return 0;
if ((outmode & BURN_MODE_BITS) == (inmode & BURN_MODE_BITS)) {

View File

@ -35,11 +35,6 @@ Present implementation: default dummy which enables libburn only to work
#include <sys/statvfs.h>
#endif /* Libburn_os_has_stavtfS */
/* ts B41126 : O_BINARY is needed for Cygwin but undefined elsewhere */
#ifndef O_BINARY
#define O_BINARY 0
#endif
#include "transport.h"
#include "drive.h"
#include "sg.h"
@ -146,7 +141,7 @@ int scsi_enumerate_drives(void)
/** 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 and reservation.
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)
@ -249,7 +244,7 @@ int burn_os_is_2k_seekrw(char *path, int flag)
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 write_start, off_t *bytes)
int burn_os_stdio_capacity(char *path, off_t *bytes)
{
struct stat stbuf;
@ -282,7 +277,7 @@ int burn_os_stdio_capacity(char *path, off_t write_start, off_t *bytes)
long blocks;
blocks = *bytes / 512;
fd = open(path, open_mode | O_BINARY);
fd = open(path, open_mode);
if (fd == -1)
{ret = -2; goto ex;}
ret = ioctl(fd, BLKGETSIZE, &blocks);
@ -294,7 +289,7 @@ int burn_os_stdio_capacity(char *path, off_t write_start, off_t *bytes)
#endif /* Libburn_if_this_was_linuX */
} else if(S_ISREG(stbuf.st_mode)) {
add_size = burn_sparse_file_addsize(write_start, &stbuf);
add_size = stbuf.st_blocks * (off_t) 512;
strcpy(testpath, path);
} else
{ret = 0; goto ex;}
@ -335,7 +330,7 @@ int burn_os_open_track_src(char *path, int open_flags, int flag)
{
int fd;
fd = open(path, open_flags | O_BINARY);
fd = open(path, open_flags);
return fd;
}

View File

@ -81,7 +81,7 @@ burn_os_is_2k_seekrw() tells whether the given path leads to a file object
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 offers best
burn_os_open_track_src() opens a disk file in a way that allows best
throughput with file reading and/or SCSI write command
transmission.
@ -446,7 +446,7 @@ int scsi_enumerate_drives(void)
/** 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 and reservation.
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)
@ -716,7 +716,7 @@ int burn_os_is_2k_seekrw(char *path, int flag)
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 write_start, off_t *bytes)
int burn_os_stdio_capacity(char *path, off_t *bytes)
{
struct stat stbuf;
struct statvfs vfsbuf;
@ -769,7 +769,7 @@ int burn_os_stdio_capacity(char *path, off_t write_start, off_t *bytes)
{ret = -2; goto ex;}
*bytes = add_size;
} else if(S_ISREG(stbuf.st_mode)) {
add_size = burn_sparse_file_addsize(write_start, &stbuf);
add_size = stbuf.st_blocks * (off_t) 512;
strcpy(testpath, path);
} else
{ret = 0; goto ex;}

View File

@ -1,7 +1,7 @@
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
/*
Copyright (c) 2006 - 2013 Thomas Schmitt <scdbackup@gmx.net>
Copyright (c) 2006 - 2011 Thomas Schmitt <scdbackup@gmx.net>
Provided under GPL version 2 or later
and under FreeBSD license revised, i.e. without advertising clause.
*/
@ -441,11 +441,6 @@ static void enumerate_common(char *fname, int bus_no, int host_no,
struct burn_drive *t;
struct burn_drive out;
/* Initialize pointers to managed memory */
out.devname = NULL;
out.idata = NULL;
out.mdata = NULL;
/* ts A60923 */
out.bus_no = bus_no;
out.host = host_no;
@ -454,8 +449,6 @@ static void enumerate_common(char *fname, int bus_no, int host_no,
out.lun = lun_no;
out.devname = strdup(fname);
if (out.devname == NULL)
goto could_not_allocate;
out.cam = NULL;
out.lock_fd = -1;
@ -499,23 +492,13 @@ static void enumerate_common(char *fname, int bus_no, int host_no,
out.idata = calloc(1, sizeof(struct burn_scsi_inquiry_data));
out.idata->valid = 0;
out.mdata = calloc(1, sizeof(struct scsi_mode_data));
out.mdata->valid = 0;
if (out.idata == NULL || out.mdata == NULL) {
could_not_allocate:;
libdax_msgs_submit(libdax_messenger, -1, 0x00020108,
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
"Could not allocate new drive object", 0, 0);
if (out.devname != NULL)
free(out.devname);
out.devname = NULL;
if (out.idata != NULL)
free(out.idata);
out.idata = NULL;
if (out.mdata != NULL)
free(out.mdata);
out.mdata = NULL;
return;
}
out.mdata->p2a_valid = 0;
memset(&out.params, 0, sizeof(struct params));
t = burn_drive_register(&out);
@ -878,11 +861,8 @@ int sg_issue_command(struct burn_drive *d, struct command *c)
memset(&ccb->csio.sense_data, 0, sizeof(ccb->csio.sense_data));
memset(c->sense, 0, sizeof(c->sense));
c->start_time = burn_get_time(0);
err = cam_send_ccb(d->cam, ccb);
c->end_time = burn_get_time(0);
ignore_error = sense_len = 0;
/* ts B00325 : CAM_AUTOSNS_VALID advised by Alexander Motin */
if (ccb->ccb_h.status & CAM_AUTOSNS_VALID) {
@ -979,12 +959,19 @@ int sg_issue_command(struct burn_drive *d, struct command *c)
c->sense[13] = 0x00;
done = 1;
}
}
done = scsi_eval_cmd_outcome(d, c, fp, c->sense,
sense_len, start_time,
timeout_ms, i, !!ignore_error);
if (d->cancel)
/* >>> 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);
if (d->cancel)
done = 1;
} else {
done = 1;
}
} while (!done);
ret = 1;
ex:;
@ -1068,7 +1055,7 @@ int burn_os_is_2k_seekrw(char *path, int flag)
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 write_start, off_t *bytes)
int burn_os_stdio_capacity(char *path, off_t *bytes)
{
struct stat stbuf;
struct statvfs vfsbuf;
@ -1121,7 +1108,7 @@ int burn_os_stdio_capacity(char *path, off_t write_start, off_t *bytes)
{ret = -2; goto ex;}
*bytes = add_size;
} else if(S_ISREG(stbuf.st_mode)) {
add_size = burn_sparse_file_addsize(write_start, &stbuf);
add_size = stbuf.st_blocks * (off_t) 512;
strcpy(testpath, path);
} else
{ret = 0; goto ex;}

View File

@ -1,7 +1,7 @@
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
/*
Copyright (c) 2009 - 2014 Thomas Schmitt <scdbackup@gmx.net>
Copyright (c) 2009 - 2011 Thomas Schmitt <scdbackup@gmx.net>
Provided under GPL version 2 or later.
*/
@ -78,7 +78,7 @@ burn_os_is_2k_seekrw() tells whether the given path leads to a file object
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 offers best
burn_os_open_track_src() opens a disk file in a way that allows best
throughput with file reading and/or SCSI write command
transmission.
@ -149,11 +149,6 @@ Send feedback to libburn-hackers@pykix.org .
#include <cdio/logging.h>
#include <cdio/mmc.h>
/* ts B41126 : O_BINARY is needed for Cygwin but undefined elsewhere */
#ifndef O_BINARY
#define O_BINARY 0
#endif
/* The waiting time before eventually retrying a failed SCSI command.
Before each retry wait Libburn_sg_linux_retry_incR longer than with
@ -529,7 +524,7 @@ ex:;
/** 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 and reservation.
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)
@ -674,12 +669,9 @@ int sg_issue_command(struct burn_drive *d, struct command *c)
for(i = 0; !done; i++) {
memset(c->sense, 0, sizeof(c->sense));
c->start_time = burn_get_time(0);
i_status = mmc_run_cmd(p_cdio, timeout_ms, &cdb, e_direction,
dxfer_len, c->page->data);
c->end_time = burn_get_time(0);
sense_valid = mmc_last_cmd_sense(p_cdio, &sense_pt);
if (sense_valid >= 18) {
memcpy(c->sense, (unsigned char *) sense_pt,
@ -725,7 +717,7 @@ int sg_issue_command(struct burn_drive *d, struct command *c)
else
sense_len = 0;
done = scsi_eval_cmd_outcome(d, c, fp, c->sense, sense_len,
start_time, timeout_ms, i, 0);
0, start_time, timeout_ms, i, 2);
if (d->cancel)
done = 1;
@ -870,7 +862,7 @@ int burn_os_is_2k_seekrw(char *path, int flag)
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 write_start, off_t *bytes)
int burn_os_stdio_capacity(char *path, off_t *bytes)
{
struct stat stbuf;
@ -900,7 +892,7 @@ int burn_os_stdio_capacity(char *path, off_t write_start, off_t *bytes)
/* GNU/Linux specific determination of block device size */
} else if(S_ISBLK(stbuf.st_mode)) {
int open_mode = O_RDONLY | O_BINARY, fd;
int open_mode = O_RDONLY, fd;
long blocks;
blocks = *bytes / 512;
@ -920,7 +912,7 @@ int burn_os_stdio_capacity(char *path, off_t write_start, off_t *bytes)
} else if(S_ISCHR(stbuf.st_mode)) {
int fd;
fd = open(path, O_RDONLY | O_BINARY);
fd = open(path, O_RDONLY);
if (fd == -1)
{ret = -2; goto ex;}
ret = ioctl(fd, DIOCGMEDIASIZE, &add_size);
@ -934,7 +926,7 @@ int burn_os_stdio_capacity(char *path, off_t write_start, off_t *bytes)
#ifdef Libburn_is_on_solariS
} else if(S_ISBLK(stbuf.st_mode)) {
int open_mode = O_RDONLY | O_BINARY, fd;
int open_mode = O_RDONLY, fd;
fd = open(path, open_mode);
if (fd == -1)
@ -949,7 +941,7 @@ int burn_os_stdio_capacity(char *path, off_t write_start, off_t *bytes)
#endif /* Libburn_is_on_solariS */
} else if(S_ISREG(stbuf.st_mode)) {
add_size = burn_sparse_file_addsize(write_start, &stbuf);
add_size = stbuf.st_blocks * (off_t) 512;
strcpy(testpath, path);
} else
{ret = 0; goto ex;}
@ -990,7 +982,7 @@ int burn_os_open_track_src(char *path, int open_flags, int flag)
{
int fd;
fd = open(path, open_flags | O_BINARY);
fd = open(path, open_flags);
return fd;
}

View File

@ -1,7 +1,7 @@
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
Copyright (c) 2006 - 2014 Thomas Schmitt <scdbackup@gmx.net>
Copyright (c) 2006 - 2011 Thomas Schmitt <scdbackup@gmx.net>
Provided under GPL version 2 or later.
*/
@ -84,7 +84,7 @@ burn_os_is_2k_seekrw() tells whether the given path leads to a file object
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 offers best
burn_os_open_track_src() opens a disk file in a way that allows best
throughput with file reading and/or SCSI write command
transmission.
@ -219,6 +219,14 @@ static char linux_ata_device_family[80] = {"/dev/hd%c"};
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 ----- */
#include "libburn.h"
@ -378,19 +386,15 @@ static int sg_exchange_scd_for_sr(char *fname, int flag)
static int sgio_log_cmd(unsigned char *cmd, int cmd_len, FILE *fp_in, int flag)
{
FILE *fp = fp_in;
int ret = 0;
int ret;
/* >>> ts B11110 : move this into scsi_log_command() */
if (fp == NULL && (burn_sg_log_scsi & 1)) {
fp= fopen("/tmp/libburn_sg_command_log", "a");
if (fp != NULL)
fprintf(fp,
"\n=========================================\n");
fprintf(fp, "\n=========================================\n");
}
if (fp != NULL)
ret = scsi_log_command(cmd, cmd_len, NO_TRANSFER, NULL, 0,
fp, flag);
ret = scsi_log_command(cmd, cmd_len, NO_TRANSFER, NULL, 0, fp, flag);
if (fp_in == NULL && fp != NULL)
fclose(fp);
return ret;
@ -400,13 +404,13 @@ static int sgio_log_cmd(unsigned char *cmd, int cmd_len, FILE *fp_in, int flag)
/* ts B11110 */
static int sgio_log_reply(unsigned char *opcode, int data_dir,
unsigned char *data, int dxfer_len,
void *fp_in, unsigned char sense[18], int sense_len,
double duration, int flag)
void *fp_in, unsigned char sense[18],
int sense_len, int duration, int flag)
{
int ret;
ret = scsi_log_reply(opcode, data_dir, data, dxfer_len, fp_in,
sense, sense_len, duration, flag);
sense, sense_len, duration, flag);
return ret;
}
@ -416,7 +420,6 @@ static int sgio_test(int fd)
unsigned char test_ops[] = { 0, 0, 0, 0, 0, 0 };
sg_io_hdr_t s;
int ret;
double c_start_time, c_end_time;
memset(&s, 0, sizeof(sg_io_hdr_t));
s.interface_id = 'S';
@ -427,13 +430,10 @@ static int sgio_test(int fd)
sgio_log_cmd(s.cmdp, s.cmd_len, NULL, 0);
c_start_time = burn_get_time(0);
ret= ioctl(fd, SG_IO, &s);
c_end_time = burn_get_time(0);
sgio_log_reply(s.cmdp, NO_TRANSFER, NULL, 0, NULL,
(unsigned char *) (s.sbp),
s.sb_len_wr, c_end_time - c_start_time, 0);
sgio_log_reply(s.cmdp, NO_TRANSFER, NULL, 0,
NULL, s.sbp, s.sb_len_wr, s.duration, 0);
return ret;
}
@ -446,7 +446,6 @@ static int sgio_inquiry_cd_drive(int fd, char *fname)
unsigned char *sense = NULL;
char *msg = NULL, *msg_pt;
int ret = 0, i;
double c_start_time, c_end_time;
BURN_ALLOC_MEM(buf, struct buffer, 1);
BURN_ALLOC_MEM(sense, unsigned char, 128);
@ -466,9 +465,7 @@ static int sgio_inquiry_cd_drive(int fd, char *fname)
sgio_log_cmd(s.cmdp, s.cmd_len, NULL, 0);
c_start_time = burn_get_time(0);
ret = ioctl(fd, SG_IO, &s);
c_end_time = burn_get_time(0);
if (ret == -1) {
sprintf(msg,
"INQUIRY on '%s' : ioctl(SG_IO) failed , errno= %d",
@ -479,9 +476,8 @@ static int sgio_inquiry_cd_drive(int fd, char *fname)
goto ex;
}
sgio_log_reply(s.cmdp, FROM_DRIVE, buf->data, s.dxfer_len, NULL,
(unsigned char *) (s.sbp),
s.sb_len_wr, c_end_time - c_start_time, 0);
sgio_log_reply(s.cmdp, FROM_DRIVE, buf->data, s.dxfer_len,
NULL, s.sbp, s.sb_len_wr, s.duration, 0);
if (s.sb_len_wr > 0 || s.host_status != Libburn_sg_host_oK ||
s.driver_status != Libburn_sg_driver_oK) {
@ -490,8 +486,7 @@ static int sgio_inquiry_cd_drive(int fd, char *fname)
sprintf(msg + strlen(msg), " , sense data=");
msg_pt = msg + strlen(msg);
for (i = 0 ; i < s.sb_len_wr; i++)
sprintf(msg_pt + i * 3, " %2.2X",
((unsigned char *) (s.sbp))[i]);
sprintf(msg_pt + i * 3, " %2.2X", s.sbp[i]);
}
libdax_msgs_submit(libdax_messenger, -1, 0x00000002,
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH,
@ -1417,7 +1412,7 @@ static int add_proc_info_drives(int flag)
char **list= NULL;
if (burn_sg_use_family != 0)
return(1); /* Looking only for sr , scd , sg */
return(1); /* Looking only for sr resp. scd resp. sg */
ret = proc_sys_dev_cdrom_info(&list, &list_count, 0);
if (ret <= 0)
@ -1620,8 +1615,6 @@ next_ata:;
next_proc_info:;
baseno += ata_limit;
if (burn_sg_use_family != 0) /* Only with default enumeration */
return 0;
for (i = 0; i < idx->info_count; i++) {
if ((idx->info_list)[i][0] == 0)
continue;
@ -1657,7 +1650,7 @@ return_1_pre_proc:;
and accessability. If burn activities are prone to external interference
on your system it is also necessary to obtain exclusive access locks on
the drives.
Hand over each accepted drive to enumerate_common() or its replacement
Hand over each accepted drive to enumerate_common() resp. its replacement
within your port.
See FreeBSD port sketch sg-freebsd-port.c for such an implementation.
@ -1683,7 +1676,7 @@ int scsi_enumerate_drives(void)
/** 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 and reservation.
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)
@ -1885,167 +1878,6 @@ int sg_release(struct burn_drive *d)
return 0;
}
/* @return -1= transport failed, give up drive
0= transport failed, do not retry
1= transport succeeded
2- transport failed, please retry
*/
static int evaluate_transport_success(struct burn_drive *d, struct command *c,
FILE *fp,
unsigned short host_status,
unsigned short driver_status)
{
int ret, do_retry= 0, give_up_drive= 0, sev;
char *msg = NULL, *host_problem, *driver_problem, *driver_sugg;
BURN_ALLOC_MEM(msg, char, 161);
if ((host_status == Libburn_sg_host_oK &&
(driver_status & 0xf7) == Libburn_sg_driver_oK) || c->error)
{ret = 1; goto ex;} /* No transport problems */
/* See http://www.tldp.org/HOWTO/SCSI-Generic-HOWTO/x291.html */
switch(host_status) {
case 0x00:
host_problem =
"SG_ERR_DID_OK (No error)";
break; case 0x01:
host_problem =
"SG_ERR_DID_NO_CONNECT (Could not connect before timeout period)";
give_up_drive= 1;
break; case 0x02:
host_problem =
"SG_ERR_DID_BUS_BUSY (Bus stayed busy through time out period)";
break; case 0x03:
host_problem =
"SG_ERR_DID_TIME_OUT (Timed out for miscellaneous reasons)";
break; case 0x04:
host_problem =
"SG_ERR_DID_BAD_TARGET (Bad target, device not responding ?)";
give_up_drive= 1;
break; case 0x05:
host_problem =
"SG_ERR_DID_ABORT (Told to abort)";
break; case 0x06:
host_problem =
"SG_ERR_DID_PARITY (Parity error)";
break; case 0x07:
host_problem =
"SG_ERR_DID_ERROR (Internal error detected in the host adapter)";
give_up_drive= 1;
break; case 0x08:
host_problem =
"SG_ERR_DID_RESET (The SCSI bus or the device have been reset)";
give_up_drive= 1;
break; case 0x09:
host_problem =
"SG_ERR_DID_BAD_INTR (Got an unexpected interrupt)";
break; case 0x0a:
host_problem =
"SG_ERR_DID_PASSTHROUGH (Force command past mid-layer)";
break; case 0x0b:
host_problem =
"SG_ERR_DID_SOFT_ERROR (The low level driver wants a retry)";
do_retry = 1;
break; default:
host_problem =
"? (unknown host_status code)";
}
if (host_status != Libburn_sg_host_oK) {
sprintf(msg, "SCSI command %2.2Xh yielded host problem: ",
(unsigned int) c->opcode[0]);
sprintf(msg+strlen(msg), "0x%x %s",
(unsigned int) host_status, host_problem);
sev = LIBDAX_MSGS_SEV_FAILURE;
if (do_retry && !give_up_drive)
sev = LIBDAX_MSGS_SEV_DEBUG;
libdax_msgs_submit(libdax_messenger, d->global_index,
0x000201a7, sev, LIBDAX_MSGS_PRIO_HIGH, msg, 0, 0);
sprintf(msg, "--- SG_IO: host_status= 0x%x %s",
(unsigned int) host_status, host_problem);
scsi_log_message(d, fp, msg, 0);
}
switch (driver_status & 0x07) {
case 0:
driver_problem = "SG_ERR_DRIVER_OK";
break; case 1:
driver_problem = "SG_ERR_DRIVER_BUSY";
break; case 2:
driver_problem = "SG_ERR_DRIVER_SOFT";
break; case 3:
driver_problem = "SG_ERR_DRIVER_MEDIA";
break; case 4:
driver_problem = "SG_ERR_DRIVER_ERROR";
break; case 5:
driver_problem = "SG_ERR_DRIVER_INVALID";
break; case 6:
driver_problem = "SG_ERR_DRIVER_TIMEOUT";
break; case 7:
driver_problem = "SG_ERR_DRIVER_HARD";
break; default:
driver_problem = "(unknown driver_status code)";
}
switch (driver_status & 0xf0) {
case 0:
driver_sugg = "(no suggestion)";
break; case 0x10:
driver_sugg = "SG_ERR_SUGGEST_RETRY";
do_retry = 1;
break; case 0x20:
driver_sugg = "SG_ERR_SUGGEST_ABORT";
give_up_drive= 1;
break; case 0x30:
driver_sugg = "SG_ERR_SUGGEST_REMAP";
give_up_drive= 1;
break; case 0x40:
driver_sugg = "SG_ERR_SUGGEST_DIE";
give_up_drive= 1;
break; case 0x80:
driver_sugg = "SG_ERR_SUGGEST_SENSE";
break; default:
driver_sugg = "(unknown driver_status suggestion)";
}
if ((driver_status & 0xf7) != Libburn_sg_driver_oK) {
sprintf(msg, "SCSI command %2.2Xh yielded driver problem: ",
(unsigned int) c->opcode[0]);
sprintf(msg+strlen(msg), "driver_status= 0x%x %s / %s",
(unsigned int) driver_status,
driver_problem, driver_sugg);
sev = LIBDAX_MSGS_SEV_FAILURE;
if (do_retry && !give_up_drive)
sev = LIBDAX_MSGS_SEV_DEBUG;
libdax_msgs_submit(libdax_messenger, d->global_index,
0x000201a8, sev, LIBDAX_MSGS_PRIO_HIGH, msg, 0, 0);
sprintf(msg, "--- SG_IO: driver_status= 0x%x %s / %s",
(unsigned int) driver_status,
driver_problem, driver_sugg);
scsi_log_message(d, fp, msg, 0);
}
if (! do_retry)
c->error = 1;
ret = give_up_drive ? -1 : do_retry ? 2 : 0;
ex:;
BURN_FREE_MEM(msg);
return ret;
}
static void react_on_drive_loss(struct burn_drive *d, struct command *c,
FILE *fp)
{
sg_close_drive(d);
d->released = 1;
d->busy = BURN_DRIVE_IDLE;
d->cancel = 1;
c->error = 1;
libdax_msgs_submit(libdax_messenger,
d->global_index, 0x000201a6,
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
"Lost connection to drive", 0, 0);
scsi_log_message(d, fp, "--- SG_IO: Gave up connection to drive", 0);
}
/** Sends a SCSI command to the drive, receives reply and evaluates wether
the command succeeded or shall be retried or finally failed.
@ -2085,6 +1917,8 @@ int sg_issue_command(struct burn_drive *d, struct command *c)
"\n-----------------------------------------\n");
}
}
if (burn_sg_log_scsi & 3)
scsi_log_cmd(c,fp,0);
/* ts A61010 : with no fd there is no chance to send an ioctl */
if (d->fd < 0) {
@ -2092,11 +1926,8 @@ int sg_issue_command(struct burn_drive *d, struct command *c)
{ret = 0; goto ex;}
}
c->error = 0;
memset(&s, 0, sizeof(sg_io_hdr_t));
if (burn_sg_log_scsi & 3)
scsi_log_cmd(c,fp,0);
s.interface_id = 'S';
@ -2128,26 +1959,6 @@ int sg_issue_command(struct burn_drive *d, struct command *c)
s.timeout = Libburn_scsi_default_timeouT;
if (c->page && !no_c_page) {
s.dxferp = c->page->data;
/* # def ine Libburn_debug_dxferP 1 */
#ifdef Libburn_debug_dxferP
{ char text[1024], *content; int i = c->page->bytes;
if (c->dir == FROM_DRIVE) {
for (i = 0; i < c->page->bytes && c->page->data[i] == 0; i++);
content = (i < c->page->bytes) ?
" (some nonzero)" : " (all zero)";
} else {
i = c->page->bytes;
content = "";
}
sprintf(text, "dxferp before = %lx%s",
(unsigned long) s.dxferp, content);
scsi_log_text(text, fp, 0);
}
#endif
if (c->dir == FROM_DRIVE) {
/* ts A70519 : kernel 2.4 usb-storage seems to
@ -2181,23 +1992,8 @@ int sg_issue_command(struct burn_drive *d, struct command *c)
for(i = 0; !done; i++) {
memset(c->sense, 0, sizeof(c->sense));
c->start_time = burn_get_time(0);
err = ioctl(d->fd, SG_IO, &s);
c->end_time = burn_get_time(0);
#ifdef Libburn_debug_dxferP
if (c->page && !no_c_page) {
char text[1024];
sprintf(text, "dxferp after = %lx",
(unsigned long) s.dxferp);
scsi_log_text(text, fp, 0);
}
#endif
/* ts A61010 */
/* a ssert(err != -1); */
if (err == -1) {
@ -2206,33 +2002,32 @@ int sg_issue_command(struct burn_drive *d, struct command *c)
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
"Failed to transfer command to drive",
errno, 0);
sprintf(msg, "--- SG_IO: return= -1 , ");
sprintf(msg + strlen(msg), "errno= %d , ", errno);
sprintf(msg + strlen(msg),
"host_status= 0x%x , driver_status= 0x%x",
(unsigned int) s.host_status,
(unsigned int) s.driver_status);
scsi_log_message(d, fp, msg, 0);
react_on_drive_loss(d, c, fp);
sg_close_drive(d);
d->released = 1;
d->busy = BURN_DRIVE_IDLE;
c->error = 1;
{ret = -1; goto ex;}
}
done = scsi_eval_cmd_outcome(d, c, fp,
(unsigned char *) (s.sbp),
s.sb_len_wr,
start_time, s.timeout, i, 0);
done = scsi_eval_cmd_outcome(d, c, fp, s.sbp, s.sb_len_wr,
s.duration, start_time, s.timeout, i, 0);
if (d->cancel)
break;
ret = evaluate_transport_success(d, c, fp,
s.host_status, s.driver_status);
if (ret == -1)
react_on_drive_loss(d, c, fp);
if (ret <= 0)
{ret = -1; goto ex;}
if (d->cancel)
break;
/* if ! done : loop for retry */;
done = 1;
}
if (s.host_status != Libburn_sg_host_oK ||
(s.driver_status != Libburn_sg_driver_oK && !c->error)) {
sprintf(msg,
"SCSI command %2.2Xh indicates host or driver error:",
(unsigned int) c->opcode[0]);
sprintf(msg+strlen(msg),
" host_status= %xh , driver_status= %xh",
(unsigned int) s.host_status,
(unsigned int) s.driver_status);
libdax_msgs_submit(libdax_messenger, d->global_index,
0x0002013b,
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH,
msg, 0, 0);
}
ret = 1;
ex:;
BURN_FREE_MEM(msg);
@ -2382,7 +2177,7 @@ int burn_os_is_2k_seekrw(char *path, int flag)
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 write_start, off_t *bytes)
int burn_os_stdio_capacity(char *path, off_t *bytes)
{
struct stat stbuf;
struct statvfs vfsbuf;
@ -2393,6 +2188,7 @@ int burn_os_stdio_capacity(char *path, off_t write_start, off_t *bytes)
BURN_ALLOC_MEM(testpath, char, 4096);
testpath[0] = 0;
blocks = *bytes / 512;
if (stat(path, &stbuf) == -1) {
strcpy(testpath, path);
cpt = strrchr(testpath, '/');
@ -2414,7 +2210,7 @@ int burn_os_stdio_capacity(char *path, off_t write_start, off_t *bytes)
{ret = -2; goto ex;}
*bytes = ((off_t) blocks) * (off_t) 512;
} else if(S_ISREG(stbuf.st_mode)) {
add_size = burn_sparse_file_addsize(write_start, &stbuf);
add_size = stbuf.st_blocks * (off_t) 512;
strcpy(testpath, path);
} else
{ret = 0; goto ex;}

View File

@ -1,894 +0,0 @@
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
/*
Copyright (c) 2010 - 2014 Thomas Schmitt <scdbackup@gmx.net>
Provided under GPL version 2 or later.
Derived 2014 from libburn/sg-solaris.c with information learned from
dvd+rw-tools, http://fxr.watson.org/fxr/source/sys/scsiio.h?v=NETBSD,
http://netbsd.gw.com/cgi-bin/man-cgi?scsi+4+NetBSD-current,
and experiments made by Freddy Fisker.
*/
/*
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: NetBSD 6, ioctl SCIOCCOMMAND
>>> ??? for OpenBSD too ?
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 offers 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 */
#include <sys/ioctl.h>
#include <sys/scsiio.h>
/** 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 "init.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;
}
/* ----------------------------------------------------------------------- */
/* 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 NetBSD SCIOCCOMMAND */
/* 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);
}
static int start_enum_rcdNx(burn_drive_enumerator_t *idx, int flag)
{
idx->cdno = -1;
return 1;
}
/* Trying /dev/rcd[0..63][dc] */
#define Libburn_netbsd_max_cdnuM 63
static int next_enum_rcdNx(burn_drive_enumerator_t *idx,
char adr[], int adr_size, int flag)
{
static char suffix[2] = {'d', 'c'};
struct stat stbuf;
int i, stat_ret;
char path[16];
while (idx->cdno < Libburn_netbsd_max_cdnuM) {
idx->cdno++;
for (i = 0; i < 2; i++) {
sprintf(path, "/dev/rcd%d%c", idx->cdno, suffix[i]);
stat_ret = stat(path, &stbuf);
if (stat_ret == -1)
continue;
if (!S_ISCHR(stbuf.st_mode))
continue;
if ((int) strlen(path) >= adr_size)
continue;
strcpy(adr, path);
return 1;
}
}
return 0;
}
/* Searching the first byte address that cannot be lseeked and read
*/
static int guess_size_by_seek_set(int fd, off_t *bytes, int flag)
{
static off_t abs_limit = ((off_t) 1024) * 1024 * 1024 * 1024 * 1024;
off_t i, step = ((off_t) 1024) * 1024 * 1024 * 1024, ret;
char buf[1];
*bytes = 0;
for (i = step; i < abs_limit; i += step) {
ret = lseek(fd, i, SEEK_SET);
if (ret == -1) {
i -= step;
step = step >> 1;
if (step > 0)
continue;
return 1;
}
ret = read(fd, buf, 1);
if (ret == -1) {
i -= step;
step = step >> 1;
if (step > 0)
continue;
return 1;
}
*bytes = i + 1;
}
return 0;
}
/* ------------------------------------------------------------------------ */
/* 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 NetBSD SCIOCCOMMAND adapter sg-netbsd");
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 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)
{
int ret;
if (initialize == 1) {
ret = start_enum_rcdNx(idx, 0);
if (ret <= 0)
return ret;
} else if (initialize == -1) {
return 0;
}
ret = next_enum_rcdNx(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, buf_size = 4096;
int i_host_no = -1, i_channel_no = -1, i_target_no = -1, i_lun_no = -1;
char *buf = NULL;
BURN_ALLOC_MEM(buf, char, buf_size);
while(1) {
ret = sg_give_next_adr(&idx, buf, buf_size, 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, buf_size, -1);
ret = 1;
ex:;
BURN_FREE_MEM(buf);
return ret;
}
/** 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 and 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 = NULL;
int os_errno, ret;
BURN_ALLOC_MEM(msg, char, 4096);
if (d->fd != -1) {
d->released = 0;
{ret = 1; goto ex;}
}
d->fd = open(d->devname, O_RDWR | O_NDELAY);
if (d->fd == -1) {
os_errno = errno;
sprintf(msg, "Could not grab drive '%s'", d->devname);
/* (errno == ENXIO is a device file with no drive attached) */
libdax_msgs_submit(libdax_messenger, d->global_index,
0x00020003,
errno == ENXIO ? LIBDAX_MSGS_SEV_DEBUG :
LIBDAX_MSGS_SEV_SORRY,
LIBDAX_MSGS_PRIO_HIGH,
msg, os_errno, 0);
{ret = 0; goto ex;}
}
d->released = 0;
/* Make sure by INQUIRY that this is really a MMC drive */
ret = spc_confirm_cd_drive(d, 0);
if (ret <= 0)
goto revoke;
/* # define Libburn_sg_netbsd_scsi_debuG */
#ifdef Libburn_sg_netbsd_scsi_debuG
{
static int sc_db = SC_DB_CMDS | SC_DB_FLOW;
ret = ioctl(d->fd, SCIOCDEBUG, &sc_db);
if (ret == -1)
fprintf(stderr,
"libburn_DEBUG: ioctl(%d, SCIOCDEBUG, &(0x%X)) returns %d, errno = %d\n",
d->fd, (unsigned int) sc_db, ret, errno);
}
#endif
{ret = 1; goto ex;}
revoke:;
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, 0, 0);
if (d->fd >= 0) {
close(d->fd);
d->fd = -1;
d->released = 1;
}
ret = 0;
ex:;
BURN_FREE_MEM(msg);
return ret;
}
/** 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)
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, sense_len, max_sl;
time_t start_time;
scsireq_t req;
char msg[160];
static FILE *fp = NULL;
c->error = 0;
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);
if (c->timeout > 0)
timeout_ms = c->timeout;
else
timeout_ms = 200000;
memset (&req, 0, sizeof(req));
memcpy(req.cmd, c->opcode, c->oplen);
req.cmdlen = c->oplen;
req.databuf = (caddr_t) c->page->data;
req.flags = SCCMD_ESCAPE; /* probably to make req.cmdlen significant */
req.timeout = timeout_ms;
max_sl = sizeof(c->sense) > SENSEBUFLEN ?
SENSEBUFLEN : sizeof(c->sense);
req.senselen = max_sl;
if (c->dir == TO_DRIVE) {
req.datalen = c->page->bytes;
req.flags |= SCCMD_WRITE;
} else if (c->dir == FROM_DRIVE) {
req.flags |= SCCMD_READ;
if (c->dxfer_len >= 0)
req.datalen = c->dxfer_len;
else
req.datalen = BUFFER_SIZE;
/* touch page so we can use valgrind */
memset(c->page->data, 0, BUFFER_SIZE);
} else {
req.flags |= SCCMD_READ;
req.datalen = 0;
}
/* retry-loop */
start_time = time(NULL);
for(i = 0; !done; i++) {
memset(c->sense, 0, sizeof(c->sense));
c->start_time = burn_get_time(0);
ret = ioctl(d->fd, SCIOCCOMMAND, &req);
/* <<< Fault mock-up
if (c->opcode[0] == 0x28) {
ret = -1;
errno = 9;
}
*/
c->end_time = burn_get_time(0);
/* #define Libburn_debug_sg_netbsD */
#ifdef Libburn_debug_sg_netbsD
fprintf(stderr, "libburn_DEBUG: ret= %d, retsts = 0x%X, senselen_used = %d, status = 0x%X, error= 0x%X\n", ret, (unsigned int) req.retsts, (int) req.senselen_used, (unsigned int) req.status, req.error);
fprintf(stderr, "libburn_DEBUG: datalen_used = %u\n",
(unsigned int) req.datalen_used);
#endif
if (ret != 0 ||
(req.retsts != SCCMD_SENSE && req.retsts != SCCMD_OK)) {
sprintf(msg, "Failed to transfer command to drive. (ioctl(%d, SCIOCCOMMAND) = %d, scsireq_t.retsts = 0x%X, errno= %d)",
d->fd, ret, (unsigned int) req.retsts, errno);
if (burn_sg_log_scsi & 3)
scsi_log_message(d, fp, msg, 0);
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;
}
sense_len = 0;
if (req.retsts == SCCMD_SENSE) {
memcpy(c->sense, req.sense, max_sl);
sense_len = req.senselen > max_sl ?
max_sl : req.senselen;
}
spc_decode_sense(c->sense, sense_len, &key, &asc, &ascq);
if (key || asc || ascq)
sense_len = req.senselen;
else
sense_len = 0;
/* <<< Fault mock-up
if (c->opcode[0] == 0x5a) {
req.datalen_used = 0;
memset(c->page->data, 0, BUFFER_SIZE);
}
*/
if (c->dir == FROM_DRIVE && sense_len == 0 &&
req.datalen > 0 && req.datalen_used < req.datalen) {
sprintf(msg, "Short reply from SCSI command %2.2X: expected: %d, got: %d, req.retsts: 0x%X",
(unsigned int) c->opcode[0],
(int) req.datalen, (int) req.datalen_used,
(unsigned int) req.retsts);
if (burn_sg_log_scsi & 3)
scsi_log_message(d, fp, msg, 0);
libdax_msgs_submit(libdax_messenger,
d->global_index, 0x00000002,
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH,
msg, 0, 0);
if (req.datalen_used == 0)
c->error = 1;
c->dxfer_len = req.datalen_used;
}
done = scsi_eval_cmd_outcome(d, c, fp, c->sense, sense_len,
start_time, timeout_ms, i, 0);
if (d->cancel)
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, fd = -1;
struct scsi_addr addr;
fd = open(path, O_RDWR | O_NDELAY);
if (fd == -1)
return 0;
*bus_no = *host_no = *channel_no = *target_no = *lun_no = 0;
memset(&addr, 0, sizeof(addr));
ret = ioctl(fd, SCIOCIDENTIFY, &addr);
if (ret != 0)
{ret = 0; goto ex;}
if (addr.type != TYPE_SCSI)
{ret = 0; goto ex;}
*bus_no = *host_no = addr.addr.scsi.scbus;
*channel_no = 0;
*target_no = addr.addr.scsi.target;
*lun_no = addr.addr.scsi.lun;
ret = 1;
ex:;
if (fd != -1)
close(fd);
return (0);
}
/** Tells wether a text is a persistent address as listed by the enumeration
functions.
*/
int sg_is_enumerable_adr(char* adr)
{
burn_drive_enumerator_t idx;
int initialize = 1, ret;
char buf[64];
while(1) {
ret = sg_give_next_adr(&idx, buf, sizeof(buf), initialize);
initialize = 0;
if (ret <= 0)
break;
if (strcmp(adr, buf) == 0) {
sg_give_next_adr(&idx, buf, sizeof(buf), -1);
return 1;
}
}
sg_give_next_adr(&idx, buf, sizeof(buf), -1);
return (0);
}
/* Return 1 if the given path leads to a regular file or a device that can be
seeked, read, and possibly written with 2 kB granularity.
*/
int burn_os_is_2k_seekrw(char *path, int flag)
{
struct stat stbuf;
int l, i, dev, tl;
char try[16];
/* >>> ??? Is this a comprehensive list of lseek()-capable devices ? */
/* http://www.netbsd.org/docs/guide/en/chap-rmmedia.html */
static char dev_names[][4] = {
"fd", "rfd", "sd" , "cd", "rcd", "wd", ""};
if (path[0] == 0)
return 0;
if (stat(path, &stbuf) == -1)
return 0;
if (S_ISREG(stbuf.st_mode))
return 1;
if (S_ISBLK(stbuf.st_mode))
return 1;
/* Look for known device names which promise the desired capabilities */
if (strncmp(path, "/dev/", 5) != 0)
return 0;
l = strlen(path);
for (dev = 0; dev_names[dev][0] != 0; dev++) {
sprintf(try, "/dev/%s", dev_names[dev]);
tl = strlen(try);
if (strncmp(path, try, tl) != 0)
continue;
l -= tl;
for (i = 0; i < Libburn_netbsd_max_cdnuM; i++) {
sprintf(try + tl, "%d", i);
if (strncmp(path, try, strlen(try)) == 0)
break;
}
if (i >= Libburn_netbsd_max_cdnuM)
continue;
tl += strlen(try + tl);
if (l == tl)
return 1;
if (l > tl + 1)
continue;
if (path[l - 1] >= 'a' && path[l - 1] <= 'z')
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 write_start, off_t *bytes)
{
struct stat stbuf;
int ret;
#ifdef Libburn_os_has_statvfS
struct statvfs vfsbuf;
#endif
char *testpath = NULL, *cpt;
off_t add_size = 0;
BURN_ALLOC_MEM(testpath, char, 4096);
testpath[0] = 0;
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)
{ret = -1; goto ex;}
} else if(S_ISBLK(stbuf.st_mode)) {
int open_mode = O_RDONLY, fd;
fd = open(path, open_mode);
if (fd == -1)
{ret = -2; goto ex;}
*bytes = lseek(fd, 0, SEEK_END);
if (*bytes <= 0)
guess_size_by_seek_set(fd, bytes, 0);
close(fd);
if (*bytes == -1) {
*bytes = 0;
{ret = 0; goto ex;}
}
} else if(S_ISREG(stbuf.st_mode)) {
add_size = burn_sparse_file_addsize(write_start, &stbuf);
strcpy(testpath, path);
} else
{ret = 0; goto ex;}
if (testpath[0]) {
#ifdef Libburn_os_has_statvfS
if (statvfs(testpath, &vfsbuf) == -1)
{ret = -2; goto ex;}
*bytes = add_size + ((off_t) vfsbuf.f_frsize) *
(off_t) vfsbuf.f_bavail;
#else /* Libburn_os_has_statvfS */
{ret = 0; goto ex;}
#endif /* ! Libburn_os_has_stavtfS */
}
ret = 1;
ex:;
BURN_FREE_MEM(testpath);
return ret;
}
/* 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;
}

View File

@ -1,7 +1,7 @@
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
/*
Copyright (c) 2010 - 2014 Thomas Schmitt <scdbackup@gmx.net>
Copyright (c) 2010 - 2011 Thomas Schmitt <scdbackup@gmx.net>
Provided under GPL version 2 or later.
*/
@ -78,7 +78,7 @@ burn_os_is_2k_seekrw() tells whether the given path leads to a file object
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 offers best
burn_os_open_track_src() opens a disk file in a way that allows best
throughput with file reading and/or SCSI write command
transmission.
@ -116,7 +116,6 @@ Send feedback to libburn-hackers@pykix.org .
#include <sys/statvfs.h>
#endif /* Libburn_os_has_stavtfS */
#include <volmgt.h>
#include <sys/dkio.h>
#include <sys/vtoc.h>
@ -201,13 +200,13 @@ static int decode_btl_number(char **cpt, int stopper, int *no)
}
/* Read bus, target, lun from name "cXtYdZs2" or "cXtYdZ/...".
/* 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, *cpt_mem;
char *cpt;
int ret;
*busno = *tgtno = *lunno = -1;
@ -220,15 +219,9 @@ static int decode_btl_solaris(char *name, int *busno, int *tgtno, int *lunno,
ret = decode_btl_number(&cpt, 'd', tgtno);
if (ret <= 0)
return ret;
cpt_mem = cpt;
ret = decode_btl_number(&cpt, 's', lunno);
if (ret <= 0) {
cpt = cpt_mem;
ret = decode_btl_number(&cpt, '/', lunno);
if (ret <= 0)
return ret;
return(1);
}
if (ret <= 0)
return ret;
cpt++;
if (*cpt != '2' || *(cpt + 1) != 0)
return 0;
@ -254,64 +247,16 @@ static int start_enum_cXtYdZs2(burn_drive_enumerator_t *idx, int flag)
}
static int sg_solaris_convert_devname(char *path, char **dev_to_open, int flag)
{
char *sym_name = NULL, *media_name = NULL, *curr_name, *msg = NULL;
int ret;
BURN_ALLOC_MEM(msg, char, 4096);
BURN_FREE_MEM(*dev_to_open);
*dev_to_open = NULL;
curr_name = path;
if (! volmgt_running())
goto set_name;
sym_name = volmgt_symname(path);
sprintf(msg, "Volume Management symbolic name: '%s' -> %s",
path, sym_name == NULL ? "NULL" : sym_name);
libdax_msgs_submit(libdax_messenger, -1,
0x00000002,
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH,
msg, 0, 0);
if (sym_name != NULL)
media_name = media_findname(sym_name);
else
media_name = media_findname(path);
if (media_name != NULL)
curr_name = media_name;
sprintf(msg, "Media name: %s -> %s",
sym_name == NULL ? path : sym_name,
media_name == NULL ? "NULL" : media_name);
libdax_msgs_submit(libdax_messenger, -1,
0x00000002,
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH,
msg, 0, 0);
set_name:
BURN_ALLOC_MEM(*dev_to_open, char, strlen(curr_name) + 1);
strcpy(*dev_to_open, curr_name);
ret = 1;
ex:
if (media_name != NULL)
free(media_name);
if (sym_name != NULL)
free(sym_name);
BURN_FREE_MEM(msg);
return(ret);
}
static int next_enum_cXtYdZs2(burn_drive_enumerator_t *idx,
char adr[], int adr_size, int flag)
{
int busno, tgtno, lunno, ret, fd = -1, volpath_size = 160, os_errno;
char *volpath = NULL, *msg = NULL, *dev_to_open = NULL;
int busno, tgtno, lunno, ret, fd = -1, volpath_size = 160;
char *volpath = NULL;
struct dirent *entry;
struct dk_cinfo cinfo;
DIR *dir;
BURN_ALLOC_MEM(volpath, char, volpath_size);
BURN_ALLOC_MEM(msg, char, 4096);
dir = idx->dir;
while (1) {
@ -337,68 +282,25 @@ static int next_enum_cXtYdZs2(burn_drive_enumerator_t *idx,
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;
ret = sg_solaris_convert_devname(volpath, &dev_to_open, 0);
if (ret <= 0)
continue;
fd = open(dev_to_open, O_RDONLY | O_NDELAY);
if (fd < 0) {
os_errno = errno;
sprintf(msg, "Could not open '%s' , errno = %d",
dev_to_open, os_errno);
libdax_msgs_submit(libdax_messenger, -1,
0x00000002,
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH,
msg, os_errno, 0);
continue;
}
/* See man dkio */
ret = ioctl(fd, DKIOCINFO, &cinfo);
close(fd);
if (ret < 0) {
os_errno = errno;
sprintf(msg,
"ioctl(DKIOCINFO) failed on drive '%s', errno = %d",
volpath, os_errno);
libdax_msgs_submit(libdax_messenger, -1,
0x00000002,
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH,
msg, os_errno, 0);
if (ret < 0)
continue;
}
if (cinfo.dki_ctype != DKC_CDROM) {
sprintf(msg,
"ioctl(DKIOCINFO) classifies drive '%s' as dki_ctype %ld, not as DKC_CDROM = %ld",
volpath, (long int) cinfo.dki_ctype,
(long int) DKC_CDROM);
libdax_msgs_submit(libdax_messenger, -1,
0x00000002,
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH,
msg, 0, 0);
if (cinfo.dki_ctype != DKC_CDROM)
continue;
}
if (adr_size <= (int) strlen(volpath)) {
sprintf(msg,
"Device path '%s' too long. (Max. %d)",
volpath, adr_size - 1);
libdax_msgs_submit(libdax_messenger, -1,
0x00000002,
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH,
msg, 0, 0);
if (adr_size <= (int) strlen(volpath))
{ret = -1; goto ex;}
}
strcpy(adr, volpath);
sprintf(msg, "Accepted as valid drive '%s'", volpath);
libdax_msgs_submit(libdax_messenger, -1,
0x00000002,
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH,
msg, 0, 0);
{ret = 1; goto ex;}
}
ret = 0;
ex:;
BURN_FREE_MEM(dev_to_open);
BURN_FREE_MEM(msg);
BURN_FREE_MEM(volpath);
return ret;
}
@ -590,7 +492,7 @@ ex:;
/** 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 and reservation.
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)
@ -607,7 +509,7 @@ int sg_drive_is_open(struct burn_drive * d)
*/
int sg_grab(struct burn_drive *d)
{
char *msg = NULL, *dev_to_open = NULL;
char *msg = NULL;
int os_errno, ret;
struct dk_cinfo cinfo;
@ -617,16 +519,10 @@ int sg_grab(struct burn_drive *d)
d->released = 0;
{ret = 1; goto ex;}
}
ret = sg_solaris_convert_devname(d->devname, &dev_to_open, 0);
if (ret <= 0)
goto ex;
d->fd = open(dev_to_open, O_RDONLY | O_NDELAY);
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);
if (strcmp(d->devname, dev_to_open))
sprintf(msg + strlen(msg), " via '%s'", dev_to_open);
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,
@ -634,27 +530,10 @@ int sg_grab(struct burn_drive *d)
{ret = 0; goto ex;}
}
ret = ioctl(d->fd, DKIOCINFO, &cinfo);
if (ret < 0) {
os_errno = errno;
sprintf(msg, "ioctl(DKIOCINFO) failed on drive '%s'",
d->devname);
libdax_msgs_submit(libdax_messenger, d->global_index,
0x00000002,
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH,
msg, os_errno, 0);
if (ret < 0)
goto revoke;
}
if (cinfo.dki_ctype != DKC_CDROM) {
sprintf(msg,
"ioctl(DKIOCINFO) classifies drive '%s' as dki_ctype %ld, not as DKC_CDROM = %ld",
d->devname, (long int) cinfo.dki_ctype,
(long int) DKC_CDROM);
libdax_msgs_submit(libdax_messenger, d->global_index,
0x00000002,
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH,
msg, 0, 0);
if (cinfo.dki_ctype != DKC_CDROM)
goto revoke;
}
/* >>> obtain eventual locks */;
@ -669,7 +548,6 @@ revoke:;
msg, 0, 0);
ret = 0;
ex:;
BURN_FREE_MEM(dev_to_open);
BURN_FREE_MEM(msg);
return ret;
}
@ -759,12 +637,8 @@ int sg_issue_command(struct burn_drive *d, struct command *c)
for(i = 0; !done; i++) {
memset(c->sense, 0, sizeof(c->sense));
c->start_time = burn_get_time(0);
ret = ioctl(d->fd, USCSICMD, &cgc);
c->end_time = burn_get_time(0);
/* For cgc.uscsi_status see SAM-3 5.3.1, Table 22
0 = GOOD , 2 = CHECK CONDITION : Sense Data are delivered
8 = BUSY
@ -795,8 +669,8 @@ int sg_issue_command(struct burn_drive *d, struct command *c)
sense_len = 18;
else
sense_len = 0;
done = scsi_eval_cmd_outcome(d, c, fp, c->sense, sense_len,
start_time, timeout_ms, i, 0);
done = scsi_eval_cmd_outcome(d, c, fp, c->sense, sense_len, 0,
start_time, timeout_ms, i, 2);
if (d->cancel)
done = 1;
@ -907,7 +781,7 @@ int burn_os_is_2k_seekrw(char *path, int flag)
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 write_start, off_t *bytes)
int burn_os_stdio_capacity(char *path, off_t *bytes)
{
struct stat stbuf;
int ret;
@ -948,7 +822,7 @@ int burn_os_stdio_capacity(char *path, off_t write_start, off_t *bytes)
}
} else if(S_ISREG(stbuf.st_mode)) {
add_size = burn_sparse_file_addsize(write_start, &stbuf);
add_size = stbuf.st_blocks * (off_t) 512;
strcpy(testpath, path);
} else
{ret = 0; goto ex;}

View File

@ -1,7 +1,7 @@
/* sg.c
Switcher for operating system dependent transport level modules of libburn.
Copyright (C) 2009 - 2014 Thomas Schmitt <scdbackup@gmx.net>,
Copyright (C) 2009 - 2010 Thomas Schmitt <scdbackup@gmx.net>,
provided under GPLv2+
*/
@ -11,12 +11,6 @@
#endif
/* <<< Until it is known whether this adapter would work on OpenBSD too */
#ifdef __NetBSD__
#define Libburn_use_sg_netbsD
#endif
#ifdef Libburn_use_sg_dummY
#include "sg-dummy.c"
@ -26,12 +20,6 @@
#include "sg-libcdio.c"
#else
#ifdef Libburn_use_sg_netbsD
/* To become: # ifdef __NetBSD__ */
#include "sg-netbsd.c"
#else
#ifdef __FreeBSD__
@ -70,13 +58,11 @@
static int intentional_compiler_warning(void)
{
int INTENTIONAL_COMPILER_WARNING_;
int Cannot_recognize_supported_operating_system_;
int Like_GNU_Linux_or_FreeBSD_or_Solaris_or_NetBSD_;
int Cannot_recognize_GNU_Linux_nor_FreeBSD_nor_Solaris_;
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 Like_GNU_Linux_or_FreeBSD_or_Solaris_or_NetBSD;
int Cannot_recognize_supported_operating_system;
int Cannot_recognize_GNU_Linux_nor_FreeBSD_nor_Solaris;
int INTENTIONAL_COMPILER_WARNING;
return(0);
@ -88,7 +74,6 @@ static int intentional_compiler_warning(void)
#endif /* ! __linux */
#endif /* ! __FreeBSD_kernel__ */
#endif /* ! __FreeBSD__ */
#endif /* ! Libburn_use_sg_netbsD */
#endif /* ! Libburn_use_libcdiO */
#endif /* ! Libburn_use_sg_dummY */

View File

@ -36,7 +36,7 @@ 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 write_start, 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

View File

@ -1,7 +1,7 @@
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
Copyright (c) 2006 - 2014 Thomas Schmitt <scdbackup@gmx.net>
Copyright (c) 2006 - 2012 Thomas Schmitt <scdbackup@gmx.net>
Provided under GPL version 2 or later.
*/
@ -33,7 +33,6 @@
#include "debug.h"
#include "options.h"
#include "init.h"
#include "util.h"
#include "libdax_msgs.h"
extern struct libdax_msgs *libdax_messenger;
@ -59,10 +58,6 @@ static unsigned char SPC_MODE_SELECT[] = { 0x55, 16, 0, 0, 0, 0, 0, 0, 0, 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 };
#ifdef Libburn_enable_scsi_cmd_ABh
static unsigned char SPC_READ_MEDIA_SERIAL_NUMBER[] =
{ 0xAB, 0x01, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
#endif
/* ts A70519 : An initializer for the abstract SCSI command structure */
int scsi_init_command(struct command *c, unsigned char *opcode, int oplen)
@ -128,7 +123,7 @@ int spc_test_unit_ready_r(struct burn_drive *d, int *key, int *asc, int *ascq,
((c->sense[2] & 0x0f) == 0 || (c->sense[2] & 0x0f) == 2) &&
(c->sense[15] & 0x80))
*progress = (c->sense[16] << 8) + c->sense[17];
return (*key == 0);
return (key == 0);
}
return 1;
}
@ -265,34 +260,7 @@ void spc_request_sense(struct burn_drive *d, struct buffer *buf)
d->issue_command(d, c);
}
static int spc_report_async_error(struct burn_drive *d,
int key, int asc, int ascq, int flag)
{
char *msg = NULL;
unsigned char sense[14];
int ret;
BURN_ALLOC_MEM(msg, char, BURN_DRIVE_ADR_LEN + 160);
sprintf(msg, "Asynchronous SCSI error : ");
sense[0] = 0x70; /* Fixed format sense data */
sense[2] = key;
sense[12] = asc;
sense[13] = ascq;
scsi_error_msg(d, sense, 14, msg + strlen(msg), &key, &asc, &ascq);
libdax_msgs_submit(libdax_messenger, d->global_index,
0x000201a5,
LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH,
msg, 0, 0);
ret = 1;
ex:;
BURN_FREE_MEM(msg);
return ret;
}
/* @return -3 = other error reported
-2 = drive is ready ,
-1 = not ready, but no progress reported ,
/* @return -2 = drive is ready , -1 = not ready, but no progress reported
>= 0 progress indication between 0 and 65535
*/
int spc_get_erase_progress(struct burn_drive *d)
@ -310,14 +278,6 @@ int spc_get_erase_progress(struct burn_drive *d)
ret = spc_test_unit_ready_r(d, &key, &asc, &ascq, &progress);
if (ret > 0)
{ret = -2; goto ex;}
/* Check key, asc, ascq for errors other than "not yet ready" */
if (key != 0 &&
(key != 0x2 || asc != 0x04 || ascq == 0x02 || ascq ==0x03)) {
spc_report_async_error(d, key, asc, ascq, 0);
ret= -3; goto ex;
}
if (progress >= 0)
{ret = progress; goto ex;}
@ -356,8 +316,6 @@ void spc_inquiry(struct burn_drive *d)
c->dir = FROM_DRIVE;
d->issue_command(d, c);
id = (struct burn_scsi_inquiry_data *)d->idata;
id->peripheral = 0x7f; /* SPC-3: incabable undefined peripheral type */
id->version = 0; /* SPC-3: no claim for conformance */
memset(id->vendor, 0, 9);
memset(id->product, 0, 17);
memset(id->revision, 0, 5);
@ -365,8 +323,6 @@ void spc_inquiry(struct burn_drive *d)
id->valid = -1;
goto ex;
}
id->peripheral = ((char *) c->page->data)[0];
id->version = ((char *) c->page->data)[2];
memcpy(id->vendor, c->page->data + 8, 8);
memcpy(id->product, c->page->data + 16, 16);
memcpy(id->revision, c->page->data + 32, 4);
@ -410,39 +366,10 @@ void spc_allow(struct burn_drive *d)
d->issue_command(d, c);
}
/* ts B40216 : Outsourced from spc_sense_caps_al().
To be called by spc_sense_caps() after spc_sense_caps_al()
*/
static int spc_try_get_performance(struct burn_drive *d, int flag)
{
int ret;
struct burn_feature_descr *feature_descr;
/* ts B40107 : Feature 0x107 announces availability of GET PERFORMANCE
Its WSPD bit announces Type 3.
Try this even if the feature is not current.
*/
ret = burn_drive_has_feature(d, 0x107, &feature_descr, 0);
if (ret <= 0)
return ret;
if (feature_descr->data_lenght <= 0)
return 1;
if (feature_descr->data[0] & 2) /* WSPD */
ret = mmc_get_write_performance(d);
/* Get read performance */
mmc_get_performance(d, 0x00, 0);
return 1;
}
/*
ts A70518 - A90603 : Do not call with *alloc_len < 10
*/
/** @param flag bit0= do only inquire alloc_len
@return 1=ok , <=0 error ,
2=Block Descriptor Length > 0, retry with flag bit1
*/
/** flag&1= do only inquire alloc_len */
static int spc_sense_caps_al(struct burn_drive *d, int *alloc_len, int flag)
{
struct buffer *buf = NULL;
@ -466,7 +393,7 @@ static int spc_sense_caps_al(struct burn_drive *d, int *alloc_len, int flag)
/* ts A90602 : Clearing mdata before command execution */
m = d->mdata;
m->p2a_valid = 0;
m->valid = 0;
burn_mdata_free_subs(m);
memset(buf, 0, sizeof(struct buffer));
@ -483,7 +410,7 @@ static int spc_sense_caps_al(struct burn_drive *d, int *alloc_len, int flag)
d->issue_command(d, c);
if (c->error) {
memset(buf, 0, sizeof(struct buffer));
m->p2a_valid = -1;
m->valid = -1;
was_error = 1;
}
@ -492,22 +419,6 @@ static int spc_sense_caps_al(struct burn_drive *d, int *alloc_len, int flag)
*/
block_descr_len = c->page->data[6] * 256 + c->page->data[7];
if (block_descr_len + 8 + 2 > *alloc_len) {
if (block_descr_len + 8 + 2 > BUFFER_SIZE || !(flag & 1)) {
m->p2a_valid = -1;
sprintf(msg,
"MODE SENSE page 2A with oversized Block Descriptors: %s : %d",
d->devname, block_descr_len);
libdax_msgs_submit(libdax_messenger, d->global_index,
0x0002016e, LIBDAX_MSGS_SEV_DEBUG,
LIBDAX_MSGS_PRIO_LOW, msg, 0, 0);
{ret = 0; goto ex;}
}
*alloc_len = block_descr_len + 10;
{ret = 2; goto ex;}
}
/* Skip over Mode Data Header and block descriptors */
page = c->page->data + 8 + block_descr_len;
@ -526,7 +437,7 @@ static int spc_sense_caps_al(struct burn_drive *d, int *alloc_len, int flag)
*/
page_length = page[1];
old_alloc_len = *alloc_len;
*alloc_len = page_length + 10 + block_descr_len;
*alloc_len = page_length + 10;
if (flag & 1)
{ret = !was_error; goto ex;}
if (page_length + 10 > old_alloc_len)
@ -535,7 +446,7 @@ static int spc_sense_caps_al(struct burn_drive *d, int *alloc_len, int flag)
/* ts A90602 : page_length N asserts page[N+1]. (see SPC-1 8.3.3) */
/* ts B11031 : qemu drive has a page_length of 18 */
if (page_length < 18) {
m->p2a_valid = -1;
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,
@ -577,11 +488,13 @@ static int spc_sense_caps_al(struct burn_drive *d, int *alloc_len, int flag)
m->max_end_lba = 0;
if (!was_error)
m->p2a_valid = 1;
m->valid = 1;
mmc_get_configuration(d);
/* ts A61225 : end of MMC-1 , begin of MMC-3 */
if (page_length < 30) /* no write speed descriptors ? */
goto no_speed_descriptors;
goto try_mmc_get_performance;
m->cur_write_speed = page[28] * 256 + page[29];
@ -635,7 +548,24 @@ static int spc_sense_caps_al(struct burn_drive *d, int *alloc_len, int flag)
"LIBBURN_DEBUG: 5Ah,2Ah min_write_speed = %d , max_write_speed = %d\n",
m->min_write_speed, m->max_write_speed);
no_speed_descriptors:;
try_mmc_get_performance:;
if (m->cdrw_write || page_length >= 32) {
/* ts A90823:
One has to avoid U3 enhanced memory sticks here. On my
SuSE 10.2 a SanDisk Cruzer 4GB stalls at the second occasion
of ACh GET PERFORMANCE. (The first one is obviously called
by the OS at plug time.)
This pseudo drive returns no write capabilities and a page
length of 28. MMC-3 describes page length 32. Regrettably
MMC-2 prescribes a page length of 26. Here i have to trust
m->cdrw_write to reliably indicate any MMC-2 burner.
*/
ret = mmc_get_write_performance(d);
if (ret > 0 && speed_debug)
fprintf(stderr,
"LIBBURN_DEBUG: ACh min_write_speed = %d , max_write_speed = %d\n",
m->min_write_speed, m->max_write_speed);
}
ret = !was_error;
ex:
@ -654,19 +584,13 @@ void spc_sense_caps(struct burn_drive *d)
if (mmc_function_spy(d, "sense_caps") <= 0)
return;
mmc_get_configuration(d);
/* first command execution to learn Allocation Length */
alloc_len = start_len;
ret = spc_sense_caps_al(d, &alloc_len, 1);
if (ret == 2) {
/* ts B40205: Unexpectedly found Block Descriptors.
Repeat with new alloc_len.
*/
ret = spc_sense_caps_al(d, &alloc_len, 1);
if (ret == 2)
goto try_get_performance;
}
/*
fprintf(stderr,"LIBBURN_DEBUG: 5Ah alloc_len = %d , ret = %d\n",
alloc_len, ret);
*/
/* ts B11103:
qemu ATAPI DVD-ROM delivers only 28.
SanDisk Cruzer U3 memory stick throws error on alloc_len < 30.
@ -675,9 +599,6 @@ void spc_sense_caps(struct burn_drive *d)
if (alloc_len >= minimum_len && ret > 0)
/* second execution with announced length */
spc_sense_caps_al(d, &alloc_len, 0);
try_get_performance:;
spc_try_get_performance(d, 0);
}
@ -707,6 +628,7 @@ void spc_sense_error_params(struct burn_drive *d)
c->page->sectors = 0;
c->dir = FROM_DRIVE;
d->issue_command(d, c);
m = d->mdata;
page = c->page->data + 8;
d->params.retries = page[3];
@ -732,8 +654,6 @@ void spc_select_error_params(struct burn_drive *d,
scsi_init_command(c, SPC_MODE_SELECT, sizeof(SPC_MODE_SELECT));
c->retry = 1;
if (d->mdata->retry_page_valid <= 0)
d->mdata->retry_page_length = 0;
c->opcode[8] = 8 + 2 + d->mdata->retry_page_length;
c->page = buf;
c->page->bytes = 0;
@ -793,11 +713,9 @@ void spc_sense_write_params(struct burn_drive *d)
if (!c->error) {
page = c->page->data + 8;
m->write_page_length = page[1];
if (m->write_page_length > 0)
m->write_page_valid = 1;
else
m->write_page_length = 0x32;
}
m->write_page_valid = 1;
} else
m->write_page_valid = 0;
mmc_read_disc_info(d);
/* ts A70212 : try to setup d->media_capacity_remaining */
@ -895,109 +813,6 @@ ex:;
BURN_FREE_MEM(c);
}
#ifdef Libburn_enable_scsi_cmd_ABh
/* At least on Linux kernel 3.16 the command ABh causes EFAULT if not sent
from the superuser.
For a test it may be replaced by a dummy 28h READ12 on block 0.
This causes no EFAULT although it sets the wrong dxfer_len 4 rather
than 2048. So it is indeed a permission problem and not bad alignment.
*/
/* ts B51016 */
int spc_read_media_serial_number_al(struct burn_drive *d, int *alloc_len)
{
struct buffer *buf = NULL;
struct command *c = NULL;
unsigned char *data;
int ret;
if (*alloc_len < 4)
{ret = 0; goto ex;}
BURN_ALLOC_MEM(buf, struct buffer, 1);
BURN_ALLOC_MEM(c, struct command, 1);
if (mmc_function_spy(d, "spc_read_media_serial_number") <= 0)
{ret = 0; goto ex;}
/*
#de fine Spc_read_media_serial_number_dummY yes
*/
#ifdef Spc_read_media_serial_number_dummY
{
static unsigned char MMC_READ_12[] =
{ 0x28, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 };
scsi_init_command(c, MMC_READ_12, sizeof(MMC_READ_12));
c->dxfer_len = *alloc_len;
}
#else
scsi_init_command(c, SPC_READ_MEDIA_SERIAL_NUMBER,
sizeof(SPC_READ_MEDIA_SERIAL_NUMBER));
c->dxfer_len = *alloc_len;
/* (Will not accept more than 32 KB anyway) */
c->opcode[8] = (c->dxfer_len >> 8) & 0xff;
c->opcode[9] = c->dxfer_len & 0xff;
#endif /* ! Spc_read_media_serial_number_dummY */
c->retry = 1;
c->page = buf;
memset(c->page->data, 0, *alloc_len);
c->page->bytes = 0;
c->page->sectors = 0;
c->dir = FROM_DRIVE;
d->issue_command(d, c);
if (c->error)
{ret = 0; goto ex;}
data = c->page->data;
#ifdef Spc_read_media_serial_number_dummY
d->media_serial_number_len = 0;
#else
d->media_serial_number_len =
(data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[7];
#endif
if (*alloc_len >= d->media_serial_number_len + 4) {
if (d->media_serial_number != NULL)
BURN_FREE_MEM(d->media_serial_number);
BURN_ALLOC_MEM(d->media_serial_number, char,
d->media_serial_number_len + 1);
if (d->media_serial_number_len > 0)
memcpy(d->media_serial_number, data + 4,
d->media_serial_number_len);
d->media_serial_number[d->media_serial_number_len] = 0;
}
*alloc_len = d->media_serial_number_len + 4;
ret = 1;
ex:;
BURN_FREE_MEM(c);
BURN_FREE_MEM(buf);
return ret;
}
int spc_read_media_serial_number(struct burn_drive *d)
{
int alloc_len = 4, ret;
ret = spc_read_media_serial_number_al(d, &alloc_len);
if (alloc_len > 4 && alloc_len <= 0x8000 && ret > 0)
ret = spc_read_media_serial_number_al(d, &alloc_len);
return ret;
}
#endif /* Libburn_enable_scsi_cmd_ABh */
void spc_getcaps(struct burn_drive *d)
{
if (mmc_function_spy(d, "getcaps") <= 0)
@ -1203,14 +1018,8 @@ int burn_scsi_setup_drive(struct burn_drive *d, int bus_no, int host_no,
return -1;
}
d->idata->valid = 0;
d->mdata->p2a_valid = 0;
d->mdata->max_read_speed = 0;
d->mdata->cur_read_speed = 0;
d->mdata->max_write_speed = 0;
d->mdata->cur_write_speed = 0;
d->mdata->valid = 0;
d->mdata->speed_descriptors = NULL;
d->mdata->write_page_length = 0x32;
d->mdata->write_page_valid = 0;
if (!(flag & 1)) {
ret = spc_setup_drive(d);
if (ret<=0)
@ -1470,12 +1279,6 @@ enum response scsi_error_msg(struct burn_drive *d, unsigned char *sense,
else
break;
goto return_fail;
case 0x32:
if (*ascq == 0)
sprintf(msg, "No defect spare location available");
else
break;
goto return_fail;
case 0x3A:
if (*ascq == 0)
sprintf(msg, "Medium not present");
@ -1503,14 +1306,6 @@ enum response scsi_error_msg(struct burn_drive *d, unsigned char *sense,
else
break;
goto return_fail;
case 0x51:
if (*ascq == 0)
sprintf(msg, "Erase failure");
else if (*ascq == 1)
sprintf(msg, "Erase failure. Incomplete erase operation");
else
break;
goto return_fail;
case 0x57:
if (*ascq == 0)
sprintf(msg, "Unable to recover Table-of-Content");
@ -1661,8 +1456,6 @@ static char *scsi_command_name(unsigned int c, int flag)
return "BLANK";
case 0xaa:
return "WRITE(12)";
case 0xab:
return "READ MEDIA SERIAL NUMBER";
case 0xac:
return "GET PERFORMANCE";
case 0xad:
@ -1698,7 +1491,7 @@ int scsi_notify_error(struct burn_drive *d, struct command *c,
int key= -1, asc= -1, ascq= -1, ret;
char *msg = NULL, *scsi_msg = NULL;
if (d->silent_on_scsi_error == 1 || d->silent_on_scsi_error == 2)
if (d->silent_on_scsi_error)
{ret = 1; goto ex;}
BURN_ALLOC_MEM(msg, char, 320);
@ -1723,8 +1516,7 @@ int scsi_notify_error(struct burn_drive *d, struct command *c,
scsi_command_name((unsigned int) c->opcode[0], 0));
strcat(msg, scsi_msg);
ret = libdax_msgs_submit(libdax_messenger, d->global_index, 0x0002010f,
(flag & 2) && d->silent_on_scsi_error != 3 ?
LIBDAX_MSGS_SEV_FAILURE : LIBDAX_MSGS_SEV_DEBUG,
flag & 2 ? LIBDAX_MSGS_SEV_FAILURE : LIBDAX_MSGS_SEV_DEBUG,
LIBDAX_MSGS_PRIO_HIGH, msg,0,0);
ex:;
BURN_FREE_MEM(msg);
@ -1753,12 +1545,12 @@ int scsi_show_command(unsigned char *opcode, int oplen, int dir,
if (flag & 1)
return 1;
if (opcode[0] == 0x2A) { /* WRITE 10 */
if ((flag & 2) && oplen > 8)
if (flag & 2)
fprintf(fp, "%d -> %d\n",
(opcode[7] << 8) | opcode[8],
mmc_four_char_to_int(opcode + 2));
} else if (opcode[0] == 0xAA) { /* WRITE 12 */
if ((flag & 2) && oplen > 9)
if (flag & 2)
fprintf(fp, "%d -> %d\n",
mmc_four_char_to_int(opcode + 6),
mmc_four_char_to_int(opcode + 2));
@ -1833,24 +1625,6 @@ int scsi_log_command(unsigned char *opcode, int oplen, int data_dir,
}
/* ts B40731 */
/* Arbitrary SCSI log message */
int scsi_log_text(char *text, void *fp_in, int flag)
{
FILE *fp = fp_in;
if (fp != NULL && (fp == stderr || (burn_sg_log_scsi & 1))) {
fprintf(fp, "%s\n", text);
if (burn_sg_log_scsi & 4)
fflush(fp);
}
if (fp == stderr || !(burn_sg_log_scsi & 2))
return 1;
fprintf(stderr, "%s\n", text);
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)
@ -1875,8 +1649,9 @@ int scsi_log_cmd(struct command *c, void *fp_in, int flag)
*/
int scsi_log_reply(unsigned char *opcode, int data_dir, unsigned char *data,
int dxfer_len, void *fp_in, unsigned char sense[18],
int sense_len, double duration, int flag)
int sense_len, int duration, int flag)
{
char durtxt[20];
FILE *fp = fp_in;
int key, asc, ascq, i, l;
@ -1885,25 +1660,27 @@ int scsi_log_reply(unsigned char *opcode, int data_dir, unsigned char *data,
l = 18;
if ((sense[0] & 0x7f) == 0x72 ||
(sense[0] & 0x7f) == 0x73)
l = sense[7] + 7 + 1; /* SPC-3 4.5.2. */
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\n",
fprintf(fp, "+++ key=%X asc=%2.2Xh ascq=%2.2Xh%s\n",
(unsigned int) key, (unsigned int) asc,
(unsigned int) ascq);
(unsigned int) ascq, durtxt);
} else {
scsi_show_command_reply(opcode, data_dir, data,
dxfer_len, fp, 0);
if (!(flag & 2))
fprintf(fp,"%6d ms\n", duration);
}
if (!(flag & 2))
fprintf(fp, " %8.f us [ %.f ]\n",
duration * 1.0e6,
(burn_get_time(0) - lib_start_time) * 1.0e6);
if (burn_sg_log_scsi & 4)
fflush(fp);
}
@ -1921,38 +1698,19 @@ int scsi_log_reply(unsigned char *opcode, int data_dir, unsigned char *data,
@param flag bit0 causes an error message
bit1 do not print duration
*/
int scsi_log_err(struct burn_drive *d, struct command *c,
void *fp_in, unsigned char sense[18],
int sense_len, int flag)
int scsi_log_err(struct command *c, void *fp_in, unsigned char sense[18],
int sense_len, int duration, int flag)
{
int ret;
unsigned char *data = NULL;
if (c->page != NULL)
data = c->page->data;
ret= scsi_log_reply(c->opcode, c->dir, data, c->dxfer_len ,
fp_in, sense, sense_len,
c->end_time - c->start_time, flag);
fp_in, sense, sense_len, duration, flag);
return ret;
}
/* ts B31112 */
int scsi_log_message(struct burn_drive *d, void *fp_in, char * msg, int flag)
{
int ret;
FILE *fp = fp_in;
if (fp != NULL && (fp == stderr || (burn_sg_log_scsi & 1))) {
fprintf(fp, "%s\n", msg);
if (burn_sg_log_scsi & 4)
fflush(fp);
}
if (fp == stderr || !(burn_sg_log_scsi & 2))
return 1;
ret = scsi_log_message(d, stderr, msg, flag);
return ret;
}
/* ts B00808 */
/*
@ -1962,7 +1720,7 @@ int scsi_log_message(struct burn_drive *d, void *fp_in, char * msg, int flag)
*/
int scsi_eval_cmd_outcome(struct burn_drive *d, struct command *c, void *fp,
unsigned char *sense, int sense_len,
time_t start_time, int timeout_ms,
int duration, time_t start_time, int timeout_ms,
int loop_count, int flag)
{
enum response outcome;
@ -1970,7 +1728,7 @@ int scsi_eval_cmd_outcome(struct burn_drive *d, struct command *c, void *fp,
char *msg = NULL;
if (burn_sg_log_scsi & 3)
scsi_log_err(d, c, fp, sense, sense_len,
scsi_log_err(c, fp, sense, sense_len, duration,
(sense_len > 0) | (flag & 2));
if (sense_len <= 0)
{done = 1; goto ex;}
@ -2028,34 +1786,3 @@ ex:;
BURN_FREE_MEM(msg);
return done;
}
int spc_confirm_cd_drive(struct burn_drive *d, int flag)
{
char *msg = NULL;
int ret;
BURN_ALLOC_MEM(msg, char, strlen(d->devname) + 1024);
spc_inquiry(d);
if (d->idata->valid < 0) {
sprintf(msg, "INQUIRY failed with drive '%s'", d->devname);
libdax_msgs_submit(libdax_messenger, -1, 0x0002000a,
LIBDAX_MSGS_SEV_FAILURE,
LIBDAX_MSGS_PRIO_HIGH, msg, 0,0);
ret = 0; goto ex;
}
if (d->idata->peripheral != 0x5) {
sprintf(msg, "Does not identify itself as CD-ROM drive '%s'",
d->devname);
libdax_msgs_submit(libdax_messenger, -1, 0x0002000a,
LIBDAX_MSGS_SEV_FAILURE,
LIBDAX_MSGS_PRIO_HIGH, msg, 0,0);
ret = 0; goto ex;
}
ret = 1;
ex:;
BURN_FREE_MEM(msg);
return ret;
}

View File

@ -1,7 +1,7 @@
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
Copyright (c) 2006 - 2014 Thomas Schmitt <scdbackup@gmx.net>
Copyright (c) 2006 - 2012 Thomas Schmitt <scdbackup@gmx.net>
Provided under GPL version 2 or later.
*/
@ -23,11 +23,6 @@ void spc_sense_write_params(struct burn_drive *);
void spc_select_write_params(struct burn_drive *,
struct burn_session *, int,
const struct burn_write_opts *);
#ifdef Libburn_enable_scsi_cmd_ABh
int spc_read_media_serial_number(struct burn_drive *d);
#endif
void spc_probe_write_modes(struct burn_drive *);
void spc_request_sense(struct burn_drive *d, struct buffer *buf);
int spc_block_type(enum burn_block_types b);
@ -81,10 +76,6 @@ int scsi_log_command(unsigned char *opcode, int oplen, int data_dir,
unsigned char *data, int bytes,
void *fp_in, int flag);
/* ts B40731 */
/* Arbitrary SCSI log message */
int scsi_log_text(char *text, void *fp_in, int flag);
/* ts A91218 (former sg_log_cmd ts A70518) */
/** Legacy frontend to scsi_log_command() */
int scsi_log_cmd(struct command *c, void *fp, int flag);
@ -96,19 +87,15 @@ int scsi_log_cmd(struct command *c, void *fp, int flag);
*/
int scsi_log_reply(unsigned char *opcode, int data_dir, unsigned char *data,
int dxfer_len, void *fp_in, unsigned char sense[18],
int sense_len, double duration, int flag);
int sense_len, int duration, int flag);
/* ts A91221 (former sg_log_err ts A91108) */
/** Legacy frontend to scsi_log_reply().
@param flag bit0 causes an error message
bit1 do not print duration
*/
int scsi_log_err(struct burn_drive *d, struct command *c,
void *fp, unsigned char sense[18],
int sense_len, int flag);
/* ts B31112 */
int scsi_log_message(struct burn_drive *d, void *fp, char * msg, int flag);
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,
@ -122,14 +109,9 @@ int spc_decode_sense(unsigned char *sense, int senselen,
*/
int scsi_eval_cmd_outcome(struct burn_drive *d, struct command *c, void *fp_in,
unsigned char *sense, int sense_len,
time_t start_time, int timeout_ms,
int duration, time_t start_time, int timeout_ms,
int loop_count, int flag);
/* ts B40204 */
/* Verify by INQUIRY that the drive is indeed a MMC device.
*/
int spc_confirm_cd_drive(struct burn_drive *d, int flag);
/* The waiting time before eventually retrying a failed SCSI command.
Before each retry wait Libburn_scsi_retry_incR longer than with

View File

@ -1,6 +1,6 @@
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
Copyright (c) 2006 - 2014 Thomas Schmitt <scdbackup@gmx.net>
Copyright (c) 2006 - 2012 Thomas Schmitt <scdbackup@gmx.net>
Provided under GPL version 2 or later.
*/
@ -21,11 +21,6 @@
#include <unistd.h>
#include <errno.h>
/* ts B41126 : O_BINARY is needed for Cygwin but undefined elsewhere */
#ifndef O_BINARY
#define O_BINARY 0
#endif
#include "libburn.h"
#include "structure.h"
#include "write.h"
@ -70,11 +65,6 @@ struct burn_disc *burn_disc_create(void)
d->refcnt = 1;
d->sessions = 0;
d->session = NULL;
#ifdef Libburn_disc_with_incomplete_sessioN
d->incomplete_sessions= 0;
#endif
return d;
}
@ -701,37 +691,10 @@ void burn_session_get_leadout_entry(struct burn_session *s,
struct burn_session **burn_disc_get_sessions(struct burn_disc *d, int *num)
{
#ifdef Libburn_disc_with_incomplete_sessioN
*num = d->sessions - d->incomplete_sessions;
#else
*num = d->sessions;
#endif
return d->session;
}
/* ts B30112 : API */
int burn_disc_get_incomplete_sessions(struct burn_disc *d)
{
#ifdef Libburn_disc_with_incomplete_sessioN
return d->incomplete_sessions;
#else
return 0;
#endif
}
struct burn_track **burn_session_get_tracks(struct burn_session *s, int *num)
{
*num = s->tracks;
@ -749,23 +712,10 @@ int burn_session_get_hidefirst(struct burn_session *session)
}
static void burn_track_info_high_read(unsigned char *data,
int *higest_readable)
{
int ret;
ret = mmc_four_char_to_int(data + 8) +
mmc_four_char_to_int(data + 24);
if (ret - 1> *higest_readable)
*higest_readable = ret - 1;
}
/* ts A80808 : Enhance CD toc to DVD toc */
int burn_disc_cd_toc_extensions(struct burn_drive *drive, int flag)
{
int sidx= 0, tidx= 0, ret, track_offset, alloc_len = 34;
int higest_readable = -1;
struct burn_toc_entry *entry, *prev_entry= NULL;
struct burn_disc *d;
/* ts A81126 : ticket 146 : There was a SIGSEGV in here */
@ -787,11 +737,11 @@ int burn_disc_cd_toc_extensions(struct burn_drive *drive, int flag)
ret = 1;
goto ex;
}
track_offset = burn_session_get_start_tno(d->session[0], 0);
if (track_offset <= 0)
track_offset = 1;
for (sidx = 0; sidx < d->sessions; sidx++) {
track_offset = burn_session_get_start_tno(d->session[sidx], 0);
if (track_offset <= 0)
track_offset = 1;
if (d->session[sidx] == NULL) {
sprintf(msg, "d->session[%d of %d] == NULL",
sidx, d->sessions);
@ -848,9 +798,6 @@ int burn_disc_cd_toc_extensions(struct burn_drive *drive, int flag)
((!drive->current_is_cd_profile) ||
ret < prev_entry->track_blocks - 2))
prev_entry->track_blocks = ret;
if (!drive->mr_capacity_trusted)
burn_track_info_high_read(
buf->data, &higest_readable);
}
prev_entry->extensions_valid |= 1;
}
@ -863,19 +810,6 @@ int burn_disc_cd_toc_extensions(struct burn_drive *drive, int flag)
prev_entry = entry;
}
}
if (!drive->mr_capacity_trusted) {
if (higest_readable == drive->media_read_capacity - 2) {
drive->media_read_capacity = higest_readable;
drive->mr_capacity_trusted = 1;
libdax_msgs_submit(libdax_messenger,
drive->global_index, 0x00000002,
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_ZERO,
"Corrected READ CAPACITY by READ TRACK INFORMATION. Assuming TAO.",
0, 0);
}
}
{ret = 1; goto ex;}
failure:
libdax_msgs_submit(libdax_messenger, -1, 0x0002015f,
@ -1455,7 +1389,7 @@ static int cue_open_audioxtr(char *path, struct burn_cue_file_cursor *crs,
ret= libdax_audioxtr_new(&xtr, path, 0);
if (ret <= 0)
goto ex;
return ret;
libdax_audioxtr_get_id(xtr, &fmt, &fmt_info, &num_channels,
&sample_rate, &bits_per_sample, &msb_first, 0);
if ((flag & 255) == 1) {
@ -1517,7 +1451,7 @@ static int cue_create_file_source(char *path, struct burn_cue_file_cursor *crs,
if (ret <= 0)
goto ex;
} else {
fd = open(path, O_RDONLY | O_BINARY);
fd = open(path, O_RDONLY);
if (fd == -1) {
sprintf(msg,
"In cue sheet: Cannot open FILE '%.4000s'",
@ -1676,7 +1610,7 @@ out_of_mem:;
if (crs->file_source != NULL) {
libdax_msgs_submit(libdax_messenger, -1, 0x00020192,
LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH,
"In cue sheet file: Multiple occurrences of FILE",
"In cue sheet file: Multiple occurences of FILE",
0, 0);
ret = 0; goto ex;
}
@ -2175,12 +2109,6 @@ ex:
tracks = burn_session_get_tracks(session, &num_tracks);
for (i = 0; i < num_tracks; i++)
burn_track_free(tracks[i]);
if(text_packs != NULL) {
if(*text_packs != NULL)
free(*text_packs);
*text_packs = NULL;
*num_packs = 0;
}
} else {
if (fifo != NULL) {
*fifo = crs->fifo;
@ -2190,8 +2118,6 @@ ex:
cue_crs_destroy(&crs, 0);
BURN_FREE_MEM(line);
BURN_FREE_MEM(msg);
if (fp != NULL)
fclose(fp);
return ret;
}

View File

@ -144,11 +144,6 @@ struct burn_disc
{
int sessions;
struct burn_session **session;
#ifdef Libburn_disc_with_incomplete_sessioN
int incomplete_sessions;
#endif
int refcnt;
};

View File

@ -1,7 +1,7 @@
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
Copyright (c) 2006 - 2016 Thomas Schmitt <scdbackup@gmx.net>
Copyright (c) 2006 - 2012 Thomas Schmitt <scdbackup@gmx.net>
Provided under GPL version 2 or later.
*/
@ -65,31 +65,19 @@ struct command
int retry;
struct buffer *page;
int timeout; /* milliseconds */
double start_time;
double end_time;
};
struct burn_scsi_inquiry_data
{
char peripheral; /* bit0-4: device type should be 5
bit5-7: qualifier must be 0 */
char version; /* should be 3 (SPC-1) to 5 (SPC-3) (or higher ?)
but is often 0. */
char vendor[9];
char product[17];
char revision[5];
int valid;
};
struct scsi_mode_data
{
int p2a_valid;
int buffer_size;
int dvdram_read;
int dvdram_write;
@ -101,13 +89,8 @@ struct scsi_mode_data
int cdr_read;
int cdr_write;
int simulate;
int c2_pointers;
int underrun_proof;
int max_read_speed;
int cur_read_speed;
int max_write_speed;
int cur_write_speed;
/* ts A61021 */
int min_write_speed;
@ -118,10 +101,15 @@ struct scsi_mode_data
int max_end_lba;
struct burn_speed_descriptor *speed_descriptors;
int cur_read_speed;
int cur_write_speed;
int retry_page_length;
int retry_page_valid;
int write_page_length;
int write_page_valid;
int c2_pointers;
int valid;
int underrun_proof;
};
@ -139,26 +127,6 @@ struct burn_format_descr {
};
/* ts B40106 : represents a Feature Descriptor as of mmc5r03c.pdf 5.2.2
There can be many of them. Thus a linked list.
*/
struct burn_feature_descr {
unsigned short feature_code;
unsigned char flags; /* bit0= current
bit1= persistent
bit2-5= version
*/
unsigned char data_lenght;
/* Additional bytes after the first 4 bytes of the descriptor */
unsigned char *data;
struct burn_feature_descr *next;
};
/** Gets initialized in enumerate_common() and burn_drive_register() */
struct burn_drive
{
@ -210,24 +178,12 @@ struct burn_drive
unsigned char all_profiles[256];
int num_profiles;
/* ts B40106 : All feature descriptors as read from drive */
struct burn_feature_descr *features;
/* ts A70128 : MMC-to-MMC feature info from 46h for DVD-RW.
Quite internal. Regard as opaque :)
*/
/* 1 = incremental recording available, 0 = not available */
int current_has_feat21h;
/* Some drives announce feature 21h on fast-blanked DVD-RW
although they cannot write them in Incremental mode.
0= does not look like the recent write run failed due to
Incremental on fast blanked DVD-RW
1= it seems to have happened
2= it seems to have happened with write address 0
*/
int was_feat21h_failure;
/* Link Size item number 0 from feature 0021h descriptor */
int current_feat21h_link_size;
@ -253,16 +209,6 @@ struct burn_drive
*/
int current_feat2fh_byte4;
/* ts B51016 : Result from feature 108h : Drive Serial Number
*/
char *drive_serial_number;
int drive_serial_number_len;
/* ts B51016 : Result from command AB READ MEDIA SERIAL NUMBER
*/
char *media_serial_number;
int media_serial_number_len;
/* ts B10524 : whether the damage bit was set for the future track.
bit0= damage bit , bit1= nwa valid bit
*/
@ -319,7 +265,6 @@ struct burn_drive
1= do not report errors
2= do not report errors which the libburn function indicates in
member .had_particular_error
3= report errors with severity DEBUG
*/
int silent_on_scsi_error;
@ -342,12 +287,6 @@ struct burn_drive
/* ts A90107 */
int state_of_last_session;
#ifdef Libburn_disc_with_incomplete_sessioN
/* ts B30112 */
int incomplete_sessions;
#endif
/* ts A70129 :
from 51h READ DISC INFORMATION Last Track Number in Last Session */
int last_track_no;
@ -369,11 +308,6 @@ struct burn_drive
0x7ffffff0 = 32 bit overflow, or unknown stdio size
*/
int media_read_capacity;
/* ts B60305 : Whether READ CAPACITY of CD is credible:
-1= no READ CAPACITY yet , 0= untrusted READ CAPACITY
1= READ CAPACITY confirmed or corrected by other commands
*/
int mr_capacity_trusted;
/* ts B10314 : Next Writeable Adress for drive_role == 5 */
int role_5_nwa;
@ -412,13 +346,6 @@ struct burn_drive
volatile int cancel;
volatile enum burn_drive_status busy;
/* During write runs, this points to a copy of the applied
struct burn_write_opts. Only read this underneath
burn_disc_write_sync() which removes the copy when done.
Especially do not read it from outside the write thread.
*/
struct burn_write_opts *write_opts;
/* ts A70929 */
pid_t thread_pid;
int thread_pid_valid;

View File

@ -1,6 +1,6 @@
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
Copyright (c) 2006 - 2013 Thomas Schmitt <scdbackup@gmx.net>
Copyright (c) 2006 - 2010 Thomas Schmitt <scdbackup@gmx.net>
Provided under GPL version 2 or later.
*/
@ -15,12 +15,6 @@
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
/* ts A80914 : This is unneeded. Version info comes from libburn.h.
#include "v ersion.h"
@ -177,7 +171,6 @@ char *burn_guess_manufacturer(int prf,
{"MCC", 8, "Mitsubishi Chemical Corporation"},
{"MCI", 8, "Mitsui Chemicals Inc."},
{"MEI", 3, "Panasonic Corporation"},
{"MILLEN", 8, "Millenniata Inc."},
{"MKM", 3, "Mitsubishi Kagaku Media Co."},
{"MMC", 8, "Mitsubishi Kagaku Media Co."},
{"MXL", 8, "Hitachi Maxell Ltd."},
@ -335,68 +328,3 @@ char *burn_printify(char *msg)
return msg;
}
/* ts B30521 */
void burn_int_to_lsb(int val, char *target)
{
unsigned char *buf;
buf = (unsigned char *) target;
buf[0] = val & 0xff;
buf[1] = (val >> 8) & 0xff;
buf[2] = (val >> 16) & 0xff;
buf[3] = (val >> 24) & 0xff;
}
/* ts B30609 */
double burn_get_time(int flag)
{
int ret;
struct timeval tv;
#ifdef Libburn_use_clock_gettime_monotoniC
#ifdef _POSIX_TIMERS
#ifdef _POSIX_MONOTONIC_CLOCK
/* Enable by
export CFLAGS=-DLibburn_use_clock_gettime_monotoniC
export LIBS=-lrt
./configure ... && make clean && make
*/
struct timespec tp;
ret = clock_gettime(CLOCK_MONOTONIC, &tp);
if (ret == 0)
return ((double) tp.tv_sec) + ((double) tp.tv_nsec) * 1.0e-9;
#endif /* _POSIX_MONOTONIC_CLOCK */
#endif /* _POSIX_TIMERS */
#endif /* Xorriso_use_clock_gettime_monotoniC */
ret = gettimeofday(&tv, NULL);
if (ret == 0)
return ((double) tv.tv_sec) + ((double) tv.tv_usec) * 1.0e-6;
return (double) time(NULL);
}
/* ts B40609 */
off_t burn_sparse_file_addsize(off_t write_start, struct stat *stbuf)
{
off_t add_size;
add_size = stbuf->st_blocks * (off_t) 512;
if (add_size < stbuf->st_size) {
/* Sparse file */
if (write_start < stbuf->st_size) {
/* Might write into sparse gaps */
if (write_start > add_size)
add_size = write_start;
} else {
/* Will not write into sparse area */
add_size = stbuf->st_size;
}
}
return add_size;
}

View File

@ -1,11 +1,6 @@
#ifndef __UTIL
#define __UTIL
/* for struct stat */
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
/* ts A90905 */
int burn_util_make_printable_word(char **text, int flag);
@ -13,13 +8,4 @@ int burn_util_make_printable_word(char **text, int flag);
char *burn_sfile_fgets(char *line, int maxl, FILE *fp);
char *burn_printify(char *msg);
/* ts B30521 */
void burn_int_to_lsb(int val, char *target);
/* ts B30609 */
double burn_get_time(int flag);
/* ts B40609 */
off_t burn_sparse_file_addsize(off_t write_start, struct stat *stbuf);
#endif

View File

@ -1,7 +1,7 @@
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
Copyright (c) 2006 - 2016 Thomas Schmitt <scdbackup@gmx.net>
Copyright (c) 2006 - 2012 Thomas Schmitt <scdbackup@gmx.net>
Provided under GPL version 2 or later.
*/
@ -38,11 +38,6 @@
#include <sys/stat.h>
#include <sys/time.h>
/* ts B41126 : O_BINARY is needed for Cygwin but undefined elsewhere */
#ifndef O_BINARY
#define O_BINARY 0
#endif
#include "error.h"
#include "sector.h"
#include "libburn.h"
@ -81,19 +76,11 @@ extern struct libdax_msgs *libdax_messenger;
/* The size to be used with BD-RE media in normal, not streamed mode.
*/
#define Libburn_bd_re_obS (64 * 1024)
#define Libburn_bd_re_obS (32 * 1024)
/* The size to be used with BD-R media in normal, not streamed mode.
/* The size to be used with BD-RE media in streamed mode.
*/
#define Libburn_bd_r_obS (64 * 1024)
/* The size to be used with BD-RE and BD-R media in streamed mode.
*/
#define Libburn_bd_streamed_obS (64 * 1024)
/* The number of retries if write(2) returns a short, non-negative write count.
*/
#define Libburn_stdio_write_retrieS 16
#define Libburn_bd_re_streamed_obS (64 * 1024)
static int type_to_ctrl(int mode)
@ -226,6 +213,8 @@ int burn_write_track_minsize(struct burn_write_opts *o, struct burn_session *s,
0x0002011a,
LIBDAX_MSGS_SEV_NOTE, LIBDAX_MSGS_PRIO_HIGH, msg,0,0);
step = BUFFER_SIZE / 4096; /* shall fit any sector size */
if (step <= 0)
step = 1;
seclen = burn_sector_length(t->mode);
if (seclen <= 0)
seclen = 2048;
@ -1108,7 +1097,7 @@ int burn_write_track(struct burn_write_opts *o, struct burn_session *s,
struct burn_drive *d = o->drive;
int i, tmp = 0, open_ended = 0, ret= 0, nwa, lba;
int sectors;
char msg[160];
char msg[80];
d->rlba = -150;
@ -1325,7 +1314,7 @@ int burn_disc_init_write_status(struct burn_write_opts *o,
{
struct burn_drive *d = o->drive;
struct burn_track *t = NULL;
int sx, tx, ret;
int sx, tx;
d->cancel = 0;
@ -1370,13 +1359,6 @@ int burn_disc_init_write_status(struct burn_write_opts *o,
if (o->fill_up_media && t != NULL)
burn_track_set_fillup(t, 1);
d->was_feat21h_failure = 0;
if(d->write_opts != NULL)
burn_write_opts_free(d->write_opts);
ret = burn_write_opts_clone(o, &(d->write_opts), 0);
if (ret <= 0)
return ret;
d->busy = BURN_DRIVE_WRITING;
return 1;
@ -1798,8 +1780,7 @@ static int transact_dvd_chunk(struct burn_write_opts *opts,
static int tee_fd= -1;
if(tee_fd==-1)
tee_fd= open("/tmp/libburn_sg_readin",
O_WRONLY | O_CREAT | O_TRUNC | O_BINARY,
S_IRUSR | S_IWUSR);
O_WRONLY|O_CREAT|O_TRUNC,S_IRUSR|S_IWUSR);
#endif /* Libburn_log_in_and_out_streaM */
@ -1880,7 +1861,7 @@ int burn_dvd_write_track(struct burn_write_opts *o,
struct burn_drive *d = o->drive;
struct buffer *out = d->buffer;
int sectors;
int i, open_ended = 0, ret= 0, is_flushed = 0, track_open = 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 */
@ -1908,7 +1889,6 @@ int burn_dvd_write_track(struct burn_write_opts *o,
if (ret <= 0)
goto ex;
}
track_open = 1;
sectors = burn_track_get_sectors_2(t, 1);
open_ended = burn_track_is_open_ended(t);
@ -1991,7 +1971,7 @@ int burn_dvd_write_track(struct burn_write_opts *o,
ex:;
if (d->cancel)
burn_source_cancel(t->source);
if (track_open && !is_flushed)
if (!is_flushed)
d->sync_cache(d); /* burn_write_flush() was not called */
return ret;
}
@ -2139,16 +2119,13 @@ int burn_dvd_write_session(struct burn_write_opts *o,
if (d->current_profile == 0x11 || d->current_profile == 0x14 ||
d->current_profile == 0x15) {
/* DVD-R , DVD-RW Sequential, DVD-R/DL Sequential */
/* If feature 21h failed on write 0: do not close session */
if (d->was_feat21h_failure != 2) {
multi_mem = o->multi;
if (!is_last_session)
o->multi = 1;
ret = burn_disc_close_session_dvd_minus_r(o);
o->multi = multi_mem;
if (ret <= 0)
return 0;
}
multi_mem = o->multi;
if (!is_last_session)
o->multi = 1;
ret = burn_disc_close_session_dvd_minus_r(o);
o->multi = multi_mem;
if (ret <= 0)
return 0;
} else if (d->current_profile == 0x12 || d->current_profile == 0x43) {
/* DVD-RAM , BD-RE */
/* ??? any finalization needed ? */;
@ -2329,7 +2306,7 @@ int burn_dvd_write_sync(struct burn_write_opts *o,
if (o->obs_pad < 2)
o->obs_pad = 1;
if (d->current_profile == 0x43) /* BD-RE */
o->obs = Libburn_bd_streamed_obS;
o->obs = Libburn_bd_re_streamed_obS;
}
} else if (d->current_profile == 0x13) {
@ -2407,12 +2384,10 @@ int burn_dvd_write_sync(struct burn_write_opts *o,
}
/* ??? padding needed ??? cowardly doing it for now */
if (o->obs_pad < 2)
o->obs_pad = 1; /* fill-up track's last obs buffer */
if (d->current_profile == 0x41) /* BD-R */
o->obs = Libburn_bd_r_obS;
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_streamed_obS;
o->obs = Libburn_bd_re_streamed_obS;
}
}
@ -2442,10 +2417,10 @@ int burn_dvd_write_sync(struct burn_write_opts *o,
if (d->do_stream_recording &&
(d->current_profile == 0x43 || d->current_profile == 0x41) &&
o->obs < Libburn_bd_streamed_obS) {
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 output buffer");
"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);
@ -2528,7 +2503,7 @@ int burn_stdio_open_write(struct burn_drive *d, off_t start_byte,
if (fd >= 0)
fd = dup(fd); /* check validity and make closeable */
else
fd = open(d->devname, mode | O_BINARY,
fd = open(d->devname, mode,
S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
if (fd == -1) {
libdax_msgs_submit(libdax_messenger, d->global_index,
@ -2583,41 +2558,29 @@ int burn_stdio_read_source(struct burn_source *source, char *buf, int bufsize,
int burn_stdio_write(int fd, char *buf, int count, struct burn_drive *d,
int flag)
{
int ret = 0;
int ret;
char *msg = NULL;
int todo, done, retries;
if (d->cancel || count <= 0)
if (d->cancel)
return 0;
todo = count;
done = 0;
for (retries = 0; todo > 0 && retries <= Libburn_stdio_write_retrieS;
retries++) {
/*
fprintf(stderr, "libburn_DEBUG: write(%d, %lX, %d)\n",
fd, (unsigned long) buf, count);
*/
ret = write(fd, buf + done, todo);
if (ret < 0)
break;
done += ret;
todo -= ret;
}
if (done != count) {
ret = write(fd, buf, count);
if (ret != count) {
BURN_ALLOC_MEM(msg, char, 160);
sprintf(msg, "Cannot write desired amount of %d bytes.", count);
if (retries > 1)
sprintf(msg + strlen(msg), " Did %d retries. Last",
retries - 1);
sprintf(msg + strlen(msg), " write(2) returned %d.", ret);
sprintf(msg,
"Cannot write desired amount of data. write(2) returned %d.",
ret);
libdax_msgs_submit(libdax_messenger, d->global_index,
0x00020148,
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
msg, errno, 0);
d->cancel = 1;
ret = 0; goto ex;
return 0;
}
ex:;
BURN_FREE_MEM(msg);
@ -2682,11 +2645,10 @@ int burn_stdio_mmc_dummy_write(struct burn_drive *d, int start,
/* ts A70911 */
/* Flush stdio system buffer to physical device.
@param flag bit0= do not report debug message (intermediate sync)
bit1= do fsync(2) unconditionally
*/
int burn_stdio_sync_cache(int fd, struct burn_drive *d, int flag)
{
int ret, do_fsync;
int ret;
char *msg = NULL;
if (fd < 0) {
@ -2696,23 +2658,14 @@ int burn_stdio_sync_cache(int fd, struct burn_drive *d, int flag)
"Invalid file descriptor with stdio pseudo-drive",
0, 0);
d->cancel = 1;
ret = 0; goto ex;
return 0;
}
d->needs_sync_cache = 0;
do_fsync = 0;
if (flag & 2)
do_fsync = 1;
else if (d->write_opts != NULL)
do_fsync = (d->write_opts->stdio_fsync_size >= 0);
if (do_fsync) {
if (!(flag & 1))
libdax_msgs_submit(libdax_messenger, -1, 0x00000002,
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_ZERO,
"syncing cache (stdio fsync)", 0, 0);
ret = fsync(fd);
} else {
ret = 0;
}
if (!(flag & 1))
libdax_msgs_submit(libdax_messenger, -1, 0x00000002,
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_ZERO,
"syncing cache (stdio fsync)", 0, 0);
ret = fsync(fd);
if (ret != 0 && errno == EIO) {
BURN_ALLOC_MEM(msg, char, 160);
@ -2724,7 +2677,7 @@ int burn_stdio_sync_cache(int fd, struct burn_drive *d, int flag)
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
msg, errno, 0);
d->cancel = 1;
ret = 0; goto ex;
return 0;
}
ret = 1;
ex:;
@ -2748,15 +2701,16 @@ int burn_stdio_slowdown(struct burn_drive *d, struct timeval *prev_time,
int amount, int flag)
{
struct timeval tnow;
struct timezone dummy_tz;
double to_wait;
if (flag & 1) {
gettimeofday(prev_time, NULL);
gettimeofday(prev_time, &dummy_tz);
return 1;
}
if(d->nominal_write_speed <= 0)
return 2;
gettimeofday(&tnow, NULL);
gettimeofday(&tnow, &dummy_tz);
to_wait = ( ((double) amount) / (double) d->nominal_write_speed ) -
(double) ( tnow.tv_sec - prev_time->tv_sec ) -
(double) ( tnow.tv_usec - prev_time->tv_usec ) / 1.0e6
@ -2764,7 +2718,7 @@ int burn_stdio_slowdown(struct burn_drive *d, struct timeval *prev_time,
if (to_wait >= 0.0001) {
usleep((int) (to_wait * 1000000.0));
}
gettimeofday(prev_time, NULL);
gettimeofday(prev_time, &dummy_tz);
return 1;
}
@ -2889,10 +2843,10 @@ ex:;
close(d->stdio_fd);
d->stdio_fd = -1;
/* update pseudo-media state records by re-grabbing */
/* update media state records */
burn_drive_mark_unready(d, 8);
burn_drive_grab_stdio(d, 1);
/* <<< d->busy = BURN_DRIVE_IDLE; */
return ret;
}
@ -3168,10 +3122,6 @@ ex:;
burn_os_free_buffer((char *) d->buffer,
sizeof(struct buffer), 0);
d->buffer = buffer_mem;
if (d->write_opts != NULL) {
burn_write_opts_free(d->write_opts);
d->write_opts = NULL;
}
return;
}
@ -3180,7 +3130,6 @@ int burn_random_access_write(struct burn_drive *d, off_t byte_address,
char *data, off_t data_count, int flag)
{
int alignment = 0, start, upto, chunksize, err, fd = -1, ret;
int do_close = 0, getfl_ret;
char msg[81], *rpt;
struct buffer *buf = NULL, *buffer_mem = d->buffer;
@ -3253,27 +3202,11 @@ int burn_random_access_write(struct burn_drive *d, off_t byte_address,
"Drive is busy on attempt to write random access",0,0);
{ret = 0; goto ex;}
}
if (d->drive_role != 1) {
if (d->stdio_fd >= 0) {
/* Avoid to have a read-only fd open */
getfl_ret = fcntl(d->stdio_fd, F_GETFL);
if (((O_RDWR | O_WRONLY | O_RDONLY) & getfl_ret) ==
O_RDONLY) {
close(d->stdio_fd);
d->stdio_fd = -1;
}
}
if (d->stdio_fd >= 0) {
/* Avoid to have two fds open */
fd = d->stdio_fd;
} else {
fd = burn_stdio_open_write(d, byte_address, 2048, 0);
if (fd == -1)
{ret = 0; goto ex;}
do_close = 1;
}
if(d->drive_role != 1) {
fd = burn_stdio_open_write(d, byte_address, 2048, 0);
if (fd == -1)
{ret = 0; goto ex;}
}
d->cancel = 0;
d->busy = BURN_DRIVE_WRITING_SYNC;
d->buffer = buf;
@ -3300,7 +3233,7 @@ int burn_random_access_write(struct burn_drive *d, off_t byte_address,
}
if (err == BE_CANCELLED) {
d->busy = BURN_DRIVE_IDLE;
if(fd >= 0 && do_close)
if(fd >= 0)
close(fd);
{ret = -(start * 2048 - byte_address); goto ex;}
}
@ -3312,11 +3245,11 @@ int burn_random_access_write(struct burn_drive *d, off_t byte_address,
if(d->drive_role == 1)
d->sync_cache(d);
else
burn_stdio_sync_cache(fd, d, 2);
burn_stdio_sync_cache(fd, d, 0);
d->needs_sync_cache = 0;
}
if(fd >= 0 && do_close)
if(fd >= 0)
close(fd);
d->buffer = buffer_mem;
d->busy = BURN_DRIVE_IDLE;

View File

@ -3,8 +3,7 @@
Fakes a file in SUN .au format from a raw little-endian PCM audio file
(e.g. a file extracted from .wav by test/dewav). The input data are assumed
to be 16 bit, stereo, 44100 Hz.
Copyright (C) 2006 - 2015 Thomas Schmitt <scdbackup@gmx.net>
Provided under GPL version 2 or later.
Copyright (C) 2006 Thomas Schmitt <scdbackup@gmx.net>, provided under GPL
Info used: http://www.opengroup.org/public/pubs/external/auformat.html
*/
@ -48,13 +47,6 @@ int main(int argc, char **argv)
exit_value= 1;
goto help;
}
for(i= 1; i<argc; i++) {
if(strlen(argv[i]) >= 4096) {
fprintf(stderr,"%s: argument at position %d is much too long.\n",
argv[0], i);
exit(1);
}
}
for(i= 1; i<argc; i++) {
if(strcmp(argv[i],"-o")==0) {
if(i>=argc-1) {

View File

@ -1,6 +1,6 @@
/* test/libburner.c , API illustration of burning data or audio tracks to CD */
/* Copyright (C) 2005 - 2015 Thomas Schmitt <scdbackup@gmx.net> */
/* Copyright (C) 2005 - 2011 Thomas Schmitt <scdbackup@gmx.net> */
/* Provided under GPL, see also "License and copyright aspects" at file end */
@ -16,8 +16,6 @@
to serve the libburnia team as reference application. libburner.c does indeed
define the standard way how above three gestures can be implemented and
stay upward compatible for a good while.
There is another demo program, test/telltoc.c, which inspects drive, media
state, and media contents.
Before you can do anything, you have to initialize libburn by
burn_initialize()
@ -103,7 +101,7 @@ static int current_profile= -1;
static char current_profile_name[80]= {""};
/* Some in-advance definitions make possible a more comprehensive ordering
/* Some in-advance definitions to allow a more comprehensive ordering
of the functions and their explanations in here */
int libburner_aquire_by_adr(char *drive_adr);
int libburner_aquire_by_driveno(int *drive_no);
@ -246,7 +244,7 @@ int libburner_aquire_by_driveno(int *driveno)
before accessing any drives again.
In both cases you have to be aware that the desired drive might get
aquired in the meantime by another user or libburn process.
aquired in the meantime by another user resp. libburn process.
*/
/* We already made our choice via command line. (default is 0)
@ -435,31 +433,28 @@ int libburner_format(struct burn_drive *drive)
In case of external signals expect abort handling of an ongoing burn to
last up to a minute. Wait the normal burning timespan before any kill -9.
For simplicity, this function allows memory leaks in case of failure.
In apps which do not abort immediately, one should clean up better.
*/
int libburner_payload(struct burn_drive *drive,
char source_adr[][4096], int source_adr_count,
int multi, int simulate_burn, int all_tracks_type)
{
struct burn_source *data_src = NULL, *fifo_src[99];
struct burn_disc *target_disc = NULL;
struct burn_session *session = NULL;
struct burn_write_opts *burn_options = NULL;
struct burn_source *data_src, *fifo_src[99];
struct burn_disc *target_disc;
struct burn_session *session;
struct burn_write_opts *burn_options;
enum burn_disc_status disc_state;
struct burn_track *track, *tracklist[99];
struct burn_progress progress;
time_t start_time;
int last_sector = 0, padding = 0, trackno, unpredicted_size = 0, fd;
int fifo_chunksize = 2352, fifo_chunks = 1783; /* ~ 4 MB fifo */
int ret;
off_t fixed_size;
char *adr, reasons[BURN_REASONS_LEN];
struct stat stbuf;
for (trackno = 0 ; trackno < source_adr_count; trackno++) {
fifo_src[trackno] = NULL;
tracklist[trackno] = NULL;
}
if (all_tracks_type != BURN_AUDIO) {
all_tracks_type = BURN_MODE1;
/* a padding of 300 kiB helps to avoid the read-ahead bug */
@ -493,7 +488,7 @@ int libburner_payload(struct burn_drive *drive,
/* Convert this filedescriptor into a burn_source object */
data_src = NULL;
if (fd >= 0)
if (fd>=0)
data_src = burn_fd_source_new(fd, -1, fixed_size);
if (data_src == NULL) {
fprintf(stderr,
@ -501,7 +496,7 @@ int libburner_payload(struct burn_drive *drive,
if(errno!=0)
fprintf(stderr,"(Most recent system error: %s )\n",
strerror(errno));
{ret = 0; goto ex;}
return 0;
}
/* Install a fifo object on top of that data source object */
fifo_src[trackno] = burn_fifo_source_new(data_src,
@ -509,7 +504,7 @@ int libburner_payload(struct burn_drive *drive,
if (fifo_src[trackno] == NULL) {
fprintf(stderr,
"FATAL: Could not create fifo object of 4 MB\n");
{ret = 0; goto ex;}
return 0;
}
/* Use the fifo object as data source for the track */
@ -517,7 +512,7 @@ int libburner_payload(struct burn_drive *drive,
!= BURN_SOURCE_OK) {
fprintf(stderr,
"FATAL: Cannot attach source object to track object\n");
{ret = 0; goto ex;}
return 0;
}
burn_session_add_track(session, track, BURN_POS_END);
@ -525,7 +520,6 @@ int libburner_payload(struct burn_drive *drive,
/* Give up local reference to the data burn_source object */
burn_source_free(data_src);
data_src = NULL;
} /* trackno loop end */
@ -542,7 +536,7 @@ int libburner_payload(struct burn_drive *drive,
else
fprintf(stderr,
"FATAL: Cannot recognize state of drive and media\n");
{ret = 0; goto ex;}
return 0;
}
burn_options = burn_write_opts_new(drive);
@ -557,7 +551,7 @@ int libburner_payload(struct burn_drive *drive,
reasons, 0) == BURN_WRITE_NONE) {
fprintf(stderr, "FATAL: Failed to find a suitable write mode with this media.\n");
fprintf(stderr, "Reasons given:\n%s\n", reasons);
{ret = 0; goto ex;}
return 0;
}
burn_set_signal_handling("libburner : ", NULL, 0x30);
@ -565,6 +559,7 @@ int libburner_payload(struct burn_drive *drive,
start_time = time(0);
burn_disc_write(burn_options, target_disc);
burn_write_opts_free(burn_options);
while (burn_drive_get_status(drive, NULL) == BURN_DRIVE_SPAWNING)
usleep(100002);
while (burn_drive_get_status(drive, &progress) != BURN_DRIVE_IDLE) {
@ -600,32 +595,21 @@ int libburner_payload(struct burn_drive *drive,
}
printf("\n");
for (trackno = 0 ; trackno < source_adr_count; trackno++) {
burn_source_free(fifo_src[trackno]);
burn_track_free(tracklist[trackno]);
}
burn_session_free(session);
burn_disc_free(target_disc);
if (burn_is_aborting(0) > 0)
{ret = -1; goto ex;}
return -1;
if (multi && current_profile != 0x1a && current_profile != 0x13 &&
current_profile != 0x12 && current_profile != 0x43)
/* not with DVD+RW, formatted DVD-RW, DVD-RAM, BD-RE */
printf("NOTE: Media left appendable.\n");
if (simulate_burn)
printf("\n*** Did TRY to SIMULATE burning ***\n\n");
ret = 1;
ex:;
/* Dispose objects */
if (burn_options != NULL)
burn_write_opts_free(burn_options);
for (trackno = 0 ; trackno < source_adr_count; trackno++) {
if (fifo_src[trackno] != NULL)
burn_source_free(fifo_src[trackno]);
if (tracklist[trackno])
burn_track_free(tracklist[trackno]);
}
if (data_src != NULL)
burn_source_free(data_src);
if (session != NULL)
burn_session_free(session);
if (target_disc != NULL)
burn_disc_free(target_disc);
return ret;
return 1;
}

View File

@ -7,7 +7,6 @@
#include <unistd.h>
#include <stdio.h>
#include <signal.h>
#include <string.h>
#include <assert.h>
static struct burn_drive_info *drives;
@ -63,7 +62,6 @@ int main()
return 1;
}
memset(&newact, 0, sizeof(newact));
newact.sa_handler = catch_int;
sigaction(SIGINT, &newact, &oldact);
for (i = 0; i < (int) n_drives; i++) {

51
test/structest.c Normal file
View File

@ -0,0 +1,51 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <libburn/libburn.h>
int main(int argc, char **argv)
{
int i;
const char *path;
struct burn_track *track;
struct burn_disc *disc;
struct burn_session *session;
struct burn_source *src;
burn_initialize();
burn_msgs_set_severities("NEVER", "ALL", "structest: ");
disc = burn_disc_create();
session = burn_session_create();
burn_disc_add_session(disc, session, BURN_POS_END);
/* Define a source for all of the tracks */
path = strdup("/etc/hosts");
src = burn_file_source_new(path, NULL);
/* Add ten tracks to a session */
for (i = 0; i < 10; i++) {
track = burn_track_create();
burn_session_add_track(session, track, 0);
if (burn_track_set_source(track, src) != BURN_SOURCE_OK) {
printf("problem with the source\n");
return 0;
}
}
/* Add ten tracks to a session */
for (i = 0; i < 10; i++) {
track = burn_track_create();
burn_session_add_track(session, track, 0);
if (burn_track_set_source(track, src) != BURN_SOURCE_OK) {
printf("problem with the source\n");
return 0;
}
}
/* Delete a session */
burn_session_remove_track(session, track);
burn_structure_print_disc(disc);
return EXIT_SUCCESS;
}

View File

@ -1,6 +1,6 @@
/* test/telltoc.c , API illustration of obtaining media status info */
/* Copyright (C) 2006 - 2015 Thomas Schmitt <scdbackup@gmx.net>
/* Copyright (C) 2006 - 2011 Thomas Schmitt <scdbackup@gmx.net>
Provided under GPL */
/** Overview
@ -14,7 +14,6 @@
to serve the libburn team as reference application. telltoc.c does indeed
define the standard way how above gestures can be implemented and stay upward
compatible for a good while.
The burn aspects of libburn are demonstrated by program test/libburner.c .
Before you can do anything, you have to initialize libburn by
burn_initialize()
@ -72,7 +71,7 @@ static unsigned int drive_count;
static int drive_is_grabbed = 0;
/* Some in-advance definitions to make possible a more comprehensive ordering
/* Some in-advance definitions to allow a more comprehensive ordering
of the functions and their explanations in here */
int telltoc_aquire_by_adr(char *drive_adr);
int telltoc_aquire_by_driveno(int *drive_no, int silent);
@ -120,6 +119,10 @@ int telltoc_aquire_by_adr(char *drive_adr)
int ret;
char libburn_drive_adr[BURN_DRIVE_ADR_LEN];
/* <<< ts A70907 FOR TESTING ONLY !
struct burn_drive_info *test_drive_list;
*/
/* This tries to resolve links or alternative device files */
ret = burn_drive_convert_fs_adr(drive_adr, libburn_drive_adr);
if (ret<=0) {
@ -128,6 +131,10 @@ int telltoc_aquire_by_adr(char *drive_adr)
return 0;
}
/* <<< ts A70907 FOR TESTING ONLY !
ret = burn_drive_scan_and_grab(&test_drive_list, "/dev/sg2", 1);
*/
fprintf(stderr,"Aquiring drive '%s' ...\n", libburn_drive_adr);
ret = burn_drive_scan_and_grab(&drive_list, libburn_drive_adr, 1);
@ -139,6 +146,10 @@ int telltoc_aquire_by_adr(char *drive_adr)
drive_is_grabbed = 1;
}
/* <<< ts A70907 FOR TESTING ONLY !
burn_drive_info_free(test_drive_list);
*/
return ret;
}
@ -240,14 +251,12 @@ int telltoc_regrab(struct burn_drive *drive) {
int telltoc_media(struct burn_drive *drive)
{
int ret, media_found = 0, profile_no = -1, num_profiles = 0, i;
int profiles[64];
char is_current_profile[64];
int ret, media_found = 0, profile_no = -1;
double max_speed = 0.0, min_speed = 0.0, speed_conv;
off_t available = 0;
enum burn_disc_status s;
char profile_name[80], speed_unit[40];
struct burn_multi_caps *caps = NULL;
struct burn_multi_caps *caps;
struct burn_write_opts *o = NULL;
printf("Media current: ");
@ -260,32 +269,15 @@ int telltoc_media(struct burn_drive *drive)
} else
printf("is not recognizable\n");
/* Determine speed unit before profile_name gets reused */
speed_conv = 176.4;
strcpy(speed_unit,"176.4 kB/s (CD, data speed 150 KiB/s)");
if (strstr(profile_name, "DVD") == profile_name) {
speed_conv = 1385.0;
strcpy(speed_unit,"1385.0 kB/s (DVD)");
} else if (strstr(profile_name, "BD") == profile_name) {
speed_conv = 4495.625;
strcpy(speed_unit,"4495.625 kB/s (BD)");
}
ret = burn_drive_get_all_profiles(drive, &num_profiles, profiles,
is_current_profile);
if (ret > 0) {
for (i = 0; i < num_profiles; i++) {
ret = burn_obtain_profile_name(profiles[i],
profile_name);
if (ret <= 0)
sprintf(profile_name,
"Unknown media type 0x%4.4X",
(unsigned int) profiles[i]);
printf("Drive can do : %s%s\n", profile_name,
is_current_profile[i] ? " (current)" : "");
}
}
/* >>> libburn does not obtain full profile list yet */
printf("Media status : ");
s = burn_disc_get_status(drive);
if (s == BURN_DISC_FULL) {
@ -316,15 +308,15 @@ int telltoc_media(struct burn_drive *drive)
/* Media appears writeable */
printf("Write multi : ");
printf("%s multi-session , ",
caps->multi_session == 1 ? "offers" : "cannot do");
caps->multi_session == 1 ? "allows" : "prohibits");
if (caps->multi_track)
printf("offers multiple tracks\n");
printf("allows multiple tracks\n");
else
printf("offers only single track\n");
printf("enforces single track\n");
printf("Write start : ");
if (caps->start_adr == 1)
printf(
"offers addresses [%.f , %.f]s , alignment=%.fs\n",
"allows addresses [%.f , %.f]s , alignment=%.fs\n",
(double) caps->start_range_low / 2048 ,
(double) caps->start_range_high / 2048 ,
(double) caps->start_alignment / 2048 );
@ -399,8 +391,6 @@ int telltoc_media(struct burn_drive *drive)
}
printf("Speed unit 1x: %s\n", speed_unit);
if (caps != NULL)
burn_disc_free_multi_caps(&caps);
return 1;
}
@ -535,8 +525,8 @@ int telltoc_toc(struct burn_drive *drive)
cd_is_audio = -1;
}
printf("Media content: session %3d ", session_no+1);
printf("track %3d %s lba: %9d %4.2d:%2.2d:%2.2d\n",
printf("Media content: session %2d ", session_no+1);
printf("track %2d %s lba: %9d %4.2d:%2.2d:%2.2d\n",
track_count,
(track_is_audio ? "audio" : "data "),
lba, pmin, psec, pframe);
@ -553,8 +543,8 @@ int telltoc_toc(struct burn_drive *drive)
pframe = toc_entry.pframe;
lba= burn_msf_to_lba(pmin, psec, pframe);
}
printf("Media content: session %3d ", session_no+1);
printf("leadout lba: %9d %4.2d:%2.2d:%2.2d\n",
printf("Media content: session %2d ", session_no+1);
printf("leadout lba: %9d %4.2d:%2.2d:%2.2d\n",
lba, pmin, psec, pframe);
last_track_size = lba - last_track_start;
telltoc_detect_cd(drive);
@ -714,16 +704,8 @@ int telltoc_read_and_print(struct burn_drive *drive,
print_result:;
total_count += data_count;
if (encoding == 1) {
if (data_count > 0) {
ret = fwrite(buf, data_count, 1, raw_fp);
if (ret < 1) {
fprintf(stderr,
"FAILURE: writing to '%s' : %s\n",
raw_file, strerror(errno));
fclose(raw_fp);
return 1;
}
}
if (data_count > 0)
fwrite(buf, data_count, 1, raw_fp);
} else for (i = 0; i < data_count; i += 16) {
if (encoding == 0) {
sprintf(line, "%8ds + %4d : ",
@ -782,8 +764,6 @@ print_result:;
start_sector, sector_count,
(int) (total_count / (off_t) sector_size));
if (raw_fp != NULL)
fclose(raw_fp);
return ret;
}
@ -808,13 +788,6 @@ int telltoc_setup(int argc, char **argv)
{
int i;
for (i = 1; i < argc; ++i) {
if (strlen(argv[i]) >= 4096) {
fprintf(stderr,
"Argument at position %d is much too long. (Max 4095)\n", i);
return 2;
}
}
for (i = 1; i < argc; ++i) {
if (!strcmp(argv[i], "--drive")) {
++i;
@ -856,8 +829,7 @@ int telltoc_setup(int argc, char **argv)
sscanf(argv[i-2], "%d", &read_start);
sscanf(argv[i-1], "%d", &read_count);
print_encoding = 0;
if(strncmp(argv[i], "raw:", 4) == 0 ||
strncmp(argv[i], "1:", 2) == 0) {
if(strncmp(argv[i], "raw:", 4) == 0 || strcmp(argv[i],"1:") == 0) {
print_encoding = 1;
strcpy(print_raw_file, strchr(argv[i], ':') + 1);
if (strcmp(print_raw_file, "-") == 0) {
@ -1004,6 +976,6 @@ finish_libburn:;
}
/* License and copyright aspects:
See test/libburner.c
See libburner.c
*/