Compare commits
4 Commits
Author | SHA1 | Date |
---|---|---|
Thomas Schmitt | a5eb672b8c | |
Thomas Schmitt | 1bfa02a416 | |
Thomas Schmitt | 9c9763b4d0 | |
Thomas Schmitt | 0c0ef2dccf |
|
@ -1,7 +1,7 @@
|
||||||
Derek Foreman <derek@signalmarketing.com> and Ben Jansens <xor@orodu.net>
|
Derek Foreman <derek@signalmarketing.com> and Ben Jansens <xor@orodu.net>
|
||||||
Copyright (C) 2002-2006 Derek Foreman and Ben Jansens
|
Copyright (C) 2002-2006 Derek Foreman and Ben Jansens
|
||||||
Mario Danic <mario.danic@gmail.com>, Thomas Schmitt <scdbackup@gmx.net>
|
Mario Danic <mario.danic@gmail.com>, Thomas Schmitt <scdbackup@gmx.net>
|
||||||
Copyright (C) 2006-2017 Mario Danic, Thomas Schmitt
|
Copyright (C) 2006-2011 Mario Danic, Thomas Schmitt
|
||||||
|
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
|
206
ChangeLog
206
ChangeLog
|
@ -1,209 +1,3 @@
|
||||||
git clone git@dev.lovelyhq.com:libburnia/libburn.git
|
|
||||||
(to become libburn-1.5.8 or higher)
|
|
||||||
===============================================================================
|
|
||||||
- no novelties yet -
|
|
||||||
|
|
||||||
|
|
||||||
libburn-1.5.6.tar.gz Wed Jun 07 2023
|
|
||||||
===============================================================================
|
|
||||||
* Bug fix: Overburning with cdrskin option -force ended by a libburn error
|
|
||||||
* New API call burn_write_opts_set_bdr_obs_exempt()
|
|
||||||
* New cdrskin option --bdr_obs_exempt
|
|
||||||
* Officially enabled overburning with burn_write_opts_set_force(,1)
|
|
||||||
|
|
||||||
libburn-1.5.4.tar.gz Sat Jan 30 2021
|
|
||||||
===============================================================================
|
|
||||||
* Bug fix: Early SCSI commands from sg-linux.c were not logged
|
|
||||||
* New API call burn_drive_set_speed_exact()
|
|
||||||
* New API call burn_nominal_slowdown()
|
|
||||||
|
|
||||||
libburn-1.5.2.pl01.tar.gz Mon Nov 25 2019
|
|
||||||
===============================================================================
|
|
||||||
* Bug fix: cdrskin multi-track burning was slow and stalled after track 1.
|
|
||||||
Regression introduced in version 1.5.0 by commit 84fad99, 2018.02.05
|
|
||||||
O_DIRECT is now disabled for track sources.
|
|
||||||
|
|
||||||
libburn-1.5.2.tar.gz Sat Oct 26 2019
|
|
||||||
===============================================================================
|
|
||||||
* Bug fix: No lock was obtained for setting up a fifo object
|
|
||||||
* Bug fix: Stream recording was applied regardless whether the drive offers it.
|
|
||||||
This caused Xfburn failures with some MATSHITA laptop drives.
|
|
||||||
* Bug fix: TDK Corporation was not recognized as manufacturer of DVD-R "TTH02"
|
|
||||||
* Made libburn ready for building out-of-source. Thanks Ross Burton.
|
|
||||||
* New API calls burn_drive_get_feature_codes(), burn_drive_get_feature()
|
|
||||||
* New cdrskin option --list_features
|
|
||||||
|
|
||||||
libburn-1.5.0.tar.gz Sat Sep 15 2018
|
|
||||||
===============================================================================
|
|
||||||
* Bug fix: cdrskin threw errno 22 on data file input if libburn is
|
|
||||||
configured with --enable-track-src-odirect
|
|
||||||
* Bug fix: SIGSEGV could happen if a track ended by reaching its fixed size
|
|
||||||
while the track source still was willing to deliver bytes.
|
|
||||||
Thanks to user swordragon.
|
|
||||||
* Bug fix: Device file comparison parameters were recorded wrong with Linux sg
|
|
||||||
|
|
||||||
libburn-1.4.8.tar.gz Tue Sep 12 2017
|
|
||||||
===============================================================================
|
|
||||||
* Bug fix: Option -dummy did not affect writing by direct_write_amount=
|
|
||||||
* New API call burn_drive_reset_simulate()
|
|
||||||
* New API call burn_drive_get_bd_r_pow()
|
|
||||||
* Refusing to write to BD-R if formatted to Pseudo Overwrite
|
|
||||||
|
|
||||||
libburn-1.4.6.tar.gz Fri Sep 16 2016
|
|
||||||
===============================================================================
|
|
||||||
* Bug fix: SAO CD could be perceived 2 blocks to short.
|
|
||||||
Regression in 1.4.4 by rev 5672.
|
|
||||||
* Now operating optical drives on OpenBSD. Thanks to SASANO Takayoshi.
|
|
||||||
* New API call burn_drive_set_immed()
|
|
||||||
* New cdrskin option use_immed_bit=
|
|
||||||
|
|
||||||
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
|
|
||||||
* 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
|
|
||||||
|
|
||||||
libburn-1.2.2.tar.gz Mon Apr 02 2012
|
|
||||||
===============================================================================
|
|
||||||
* Small internal refinements
|
|
||||||
|
|
||||||
libburn-1.2.0.tar.gz Sat Jan 28 2012
|
|
||||||
===============================================================================
|
|
||||||
* Bug fix: cdrskin produced a memory fault if interupted before writing began
|
|
||||||
* Bug fix: Solaris adapter mishandled write commands which failed on first try
|
|
||||||
* Bug fix: Interrupting libburn while drive tray is loading led to endless loop
|
|
||||||
* Bug fix: Progress report with blanking and formatting could be bogus
|
|
||||||
* New API calls burn_disc_get_leadin_text(), burn_write_opts_set_leadin_text()
|
|
||||||
* New API calls for composing CD-TEXT, see doc/cdtext.txt
|
|
||||||
* New API call burn_session_by_cue_file() for reading CDRWIN .cue files
|
|
||||||
* New API call burn_track_set_isrc_string()
|
|
||||||
* New API calls burn_track_set_index(), burn_track_clear_indice()
|
|
||||||
* New API calls burn_session_set_start_tno(), burn_session_get_start_tno()
|
|
||||||
* New API calls burn_track_set_pregap_size(), burn_track_set_postgap_size()
|
|
||||||
* Implemented cdrskin option textfile=
|
|
||||||
* Implemented cdrskin option combination -vv -toc for cdtext.dat production
|
|
||||||
* Implemented cdrskin options mcn= and isrc=
|
|
||||||
* Implemented cdrskin options -scms -copy -nocopy -preemp -nopreemp
|
|
||||||
* Implemented cdrskin option index=
|
|
||||||
* Partly implemented cdrskin options cuefile= and -text
|
|
||||||
* New cdrskin option input_sheet_v07t= for CD-TEXT definition
|
|
||||||
* New cdrskin options --cdtext_dummy and --cdtext_verbose
|
|
||||||
* New cdrskin options --four_channel --two_channel
|
|
||||||
* New cdrskin option cd_start_tno=
|
|
||||||
* New cdrskin options sao_pregap=, sao_postgap=
|
|
||||||
|
|
||||||
libburn-1.1.8.tar.gz Mon Nov 21 2011
|
|
||||||
===============================================================================
|
|
||||||
* Bug fix: Misinterpreted mode page 2A if block descriptors are present
|
|
||||||
* Enabled recognition of QEMU DVD-ROM 0.12
|
|
||||||
* Avoiding to intermediately close and open drive device file
|
|
||||||
* New API call burn_drive_re_assess()
|
|
||||||
|
|
||||||
libburn-1.1.6.tar.gz Tue Sep 27 2011
|
libburn-1.1.6.tar.gz Tue Sep 27 2011
|
||||||
===============================================================================
|
===============================================================================
|
||||||
* Bug fix: stdio sizes > 4 TB - 32 kB caused integer rollover
|
* Bug fix: stdio sizes > 4 TB - 32 kB caused integer rollover
|
||||||
|
|
31
Makefile.am
31
Makefile.am
|
@ -12,7 +12,7 @@ ACLOCAL_AMFLAGS = -I ./
|
||||||
|
|
||||||
# Build libraries
|
# Build libraries
|
||||||
libburn_libburn_la_LDFLAGS = \
|
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
|
# This causes undesired .o names
|
||||||
# configure.ac appends -D options to variable CFLAG
|
# configure.ac appends -D options to variable CFLAG
|
||||||
### libburn_libburn_la_CFLAGS = $(LIBBURN_DVD_OBS_64K)
|
### libburn_libburn_la_CFLAGS = $(LIBBURN_DVD_OBS_64K)
|
||||||
|
@ -21,7 +21,6 @@ libburn_libburn_la_SOURCES = \
|
||||||
libburn/async.c \
|
libburn/async.c \
|
||||||
libburn/async.h \
|
libburn/async.h \
|
||||||
libburn/back_hacks.h \
|
libburn/back_hacks.h \
|
||||||
libburn/cdtext.c \
|
|
||||||
libburn/cleanup.c \
|
libburn/cleanup.c \
|
||||||
libburn/cleanup.h \
|
libburn/cleanup.h \
|
||||||
libburn/crc.c \
|
libburn/crc.c \
|
||||||
|
@ -69,7 +68,8 @@ libburn_libburn_la_SOURCES = \
|
||||||
libburn/util.c \
|
libburn/util.c \
|
||||||
libburn/util.h \
|
libburn/util.h \
|
||||||
libburn/write.c \
|
libburn/write.c \
|
||||||
libburn/write.h
|
libburn/write.h \
|
||||||
|
version.h
|
||||||
|
|
||||||
## libburn/sg-@ARCH@.c \
|
## libburn/sg-@ARCH@.c \
|
||||||
|
|
||||||
|
@ -77,7 +77,7 @@ libinclude_HEADERS = \
|
||||||
libburn/libburn.h
|
libburn/libburn.h
|
||||||
|
|
||||||
install-exec-hook:
|
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/telltoc \
|
||||||
test/dewav \
|
test/dewav \
|
||||||
test/fake_au \
|
test/fake_au \
|
||||||
test/poll
|
test/poll \
|
||||||
|
test/structest
|
||||||
|
|
||||||
bin_PROGRAMS = \
|
bin_PROGRAMS = \
|
||||||
cdrskin/cdrskin
|
cdrskin/cdrskin
|
||||||
|
@ -113,10 +114,13 @@ test_fake_au_SOURCES = test/fake_au.c
|
||||||
test_poll_CPPFLAGS = -Ilibburn
|
test_poll_CPPFLAGS = -Ilibburn
|
||||||
test_poll_LDADD = $(libburn_libburn_la_OBJECTS) $(LIBBURN_EXTRALIBS)
|
test_poll_LDADD = $(libburn_libburn_la_OBJECTS) $(LIBBURN_EXTRALIBS)
|
||||||
test_poll_SOURCES = test/poll.c
|
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 - C30607
|
## cdrskin construction site - ts A60816 - B10808
|
||||||
cdrskin_cdrskin_CPPFLAGS = -Ilibburn
|
cdrskin_cdrskin_CPPFLAGS = -Ilibburn
|
||||||
cdrskin_cdrskin_CFLAGS = -DCdrskin_libburn_1_5_7
|
cdrskin_cdrskin_CFLAGS = -DCdrskin_libburn_1_1_6
|
||||||
|
|
||||||
# cdrskin_cdrskin_LDADD = $(libburn_libburn_la_OBJECTS) $(LIBBURN_EXTRALIBS)
|
# cdrskin_cdrskin_LDADD = $(libburn_libburn_la_OBJECTS) $(LIBBURN_EXTRALIBS)
|
||||||
# ts A80123, change proposed by Simon Huggins to cause dynamic libburn linking
|
# ts A80123, change proposed by Simon Huggins to cause dynamic libburn linking
|
||||||
|
@ -127,11 +131,6 @@ cdrskin_cdrskin_SOURCES = cdrskin/cdrskin.c cdrskin/cdrfifo.c cdrskin/cdrfifo.h
|
||||||
## Open questions: how to compute $timestamp and express -DX="$timestamp"
|
## Open questions: how to compute $timestamp and express -DX="$timestamp"
|
||||||
##
|
##
|
||||||
|
|
||||||
# "make clean" shall remove a few stubborn .libs directories
|
|
||||||
# which George Danchev reported Dec 03 2011.
|
|
||||||
# Learned from: http://www.gnu.org/software/automake/manual/automake.html#Clean
|
|
||||||
clean-local:
|
|
||||||
-rm -rf cdrskin/.libs test/.libs
|
|
||||||
|
|
||||||
|
|
||||||
## ========================================================================= ##
|
## ========================================================================= ##
|
||||||
|
@ -171,7 +170,8 @@ uninstall-local:
|
||||||
# Indent source files
|
# Indent source files
|
||||||
indent_files = \
|
indent_files = \
|
||||||
$(libburn_libburn_la_SOURCES) \
|
$(libburn_libburn_la_SOURCES) \
|
||||||
$(test_poll_SOURCES)
|
$(test_poll_SOURCES) \
|
||||||
|
$(test_structest_SOURCES)
|
||||||
|
|
||||||
|
|
||||||
indent: $(indent_files)
|
indent: $(indent_files)
|
||||||
|
@ -193,15 +193,12 @@ nodist_pkgconfig_DATA = \
|
||||||
man_MANS = cdrskin/cdrskin.1
|
man_MANS = cdrskin/cdrskin.1
|
||||||
|
|
||||||
EXTRA_DIST = \
|
EXTRA_DIST = \
|
||||||
bootstrap \
|
|
||||||
libburn-1.pc.in \
|
libburn-1.pc.in \
|
||||||
version.h.in \
|
version.h.in \
|
||||||
doc/comments \
|
doc/comments \
|
||||||
doc/doxygen.conf.in \
|
doc/doxygen.conf.in \
|
||||||
doc/cookbook.txt \
|
doc/cookbook.txt \
|
||||||
doc/mediainfo.txt \
|
doc/mediainfo.txt \
|
||||||
doc/cdtext.txt \
|
|
||||||
doc/waveformat.txt \
|
|
||||||
README \
|
README \
|
||||||
AUTHORS \
|
AUTHORS \
|
||||||
CONTRIBUTORS \
|
CONTRIBUTORS \
|
||||||
|
@ -221,13 +218,11 @@ EXTRA_DIST = \
|
||||||
libburn/os-linux.h \
|
libburn/os-linux.h \
|
||||||
libburn/os-libcdio.h \
|
libburn/os-libcdio.h \
|
||||||
libburn/os-solaris.h \
|
libburn/os-solaris.h \
|
||||||
libburn/os-netbsd.h \
|
|
||||||
libburn/sg-dummy.c \
|
libburn/sg-dummy.c \
|
||||||
libburn/sg-freebsd.c \
|
libburn/sg-freebsd.c \
|
||||||
libburn/sg-linux.c \
|
libburn/sg-linux.c \
|
||||||
libburn/sg-libcdio.c \
|
libburn/sg-libcdio.c \
|
||||||
libburn/sg-solaris.c \
|
libburn/sg-solaris.c \
|
||||||
libburn/sg-netbsd.c \
|
|
||||||
COPYING \
|
COPYING \
|
||||||
NEWS \
|
NEWS \
|
||||||
ChangeLog \
|
ChangeLog \
|
||||||
|
|
255
README
255
README
|
@ -4,14 +4,14 @@
|
||||||
This all is under GPL.
|
This all is under GPL.
|
||||||
(See GPL reference, our clarification and commitment at the end of this text)
|
(See GPL reference, our clarification and commitment at the end of this text)
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
libburnia-project.org
|
libburn-project.org
|
||||||
By Mario Danic <mario.danic@gmail.com> and Thomas Schmitt <scdbackup@gmx.net>
|
By Mario Danic <mario.danic@gmail.com> and Thomas Schmitt <scdbackup@gmx.net>
|
||||||
Copyright (C) 2006-2023 Mario Danic, Thomas Schmitt
|
Copyright (C) 2006-2011 Mario Danic, Thomas Schmitt
|
||||||
Still containing parts of Libburn. By Derek Foreman <derek@signalmarketing.com>
|
Still containing parts of Libburn. By Derek Foreman <derek@signalmarketing.com>
|
||||||
and Ben Jansens <xor@orodu.net>
|
and Ben Jansens <xor@orodu.net>
|
||||||
Copyright (C) 2002-2006 Derek Foreman and Ben Jansens
|
Copyright (C) 2002-2006 Derek Foreman and Ben Jansens
|
||||||
|
|
||||||
http://files.libburnia-project.org/releases/libburn-1.5.6.tar.gz
|
http://files.libburnia-project.org/releases/libburn-1.1.6.tar.gz
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
@ -19,14 +19,14 @@ Copyright (C) 2002-2006 Derek Foreman and Ben Jansens
|
||||||
|
|
||||||
From tarball
|
From tarball
|
||||||
|
|
||||||
Obtain libburn-1.5.6.tar.gz, take it to a directory of your choice and do:
|
Obtain libburn-1.1.6.tar.gz, take it to a directory of your choice and do:
|
||||||
|
|
||||||
tar xzf libburn-1.5.6.tar.gz
|
tar xzf libburn-1.1.6.tar.gz
|
||||||
cd libburn-1.5.6
|
cd libburn-1.1.6
|
||||||
./configure --prefix=/usr
|
./configure --prefix=/usr
|
||||||
make
|
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
|
and to install the cdrecord compatibility binary cdrskin, do
|
||||||
(as Superuser):
|
(as Superuser):
|
||||||
|
|
||||||
|
@ -41,21 +41,21 @@ You may have to keep your hald away from the drive. See for example
|
||||||
http://www.freebsd.org/gnome/docs/halfaq.html
|
http://www.freebsd.org/gnome/docs/halfaq.html
|
||||||
|
|
||||||
|
|
||||||
From git
|
From SVN
|
||||||
|
|
||||||
Our build system is based on autotools. For preparing the build of a git
|
Our build system is based on autotools. For preparing the build of a SVN
|
||||||
snapshot you will need autotools of at least version 1.7.
|
snapshot you will need autotools of at least version 1.7.
|
||||||
Do in a directory of your choice:
|
Do in a directory of your choice:
|
||||||
|
|
||||||
git clone https://dev.lovelyhq.com/libburnia/libburn.git libburn-git
|
svn co http://svn.libburnia-project.org/libburn/trunk libburn-svn
|
||||||
cd libburn-git
|
cd libburn-svn
|
||||||
./bootstrap
|
./bootstrap
|
||||||
./configure --prefix=/usr
|
./configure --prefix=/usr
|
||||||
make
|
make
|
||||||
make install
|
make install
|
||||||
|
|
||||||
Warning: The master branch might contain experimental features which might
|
Warning: The trunk might contain experimental features which might not
|
||||||
not persist until next release.
|
persist until next release.
|
||||||
|
|
||||||
|
|
||||||
Special ./configure options
|
Special ./configure options
|
||||||
|
@ -77,10 +77,6 @@ configure time by:
|
||||||
--enable-dvd-obs-64k
|
--enable-dvd-obs-64k
|
||||||
This may be combined with above --enable-track-src-odirect .
|
This may be combined with above --enable-track-src-odirect .
|
||||||
|
|
||||||
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:
|
|
||||||
--enable-dvd-obs-pad
|
|
||||||
|
|
||||||
Alternatively the transport of SCSI commands can be done via libcdio-0.83.
|
Alternatively the transport of SCSI commands can be done via libcdio-0.83.
|
||||||
You may install it and re-run libburn's ./configure with option
|
You may install it and re-run libburn's ./configure with option
|
||||||
--enable-libcdio
|
--enable-libcdio
|
||||||
|
@ -113,11 +109,12 @@ closing it immediately, waiting, and only then opening it for real:
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
The other parts of the the libburnia project are hosted as neighbors of
|
An important part of the project, libisofs, is hosted in a bzr repository at
|
||||||
libburn:
|
launchpad.net :
|
||||||
|
bzr branch lp:libisofs
|
||||||
|
|
||||||
git clone https://dev.lovelyhq.com/libburnia/libisofs.git
|
Another part the project, libisoburn, is hosted in the libburnia SVN, too:
|
||||||
git clone https://dev.lovelyhq.com/libburnia/libisoburn.git
|
svn co http://svn.libburnia-project.org/libisoburn/trunk libisoburn
|
||||||
|
|
||||||
See README files there.
|
See README files there.
|
||||||
|
|
||||||
|
@ -136,13 +133,12 @@ These are libraries, language bindings, and middleware binaries which emulate
|
||||||
classical (and valuable) Linux tools.
|
classical (and valuable) Linux tools.
|
||||||
Currently it is supported on GNU/Linux with kernels >= 2.4,
|
Currently it is supported on GNU/Linux with kernels >= 2.4,
|
||||||
on FreeBSD with ATAPI/CAM enabled in the kernel (see man atapicam),
|
on FreeBSD with ATAPI/CAM enabled in the kernel (see man atapicam),
|
||||||
on OpenSolaris (tested with kernel 5.11),
|
and on OpenSolaris (tested with kernel 5.11).
|
||||||
on NetBSD (tested with 6.1.3).
|
|
||||||
On other X/Open compliant systems there will only be pseudo drives, but no
|
On other X/Open compliant systems there will only be pseudo drives, but no
|
||||||
direct MMC operation on real CD/DVD/BD drives.
|
direct MMC operation on real CD/DVD/BD drives.
|
||||||
|
|
||||||
For full ports to other systems we would need : login on a development machine
|
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.
|
of Linux sg or FreeBSD CAM, volunteers for testing of realistic use cases.
|
||||||
|
|
||||||
We have a well tested code base for burning data and audio CDs, DVDs and BDs.
|
We have a well tested code base for burning data and audio CDs, DVDs and BDs.
|
||||||
|
@ -173,8 +169,8 @@ The project components (list subject to growth, hopefully):
|
||||||
content.
|
content.
|
||||||
|
|
||||||
- libisoburn is an add-on to libburn and libisofs which coordinates both and
|
- libisoburn is an add-on to libburn and libisofs which coordinates both and
|
||||||
also can grow ISO-9660 filesystem images on multi-session media
|
also allows to grow ISO-9660 filesystem images on multi-session
|
||||||
as well as on overwriteable media via the same API.
|
media as well as on overwriteable media via the same API.
|
||||||
All media peculiarities are handled automatically.
|
All media peculiarities are handled automatically.
|
||||||
It also contains the methods of command oriented application
|
It also contains the methods of command oriented application
|
||||||
xorriso and offers them via a C language API.
|
xorriso and offers them via a C language API.
|
||||||
|
@ -254,7 +250,7 @@ Project history as far as known to me:
|
||||||
which by about nearly everybody else was perceived as unfriendly fork.
|
which by about nearly everybody else was perceived as unfriendly fork.
|
||||||
Derek Foreman four days later posted a message which expressed his
|
Derek Foreman four days later posted a message which expressed his
|
||||||
discontent.
|
discontent.
|
||||||
The situation first caused me to publicly regret it and then - after i
|
The situation first caused me to publically regret it and then - after i
|
||||||
got the opportunity to move in with cdrskin - gave me true reason to
|
got the opportunity to move in with cdrskin - gave me true reason to
|
||||||
personally apologize to Derek Foreman, Ben Jansens and the contributors at
|
personally apologize to Derek Foreman, Ben Jansens and the contributors at
|
||||||
icculus.org/burn. Posted to both projects:
|
icculus.org/burn. Posted to both projects:
|
||||||
|
@ -328,7 +324,7 @@ Project history as far as known to me:
|
||||||
and write modes, and better protection against typical user mishaps.
|
and write modes, and better protection against typical user mishaps.
|
||||||
|
|
||||||
- 24th October 2007 version 0.4.0 is the foundation of new library libisoburn
|
- 24th October 2007 version 0.4.0 is the foundation of new library libisoburn
|
||||||
and an upcoming integrated application for manipulating and writing
|
and an upcomming integrated application for manipulating and writing
|
||||||
ISO 9660 + Rock Ridge images. cdrskin-0.4.0 got capabilities like growisofs
|
ISO 9660 + Rock Ridge images. cdrskin-0.4.0 got capabilities like growisofs
|
||||||
by these enhancements: growing of overwriteable media and disk files.
|
by these enhancements: growing of overwriteable media and disk files.
|
||||||
Taking again a bow towards Andy Polyakov.
|
Taking again a bow towards Andy Polyakov.
|
||||||
|
@ -354,7 +350,7 @@ Project history as far as known to me:
|
||||||
- 27th Apr 2008 libisofs-0.6.4 can now read data file content from images
|
- 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
|
and can map pieces of disk files onto image files. Image directory iteration
|
||||||
has been enhanced. Input data streams and extended information have been
|
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
|
- 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.
|
image tree nodes. It now depends on libisofs-0.6.4 and libburn-0.4.4.
|
||||||
|
@ -368,8 +364,7 @@ Project history as far as known to me:
|
||||||
type with automatic media state recognition.
|
type with automatic media state recognition.
|
||||||
|
|
||||||
- 17th May 2008 an old bug with DVD-RAM and now with BD-RE is fixed by
|
- 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
|
libburn-0.4.8 to allow libisoburn emulation of multisession on those media.
|
||||||
on those media.
|
|
||||||
|
|
||||||
- 19th May 2008 libisoburn-0.1.6 brings better table-of-content emulation
|
- 19th May 2008 libisoburn-0.1.6 brings better table-of-content emulation
|
||||||
on overwriteble media and disk files.
|
on overwriteble media and disk files.
|
||||||
|
@ -388,14 +383,14 @@ Project history as far as known to me:
|
||||||
and cdrecord style. xorriso now can serve underneath growisofs.
|
and cdrecord style. xorriso now can serve underneath growisofs.
|
||||||
|
|
||||||
- 20th Aug 2008 libburn-0.5.2 revokes the necessity that a drive must be
|
- 20th Aug 2008 libburn-0.5.2 revokes the necessity that a drive must be
|
||||||
enumerable in order to be addressable. Enumeration is enhanced by examining
|
enumerable in order to be adressable. Enumeration is enhanced by examining
|
||||||
/proc/sys/dev/cdrom/info.
|
/proc/sys/dev/cdrom/info.
|
||||||
|
|
||||||
- 24th Aug 2008 libisoburn/xorriso-0.2.4 introduces a media readability check
|
- 24th Aug 2008 libisoburn/xorriso-0.2.4 introduces a media readability check
|
||||||
with data retrieval option.
|
with data retrieval option.
|
||||||
|
|
||||||
- 18th Sep 2008 libisofs-0.6.8 supports ISO 9660 Level 3 which can represent
|
- 18th Sep 2008 libisofs-0.6.8 supports ISO 9660 Level 3 which allows very
|
||||||
very large data files in the image.
|
large data files in the image.
|
||||||
|
|
||||||
- 20th Sep 2008 libisoburn/xorriso-0.2.6 takes into respect the new Level 3
|
- 20th Sep 2008 libisoburn/xorriso-0.2.6 takes into respect the new Level 3
|
||||||
capabilities of libisofs.
|
capabilities of libisofs.
|
||||||
|
@ -413,19 +408,19 @@ Project history as far as known to me:
|
||||||
of an aborted burn run.
|
of an aborted burn run.
|
||||||
|
|
||||||
- 26th Nov 2008 libisofs-0.6.12 can produce a ISOLINUX isohybrid MBR on the fly
|
- 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
|
- 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
|
sets, for legacy FreeBSD systems which expect an outdated Rock Ridge
|
||||||
signature, and for producing ISO images with MBR which boot from hard disk
|
signature, and for producing ISO images with MBR which boot from hard disk
|
||||||
or USB stick. Three minor bugs were fixed.
|
or USB stick. Three minor bugs were fixed.
|
||||||
|
|
||||||
- 7th Dec 2008 libburn-0.5.8 prevents a SIGSEGV with weird CD table-of-content
|
- 7th Dec 2008 libburn-0.5.8 prevents a SIGSEGV with wierd CD table-of-content
|
||||||
and improves BD-RE formatting.
|
and improves BD-RE formatting.
|
||||||
|
|
||||||
- 9th Dec 2008 Our project received a donation from Thomas Weber.
|
- 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.
|
formatted or unformatted BD-R.
|
||||||
|
|
||||||
- 6th Jan 2009 libisoburn-0.3.2. xorriso can produce and execute commands for
|
- 6th Jan 2009 libisoburn-0.3.2. xorriso can produce and execute commands for
|
||||||
|
@ -448,16 +443,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.
|
- 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
|
It will show no drives and thus libburn will only be able to perform
|
||||||
operations on "stdio:" pseudo drives. Nevertheless this was precondition
|
operations on "stdio:" pseudo drives. Nevertheless this allowed to lift the
|
||||||
to lift the ban to build libburn on operating systems other than Linux
|
ban to build libburn on operating systems other than Linux and FreeBSD.
|
||||||
and FreeBSD.
|
|
||||||
|
|
||||||
- 16 Mar 2009 libisoburn-0.3.6: xorriso uses RRIP version 1.10 as default
|
- 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.
|
in order to be mountable where mkisofs images are mountable.
|
||||||
|
|
||||||
- 17 Apr 2009 libisofs-0.6.18 introduces content filtering of data files.
|
- 17 Apr 2009 libisofs-0.6.18 introduces content filtering of data files.
|
||||||
Built-in filters implement compression to formats gzip and zisofs. External
|
Built-in filters allow compression to formats gzip and zisofs. External
|
||||||
filter processes can perform arbitrary data conversions like encryption.
|
filter processes allow arbitrary data conversions like encryption.
|
||||||
|
|
||||||
- 19 Apr 2009 libisoburn-0.3.8 makes use of the new libisofs capability to
|
- 19 Apr 2009 libisoburn-0.3.8 makes use of the new libisofs capability to
|
||||||
perform content filtering of data files.
|
perform content filtering of data files.
|
||||||
|
@ -482,10 +476,10 @@ Project history as far as known to me:
|
||||||
Affected are releases since libisoburn-0.3.2 in january 2009.
|
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
|
- 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 for each single data file. Checksum tags allow to verify superblock and
|
||||||
and directory tree before importing them.
|
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
|
supported profiles. It works around some pitfalls with U3 enhanced memory
|
||||||
sticks which emulate a CD-ROM.
|
sticks which emulate a CD-ROM.
|
||||||
|
|
||||||
|
@ -519,7 +513,7 @@ Project history as far as known to me:
|
||||||
provides throughput enhancements with hampered busses on Linux, and new
|
provides throughput enhancements with hampered busses on Linux, and new
|
||||||
API calls to log SCSI commands and to control the libburn fifo.
|
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.
|
drives or disk files.
|
||||||
|
|
||||||
- 26 Dec 2009 libburn-0.7.4.pl01 fixes the release tarball which was lacking
|
- 26 Dec 2009 libburn-0.7.4.pl01 fixes the release tarball which was lacking
|
||||||
|
@ -532,7 +526,7 @@ Project history as far as known to me:
|
||||||
portability.
|
portability.
|
||||||
|
|
||||||
- 22 Jan 2010 libburn-0.7.6 has an improved system adapter for FreeBSD,
|
- 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.
|
libcdio >= 0.83 as SCSI transport facility.
|
||||||
|
|
||||||
- 10 Feb 2010 libisofs-0.6.28 fixes a regression about bootable images which
|
- 10 Feb 2010 libisofs-0.6.28 fixes a regression about bootable images which
|
||||||
|
@ -554,8 +548,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
|
- 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
|
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
|
specs can be set and inquired. This allows to use GRUB boot images for EFI.
|
||||||
for EFI.
|
|
||||||
|
|
||||||
- 04 May 2010 Release 0.5.6.pl00 of libisoburn makes use of the new libisofs
|
- 04 May 2010 Release 0.5.6.pl00 of libisoburn makes use of the new libisofs
|
||||||
capabilities about boot images.
|
capabilities about boot images.
|
||||||
|
@ -609,11 +602,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
|
- 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.
|
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
|
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).
|
is ready to allow untranslated ECMA-119 names (violating the specs).
|
||||||
libburn-1.0.0.pl00 is now willing to create stdio-drive files with
|
libburn-1.0.0.pl00 allows umask to create stdio-drive files with
|
||||||
rw-permissions for all, if umask really asks for it. cdrskin now refuses
|
rw-permissions for all. cdrskin now refuses to burn if the foreseeable size
|
||||||
to burn if the foreseeable size exceeds media capacity
|
exceeds media capacity
|
||||||
libisoburn-1.0.0.pl00 can now create an ISO 9660:1999 directory tree,
|
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
|
improved the emulation fidelity of command -as mkisofs, lowered the default
|
||||||
abort threshold for xorriso batch mode, and increased that threshold for
|
abort threshold for xorriso batch mode, and increased that threshold for
|
||||||
xorriso dialog mode.
|
xorriso dialog mode.
|
||||||
|
@ -645,7 +638,7 @@ Project history as far as known to me:
|
||||||
|
|
||||||
- Sat Jun 18 2011 release 1.1.0:
|
- Sat Jun 18 2011 release 1.1.0:
|
||||||
The consumption of stack memory was reduced. Statical program analysis found
|
The consumption of stack memory was reduced. Statical program analysis found
|
||||||
some rarely occurring memory leaks. Several small bugs were fixed.
|
some rarely occuring memory leaks. Several small bugs were fixed.
|
||||||
The suffix .plXY was dropped from tarball names of libburn and libisoburn.
|
The suffix .plXY was dropped from tarball names of libburn and libisoburn.
|
||||||
|
|
||||||
- Mon Jun 20 2011 patch release libburn-1.1.0.pl01:
|
- Mon Jun 20 2011 patch release libburn-1.1.0.pl01:
|
||||||
|
@ -668,158 +661,6 @@ Project history as far as known to me:
|
||||||
in several rarely used features. Processing of ACL and extattr was enabled
|
in several rarely used features. Processing of ACL and extattr was enabled
|
||||||
on FreeBSD. Workarounds try to cope with vanishing udev links on GNU/Linux.
|
on FreeBSD. Workarounds try to cope with vanishing udev links on GNU/Linux.
|
||||||
|
|
||||||
- Mon Nov 21 2011 release libburn-1.1.8 and libisoburn-1.1.8:
|
|
||||||
libburn avoids to close and open drive device files while operating on them.
|
|
||||||
xorriso emulation mode xorrecord now has an own manual. libburn and xorriso
|
|
||||||
were prepared to operate on qemu virtio-blk-pci devices.
|
|
||||||
|
|
||||||
- Sat Jan 28 2012 release 1.2.0:
|
|
||||||
libburn has learned to read and write CD-TEXT with CD SAO audio sessions.
|
|
||||||
It can now read CDRWIN .cue files which define pure audio or pure data
|
|
||||||
sessions. libisofs and libisoburn improved timestamp handling. Several
|
|
||||||
minor bugs were fixed.
|
|
||||||
|
|
||||||
- Mon Apr 02 2012 release 1.2.2:
|
|
||||||
The handling of intentional deviations from ECMA-119 specifications has
|
|
||||||
been improved in libisofs. libisoburn and xorriso now make use of these
|
|
||||||
improvements. Some rarely occurring bugs have been fixed.
|
|
||||||
|
|
||||||
- Fri Jul 20 2012 release 1.2.4:
|
|
||||||
libburn and libisofs got some rarely occurring bugs fixed. libisofs learned
|
|
||||||
to produce HFS+ metadata and Apple Partition Map. The capabilities of
|
|
||||||
isohybrid options --efi and --mac have been implemented (GPT and APM).
|
|
||||||
|
|
||||||
- Tue Jan 08 2013 release 1.2.6:
|
|
||||||
Small improvements were made in libburn. Minor bugs were fixed in the
|
|
||||||
libraries. xorriso improved its capabilities to serve the needs of frontend
|
|
||||||
programs. A proof of concept for a GUI frontend has been implemented:
|
|
||||||
xorriso-tcltk
|
|
||||||
|
|
||||||
- Mon Mar 18 2013 release 1.2.8:
|
|
||||||
Some rarely occurring 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 acquired 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 occurring 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.
|
|
||||||
|
|
||||||
- Fri Sep 16 2016 release 1.4.6:
|
|
||||||
libburn now operates optical drives on OpenBSD. libisofs makes pseudo-random
|
|
||||||
id generation reproducible by relating it to the volume date.
|
|
||||||
xorriso interprets environment variable SOURCE_DATE_EPOCH of
|
|
||||||
reproducible-builds.org to prepare a default setting which leads to identical
|
|
||||||
ISO images on identical input and identical constant options.
|
|
||||||
Several moderately embarrassing bugs have been fixed.
|
|
||||||
|
|
||||||
- Tue Sep 12 2017 release 1.4.8:
|
|
||||||
libburn now refuses to write to SRM+POW formatted BD-R, because it would
|
|
||||||
spoil them. libisofs got several bugs fixed and offers new API calls to
|
|
||||||
support new xorriso features. libisoburn and xorriso offer more detail
|
|
||||||
control with particular boot sector types. New bugs and a regression from
|
|
||||||
version 1.4.4 were fixed.
|
|
||||||
|
|
||||||
- Sat Sep 15 2018 release 1.5.0
|
|
||||||
libisofs now can record all xattr namespaces, user defined padding was moved
|
|
||||||
after appended partitions. libisoburn and xorriso make use of the new xattr
|
|
||||||
capability of libisofs.
|
|
||||||
All three libraries got some rarely triggered bugs fixed.
|
|
||||||
|
|
||||||
- Sat Oct 26 2019 release 1.5.2
|
|
||||||
The libraries are now ready for building out-of-source. libisofs got minor
|
|
||||||
API extensions. libburn got a bug fixed which spoiled burn runs on
|
|
||||||
some MATSHITA laptop drives. It is now able to list all features which
|
|
||||||
the drive announces. xorriso can now set GPT type GUIDs with appended
|
|
||||||
partitions and the ISO partition.
|
|
||||||
All three libraries got some rarely triggered bugs fixed.
|
|
||||||
|
|
||||||
- Mon Nov 25 2019 patch release 1.5.2.pl01
|
|
||||||
cdrskin did not properly burn multiple tracks. Track 1 was slow and burning
|
|
||||||
stalled before track 2. Regression introduced by 1.5.0.
|
|
||||||
|
|
||||||
- Sat Jan 30 2021 , 07 Feb 2021 release 1.5.4
|
|
||||||
libburn offers new opportunities to influence drive speed.
|
|
||||||
libisofs got a bug fixed which under medium rare circumstances spoiled
|
|
||||||
zisofs production. libisofs switched to usage of libjte-2.0.0. Further it
|
|
||||||
can now write and read zisofs2 format, which enables compression of files
|
|
||||||
>= 4 GiB. When reading Joliet file trees, the names get stripped of their
|
|
||||||
version numbers by default. After loading metadata, libisofs can now tell
|
|
||||||
which directory tree was loaded and whether Rock Ridge is used.
|
|
||||||
libisoburn and xorriso make use of these new features.
|
|
||||||
xorriso can put out the data stream of -check_media to standard output. It
|
|
||||||
can restore files with many zero bytes as sparse files and it is able to
|
|
||||||
extract recognized boot images into data files on hard disk.
|
|
||||||
A new script xorriso-dd-target helps to put an ISO image onto an USB stick
|
|
||||||
without endangering valuable hard disk content.
|
|
||||||
Several rarely triggered bugs were fixed.
|
|
||||||
|
|
||||||
- Wed Jun 07 2023 release 1.5.6
|
|
||||||
libburn can overburn CD media, i.e. write more data than the drive announced
|
|
||||||
as medium capacity.
|
|
||||||
libisofs can assess many of the features which were in effect when a
|
|
||||||
given ISO 9660 filesystem was created. A safety limit was introduced not
|
|
||||||
to exceed the limit of Linux which is imposed on the number of SUSP CE
|
|
||||||
entries which is good for about 60 KiB of AAIP data. Some rarely occuring
|
|
||||||
bugs were fixed in libisofs.
|
|
||||||
libisoburn and xorriso expose the new library features to the user and
|
|
||||||
got some minor improvements. Many minor bugs were fixed.
|
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
150
acinclude.m4
150
acinclude.m4
|
@ -1,7 +1,7 @@
|
||||||
AC_DEFUN([LIBBURNIA_SET_FLAGS],
|
AC_DEFUN([LIBBURNIA_SET_FLAGS],
|
||||||
[
|
[
|
||||||
case $target_os in
|
case $target_os in
|
||||||
freebsd* | netbsd*)
|
freebsd*)
|
||||||
LDFLAGS="$LDFLAGS -L/usr/local/lib"
|
LDFLAGS="$LDFLAGS -L/usr/local/lib"
|
||||||
CPPFLAGS="$CPPFLAGS -I/usr/local/include"
|
CPPFLAGS="$CPPFLAGS -I/usr/local/include"
|
||||||
;;
|
;;
|
||||||
|
@ -16,28 +16,22 @@ AC_DEFUN([TARGET_SHIZZLE],
|
||||||
|
|
||||||
AC_MSG_CHECKING([target operating system])
|
AC_MSG_CHECKING([target operating system])
|
||||||
|
|
||||||
libburn_check_libcam=
|
|
||||||
LIBBURNIA_LDCONFIG_CMD="echo 'No ldconfig run performed. If needed, configure manually for:'"
|
LIBBURNIA_LDCONFIG_CMD="echo 'No ldconfig run performed. If needed, configure manually for:'"
|
||||||
|
|
||||||
case $target in
|
case $target_os in
|
||||||
*-*-linux*)
|
linux*)
|
||||||
ARCH=linux
|
ARCH=linux
|
||||||
LIBBURN_ARCH_LIBS=
|
LIBBURN_ARCH_LIBS=
|
||||||
LIBBURNIA_LDCONFIG_CMD=ldconfig
|
LIBBURNIA_LDCONFIG_CMD=ldconfig
|
||||||
;;
|
;;
|
||||||
*-*-freebsd*)
|
freebsd*)
|
||||||
ARCH=freebsd
|
ARCH=freebsd
|
||||||
LIBBURN_ARCH_LIBS=-lcam
|
LIBBURN_ARCH_LIBS=-lcam
|
||||||
LIBBURNIA_PKGCONFDIR=$(echo "$libdir" | sed 's/\/lib$/\/libdata/')/pkgconfig
|
LIBBURNIA_PKGCONFDIR=$(echo "$libdir" | sed 's/\/lib$/\/libdata/')/pkgconfig
|
||||||
;;
|
;;
|
||||||
*-kfreebsd*-gnu*)
|
kfreebsd*-gnu)
|
||||||
ARCH=freebsd
|
ARCH=freebsd
|
||||||
LIBBURN_ARCH_LIBS=-lcam
|
LIBBURN_ARCH_LIBS=-lcam
|
||||||
libburn_check_libcam=yes
|
|
||||||
;;
|
|
||||||
*-solaris*)
|
|
||||||
ARCH=solaris
|
|
||||||
LIBBURN_ARCH_LIBS=-lvolmgt
|
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
ARCH=
|
ARCH=
|
||||||
|
@ -45,12 +39,8 @@ AC_DEFUN([TARGET_SHIZZLE],
|
||||||
# AC_ERROR([You are attempting to compile for an unsupported platform])
|
# AC_ERROR([You are attempting to compile for an unsupported platform])
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
AC_MSG_RESULT([$ARCH])
|
|
||||||
|
|
||||||
if test x"$libburn_check_libcam" = xyes
|
AC_MSG_RESULT([$ARCH])
|
||||||
then
|
|
||||||
LIBBURNIA_CHECK_LIBCAM
|
|
||||||
fi
|
|
||||||
])
|
])
|
||||||
|
|
||||||
|
|
||||||
|
@ -59,17 +49,15 @@ dnl It tests whether -Wl,--version-script=... works with the compiler
|
||||||
AC_DEFUN([LIBBURN_ASSERT_VERS_LIBS],
|
AC_DEFUN([LIBBURN_ASSERT_VERS_LIBS],
|
||||||
[
|
[
|
||||||
libburnia_save_LDFLAGS="$LDFLAGS"
|
libburnia_save_LDFLAGS="$LDFLAGS"
|
||||||
LDFLAGS="$LDFLAGS -Wl,--version-script=$srcdir/libburn/libburn.ver"
|
LDFLAGS="$LDFLAGS -Wl,--version-script=libburn/libburn.ver"
|
||||||
AC_TRY_LINK([#include <stdio.h>], [printf("Hello\n");],
|
AC_TRY_LINK([#include <stdio.h>], [printf("Hello\n");],
|
||||||
[vers_libs_test="yes"], [vers_libs_test="no"])
|
[vers_libs_test="yes"], [vers_libs_test="no"])
|
||||||
if test x$vers_libs_test = xyes
|
if test x$vers_libs_test = xno
|
||||||
then
|
then
|
||||||
LIBLDFLAGS="-Wl,--version-script=$srcdir/libburn/libburn.ver"
|
LDFLAGS="$libburnia_save_LDFLAGS"
|
||||||
fi
|
fi
|
||||||
LDFLAGS="$libburnia_save_LDFLAGS"
|
|
||||||
AC_SUBST(LIBLDFLAGS)
|
|
||||||
])
|
])
|
||||||
|
|
||||||
|
|
||||||
dnl LIBBURNIA_SET_PKGCONFIG determines the install directory for the *.pc file.
|
dnl LIBBURNIA_SET_PKGCONFIG determines the install directory for the *.pc file.
|
||||||
dnl Important: Must be performed _after_ TARGET_SHIZZLE
|
dnl Important: Must be performed _after_ TARGET_SHIZZLE
|
||||||
|
@ -121,121 +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.
|
|
||||||
dnl "silent" is like "optional" but without message.
|
|
||||||
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
|
|
||||||
if test x"$1" = xoptional
|
|
||||||
then
|
|
||||||
echo "disabled linking with $LIBBURN_ARCH_LIBS (because not found)"
|
|
||||||
fi
|
|
||||||
LIBBURN_ARCH_LIBS=""
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
if test x"$1" = xsilent
|
|
||||||
then
|
|
||||||
dummy=dummy
|
|
||||||
else
|
|
||||||
echo "enabled linking with $LIBBURN_ARCH_LIBS"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
])
|
|
||||||
|
|
||||||
|
|
||||||
dnl LIBBURNIA_CHECK_LINUX_SCSI is by Thomas Schmitt, libburnia project
|
|
||||||
dnl
|
|
||||||
AC_DEFUN([LIBBURNIA_CHECK_LINUX_SCSI],
|
|
||||||
[
|
|
||||||
dnl Check whether it is a Linux without scsi/scsi.h
|
|
||||||
libburn_scsi_disabled=
|
|
||||||
if test x"$ARCH" = xlinux
|
|
||||||
then
|
|
||||||
AH_TEMPLATE([Libburn_use_sg_dummY],
|
|
||||||
[Define to compile without OS specific SCSI features])
|
|
||||||
AC_MSG_CHECKING([for missing scsi/scsi.h on Linux])
|
|
||||||
AC_TRY_COMPILE([
|
|
||||||
#ifdef __linux
|
|
||||||
#include <scsi/scsi.h>
|
|
||||||
#endif
|
|
||||||
],
|
|
||||||
[;],
|
|
||||||
[AC_MSG_RESULT([no])],
|
|
||||||
[AC_DEFINE([Libburn_use_sg_dummY], [yes])
|
|
||||||
libburn_scsi_disabled=yes
|
|
||||||
AC_MSG_RESULT([yes])]
|
|
||||||
)
|
|
||||||
fi
|
|
||||||
if test x"$libburn_scsi_disabled" = xyes
|
|
||||||
then
|
|
||||||
echo "disabled operation of optical drives via SCSI"
|
|
||||||
fi
|
|
||||||
])
|
|
||||||
|
|
||||||
|
|
||||||
dnl LIBBURNIA_CHECK_LIBCAM is by Thomas Schmitt, libburnia project
|
|
||||||
dnl
|
|
||||||
AC_DEFUN([LIBBURNIA_CHECK_LIBCAM],
|
|
||||||
[
|
|
||||||
dnl Check whether libcam is requested for FreeBSD kernel but missing
|
|
||||||
libburn_scsi_disabled=
|
|
||||||
if test x"$LIBBURN_ARCH_LIBS" = x"-lcam"
|
|
||||||
then
|
|
||||||
AH_TEMPLATE([Libburn_use_sg_dummY],
|
|
||||||
[Define to compile without OS specific SCSI features])
|
|
||||||
AC_MSG_CHECKING([for missing libcam for SCSI on FreeBSD kernel])
|
|
||||||
dnl If libcam is not available, LIBBURN_ARCH_LIBS will be made empty
|
|
||||||
LIBBURNIA_CHECK_ARCH_LIBS(silent)
|
|
||||||
if test x"$LIBBURN_ARCH_LIBS" = x
|
|
||||||
then
|
|
||||||
AC_DEFINE([Libburn_use_sg_dummY], [yes])
|
|
||||||
libburn_scsi_disabled=yes
|
|
||||||
AC_MSG_RESULT([yes])
|
|
||||||
else
|
|
||||||
AC_MSG_RESULT([no])
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
if test x"$LIBBURN_ARCH_LIBS" = x"-lcam"
|
|
||||||
then
|
|
||||||
AC_MSG_CHECKING([for missing libcam headers])
|
|
||||||
AC_TRY_COMPILE([
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <camlib.h>
|
|
||||||
#include <cam/scsi/scsi_message.h>
|
|
||||||
#include <cam/scsi/scsi_pass.h>
|
|
||||||
],
|
|
||||||
[;],
|
|
||||||
[AC_MSG_RESULT([no])],
|
|
||||||
[AC_DEFINE([Libburn_use_sg_dummY], [yes])
|
|
||||||
libburn_scsi_disabled=yes
|
|
||||||
AC_MSG_RESULT([yes])]
|
|
||||||
)
|
|
||||||
fi
|
|
||||||
if test x"$libburn_scsi_disabled" = xyes
|
|
||||||
then
|
|
||||||
echo "disabled operation of optical drives via SCSI"
|
|
||||||
fi
|
|
||||||
])
|
|
||||||
|
|
||||||
|
|
|
@ -4,18 +4,18 @@
|
||||||
cdrskin. By Thomas Schmitt <scdbackup@gmx.net>
|
cdrskin. By Thomas Schmitt <scdbackup@gmx.net>
|
||||||
Integrated sub project of libburnia-project.org but also published via:
|
Integrated sub project of libburnia-project.org but also published via:
|
||||||
http://scdbackup.sourceforge.net/cdrskin_eng.html
|
http://scdbackup.sourceforge.net/cdrskin_eng.html
|
||||||
http://scdbackup.sourceforge.net/cdrskin-1.5.7.tar.gz
|
http://scdbackup.sourceforge.net/cdrskin-1.1.6.tar.gz
|
||||||
|
|
||||||
Copyright (C) 2006-2023 Thomas Schmitt, provided under GPL version 2 or later.
|
Copyright (C) 2006-2011 Thomas Schmitt, provided under GPL version 2 or later.
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
cdrskin is a limited cdrecord compatibility wrapper which allows to use
|
cdrskin is a limited cdrecord compatibility wrapper which allows to use
|
||||||
most of the libburn features from the command line.
|
most of the libburn features from the command line.
|
||||||
|
|
||||||
Currently it is fully supported on GNU/Linux with kernels >= 2.4, on FreeBSD,
|
Currently it is supported on GNU/Linux with kernels >= 2.4,
|
||||||
on OpenSolaris, and on NetBSD.
|
on FreeBSD and on OpenSolaris.
|
||||||
IDE drives under Linux 2.4 need kernel module ide-scsi.
|
IDE drives under Linux 2.4. need kernel module ide-scsi.
|
||||||
ATA and SATA drives under FreeBSD need kernel module atapicam.
|
ATA and SATA drives under FreeBSD need kernel module atapicam.
|
||||||
On other X/Open compliant systems there will only be emulated drives, but no
|
On other X/Open compliant systems there will only be emulated drives, but no
|
||||||
direct MMC operation on real CD/DVD/BD drives.
|
direct MMC operation on real CD/DVD/BD drives.
|
||||||
|
@ -26,10 +26,10 @@ By using this software you agree to the disclaimer at the end of this text
|
||||||
|
|
||||||
Compilation, First Glimpse, Installation
|
Compilation, First Glimpse, Installation
|
||||||
|
|
||||||
Obtain cdrskin-1.5.7.tar.gz, take it to a directory of your choice and do:
|
Obtain cdrskin-1.1.6.tar.gz, take it to a directory of your choice and do:
|
||||||
|
|
||||||
tar xzf cdrskin-1.5.7.tar.gz
|
tar xzf cdrskin-1.1.6.tar.gz
|
||||||
cd cdrskin-1.5.7
|
cd cdrskin-1.1.6
|
||||||
|
|
||||||
Within that directory execute:
|
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
|
chmod a+rw /dev/sr0 /dev/hda
|
||||||
This is equivalent to the traditional setup chmod a+x,u+s cdrecord.
|
This is equivalent to the traditional setup chmod a+x,u+s cdrecord.
|
||||||
|
|
||||||
On FreeBSD, device 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 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".
|
See below "System Dependend Drive Permission Examples".
|
||||||
|
|
||||||
I strongly discourage to run cdrskin with setuid root or via sudo !
|
I strongly discourage to run cdrskin with setuid root or via sudo !
|
||||||
|
@ -192,11 +191,6 @@ See below "Audio CD" for specifications.
|
||||||
cdrskin -v dev=0,1,0 blank=fast -eject speed=48 -sao \
|
cdrskin -v dev=0,1,0 blank=fast -eject speed=48 -sao \
|
||||||
-audio -swab track0[1-5].cd /path/to/track6.wav
|
-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
|
Restrictions
|
||||||
|
|
||||||
|
@ -206,7 +200,7 @@ See output of command
|
||||||
If you have use cases for them, please report your wishes and expectations.
|
If you have use cases for them, please report your wishes and expectations.
|
||||||
|
|
||||||
On the other hand, the capability of multi-session and of writing streams
|
On the other hand, the capability of multi-session and of writing streams
|
||||||
of unpredicted length surpass the current DVD capabilities of cdrecord.
|
of unpredicted lenght surpass the current DVD capabilities of cdrecord.
|
||||||
|
|
||||||
|
|
||||||
Inspiration and Standard
|
Inspiration and Standard
|
||||||
|
@ -357,7 +351,7 @@ but leaves the media in "intermediate" state. In the first session of writing
|
||||||
one may only write sequentially to such a DVD. After that, it gets random
|
one may only write sequentially to such a DVD. After that, it gets random
|
||||||
addressable by cdrskin. DVD-ROM drives might show ill behavior with them.
|
addressable by cdrskin. DVD-ROM drives might show ill behavior with them.
|
||||||
|
|
||||||
blank=format_overwrite_full uses preferably "Full Format" (type 00h).
|
blank=format_overwrite_full uses preferrably "Full Format" (type 00h).
|
||||||
This formatting lasts as long as writing a full DVD. It includes writing of
|
This formatting lasts as long as writing a full DVD. It includes writing of
|
||||||
lead-out which is said to be good for DVD ROM compatibility.
|
lead-out which is said to be good for DVD ROM compatibility.
|
||||||
|
|
||||||
|
@ -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.
|
Alternatively the transport of SCSI commands can be done via libcdio-0.83.
|
||||||
You may install it and re-run libburn's ./configure with option
|
You may install it and re-run libburn's ./configure with option
|
||||||
--enable-libcdio
|
--enable-libcdio
|
||||||
Add option
|
|
||||||
-use_libcdio
|
|
||||||
to your run of cdrskin/compile_cdrskin.sh .
|
|
||||||
|
|
||||||
You may get a (super fat) statically linked binary by :
|
You may get a (super fat) statically linked binary by :
|
||||||
cdrskin/compile_cdrskin.sh -static
|
cdrskin/compile_cdrskin.sh -static
|
||||||
|
@ -468,7 +459,7 @@ closing it immediately, waiting, and only then opening it for real:
|
||||||
System Dependend Drive Permission Examples
|
System Dependend Drive Permission Examples
|
||||||
|
|
||||||
Accessing the optical drives requires privileges which usually are granted
|
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.
|
approaches for avoiding the need for unrestricted privileges.
|
||||||
|
|
||||||
First check whether some friendly system setting already allows you to
|
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
|
If there remain drives invisible which the superuser can see by the same
|
||||||
command, then the following examples might help:
|
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.
|
Add the authorized users of CD drives to group "floppy" in /etc/group.
|
||||||
If missing: create this group.
|
If missing: create this group.
|
||||||
Changes to /etc/group often only affect new login sessions. So log out and in
|
Changes to /etc/group often only affect new login sessions. So log out and in
|
||||||
|
@ -526,7 +517,7 @@ Run cdrskin by
|
||||||
The following settings will make pfexec keep original UID and EUID and prevent
|
The following settings will make pfexec keep original UID and EUID and prevent
|
||||||
most superuser powers. Be aware that you still can manipulate all device files
|
most superuser powers. Be aware that you still can manipulate all device files
|
||||||
if you have the file permissions for that.
|
if you have the file permissions for that.
|
||||||
Full root privileges for cdrskin can then be acquired only by command su.
|
Full root privileges for cdrskin can then be aquired only by command su.
|
||||||
|
|
||||||
Edit /etc/security/exec_attr and add this line to the other "Media Backup"
|
Edit /etc/security/exec_attr and add this line to the other "Media Backup"
|
||||||
lines:
|
lines:
|
||||||
|
@ -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 last two commands have to be executed after each boot. I do not know
|
||||||
the relevant device configuration files yet.
|
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
|
Project aspects and legal stuff
|
||||||
|
@ -563,7 +548,7 @@ are the cause. Any mistake of the burn program is supposed to be caught
|
||||||
by the drive's firmware and to lead to mere misburns.
|
by the drive's firmware and to lead to mere misburns.
|
||||||
The worst mishaps which hit the author imposed the need to reboot the
|
The worst mishaps which hit the author imposed the need to reboot the
|
||||||
system because of drives gnawing endlessly on ill media. Permanent hardware
|
system because of drives gnawing endlessly on ill media. Permanent hardware
|
||||||
damage did not occur in 13 years of development. But one never knows ...
|
damage did not occur in 3.5 years of development. But one never knows ...
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
@ -591,7 +576,7 @@ contributions in a due way.
|
||||||
Based on and sub project of:
|
Based on and sub project of:
|
||||||
libburnia-project.org
|
libburnia-project.org
|
||||||
By Mario Danic <mario.danic@gmail.com> and Thomas Schmitt <scdbackup@gmx.net>
|
By Mario Danic <mario.danic@gmail.com> and Thomas Schmitt <scdbackup@gmx.net>
|
||||||
Copyright (C) 2006-2023 Mario Danic, Thomas Schmitt
|
Copyright (C) 2006-2011 Mario Danic, Thomas Schmitt
|
||||||
|
|
||||||
libburnia-project.org is inspired by and in other components still containing
|
libburnia-project.org is inspired by and in other components still containing
|
||||||
parts of
|
parts of
|
||||||
|
|
|
@ -18,7 +18,7 @@ set -x
|
||||||
# Both binaries are static in respect to libburn.
|
# Both binaries are static in respect to libburn.
|
||||||
#
|
#
|
||||||
# The script is to be run in the directory above the toplevel
|
# 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
|
# 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
|
# My changes are in $changes , mainly in $changes/cdrskin
|
||||||
changes="./libburn-release"
|
changes="./libburn-release"
|
||||||
|
|
||||||
skin_release="1.5.6"
|
skin_release="1.1.6"
|
||||||
patch_level=""
|
patch_level=""
|
||||||
# patch_level=".pl00"
|
# patch_level=".pl00"
|
||||||
skin_rev="$skin_release""$patch_level"
|
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"
|
man_page_html="cdrskin/man_1_cdrskin.html"
|
||||||
|
|
||||||
# bintarget_dynamic="cdrskin_${skin_rev}-x86-suse9_0"
|
# bintarget_dynamic="cdrskin_${skin_rev}-x86-suse9_0"
|
||||||
# bintarget_dynamic="cdrskin_${skin_rev}-amd64-suse10_2"
|
bintarget_dynamic="cdrskin_${skin_rev}-amd64-suse10_2"
|
||||||
bintarget_dynamic="cdrskin_${skin_rev}-amd64-debian8_0"
|
|
||||||
bintarget_static="$bintarget_dynamic"-static
|
bintarget_static="$bintarget_dynamic"-static
|
||||||
|
|
||||||
if test -d "$changes"
|
if test -d "$changes"
|
||||||
|
@ -229,7 +228,6 @@ tar czf "$cdrskin_tarball" "$target"
|
||||||
"$compile_cmd" $compile_static_opts -O2 -do_strip
|
"$compile_cmd" $compile_static_opts -O2 -do_strip
|
||||||
cp "$compile_result" "../$bintarget_static"
|
cp "$compile_result" "../$bintarget_static"
|
||||||
fi
|
fi
|
||||||
( cd cdrskin ; cc -g -Wall -o unite_html_b_line unite_html_b_line.c )
|
|
||||||
"$man_to_html_cmd"
|
"$man_to_html_cmd"
|
||||||
mv "$man_page_html" ..
|
mv "$man_page_html" ..
|
||||||
)
|
)
|
|
@ -18,7 +18,7 @@ set -x
|
||||||
# Both binaries are static in respect to libburn.
|
# Both binaries are static in respect to libburn.
|
||||||
#
|
#
|
||||||
# The script is to be run in the directory above the toplevel
|
# 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
|
# 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
|
# My changes are in $changes , mainly in $changes/cdrskin
|
||||||
changes="./libburn-develop"
|
changes="./libburn-develop"
|
||||||
|
|
||||||
skin_release="1.5.7"
|
skin_release="1.1.7"
|
||||||
patch_level=""
|
patch_level=""
|
||||||
skin_rev="$skin_release""$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_to_html_cmd="./cdrskin/convert_man_to_html.sh"
|
||||||
man_page_html="cdrskin/man_1_cdrskin.html"
|
man_page_html="cdrskin/man_1_cdrskin.html"
|
||||||
|
|
||||||
# bintarget_dynamic="cdrskin_${skin_rev}-amd64-suse10_2"
|
bintarget_dynamic="cdrskin_${skin_rev}-amd64-suse10_2"
|
||||||
bintarget_dynamic="cdrskin_${skin_rev}-amd64-debian8_0"
|
|
||||||
bintarget_static="$bintarget_dynamic"-static
|
bintarget_static="$bintarget_dynamic"-static
|
||||||
|
|
||||||
if test -d "$changes"
|
if test -d "$changes"
|
||||||
|
@ -229,8 +228,6 @@ tar czf "$cdrskin_tarball" "$target"
|
||||||
fi
|
fi
|
||||||
# "$compile_cmd" -libburn_svn -O2 -do_diet -do_strip
|
# "$compile_cmd" -libburn_svn -O2 -do_diet -do_strip
|
||||||
# cp "$compile_result" "../$bintarget_dynamic"_diet
|
# cp "$compile_result" "../$bintarget_dynamic"_diet
|
||||||
|
|
||||||
( cd cdrskin ; cc -g -Wall -o unite_html_b_line unite_html_b_line.c )
|
|
||||||
"$man_to_html_cmd"
|
"$man_to_html_cmd"
|
||||||
mv "$man_page_html" ..
|
mv "$man_page_html" ..
|
||||||
)
|
)
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
cdrfifo.c , Copyright 2006 - 2016 Thomas Schmitt <scdbackup@gmx.net>
|
cdrfifo.c , Copyright 2006 Thomas Schmitt <scdbackup@gmx.net>
|
||||||
|
|
||||||
A fd-to-fd or fd-to-memory fifo to be used within cdrskin or independently.
|
A fd-to-fd or fd-to-memory fifo to be used within cdrskin or independently.
|
||||||
By chaining of fifo objects, several fifos can be run simultaneously
|
By chaining of fifo objects, several fifos can be run simultaneously
|
||||||
|
@ -26,22 +26,8 @@
|
||||||
#include <sys/select.h>
|
#include <sys/select.h>
|
||||||
|
|
||||||
#ifndef Cdrfifo_standalonE
|
#ifndef Cdrfifo_standalonE
|
||||||
/* for burn_os_alloc_buffer() */
|
/* <<< until release of 0.7.4 : for Libburn_has_open_trac_srC */
|
||||||
#include "../libburn/libburn.h"
|
#include "../libburn/libburn.h"
|
||||||
|
|
||||||
/* ts B91124:
|
|
||||||
DISABLED, because this spoils multi-track burning by slowing down first
|
|
||||||
track and stalling before the second track begins. Obviously a problem
|
|
||||||
with chained input and waiting for full O_DRIECT suitable read chunks.
|
|
||||||
DO NOT ENABLE before the wait code in this source file is fixed.
|
|
||||||
That long, ./configure option --enable-track-src-odirect must not
|
|
||||||
get into effect in libburn. NO -DLibburn_read_o_direcT either.
|
|
||||||
|
|
||||||
For extra safety, O_DIRECT has been banned in libburn/sg-linux.c too.
|
|
||||||
|
|
||||||
# def ine Libburn_has_open_trac_srC 1
|
|
||||||
*/
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "cdrfifo.h"
|
#include "cdrfifo.h"
|
||||||
|
@ -121,9 +107,6 @@ struct CdrfifO {
|
||||||
/* index of currently active (i.e. reading) follow-up */
|
/* index of currently active (i.e. reading) follow-up */
|
||||||
int follow_up_fd_idx;
|
int follow_up_fd_idx;
|
||||||
|
|
||||||
/* short read encountered, take subsequent errno 22 with O_DIRECT as EOF */
|
|
||||||
int o_direct_was_short;
|
|
||||||
|
|
||||||
|
|
||||||
/* (simultaneous) peer chaining */
|
/* (simultaneous) peer chaining */
|
||||||
struct CdrfifO *next;
|
struct CdrfifO *next;
|
||||||
|
@ -194,7 +177,6 @@ int Cdrfifo_new(struct CdrfifO **ff, int source_fd, int dest_fd,
|
||||||
}
|
}
|
||||||
o->follow_up_fd_counter= 0;
|
o->follow_up_fd_counter= 0;
|
||||||
o->follow_up_fd_idx= -1;
|
o->follow_up_fd_idx= -1;
|
||||||
o->o_direct_was_short= 0;
|
|
||||||
o->next= o->prev= NULL;
|
o->next= o->prev= NULL;
|
||||||
o->chain_idx= 0;
|
o->chain_idx= 0;
|
||||||
|
|
||||||
|
@ -714,17 +696,8 @@ after_write:;
|
||||||
else if(can_read < Cdrfifo_o_direct_chunK)
|
else if(can_read < Cdrfifo_o_direct_chunK)
|
||||||
can_read= -1;
|
can_read= -1;
|
||||||
ret= 0;
|
ret= 0;
|
||||||
if(can_read>0) {
|
if(can_read>0)
|
||||||
ret= read(o->source_fd,o->buffer+o->write_idx,can_read);
|
ret= read(o->source_fd,o->buffer+o->write_idx,can_read);
|
||||||
if(ret > 0) {
|
|
||||||
if(ret < can_read) {
|
|
||||||
/* Probably EOF. Prepare for errno = 22 in the next read. */
|
|
||||||
o->o_direct_was_short= 1;
|
|
||||||
} else {
|
|
||||||
o->o_direct_was_short= 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(can_read < 0) {
|
if(can_read < 0) {
|
||||||
/* waiting for a full Cdrfifo_o_direct_chunK to fit */
|
/* waiting for a full Cdrfifo_o_direct_chunK to fit */
|
||||||
if(can_write <= 0 && o->dest_fd >= 0) {
|
if(can_write <= 0 && o->dest_fd >= 0) {
|
||||||
|
@ -758,8 +731,6 @@ after_write:;
|
||||||
#endif /* ! Libburn_has_open_trac_srC */
|
#endif /* ! Libburn_has_open_trac_srC */
|
||||||
|
|
||||||
if(ret==-1) {
|
if(ret==-1) {
|
||||||
if(o->o_direct_was_short && errno == 22)
|
|
||||||
goto have_eof;
|
|
||||||
|
|
||||||
/* >>> handle input error */;
|
/* >>> handle input error */;
|
||||||
fprintf(stderr,"\ncdrfifo %d: on read: errno=%d , \"%s\"\n",
|
fprintf(stderr,"\ncdrfifo %d: on read: errno=%d , \"%s\"\n",
|
||||||
|
@ -768,7 +739,6 @@ after_write:;
|
||||||
|
|
||||||
o->source_fd= -1;
|
o->source_fd= -1;
|
||||||
} else if(ret==0) { /* eof */
|
} else if(ret==0) { /* eof */
|
||||||
have_eof:;
|
|
||||||
/* activate eventual follow-up source fd */
|
/* activate eventual follow-up source fd */
|
||||||
if(Cdrfifo_debuG || (flag&1))
|
if(Cdrfifo_debuG || (flag&1))
|
||||||
fprintf(stderr,"\ncdrfifo %d: on read(%d,buffer,%d): eof\n",
|
fprintf(stderr,"\ncdrfifo %d: on read(%d,buffer,%d): eof\n",
|
||||||
|
@ -829,7 +799,7 @@ ex:;
|
||||||
/** Check for pending data at the fifo's source file descriptor and wether the
|
/** Check for pending data at the fifo's source file descriptor and wether the
|
||||||
fifo is ready to take them. Simultaneously check the buffer for existing
|
fifo is ready to take them. Simultaneously check the buffer for existing
|
||||||
data and the destination fd for readiness to accept some. If so, a small
|
data and the destination fd for readiness to accept some. If so, a small
|
||||||
chunk of data is transferred to and/or from the fifo.
|
chunk of data is transfered to and/or from the fifo.
|
||||||
This is done for the given fifo object and all members of its next-chain.
|
This is done for the given fifo object and all members of its next-chain.
|
||||||
The check and transactions are repeated until a given timespan has elapsed.
|
The check and transactions are repeated until a given timespan has elapsed.
|
||||||
libburn applications call this function in the burn loop instead of sleep().
|
libburn applications call this function in the burn loop instead of sleep().
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
|
|
||||||
/*
|
/*
|
||||||
cdrfifo.c , Copyright 2006 - 2016 Thomas Schmitt <scdbackup@gmx.net>
|
cdrfifo.c , Copyright 2006 Thomas Schmitt <scdbackup@gmx.net>
|
||||||
|
|
||||||
A fd-to-fd or fd-to-memory fifo to be used within cdrskin or independently.
|
A fd-to-fd or fd-to-memory fifo to be used within cdrskin or independently.
|
||||||
By chaining of fifo objects, several fifos can be run simultaneously
|
By chaining of fifo objects, several fifos can be run simultaneously
|
||||||
|
@ -118,7 +118,7 @@ int Cdrfifo_get_cdr_counters(struct CdrfifO *o,
|
||||||
int flag);
|
int flag);
|
||||||
|
|
||||||
/** Inquire the eventually detected size of an eventual ISO-9660 file system
|
/** 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);
|
int Cdrfifo_get_iso_fs_size(struct CdrfifO *o, double *size_in_bytes,int flag);
|
||||||
|
|
||||||
|
@ -136,7 +136,7 @@ int Cdrfifo_adopt_iso_fs_descr(struct CdrfifO *o, char **pt, int flag);
|
||||||
/** Check for pending data at the fifo's source file descriptor and wether the
|
/** Check for pending data at the fifo's source file descriptor and wether the
|
||||||
fifo is ready to take them. Simultaneously check the buffer for existing
|
fifo is ready to take them. Simultaneously check the buffer for existing
|
||||||
data and the destination fd for readiness to accept some. If so, a small
|
data and the destination fd for readiness to accept some. If so, a small
|
||||||
chunk of data is transferred to and/or from the fifo.
|
chunk of data is transfered to and/or from the fifo.
|
||||||
This is done for the given fifo object and all members of its next-chain.
|
This is done for the given fifo object and all members of its next-chain.
|
||||||
The check and transactions are repeated until a given timespan has elapsed.
|
The check and transactions are repeated until a given timespan has elapsed.
|
||||||
libburn applications call this function in the burn loop instead of sleep().
|
libburn applications call this function in the burn loop instead of sleep().
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
.\" First parameter, NAME, should be all caps
|
.\" First parameter, NAME, should be all caps
|
||||||
.\" Second parameter, SECTION, should be 1-8, maybe w/ subsection
|
.\" Second parameter, SECTION, should be 1-8, maybe w/ subsection
|
||||||
.\" other parameters are allowed: see man(7), man(1)
|
.\" other parameters are allowed: see man(7), man(1)
|
||||||
.TH CDRSKIN 1 "Version 1.5.7, Jun 07, 2023"
|
.TH CDRSKIN 1 "Jul 28, 2011"
|
||||||
.\" Please adjust this date whenever revising the manpage.
|
.\" Please adjust this date whenever revising the manpage.
|
||||||
.\"
|
.\"
|
||||||
.\" Some roff macros, for reference:
|
.\" Some roff macros, for reference:
|
||||||
|
@ -37,7 +37,7 @@ Blanking of CD-RW and DVD-RW.
|
||||||
.br
|
.br
|
||||||
Formatting of DVD-RW, DVD+RW, DVD-RAM, BD.
|
Formatting of DVD-RW, DVD+RW, DVD-RAM, BD.
|
||||||
.br
|
.br
|
||||||
Burning of data tracks or audio tracks with CD-TEXT to CD,
|
Burning of data or audio tracks to CD,
|
||||||
.br
|
.br
|
||||||
either in versatile Track at Once mode (TAO)
|
either in versatile Track at Once mode (TAO)
|
||||||
.br
|
.br
|
||||||
|
@ -55,8 +55,6 @@ on overwriteable DVD+RW, DVD-RW, DVD-RAM, BD-RE
|
||||||
.br
|
.br
|
||||||
or on data file or block device.
|
or on data file or block device.
|
||||||
.br
|
.br
|
||||||
Extraction of audio tracks and CD-TEXT to hard disk files.
|
|
||||||
.br
|
|
||||||
Bus scan, burnfree, speed options, retrieving media info, padding, fifo.
|
Bus scan, burnfree, speed options, retrieving media info, padding, fifo.
|
||||||
.br
|
.br
|
||||||
See section EXAMPLES at the end of this text.
|
See section EXAMPLES at the end of this text.
|
||||||
|
@ -82,19 +80,15 @@ Emulated drives
|
||||||
The input-output entities which get processed are called tracks.
|
The input-output entities which get processed are called tracks.
|
||||||
A \fBtrack\fP stores a stream of bytes.
|
A \fBtrack\fP stores a stream of bytes.
|
||||||
.br
|
.br
|
||||||
|
Each track is initiated by one track source address argument, which may either
|
||||||
|
be "-" for standard input or the address of a readable file. If no write mode
|
||||||
|
is given explicitly then one will be chosen which matches the peculiarities
|
||||||
|
of track sources and the state of the output media.
|
||||||
|
.PP
|
||||||
More than one track can be burned by a single run of cdrskin.
|
More than one track can be burned by a single run of cdrskin.
|
||||||
In the terms of the MMC standard all tracks written by the same run constitute
|
In the terms of the MMC standard all tracks written by the same run constitute
|
||||||
a \fBsession\fP.
|
a \fBsession\fP.
|
||||||
.br
|
.br
|
||||||
Normally, each track is initiated by one track source address argument,
|
|
||||||
which may either be "-" for standard input or the address of a readable file.
|
|
||||||
Alternatively, option cuefile= may be used to read a session description
|
|
||||||
from a text file and to read the session content from a single data file.
|
|
||||||
.br
|
|
||||||
If no write mode
|
|
||||||
is given explicitly then one will be chosen which matches the peculiarities
|
|
||||||
of track sources and the state of the output media.
|
|
||||||
.PP
|
|
||||||
Some media types can be kept appendable so that further tracks can
|
Some media types can be kept appendable so that further tracks can
|
||||||
be written to them in subsequent runs of cdrskin (see option -multi).
|
be written to them in subsequent runs of cdrskin (see option -multi).
|
||||||
Info about the addresses of burned tracks is kept in a table of
|
Info about the addresses of burned tracks is kept in a table of
|
||||||
|
@ -103,15 +97,15 @@ This information is also used by the operating systems' CD-ROM read drivers.
|
||||||
.PP
|
.PP
|
||||||
In general there are two types of tracks: data and audio. They differ in
|
In general there are two types of tracks: data and audio. They differ in
|
||||||
sector size, throughput and readability via the systems' CD-ROM drivers
|
sector size, throughput and readability via the systems' CD-ROM drivers
|
||||||
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
|
.br
|
||||||
If not explicitly option -audio is given, then any track is burned as type
|
If not explicitly option -audio is given, then any track is burned as type
|
||||||
data, unless the track source is a file with suffix ".wav" or ".au" and has a
|
data, unless the track source is a file with suffix ".wav" or ".au" and has a
|
||||||
header part which identifies it as MS-WAVE 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.
|
parameters. Such files are burned as audio tracks by default.
|
||||||
.PP
|
.PP
|
||||||
While audio tracks just contain a given time span of acoustic vibrations,
|
While audio tracks just contain a given time span of acoustic vibrations,
|
||||||
data tracks may have an arbitrary meaning. Nevertheless, ISO-9660 filesystems
|
data tracks may have an arbitray meaning. Nevertheless, ISO-9660 filesystems
|
||||||
are established as a format which can represent a tree of directories and
|
are established as a format which can represent a tree of directories and
|
||||||
files on all major operating systems. Such filesystem images can be
|
files on all major operating systems. Such filesystem images can be
|
||||||
produced by programs mkisofs or genisoimage or xorriso.
|
produced by programs mkisofs or genisoimage or xorriso.
|
||||||
|
@ -128,16 +122,16 @@ the archivers afio and star. Not suitable seems GNU tar.
|
||||||
.br
|
.br
|
||||||
In general there are two approaches for writing media:
|
In general there are two approaches for writing media:
|
||||||
.br
|
.br
|
||||||
A permissive mode selected by option
|
A permissive mode depicted by option
|
||||||
.B -tao
|
.B -tao
|
||||||
which needs no predicted track size and can use
|
which needs no predicted track size and allows to make use of
|
||||||
multi-session capabilities if offered by drive and medium.
|
eventual multi-session capabilities.
|
||||||
.br
|
.br
|
||||||
A more restrictive mode
|
A more restrictive mode
|
||||||
.B -sao
|
.B -sao
|
||||||
(alias -dao) which usually demands a predictable track size and is not
|
(alias -dao) which usually demands a predictable track size and is not
|
||||||
necessarily capable of multi-session. It can be used to write CD-TEXT and
|
necessarily capable of multi-session. It may have advantages for some
|
||||||
it is the only one that works with option cuefile=.
|
readers resp. players of the recorded tracks.
|
||||||
.br
|
.br
|
||||||
If none of the options -dao, -tao or -sao is given then the program will
|
If none of the options -dao, -tao or -sao is given then the program will
|
||||||
try to choose a write mode which matches the defined recording job,
|
try to choose a write mode which matches the defined recording job,
|
||||||
|
@ -156,8 +150,8 @@ read-only. Closing is done automatically unless option
|
||||||
is given which keeps the media appendable.
|
is given which keeps the media appendable.
|
||||||
.br
|
.br
|
||||||
Write mode
|
Write mode
|
||||||
-tao is able to use track sources of unpredictable length (like stdin) and
|
-tao allows to use track sources of unpredictable length (like stdin) and
|
||||||
to write further sessions to appendable media.
|
allows to write further sessions to appendable media.
|
||||||
-sao produces audio sessions with seamless tracks but needs predicted track
|
-sao produces audio sessions with seamless tracks but needs predicted track
|
||||||
sizes and cannot append sessions to media.
|
sizes and cannot append sessions to media.
|
||||||
.br
|
.br
|
||||||
|
@ -185,8 +179,7 @@ Used DVD-RW get into blank sequential state by option
|
||||||
With DVD-R[W] two write modes may be available:
|
With DVD-R[W] two write modes may be available:
|
||||||
.br
|
.br
|
||||||
Mode DAO has many restrictions. It does not work with
|
Mode DAO has many restrictions. It does not work with
|
||||||
appendable media, cannot do -multi and writes only a single track.
|
appendable media, allows no -multi and only a single track. The size of the
|
||||||
The size of the
|
|
||||||
track needs to be known in advance. So either its source has to be a disk file
|
track needs to be known in advance. So either its source has to be a disk file
|
||||||
of recognizable size or the size has to be announced explicitly by options
|
of recognizable size or the size has to be announced explicitly by options
|
||||||
.B tsize=
|
.B tsize=
|
||||||
|
@ -203,8 +196,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.
|
it is available and if the restrictions of DAO would prevent the job.
|
||||||
Incremental Streaming may be selected explicitly by option
|
Incremental Streaming may be selected explicitly by option
|
||||||
.B -tao
|
.B -tao
|
||||||
as it resembles much CD TAO by accepting track sources of
|
as it resembles much CD TAO by allowing track sources of
|
||||||
unpredicted length and being able to keep media appendable by option
|
unpredicted length and to keep media appendable by option
|
||||||
.B -multi . It does not work with DVD-R DL and minimally blanked DVD-RW.
|
.B -multi . It does not work with DVD-R DL and minimally blanked DVD-RW.
|
||||||
The only restriction towards CD-R[W] is the lack of support for -audio tracks.
|
The only restriction towards CD-R[W] is the lack of support for -audio tracks.
|
||||||
Multiple tracks per session are permissible.
|
Multiple tracks per session are permissible.
|
||||||
|
@ -215,7 +208,7 @@ with DVD+R[/DL] or BD-R.
|
||||||
.br
|
.br
|
||||||
Quite deliberately write mode -sao insists in the tradition of a predicted
|
Quite deliberately write mode -sao insists in the tradition of a predicted
|
||||||
track size and blank media, whereas -tao writes the tracks open ended and
|
track size and blank media, whereas -tao writes the tracks open ended and
|
||||||
can be applied to appendable media.
|
allows appendable media.
|
||||||
.br
|
.br
|
||||||
BD-R may be formatted before first use to enable the Defect Management which
|
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
|
might catch and repair some bad spots at the expense of slow speed
|
||||||
|
@ -238,7 +231,7 @@ of option
|
||||||
.B --grow_overwriteable_iso .
|
.B --grow_overwriteable_iso .
|
||||||
Without this option or without an ISO-9660 filesystem image present
|
Without this option or without an ISO-9660 filesystem image present
|
||||||
on media, -toc does not return information about the media content and
|
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
|
.br
|
||||||
Currently there is no difference between -sao and -tao. If ever, then -tao
|
Currently there is no difference between -sao and -tao. If ever, then -tao
|
||||||
will be the mode which preserves the current behavior.
|
will be the mode which preserves the current behavior.
|
||||||
|
@ -320,7 +313,7 @@ redirected to stderr and the stream data of a burn run will appear on stdout.
|
||||||
.br
|
.br
|
||||||
Not good for terminals ! Redirect it.
|
Not good for terminals ! Redirect it.
|
||||||
.br
|
.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.
|
-dummy burn runs touch the file but do not modify its data content.
|
||||||
.br
|
.br
|
||||||
Note: --allow_emulated_drives is restricted to stdio:/dev/null if cdrskin
|
Note: --allow_emulated_drives is restricted to stdio:/dev/null if cdrskin
|
||||||
|
@ -361,7 +354,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,
|
The source is supposed to be uncompressed headerless PCM, 44100 Hz, 16 bit,
|
||||||
stereo. For little-endian byte order (which is usual on PCs) use option
|
stereo. For little-endian byte order (which is usual on PCs) use option
|
||||||
-swab. Unless marked explicitly by option -data, input files with suffix
|
-swab. Unless marked 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
|
those parameters and eventually raw audio data get extracted and burned as
|
||||||
audio track. Same is done for suffix ".au" and SUN Audio.
|
audio track. Same is done for suffix ".au" and SUN Audio.
|
||||||
.br
|
.br
|
||||||
|
@ -427,7 +420,7 @@ Format a DVD-RW to "Restricted Overwrite". The user should bring some patience.
|
||||||
.TP
|
.TP
|
||||||
format_overwrite_quickest
|
format_overwrite_quickest
|
||||||
Like format_overwrite without creating a 128 MiB trailblazer session.
|
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.
|
beginning from address 0.
|
||||||
The "intermediate" state ends after the first session of writing data.
|
The "intermediate" state ends after the first session of writing data.
|
||||||
.TP
|
.TP
|
||||||
|
@ -446,7 +439,7 @@ format_defectmgt
|
||||||
Format DVD-RAM or BD to reserve the default amount of spare blocks for
|
Format DVD-RAM or BD to reserve the default amount of spare blocks for
|
||||||
defect management.
|
defect management.
|
||||||
.br
|
.br
|
||||||
The following format_defectmgt_* 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
|
nevertheless have to match one of the available formats. These formats are
|
||||||
offered by the drive after examining the media.
|
offered by the drive after examining the media.
|
||||||
.TP
|
.TP
|
||||||
|
@ -482,7 +475,7 @@ Unformatted blank BD-R will be left unformatted.
|
||||||
format_defectmgt_payload_<size>
|
format_defectmgt_payload_<size>
|
||||||
Format DVD-RAM or BD. The text after "format_defectmgt_payload_" gives a
|
Format DVD-RAM or BD. The text after "format_defectmgt_payload_" gives a
|
||||||
number of bytes, eventually with suffixes "s", "k", "m". The largest number
|
number of bytes, eventually with suffixes "s", "k", "m". The largest number
|
||||||
of spare blocks will be chosen which enables at least the given payload size.
|
of spare blocks will be chosen which allows at least the given payload size.
|
||||||
.TP
|
.TP
|
||||||
format_by_index_<number>
|
format_by_index_<number>
|
||||||
Format DVD-RW, DVD+RW, DVD-RAM or BD.
|
Format DVD-RW, DVD+RW, DVD-RAM or BD.
|
||||||
|
@ -501,27 +494,6 @@ Print this list of blanking types.
|
||||||
Retrieve some info about the addressed drive and then exit.
|
Retrieve some info about the addressed drive and then exit.
|
||||||
Exits with non-zero value if the drive cannot be found and opened.
|
Exits with non-zero value if the drive cannot be found and opened.
|
||||||
.TP
|
.TP
|
||||||
.BI \-copy
|
|
||||||
Create the subsequent tracks with permission for an unlimited number of copies.
|
|
||||||
.TP
|
|
||||||
.BI cuefile= path
|
|
||||||
Read a session description from a cue sheet file in CDRWIN format.
|
|
||||||
Base the tracks on a single file which is given in the sheet by command FILE.
|
|
||||||
To enable CD-TEXT from the cue sheet file, cdrskin option -text has to be
|
|
||||||
present.
|
|
||||||
.br
|
|
||||||
cdrskin currently supports TRACK datatypes AUDIO and MODE1/2048 which may
|
|
||||||
not be mixed.
|
|
||||||
Data source may be of FILE type BINARY, MOTOROLA, or WAVE.
|
|
||||||
.br
|
|
||||||
Non-CDRWIN commands ARRANGER, COMPOSER, MESSAGE are supported.
|
|
||||||
.br
|
|
||||||
Cue sheet file commands CATALOG and ISRC may be overridden by option mcn=
|
|
||||||
and by input_sheet_v07t= purpose specifiers "UPC / EAN" and "ISRC".
|
|
||||||
This does not affect their appearance in CD-TEXT, but only on Q sub-channel.
|
|
||||||
.br
|
|
||||||
The track numbers may be overridden by option cd_start_tno=.
|
|
||||||
.TP
|
|
||||||
.BI \-dao
|
.BI \-dao
|
||||||
Alias for option -sao. Write CD in Session at Once mode
|
Alias for option -sao. Write CD in Session at Once mode
|
||||||
or DVD-R[W] in Disc-at-once mode.
|
or DVD-R[W] in Disc-at-once mode.
|
||||||
|
@ -532,7 +504,6 @@ to mark the end of the range of an eventual option -audio or -xa1.
|
||||||
.br
|
.br
|
||||||
Options -mode2, -xa, and -xa2 get mapped to -data, not using the desired CD
|
Options -mode2, -xa, and -xa2 get mapped to -data, not using the desired CD
|
||||||
sector formats and thus not taking advantage of eventual higher payload.
|
sector formats and thus not taking advantage of eventual higher payload.
|
||||||
.TP
|
|
||||||
.BI \-xa1
|
.BI \-xa1
|
||||||
Subsequent tracks are data tracks with input suitable for CD-ROM XA mode 2
|
Subsequent tracks are data tracks with input suitable for CD-ROM XA mode 2
|
||||||
form 1. This differs from -data input by 8 additional header bytes per block.
|
form 1. This differs from -data input by 8 additional header bytes per block.
|
||||||
|
@ -573,14 +544,9 @@ Eject the disc after work is done.
|
||||||
.TP
|
.TP
|
||||||
.BI \-force
|
.BI \-force
|
||||||
Assume that the user knows better in situations when cdrskin or libburn are
|
Assume that the user knows better in situations when cdrskin or libburn are
|
||||||
refusing because of concerns about drive or media state.
|
insecure about drive or media state. This includes the attempt to blank
|
||||||
.br
|
|
||||||
.B Caution:
|
|
||||||
Use option -force only when in urgent need.
|
|
||||||
.br
|
|
||||||
This option enables the attempt to blank
|
|
||||||
media which are classified as unknown or unsuitable, and the attempt to use
|
media which are classified as unknown or unsuitable, and the attempt to use
|
||||||
write modes of which libburn believes they are not supported by the drive.
|
write modes which libburn believes they are not supported by the drive.
|
||||||
.br
|
.br
|
||||||
Another application is to enforce blanking or re-formatting of media
|
Another application is to enforce blanking or re-formatting of media
|
||||||
which appear to be in the desired blank or format state already.
|
which appear to be in the desired blank or format state already.
|
||||||
|
@ -589,22 +555,10 @@ This option enables a burn run with option -dummy even if libburn believes
|
||||||
that drive and media will not simulate the write mode but will write for real.
|
that drive and media will not simulate the write mode but will write for real.
|
||||||
.br
|
.br
|
||||||
It enables a burn run where cdrskin expects to exceed the available media
|
It enables a burn run where cdrskin expects to exceed the available media
|
||||||
capacity. This is known as "overburn" and might succeed on CD media with
|
capacity.
|
||||||
write type SAO.
|
|
||||||
.B Too much overburning
|
|
||||||
might be
|
|
||||||
.B harmful to the medium
|
|
||||||
and might
|
|
||||||
.B make the drive unusable
|
|
||||||
(hopefully only until it gets powered off and on). The man page of cdrecord
|
|
||||||
mentions 88 seconds = 6600 blocks as halfways safe amount over the official
|
|
||||||
medium capacity. The assessment of track sizes by libburn will be wrong if
|
|
||||||
the written size reaches or exceeds 90 minutes = 405000 sectors. The overall
|
|
||||||
medium size assessment by the Linux kernel is supposed to yield roughly the
|
|
||||||
written size, but you should test this yourself with every overburnt medium.
|
|
||||||
.br
|
.br
|
||||||
First consider to use a medium with more capacity rather than trying to
|
.B Caution:
|
||||||
overburn a CD.
|
Use this only when in urgent need.
|
||||||
.TP
|
.TP
|
||||||
.BI \-format
|
.BI \-format
|
||||||
Same as blank=format_overwrite_full -force but restricted to DVD+RW.
|
Same as blank=format_overwrite_full -force but restricted to DVD+RW.
|
||||||
|
@ -636,22 +590,7 @@ modesty_on_drive=1:min_percent=75:max_percent=95
|
||||||
The name of this cdrecord option stems from the "Immed" bit which can make some
|
The name of this cdrecord option stems from the "Immed" bit which can make some
|
||||||
long running drive commands asynchronous and thus eases the load on some
|
long running drive commands asynchronous and thus eases the load on some
|
||||||
wiring hardware types. Regardless of option -immed, cdrskin uses asynchronous
|
wiring hardware types. Regardless of option -immed, cdrskin uses asynchronous
|
||||||
commands where possible and appropriate. To really disable asynchronous command
|
commands where possible and appropriate.
|
||||||
execution, use option use_immed_bit=off .
|
|
||||||
.TP
|
|
||||||
.BI index= list
|
|
||||||
Set a comma separated list of index start address numbers for the next track.
|
|
||||||
This applies to CD SAO sessions only.
|
|
||||||
.br
|
|
||||||
The addresses count sectors from the start of the next track. The first number
|
|
||||||
is for index 1 and must be 0. The following numbers have to be larger than
|
|
||||||
their respective predecessors. Up to 99 numbers are allowed.
|
|
||||||
.br
|
|
||||||
Sector numbers are computed from Min:Sec:Frame addresses by
|
|
||||||
.br
|
|
||||||
Sector = ((Min*60)+Sec)*75+Frame
|
|
||||||
.br
|
|
||||||
E.g.: "0,7512,20408" sets index 2 to 01:40:12 and index 3 to 04:32:08.
|
|
||||||
.TP
|
.TP
|
||||||
.BI -inq
|
.BI -inq
|
||||||
Print the identification of the drive and then exit.
|
Print the identification of the drive and then exit.
|
||||||
|
@ -672,16 +611,6 @@ This option can be performed on track sources which are regular files or block
|
||||||
devices. For the first track of the session it can be performed on any type
|
devices. For the first track of the session it can be performed on any type
|
||||||
of source if there is a fifo of at least 64 kiB. See option fs= .
|
of source if there is a fifo of at least 64 kiB. See option fs= .
|
||||||
.TP
|
.TP
|
||||||
.BI isrc= text
|
|
||||||
Set the ISRC for the next track source to the given text, which must be exactly
|
|
||||||
13 characters long. It must comply to the format CCOOOYYSSSSS.
|
|
||||||
.br
|
|
||||||
CC is the country code. OOO is the owner code. Both may consist of capital
|
|
||||||
letters A to Z and of decimal digits 0 to 9. YY depicts the year (00 to 99).
|
|
||||||
SSSSS is the serial number (00000 to 99999).
|
|
||||||
.br
|
|
||||||
This option does not affect CD-TEXT but only the Q sub-channel.
|
|
||||||
.TP
|
|
||||||
.BI -load
|
.BI -load
|
||||||
Load the media and exit. Exit value is 0 if any kind of media was found, non
|
Load the media and exit. Exit value is 0 if any kind of media was found, non
|
||||||
zero else. Note: Option -eject will unload the media even if -load is given.
|
zero else. Note: Option -eject will unload the media even if -load is given.
|
||||||
|
@ -694,12 +623,6 @@ Use program "eject" or cdrskin -eject to get the tray out of the drive.
|
||||||
Runs of programs like cdrecord, growisofs, wodim, cdrskin will not be hampered
|
Runs of programs like cdrecord, growisofs, wodim, cdrskin will not be hampered
|
||||||
and normally enable the drive's eject button when they are done.
|
and normally enable the drive's eject button when they are done.
|
||||||
.TP
|
.TP
|
||||||
.BI mcn= text
|
|
||||||
Set the CD Media Catalog Number to text, which must be exactly 13 characters
|
|
||||||
long and should consist of decimal digits.
|
|
||||||
.br
|
|
||||||
This option does not affect CD-TEXT but only the Q sub-channel.
|
|
||||||
.TP
|
|
||||||
.BI minbuf= percentage
|
.BI minbuf= percentage
|
||||||
Equivalent to:
|
Equivalent to:
|
||||||
.br
|
.br
|
||||||
|
@ -761,19 +684,11 @@ for lifting the ban on -multi.
|
||||||
.br
|
.br
|
||||||
Note: -multi might make DVD media unreadable in some DVD-ROM drives.
|
Note: -multi might make DVD media unreadable in some DVD-ROM drives.
|
||||||
.TP
|
.TP
|
||||||
.BI \-nocopy
|
|
||||||
Create subsequent tracks with permission for a single level of copies.
|
|
||||||
I.e. those copies would then be marked by -scms as offering no permission
|
|
||||||
for further copies.
|
|
||||||
.TP
|
|
||||||
.BI \-nopad
|
.BI \-nopad
|
||||||
Do not add trailing zeros to the data stream. Nevertheless, since there seems
|
Do not add trailing zeros to the data stream. Nevertheless, since there seems
|
||||||
to be no use for audio tracks with incomplete last sector, this option applies
|
to be no use for audio tracks with incomplete last sector, this option applies
|
||||||
only to data tracks. There it is default.
|
only to data tracks. There it is default.
|
||||||
.TP
|
.TP
|
||||||
.BI \-nopreemp
|
|
||||||
Indicate for subsequent tracks that they were mastered without pre-emphasis.
|
|
||||||
.TP
|
|
||||||
.BI \-pad
|
.BI \-pad
|
||||||
Add 30 kiB of trailing zeros to each data track. (This is not sufficient to
|
Add 30 kiB of trailing zeros to each data track. (This is not sufficient to
|
||||||
avoid problems with various CD-ROM read drivers.)
|
avoid problems with various CD-ROM read drivers.)
|
||||||
|
@ -783,9 +698,6 @@ Add the given amount of trailing zeros to the next data track. This option
|
||||||
gets reset to padsize=0 after that next track is written. It may be set
|
gets reset to padsize=0 after that next track is written. It may be set
|
||||||
again before the next track argument. About size specifiers, see option fs=.
|
again before the next track argument. About size specifiers, see option fs=.
|
||||||
.TP
|
.TP
|
||||||
.BI \-preemp
|
|
||||||
Indicate for subsequent tracks that they were mastered with pre-emphasis.
|
|
||||||
.TP
|
|
||||||
.BI \-sao
|
.BI \-sao
|
||||||
Write CD in Session At Once mode or sequential DVD-R[W] in Disc-at-once
|
Write CD in Session At Once mode or sequential DVD-R[W] in Disc-at-once
|
||||||
(DAO) mode.
|
(DAO) mode.
|
||||||
|
@ -818,17 +730,9 @@ The useful fields in a result line are:
|
||||||
.br
|
.br
|
||||||
Bus,Target,Lun Number) 'Vendor' 'Mode' 'Revision'
|
Bus,Target,Lun Number) 'Vendor' 'Mode' 'Revision'
|
||||||
.TP
|
.TP
|
||||||
.BI \-scms
|
|
||||||
Create subsequent tracks without permission for being copied. This is usually
|
|
||||||
done for tracks which are copies of tracks that were marked with -nocopy
|
|
||||||
(but not yet with -scms). So copies of copies are prohibited.
|
|
||||||
.br
|
|
||||||
This option gets reset by option -copy. Thus the combination -copy -nocopy
|
|
||||||
means -nocopy surely without -scms.
|
|
||||||
.TP
|
|
||||||
.BI speed= number
|
.BI speed= number
|
||||||
Set speed of drive. With data CD, 1x speed corresponds to a throughput of
|
Set speed of drive. With data CD, 1x speed corresponds to a throughput of
|
||||||
153,600 bytes/second. With DVD, 1x = 1,385,000 bytes/second.
|
150,000 bytes/second. With DVD, 1x = 1,385,000 bytes/second.
|
||||||
With BD 1x = 4,495,625 bytes/second.
|
With BD 1x = 4,495,625 bytes/second.
|
||||||
It is not an error to set a speed higher than is suitable for drive
|
It is not an error to set a speed higher than is suitable for drive
|
||||||
and media. One should stay within a realistic speed range, though.
|
and media. One should stay within a realistic speed range, though.
|
||||||
|
@ -852,61 +756,16 @@ This mode also applies pro-forma to overwriteable media
|
||||||
Mode -tao can be used with track sources of unpredictable size, like standard
|
Mode -tao can be used with track sources of unpredictable size, like standard
|
||||||
input or named pipes. It is also the only mode that can be used for writing
|
input or named pipes. It is also the only mode that can be used for writing
|
||||||
to appendable media which already hold data. With unformatted DVD-R[W] it is
|
to appendable media which already hold data. With unformatted DVD-R[W] it is
|
||||||
the only mode which can keep media appendable by option -multi.
|
the only mode which allows -multi.
|
||||||
.br
|
.br
|
||||||
Mode -tao is not usable for minimally blanked DVD-RW and for DVD-R DL.
|
Mode -tao is not usable for minimally blanked DVD-RW and for DVD-R DL.
|
||||||
.TP
|
.TP
|
||||||
.BI \-text
|
|
||||||
Enable writing of CD-TEXT attributes read by option cuefile=.
|
|
||||||
Without option -text, cue sheet file command CDTEXTFILE will be ignored and
|
|
||||||
no CD-TEXT attributes will be read from the file. Nevertheless, CATALOG and
|
|
||||||
ISRC will have the same effect as options mcn= and isrc=.
|
|
||||||
.TP
|
|
||||||
.BI textfile= path
|
|
||||||
Read CD-TEXT packs from the file depicted by path and put them into the
|
|
||||||
Lead-in of the emerging session. This session has to be done by Session At Once
|
|
||||||
(SAO) mode and may only contain audio tracks.
|
|
||||||
.br
|
|
||||||
path must lead to a regular file, which consists of an optional header of four
|
|
||||||
bytes and one or more text packs of 18 bytes each. Suitable would be the
|
|
||||||
file 'cdtext.dat' which gets extracted from CD media by options -vv -toc
|
|
||||||
and shown in human readable form by -vvv -toc.
|
|
||||||
.br
|
|
||||||
The header, if present, must tell the file size minus 2, encoded as big-endian
|
|
||||||
16 bit word. The other two bytes must be 0.
|
|
||||||
.br
|
|
||||||
If there is no 4-byte header, then a trailing 0-byte, as of Sony specification,
|
|
||||||
is tolerated and ignored.
|
|
||||||
.br
|
|
||||||
A text pack consists of a pack type byte, a track number byte, a counter byte,
|
|
||||||
a Block Number and Character Indicator byte, 12 text characters or data bytes,
|
|
||||||
two optional CRC bytes. For details see libburn documentation file
|
|
||||||
doc/cdtext.txt.
|
|
||||||
.br
|
|
||||||
By default, the input file is checked for correct CRC bytes. If all CRC bytes
|
|
||||||
are 0, then the correct values get silently inserted. If there are non-zero
|
|
||||||
CRC bytes, then a mismatch causes the abort of the burn run.
|
|
||||||
This check can be disabled by option -force.
|
|
||||||
.br
|
|
||||||
Note that this option overrides option input_sheet_v07t= .
|
|
||||||
.TP
|
|
||||||
.BI \-toc
|
.BI \-toc
|
||||||
Print the table of content (TOC) which describes the tracks recorded on disc.
|
Print the table of content (TOC) which describes the tracks recorded on disc.
|
||||||
The output contains all info from option -atip plus lines which begin with
|
The output contains all info from option -atip plus lines which begin with
|
||||||
"track:", the track number, the word "lba:" and a number which gives the
|
"track:", the track number, the word "lba:" and a number which gives the
|
||||||
start address of the track. Addresses are counted in CD sectors which with
|
start address of the track. Addresses are counted in CD sectors which with
|
||||||
SAO or TAO data tracks hold 2048 bytes each.
|
SAO or TAO data tracks hold 2048 bytes each.
|
||||||
.br
|
|
||||||
If verbosity is set to level 2 (-v -v) then the CD-TEXT packs from the lead-in
|
|
||||||
of an audio CD get extracted and written into file 'cdtext.dat', if that file
|
|
||||||
does not yet exist. Prepended is a 4 byte header, followed by one or more
|
|
||||||
packs of 18 bytes each.
|
|
||||||
.br
|
|
||||||
Verbosity level 3 causes the CD-TEXT packs to be printed as hex numbers to
|
|
||||||
standard output. Bytes 4 to 15 of certain pack types are printed as ASCII
|
|
||||||
characters if they have values in the range of 32 to 126.
|
|
||||||
.br
|
|
||||||
See option textfile= for more information about the text pack format.
|
|
||||||
.RS
|
.RS
|
||||||
.TP
|
.TP
|
||||||
Example. Retrieve an afio archive from track number 2:
|
Example. Retrieve an afio archive from track number 2:
|
||||||
|
@ -939,7 +798,7 @@ then the track on media gets truncated to the predicted size and cdrskin exits
|
||||||
with non-zero value.
|
with non-zero value.
|
||||||
.TP
|
.TP
|
||||||
.BI \-v
|
.BI \-v
|
||||||
Increment verbosity level by one. Startlevel is 0 with only few messages.
|
Increment verbose level by one. Startlevel is 0 with only few messages.
|
||||||
Level 1 prints progress report with long running operations and also causes
|
Level 1 prints progress report with long running operations and also causes
|
||||||
some extra lines to be put out with info retrieval options.
|
some extra lines to be put out with info retrieval options.
|
||||||
Level 2 additionally reports about option settings derived from arguments or
|
Level 2 additionally reports about option settings derived from arguments or
|
||||||
|
@ -947,9 +806,9 @@ startup files. Level 3 is for debugging and useful mainly in conjunction with
|
||||||
somebody who had a look into the program sourcecode.
|
somebody who had a look into the program sourcecode.
|
||||||
.TP
|
.TP
|
||||||
.BI \-V
|
.BI \-V
|
||||||
Enable logging of SCSI commands to stderr. This is helpful for expert
|
Enable logging of SCSI commands to stderr. This allows expert examination
|
||||||
examination of the interaction between libburn and the drive.
|
of the interaction between libburn and the drive. The commands are specified
|
||||||
The commands are specified in SCSI-3 standards SPC, SBC, MMC.
|
in SCSI-3 standards SPC, SBC, MMC.
|
||||||
.TP
|
.TP
|
||||||
.BI \-waiti
|
.BI \-waiti
|
||||||
Wait until input data is available at stdin or EOF occurs at stdin.
|
Wait until input data is available at stdin or EOF occurs at stdin.
|
||||||
|
@ -1006,35 +865,6 @@ taken as plain block number with block size 2048 byte.
|
||||||
(E.g ...=1000 or ...=1000s means block 1000, ...=1m means block
|
(E.g ...=1000 or ...=1000s means block 1000, ...=1m means block
|
||||||
512, ...=4096b means block number 2)
|
512, ...=4096b means block number 2)
|
||||||
.TP
|
.TP
|
||||||
.BI cd_start_tno= number
|
|
||||||
Set the number which shall be written as CD track number with the first
|
|
||||||
track of the session. The following tracks will then get written with
|
|
||||||
consecutive CD track numbers. The resulting number of the last track
|
|
||||||
must not exceed 99. The lowest possible start number is 1, which is also
|
|
||||||
the default.
|
|
||||||
.br
|
|
||||||
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
|
.BI \--demand_a_drive
|
||||||
Exit with a nonzero value if no drive can be found during a bus scan.
|
Exit with a nonzero value if no drive can be found during a bus scan.
|
||||||
.TP
|
.TP
|
||||||
|
@ -1086,43 +916,17 @@ padded up to the necessary size by zeros. Size -1 revokes direct writing
|
||||||
and switches back to normal session oriented writing.
|
and switches back to normal session oriented writing.
|
||||||
.br
|
.br
|
||||||
Both, write_start_address and direct_write_amount size must be aligned to a
|
Both, write_start_address and direct_write_amount size must be aligned to a
|
||||||
media dependent transaction size. With DVD-RAM, BD-RE, DVD+RW this is 2k, with
|
media dependend transaction size. With DVD-RAM, BD-RE, DVD+RW this is 2k, with
|
||||||
overwriteable DVD-RW it is 32k.
|
overwriteable DVD-RW it is 32k.
|
||||||
.TP
|
.TP
|
||||||
.BI dvd_obs= default|32k|64k
|
.BI dvd_obs= default|32k|64k
|
||||||
|
Linux specific:
|
||||||
Set the number of bytes to be transmitted with each write operation to DVD
|
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
|
or BD media. Tracks get padded up to the next multiple of this write
|
||||||
of this write size (see option --obs_pad).
|
size. A number of 64 KB may improve throughput with bus systems which
|
||||||
A number of 64 KB may improve throughput with systems
|
show latency problems. The default depends on media type, option
|
||||||
which show latency problems. The default depends on media type, option
|
|
||||||
stream_recording=, and on compile time options.
|
stream_recording=, and on compile time options.
|
||||||
.TP
|
.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
|
|
||||||
NN.wav, where NN is the track number from 01 to at most 99.
|
|
||||||
.TP
|
|
||||||
.BI extract_basename= name
|
|
||||||
Set a filename prefix which shall be used by extract_audio_to= instead of the
|
|
||||||
empty default name prefix.
|
|
||||||
.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
|
.BI fallback_program= command
|
||||||
Set a command name to be executed if cdrskin encounters a known cdrecord
|
Set a command name to be executed if cdrskin encounters a known cdrecord
|
||||||
option which it does not yet support. If a non-empty command is given with
|
option which it does not yet support. If a non-empty command is given with
|
||||||
|
@ -1149,9 +953,6 @@ implies fallback_program=cdrecord
|
||||||
.br
|
.br
|
||||||
.B codim
|
.B codim
|
||||||
implies fallback_program=wodim
|
implies fallback_program=wodim
|
||||||
.TP
|
|
||||||
.BI --four_channel
|
|
||||||
Indicate for subsequent tracks that they were mastered with four channels.
|
|
||||||
.TP
|
.TP
|
||||||
.BI fifo_start_at= size
|
.BI fifo_start_at= size
|
||||||
Do not wait for full fifo but start burning as soon as the given number
|
Do not wait for full fifo but start burning as soon as the given number
|
||||||
|
@ -1159,7 +960,7 @@ of bytes is read. This option may be helpful to bring the average throughput
|
||||||
near to the maximum throughput of a drive. A large fs= and a small
|
near to the maximum throughput of a drive. A large fs= and a small
|
||||||
fifo_start_at= combine a quick burn start and a large savings buffer to
|
fifo_start_at= combine a quick burn start and a large savings buffer to
|
||||||
compensate for temporary lack of source data. At the beginning of burning,
|
compensate for temporary lack of source data. At the beginning of burning,
|
||||||
the software protection against buffer underrun is as weak as the size of
|
the software protection against buffer underun is as weak as the size of
|
||||||
fifo_start_at= . So it is best if the drive offers hardware protection which
|
fifo_start_at= . So it is best if the drive offers hardware protection which
|
||||||
is enabled automatically if not driveropts=noburnfree is given.
|
is enabled automatically if not driveropts=noburnfree is given.
|
||||||
.TP
|
.TP
|
||||||
|
@ -1203,105 +1004,6 @@ With multi-session DVD, blank=fast will act like dvd+rw-format -blank=full .
|
||||||
.br
|
.br
|
||||||
growisofs -dvd-compat is roughly equivalent to cdrskin without option -multi.
|
growisofs -dvd-compat is roughly equivalent to cdrskin without option -multi.
|
||||||
.TP
|
.TP
|
||||||
.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.
|
|
||||||
.br
|
|
||||||
The information in such a sheet is given by text lines of the following form:
|
|
||||||
.br
|
|
||||||
purpose specifier [whitespace] = [whitespace] content text
|
|
||||||
.br
|
|
||||||
[whitespace] is zero or more ASCII 32 (space) or ASCII 9 (tab) characters.
|
|
||||||
The purpose specifier tells the meaning of the content text.
|
|
||||||
Empty content text does not cause a CD-TEXT attribute to be attached.
|
|
||||||
.br
|
|
||||||
The following purpose specifiers apply to the session as a whole:
|
|
||||||
.br
|
|
||||||
Purpose specifier | Content example
|
|
||||||
.br
|
|
||||||
-------------------------------------------------------------
|
|
||||||
.br
|
|
||||||
Text Code = 8859
|
|
||||||
.br
|
|
||||||
Language Code = English
|
|
||||||
.br
|
|
||||||
Album Title = Joyful Nights
|
|
||||||
.br
|
|
||||||
Artist Name = United Cat Orchestra
|
|
||||||
.br
|
|
||||||
Songwriter = Various Songwriters
|
|
||||||
.br
|
|
||||||
Composer = Various Composers
|
|
||||||
.br
|
|
||||||
Arranger = Tom Cat
|
|
||||||
.br
|
|
||||||
Album Message = For all our fans
|
|
||||||
.br
|
|
||||||
Catalog Number = 1234567890
|
|
||||||
.br
|
|
||||||
Genre Code = Classical
|
|
||||||
.br
|
|
||||||
Genre Information = Feline classic music
|
|
||||||
.br
|
|
||||||
Closed Information = This is not to be shown by CD players
|
|
||||||
.br
|
|
||||||
UPC / EAN = 1234567890123
|
|
||||||
.br
|
|
||||||
Text Data Copy Protection = OFF
|
|
||||||
.br
|
|
||||||
First Track Number = 1
|
|
||||||
.br
|
|
||||||
Last Track Number = 3
|
|
||||||
.br
|
|
||||||
The following purpose specifiers apply to particular tracks:
|
|
||||||
.br
|
|
||||||
Purpose specifier | Content example
|
|
||||||
.br
|
|
||||||
-------------------------------------------------------------
|
|
||||||
.br
|
|
||||||
Track 01 Title = Song of Joy
|
|
||||||
.br
|
|
||||||
Track 01 Artist = Felix and The Purrs
|
|
||||||
.br
|
|
||||||
Track 01 Songwriter = Friedrich Schiller
|
|
||||||
.br
|
|
||||||
Track 01 Composer = Ludwig van Beethoven
|
|
||||||
.br
|
|
||||||
Track 01 Arranger = Tom Cat
|
|
||||||
.br
|
|
||||||
Track 01 Message = Fritz and Louie once were punks
|
|
||||||
.br
|
|
||||||
ISRC 01 = XYCRR1101234
|
|
||||||
.br
|
|
||||||
Track numbers are decimal despite the leading 0. There should be as many track
|
|
||||||
definitions as there are track source files given.
|
|
||||||
.br
|
|
||||||
See libburn's doc/cdtext.txt for a detailed definition of 0.7T and the
|
|
||||||
possible values for Text Code, Language Code, Genre Code, Text Data Copy
|
|
||||||
Protection.
|
|
||||||
.br
|
|
||||||
The Q sub-channel settings by "UPC / EAN" and "ISRC" may be overridden by
|
|
||||||
options mcn= and isrc=. This will not affect their appearance as CD-TEXT.
|
|
||||||
They may override cuefile= commands CATALOG and ISRC in the same way.
|
|
||||||
.br
|
|
||||||
If options -text cuefile= are given and if the cue sheet file defines CD-TEXT,
|
|
||||||
then only seven input_sheet_v07t= options may be given. They will then be
|
|
||||||
used as CD-TEXT language blocks 1 to 7.
|
|
||||||
.br
|
|
||||||
This option will get into effect only if no option textfile= is given.
|
|
||||||
The write mode must be SAO on CD. All tracks must be -audio tracks.
|
|
||||||
.br
|
|
||||||
The track numbers may be overridden by option cd_start_tno=.
|
|
||||||
.TP
|
|
||||||
.BI \--list_formats
|
.BI \--list_formats
|
||||||
List the available format descriptors as reported by the drive for the
|
List the available format descriptors as reported by the drive for the
|
||||||
loaded media. Each descriptor line begins with "Format idx" and the
|
loaded media. Each descriptor line begins with "Format idx" and the
|
||||||
|
@ -1317,45 +1019,14 @@ List all ignored cdrecord options. The "-" options cannot be used as addresses
|
||||||
of track sources. No track source address may begin with a text equal to an
|
of track sources. No track source address may begin with a text equal to an
|
||||||
option which ends by "=". The list is ended by an empty line.
|
option which ends by "=". The list is ended by an empty line.
|
||||||
.TP
|
.TP
|
||||||
.BI \--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
|
.BI \--long_toc
|
||||||
Like option -toc but marking each session start by a line "first: X last: Y"
|
Like option -toc but marking each session start by a line "first: X last: Y"
|
||||||
and each session end by "track:lout ...".
|
and each session end by "track:lout ...".
|
||||||
.TP
|
.TP
|
||||||
.BI \--no_load
|
|
||||||
When aquiring the optical drive, do not try to load its tray. This yields the
|
|
||||||
same behavior for desktop drives with tray loader as is shown by laptop drives
|
|
||||||
which usually lack a motorized tray loader.
|
|
||||||
.TP
|
|
||||||
.BI \--no_rc
|
.BI \--no_rc
|
||||||
Only if used as first command line argument this option prevents reading and
|
Only if used as first command line argument this option prevents reading and
|
||||||
interpretation of eventual startup files. See section FILES below.
|
interpretation of eventual startup files. See section FILES below.
|
||||||
.TP
|
.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
|
.BI \--prodvd_cli_compatible
|
||||||
Activates behavior modifications with some DVD situations which bring cdrskin
|
Activates behavior modifications with some DVD situations which bring cdrskin
|
||||||
nearer to the behavior of cdrecord-ProDVD:
|
nearer to the behavior of cdrecord-ProDVD:
|
||||||
|
@ -1392,8 +1063,8 @@ source cannot deliver a size prediction and no tsize= was specified and an
|
||||||
exact track size prediction is demanded by the write mode.
|
exact track size prediction is demanded by the write mode.
|
||||||
.br
|
.br
|
||||||
This was the fallback from bad old times when cdrskin was unable to burn
|
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
|
in mode -tao . It came back with minimally blanked DVD-RW which allow no
|
||||||
Incremental Streaming (-tao), and with explicitly selected write mode -sao
|
Incremental Streaming (-tao) resp. with explicitly selected write mode -sao
|
||||||
for best DVD-ROM compatibility.
|
for best DVD-ROM compatibility.
|
||||||
.br
|
.br
|
||||||
If the track source delivers less bytes than announced then the missing ones
|
If the track source delivers less bytes than announced then the missing ones
|
||||||
|
@ -1403,7 +1074,7 @@ will be filled with zeros.
|
||||||
Prepare a recording session, do not perform it but rather inquire the
|
Prepare a recording session, do not perform it but rather inquire the
|
||||||
maximum number of 2048 byte data blocks which may be written in
|
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
|
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.
|
afterwards.
|
||||||
.br
|
.br
|
||||||
It is not mandatory to give track sources but their nature may influence
|
It is not mandatory to give track sources but their nature may influence
|
||||||
|
@ -1418,72 +1089,12 @@ is possible with the given options.
|
||||||
This option redirects to stderr all message output except its own result
|
This option redirects to stderr all message output except its own result
|
||||||
string and eventual output of -msinfo.
|
string and eventual output of -msinfo.
|
||||||
.TP
|
.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
|
|
||||||
.BI write_start_address= byte_offset
|
.BI write_start_address= byte_offset
|
||||||
Set the address on media where to start writing the track. With DVD+RW, DVD-RAM
|
Set the address on media where to start writing the track. With DVD+RW, DVD-RAM
|
||||||
or BD-RE byte_offset must be aligned to 2 kiB blocks, but better is 32 kiB.
|
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.
|
With DVD-RW 32 kiB alignment is mandatory.
|
||||||
.br
|
.br
|
||||||
Other media are not suitable for this option yet.
|
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. If 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
|
.PP
|
||||||
Alphabetical list of options which are only intended for very special
|
Alphabetical list of options which are only intended for very special
|
||||||
situations and not for normal use:
|
situations and not for normal use:
|
||||||
|
@ -1502,20 +1113,6 @@ under test reservation.
|
||||||
(If you really test experimental media, then please report the outcome on
|
(If you really test experimental media, then please report the outcome on
|
||||||
libburn-hackers@pykix.org)
|
libburn-hackers@pykix.org)
|
||||||
.TP
|
.TP
|
||||||
.BI \--cdtext_dummy
|
|
||||||
Prepare a burn run, report the effective array of CD-TEXT packs to stdout,
|
|
||||||
and then end the program run without starting to burn the session.
|
|
||||||
A blank CD-R or CD-RW has to be present in the drive, nevertheless.
|
|
||||||
.br
|
|
||||||
The output is formatted in lines which describe 18 bytes as 2-digit hex
|
|
||||||
numbers or as single printable characters.
|
|
||||||
See libburn document doc/cdtext.txt about the format of these records.
|
|
||||||
.TP
|
|
||||||
.BI \--cdtext_verbose
|
|
||||||
Like --cdtext_dummy but without preventing the burn run. Combinable with
|
|
||||||
option -dummy to exercise a CD burn run with no persistent impact on the
|
|
||||||
medium.
|
|
||||||
.TP
|
|
||||||
.BI dev_translation= <sep><from><sep><to>
|
.BI dev_translation= <sep><from><sep><to>
|
||||||
Set drive address alias. This was necessary before cdrskin-0.2.4 to manually
|
Set drive address alias. This was necessary before cdrskin-0.2.4 to manually
|
||||||
translate cdrecord addresses into cdrskin addresses.
|
translate cdrecord addresses into cdrskin addresses.
|
||||||
|
@ -1546,13 +1143,13 @@ fcntl(2).
|
||||||
.TP
|
.TP
|
||||||
.BI \--drive_not_o_excl
|
.BI \--drive_not_o_excl
|
||||||
Linux specific: Do not ask the operating system to prevent opening busy drives.
|
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
|
.TP
|
||||||
.BI drive_scsi_dev_family= sr | scd | sg
|
.BI drive_scsi_dev_family= sr | scd | sg
|
||||||
Linux specific: Select a SCSI device file family to be scanned for by
|
Linux specific: Select a SCSI device file family to be scanned for by
|
||||||
options --devices, --device_links and -scanbus.
|
options --devices, --device_links and -scanbus.
|
||||||
Normally this is /dev/sgN on kernel versions < 2.6 and /dev/srN
|
Normally this is /dev/sgN on kernel versions < 2.6 and /dev/srN
|
||||||
on kernels >= 2.6 . This option 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.
|
in order to meet other programs at a common device file for each drive.
|
||||||
On kernel 2.4 families sr and scd will find no drives.
|
On kernel 2.4 families sr and scd will find no drives.
|
||||||
.br
|
.br
|
||||||
|
@ -1563,7 +1160,7 @@ Linux specific:
|
||||||
Try to exclusively reserve device files /dev/srN, /dev/scdM, /dev/sgK of drives.
|
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.
|
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
|
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
|
.TP
|
||||||
.BI \--fifo_disable
|
.BI \--fifo_disable
|
||||||
Disable fifo despite any fs=.
|
Disable fifo despite any fs=.
|
||||||
|
@ -1598,45 +1195,29 @@ 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
|
very good idea. You might end up waiting a very long time for cdrskin
|
||||||
to finish.
|
to finish.
|
||||||
.TP
|
.TP
|
||||||
.BI \--list_features
|
.BI modesty_on_drive= <mode>[:min_percent=<num>][:max_percent=<num>]
|
||||||
List the SCSI/MMC features which were obtained from the drive when it was
|
Mode 1 keeps the program from trying to write to the burner drive while its
|
||||||
last acquired or re-assessed. Although this is better readable than the
|
buffer is in danger to be filled by more than max_percent. If this filling is
|
||||||
raw reply to SCSI command GET CONFIGURATION, the MMC specification text
|
exceeded then the program will wait until the filling is at most min_percent.
|
||||||
is still needed for interpreting it.
|
|
||||||
.br
|
.br
|
||||||
The list consists of line groups of the form
|
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
|
.br
|
||||||
Code +/- : Name : Version,P/N
|
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
|
.br
|
||||||
Raw feature data bytes as hex numbers
|
Mode 0 disables this feature. Mode -1 keeps it unchanged. Default is:
|
||||||
.br
|
.br
|
||||||
Parsed info as Name=Value pairs
|
modesty_on_drive=0:min_percent=65:max_percent=95
|
||||||
.br
|
.br
|
||||||
The headline is the only one which has no blank at its start.
|
Percentages are permissible in the range of 25 to 100.
|
||||||
Code is given as 16 bit hex number.
|
|
||||||
.br
|
|
||||||
"+" marks a currently offered feature. "-" marks those which may be offered
|
|
||||||
under different circumstances.
|
|
||||||
.br
|
|
||||||
Name is the feature name as listed in MMC specs.
|
|
||||||
.br
|
|
||||||
"P" marks persistent features. "N" marks non-persistent features.
|
|
||||||
.br
|
|
||||||
The Raw data can occupy more than one line. No "=" occurs in such lines.
|
|
||||||
If no raw data are present, one line with some blanks is listed instead.
|
|
||||||
.br
|
|
||||||
The Parsed info shows some extracted field values with names which resemble
|
|
||||||
the names used in the MMC description of the particular feature. Parsed info
|
|
||||||
lines contain at least one Name=Value pair. More than one line is possible.
|
|
||||||
If no parsed info is produced, one line with some blanks is listed instead.
|
|
||||||
.br
|
|
||||||
Example:
|
|
||||||
.br
|
|
||||||
0107 - : Real Time Streaming : 4,N
|
|
||||||
.br
|
|
||||||
1f 00 00 00
|
|
||||||
.br
|
|
||||||
RBCB=1 , SCS=1 , MP2A=1 , WSPD=1 , SW=1
|
|
||||||
.TP
|
.TP
|
||||||
.BI \--no_abort_handler
|
.BI \--no_abort_handler
|
||||||
On signals exit even if the drive is in busy state. This is not a very good
|
On signals exit even if the drive is in busy state. This is not a very good
|
||||||
|
@ -1656,65 +1237,13 @@ Such opening is needed for Bus,Target,Lun addresses unless option
|
||||||
addresses which are not listed with cdrskin --devices but nevertheless point
|
addresses which are not listed with cdrskin --devices but nevertheless point
|
||||||
to a usable drive. (Like /dev/sg0 using the same SCSI address as /dev/sr0.)
|
to a usable drive. (Like /dev/sg0 using the same SCSI address as /dev/sr0.)
|
||||||
.TP
|
.TP
|
||||||
.BI \--obs_pad
|
|
||||||
Pad the data of the last write operation of a DVD-R[W] DAO session, or BD-R
|
|
||||||
session, or stdio: pseudo-drive session up to the full size of an output chunk.
|
|
||||||
This padding has to be applied automatically to the other DVD and BD media
|
|
||||||
types, where it causes e.g. ISO images to have trailing unclaimed blocks.
|
|
||||||
Whether it is applied automatically to BD-R depends on option
|
|
||||||
--bdr_obs_exempt.
|
|
||||||
.br
|
|
||||||
Use this option if there is the suspicion that DVD-R[W] DAO or BD-R sessions
|
|
||||||
abort with your kernel and/or DVD drive, if their size is not a multiple of
|
|
||||||
16 blocks.
|
|
||||||
.br
|
|
||||||
This option may also get enabled at compile time of libburn.
|
|
||||||
.TP
|
|
||||||
.BI \--bdr_obs_exempt
|
|
||||||
Exempt BD-R media from automatic unconditional transaction end padding,
|
|
||||||
provided that this padding is not requested by --obs_pad and that
|
|
||||||
no stream_recording is requested.
|
|
||||||
.br
|
|
||||||
This is a new feature introduced with version 1.5.6. It might become default
|
|
||||||
in later versions.
|
|
||||||
.TP
|
|
||||||
.BI \--old_pseudo_scsi_adr
|
.BI \--old_pseudo_scsi_adr
|
||||||
Linux specific:
|
Linux specific:
|
||||||
Use and report literal Bus,Target,Lun addresses rather than real SCSI and
|
Use and report literal Bus,Target,Lun addresses rather than real SCSI and
|
||||||
pseudo ATA addresses. This method is outdated and was never compatible with
|
pseudo ATA addresses. This method is outdated and was never compatible with
|
||||||
original cdrecord.
|
original cdrecord.
|
||||||
.TP
|
|
||||||
.BI sao_postgap= off|number
|
|
||||||
Define whether a post-gap shall be written at the end of the track and
|
|
||||||
how many sectors this gap shall have. A post-gap occupies the range of
|
|
||||||
an additional index of the track. It contains zeros. No bytes from the
|
|
||||||
track source will be read for writing the post-gap.
|
|
||||||
.br
|
|
||||||
This setting affects only CD SAO write runs.
|
|
||||||
.TP
|
|
||||||
.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
|
|
||||||
will be read for writing the pre-gap.
|
|
||||||
.br
|
|
||||||
This setting affects only CD SAO write runs.
|
|
||||||
.br
|
|
||||||
The first track automatically gets a pre-gap of at least 150 sectors. Its
|
|
||||||
size can only be enlarged by this call.
|
|
||||||
.TP
|
|
||||||
.BI use_immed_bit= on|off|default
|
|
||||||
Control whether several long lasting SCSI commands shall be executed with the
|
|
||||||
Immed bit, which makes the commands end early while the drive operation is
|
|
||||||
still going on. cdrskin then inquires progress indication until the drive
|
|
||||||
reports to be ready again. If this feature is turned off, then blanking and
|
|
||||||
formatting will show no progress indication.
|
|
||||||
.br
|
|
||||||
It may depend on the operating system whether use_immed_bit= is set to "off"
|
|
||||||
by default.
|
|
||||||
.TP
|
|
||||||
.BI --xa1-ignore
|
.BI --xa1-ignore
|
||||||
Silently interpret option -xa1 as -data. This may be necessary if a frontend
|
Silently interpret option -xa1 as -data. This may be necessary if a frontent
|
||||||
does not prepare -xa1 block headers but insists in using option -xa1.
|
does not prepare -xa1 block headers but insists in using option -xa1.
|
||||||
.SH EXAMPLES
|
.SH EXAMPLES
|
||||||
.SS
|
.SS
|
||||||
|
@ -1750,7 +1279,7 @@ cdrskin -v dev=/dev/sr0 blank=deformat_sequential
|
||||||
.br
|
.br
|
||||||
cdrskin -v dev=/dev/hdc speed=12 fs=8m \\
|
cdrskin -v dev=/dev/hdc speed=12 fs=8m \\
|
||||||
.br
|
.br
|
||||||
blank=as_needed -eject padsize=300k my_image.iso
|
blank=as_needed -eject padsize=300k my_image.iso
|
||||||
.SS
|
.SS
|
||||||
.B Write compressed afio archive on-the-fly (not possible with minimally blanked DVD-RW or DVD-R DL):
|
.B Write compressed afio archive on-the-fly (not possible with minimally blanked DVD-RW or DVD-R DL):
|
||||||
.br
|
.br
|
||||||
|
@ -1758,7 +1287,7 @@ find . | afio -oZ - | \\
|
||||||
.br
|
.br
|
||||||
cdrskin -v dev=0,1,0 fs=32m speed=8 \\
|
cdrskin -v dev=0,1,0 fs=32m speed=8 \\
|
||||||
.br
|
.br
|
||||||
blank=as_needed padsize=300k -
|
blank=as_needed padsize=300k -
|
||||||
.SS
|
.SS
|
||||||
.B Write multi-session to the same CD, DVD-R[W], DVD+R[/DL], or BD-R:
|
.B Write multi-session to the same CD, DVD-R[W], DVD+R[/DL], or BD-R:
|
||||||
.br
|
.br
|
||||||
|
@ -1780,25 +1309,16 @@ mkisofs ... -C "$c_values" ...
|
||||||
.br
|
.br
|
||||||
x=$(cdrskin dev=/dev/sr0 -multi \\
|
x=$(cdrskin dev=/dev/sr0 -multi \\
|
||||||
.br
|
.br
|
||||||
--tell_media_space 2>/dev/null)
|
--tell_media_space 2>/dev/null)
|
||||||
.br
|
.br
|
||||||
echo "Available: $x blocks of 2048 data bytes"
|
echo "Available: $x blocks of 2048 data bytes"
|
||||||
.SS
|
.SS
|
||||||
.B Write audio tracks and CD-TEXT to CD:
|
.B Write audio tracks to CD:
|
||||||
.br
|
.br
|
||||||
cdrskin -v dev=ATA:1,0,0 speed=48 -sao \\
|
cdrskin -v dev=ATA:1,0,0 speed=48 -sao \\
|
||||||
.br
|
.br
|
||||||
input_sheet_v07t=cdtext.v07t \\
|
track1.wav track2.au -audio -swab track3.raw
|
||||||
.br
|
.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
|
.SH FILES
|
||||||
.SS
|
.SS
|
||||||
Startup files:
|
Startup files:
|
||||||
|
|
3773
cdrskin/cdrskin.c
3773
cdrskin/cdrskin.c
File diff suppressed because it is too large
Load Diff
|
@ -39,8 +39,8 @@ About any CD, DVD, or BD recorder produced in the recent ten years.
|
||||||
<BR>
|
<BR>
|
||||||
<A HREF="http://libburnia-project.org">libburn</A>
|
<A HREF="http://libburnia-project.org">libburn</A>
|
||||||
supports recorders which are compliant to standards MMC-1 for CD and
|
supports recorders which are compliant to standards MMC-1 for CD and
|
||||||
MMC-5 for DVD or BD. Linux, FreeBSD, Solaris, and NetBSD can communicate
|
MMC-5 for DVD or BD. Linux, FreeBSD, and Solaris allow to access drives
|
||||||
with drives connected via SCSI, PATA (aka IDE, ATA), USB, or SATA.
|
connected via SCSI, PATA (aka IDE, ATA), USB, or SATA.
|
||||||
<BR>
|
<BR>
|
||||||
</P>
|
</P>
|
||||||
|
|
||||||
|
@ -49,14 +49,12 @@ with drives connected via SCSI, PATA (aka IDE, ATA), USB, or SATA.
|
||||||
<DL>
|
<DL>
|
||||||
<DT>Linux with kernel 2.4 or higher (and libc, of course) :</DT>
|
<DT>Linux with kernel 2.4 or higher (and libc, of course) :</DT>
|
||||||
<DD>With kernel 2.4 an ATA drive has to be under ide-scsi emulation.</DD>
|
<DD>With kernel 2.4 an ATA drive has to be under ide-scsi emulation.</DD>
|
||||||
<DD>With kernel 2.6 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>
|
<DT>or FreeBSD (with libc, of course) :</DT>
|
||||||
<DD>ATA and SATA drives need atapicam running.</DD>
|
<DD>ATA and SATA drives need atapicam running.</DD>
|
||||||
<DD>libcam has to be installed.</DD>
|
<DD>libcam has to be installed.</DD>
|
||||||
<DT>or Solaris (with libc, of course) :</DT>
|
<DT>or Solaris (with libc, of course) :</DT>
|
||||||
<DD>Tested on kernel 5.11, hopefully suitable for older ones too.</DD>
|
<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>
|
<DT>libpthread</DT>
|
||||||
<DD>is supposed to be a standard system component.</DD>
|
<DD>is supposed to be a standard system component.</DD>
|
||||||
</DL>
|
</DL>
|
||||||
|
@ -67,7 +65,7 @@ with drives connected via SCSI, PATA (aka IDE, ATA), USB, or SATA.
|
||||||
GPL software included:<BR>
|
GPL software included:<BR>
|
||||||
</H2>
|
</H2>
|
||||||
<DL>
|
<DL>
|
||||||
<DT>libburn-1.5.6</DT>
|
<DT>libburn-1.1.6</DT>
|
||||||
<DD>(founded by Derek Foreman and Ben Jansens,
|
<DD>(founded by Derek Foreman and Ben Jansens,
|
||||||
developed and maintained since August 2006 by
|
developed and maintained since August 2006 by
|
||||||
Thomas Schmitt from team of libburnia-project.org)
|
Thomas Schmitt from team of libburnia-project.org)
|
||||||
|
@ -78,7 +76,7 @@ Thomas Schmitt from team of libburnia-project.org)
|
||||||
|
|
||||||
<P>
|
<P>
|
||||||
This program system has been tested on Intel/AMD with Linux, FreeBSD,
|
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.
|
Ports to other usable systems are appreciated. Reports are welcome.
|
||||||
</P>
|
</P>
|
||||||
|
|
||||||
|
@ -109,10 +107,10 @@ DVD-R DL, which both support no -multi.
|
||||||
<DD>#<KBD> cdrskin -scanbus</KBD></DD>
|
<DD>#<KBD> cdrskin -scanbus</KBD></DD>
|
||||||
<DD>#<KBD> cdrskin dev=ATA -scanbus</KBD></DD>
|
<DD>#<KBD> cdrskin dev=ATA -scanbus</KBD></DD>
|
||||||
<DD>#<KBD> cdrskin --devices</KBD></DD>
|
<DD>#<KBD> 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>
|
||||||
<DT>Ordinary users should then get granted access to the /dev files
|
<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>
|
On Solaris it is r-permission and privileges "basic,sys_devices".</DT>
|
||||||
<DT> </DT>
|
<DT> </DT>
|
||||||
|
|
||||||
|
@ -202,15 +200,15 @@ Standalone ISO 9660 multi-session CD/DVD/BD tool
|
||||||
<P>
|
<P>
|
||||||
<DL>
|
<DL>
|
||||||
<DT>Download as source code (see README):</DT>
|
<DT>Download as source code (see README):</DT>
|
||||||
<DD><A HREF="cdrskin-1.5.6.tar.gz">cdrskin-1.5.6.tar.gz</A>
|
<DD><A HREF="cdrskin-1.1.6.tar.gz">cdrskin-1.1.6.tar.gz</A>
|
||||||
(1075 KB).
|
(870 KB).
|
||||||
</DD>
|
</DD>
|
||||||
<DD><A HREF="cdrskin-1.5.6.tar.gz.sig">cdrskin-1.5.6.tar.gz.sig</A></DD>
|
<DD><A HREF="cdrskin-1.1.6.tar.gz.sig">cdrskin-1.1.6.tar.gz.sig</A></DD>
|
||||||
<DD>
|
<DD>
|
||||||
(detached GPG signature for verification by
|
(detached GPG signature for verification by
|
||||||
<KBD>gpg --verify cdrskin-1.5.6.tar.gz.sig cdrskin-1.5.6.tar.gz</KBD>
|
<KBD>gpg --verify cdrskin-1.1.6.tar.gz.sig cdrskin-1.1.6.tar.gz</KBD>
|
||||||
<BR>
|
<BR>
|
||||||
after <KBD>gpg --keyserver keyserver.ubuntu.com --recv-keys ABC0A854</KBD>).
|
after <KBD>gpg --keyserver keys.gnupg.net --recv-keys ABC0A854</KBD>).
|
||||||
</DD>
|
</DD>
|
||||||
<DD>
|
<DD>
|
||||||
The cdrskin tarballs are source code identical with libburn releases
|
The cdrskin tarballs are source code identical with libburn releases
|
||||||
|
@ -247,8 +245,8 @@ cdrskin_0.4.2.pl00-x86-suse9_0-static.tar.gz</A>, (310 KB), -static compiled,
|
||||||
</DL>
|
</DL>
|
||||||
<DL><DT>Contact:</DT>
|
<DL><DT>Contact:</DT>
|
||||||
<DD>Thomas Schmitt, <A HREF="mailto:scdbackup@gmx.net">scdbackup@gmx.net</A></DD>
|
<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:
|
<DD>libburn development mailing list,
|
||||||
<A HREF="mailto:bug-xorriso@gnu.org">bug-xorriso@gnu.org</A></DD>
|
<A HREF="mailto:libburn-hackers@pykix.org">libburn-hackers@pykix.org</A></DD>
|
||||||
</DL>
|
</DL>
|
||||||
<DL><DT>License:</DT>
|
<DL><DT>License:</DT>
|
||||||
<DD><A HREF="COPYING_cdrskin">GPL</A>, an <A HREF="http://www.opensource.org/">Open Source</A> approved license</DD>
|
<DD><A HREF="COPYING_cdrskin">GPL</A>, an <A HREF="http://www.opensource.org/">Open Source</A> approved license</DD>
|
||||||
|
@ -259,35 +257,42 @@ cdrskin_0.4.2.pl00-x86-suse9_0-static.tar.gz</A>, (310 KB), -static compiled,
|
||||||
<HR>
|
<HR>
|
||||||
|
|
||||||
<P>
|
<P>
|
||||||
Enhancements towards previous stable version cdrskin-1.5.4:
|
Enhancements towards previous stable version cdrskin-1.1.4:
|
||||||
<UL>
|
<UL>
|
||||||
<LI>New cdrskin option --bdr_obs_exempt</LI>
|
<LI>
|
||||||
<LI>Officially enabled overburning on CD media</LI>
|
Worked around a collision with Linux udev which lets links vanish
|
||||||
|
</LI>
|
||||||
<!--
|
<!--
|
||||||
<LI>none</LI>
|
<LI>none</LI>
|
||||||
-->
|
-->
|
||||||
</UL>
|
</UL>
|
||||||
|
|
||||||
Bug fixes towards cdrskin-1.5.4:
|
Bug fixes towards cdrskin-1.1.4:
|
||||||
<UL>
|
<UL>
|
||||||
<LI>Overburning with cdrskin option -force ended by a libburn error</LI>
|
<LI>
|
||||||
</UL>
|
stdio sizes > 4 TB - 32 kB caused integer rollover
|
||||||
|
</LI>
|
||||||
<!--
|
<!--
|
||||||
|
<LI>none</LI>
|
||||||
-->
|
-->
|
||||||
|
</UL>
|
||||||
|
|
||||||
<HR>
|
<HR>
|
||||||
|
|
||||||
<P>
|
<P>
|
||||||
<DL>
|
<DL>
|
||||||
<DT><H3>Development snapshot, version 1.5.7 :</H3></DT>
|
<DT><H3>Development snapshot, version 1.1.7 :</H3></DT>
|
||||||
<DD>Enhancements towards current stable version 1.5.6:
|
<DD>Enhancements towards current stable version 1.1.6:
|
||||||
<UL>
|
<UL>
|
||||||
<LI>none yet</LI>
|
<LI>none yet</LI>
|
||||||
<!--
|
<!--
|
||||||
<LI>none yet</LI>
|
<LI>none yet</LI>
|
||||||
-->
|
-->
|
||||||
|
|
||||||
</UL>
|
</UL>
|
||||||
Bug fixes towards cdrskin-1.5.6:
|
</DD>
|
||||||
|
|
||||||
|
<DD>Bug fixes towards cdrskin-1.1.6:
|
||||||
<UL>
|
<UL>
|
||||||
<LI>none yet</LI>
|
<LI>none yet</LI>
|
||||||
<!--
|
<!--
|
||||||
|
@ -297,15 +302,14 @@ Bug fixes towards cdrskin-1.5.6:
|
||||||
</DD>
|
</DD>
|
||||||
|
|
||||||
<DD> </DD>
|
<DD> </DD>
|
||||||
<DD><A HREF="README_cdrskin_devel">README 1.5.7</A>
|
<DD><A HREF="README_cdrskin_devel">README 1.1.7</A>
|
||||||
<DD><A HREF="cdrskin__help_devel">cdrskin-1.5.7 --help</A></DD>
|
<DD><A HREF="cdrskin__help_devel">cdrskin-1.1.7 --help</A></DD>
|
||||||
<DD><A HREF="cdrskin_help_devel">cdrskin-1.5.7 -help</A></DD>
|
<DD><A HREF="cdrskin_help_devel">cdrskin-1.1.7 -help</A></DD>
|
||||||
<DD><A HREF="man_1_cdrskin_devel.html">man cdrskin (as of 1.5.7)</A></DD>
|
<DD><A HREF="man_1_cdrskin_devel.html">man cdrskin (as of 1.1.7)</A></DD>
|
||||||
<DD> </DD>
|
<DD> </DD>
|
||||||
<DT>Maintainers of cdrskin unstable packages please use git of
|
<DT>Maintainers of cdrskin unstable packages please use SVN of
|
||||||
<A HREF="http://libburnia-project.org"> libburnia-project.org</A></DT>
|
<A HREF="http://libburnia-project.org"> libburnia-project.org</A></DT>
|
||||||
<DD>Download: <KBD>
|
<DD>Download: <KBD><B>svn co http://svn.libburnia-project.org/libburn/trunk libburn</B>
|
||||||
<B>git clone https://dev.lovelyhq.com/libburnia/libburn.git</B>
|
|
||||||
</KBD></DD>
|
</KBD></DD>
|
||||||
<DD>Build: <KBD><B>cd libburn ; ./bootstrap ; ./configure --prefix /usr ; make ; cdrskin/compile_cdrskin.sh</B>
|
<DD>Build: <KBD><B>cd libburn ; ./bootstrap ; ./configure --prefix /usr ; make ; cdrskin/compile_cdrskin.sh</B>
|
||||||
</KBD></DD>
|
</KBD></DD>
|
||||||
|
@ -316,13 +320,13 @@ vanilla tools like make and gcc are needed.</DD>
|
||||||
</DD>
|
</DD>
|
||||||
<DD> </DD>
|
<DD> </DD>
|
||||||
<DT>The following download is intended for adventurous end users or
|
<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
|
<DD>Source (./bootstrap is already applied, build tested, for more see
|
||||||
<A HREF="README_cdrskin_devel">upcoming README</A> ):
|
<A HREF="README_cdrskin_devel">upcoming README</A> ):
|
||||||
</DD>
|
</DD>
|
||||||
<DD>
|
<DD>
|
||||||
<A HREF="cdrskin-1.5.7.tar.gz">cdrskin-1.5.7.tar.gz</A>
|
<A HREF="cdrskin-1.1.7.tar.gz">cdrskin-1.1.7.tar.gz</A>
|
||||||
(1075 KB).
|
(870 KB).
|
||||||
</DD>
|
</DD>
|
||||||
|
|
||||||
<!-- This is not offered any more since spring 2008
|
<!-- This is not offered any more since spring 2008
|
||||||
|
@ -472,7 +476,7 @@ cdrecord but not vice versa.
|
||||||
<BR>
|
<BR>
|
||||||
<BR>
|
<BR>
|
||||||
I was a long time user of cdrecord and it worked fine for me.
|
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
|
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
|
maintained. So for me - there would be no problem with using it for
|
||||||
burning CDs.
|
burning CDs.
|
||||||
|
@ -497,7 +501,7 @@ opportunity is the goal of a cdrecord compatibility wrapper.
|
||||||
<BR>
|
<BR>
|
||||||
<BR>
|
<BR>
|
||||||
It is very important to me that this project is not perceived as hostile
|
It is very important to me that this project is not perceived as hostile
|
||||||
towards Joerg Schilling and his work.
|
towards Joerg Schilling and his ongoing work.
|
||||||
I owe him much. For cdrecord, for mkisofs, for star. Chapeau.
|
I owe him much. For cdrecord, for mkisofs, for star. Chapeau.
|
||||||
<BR>
|
<BR>
|
||||||
</P>
|
</P>
|
||||||
|
@ -518,15 +522,11 @@ and by <A HREF="http://sourceforge.net">sourceforge.net</A><BR>
|
||||||
<A href="http://sourceforge.net">
|
<A href="http://sourceforge.net">
|
||||||
<IMG src="sflogo-88-1.png" BORDER="0" ALT="SourceForge Logo"></A>
|
<IMG src="sflogo-88-1.png" BORDER="0" ALT="SourceForge Logo"></A>
|
||||||
<!-- on sourceforge use : <IMG src="http://sourceforge.net/sflogo.php?group_id=16010" width="88" height="31" border="0" alt="SourceForge Logo"></A> -->
|
<!-- on sourceforge use : <IMG src="http://sourceforge.net/sflogo.php?group_id=16010" width="88" height="31" border="0" alt="SourceForge Logo"></A> -->
|
||||||
|
|
||||||
<!--
|
|
||||||
<P>
|
<P>
|
||||||
Enjoying a FreeBSD shell account with the opportunity to
|
Enjoying a FreeBSD shell account with the opportunity to
|
||||||
build and install cdrskin at<BR>
|
build and install cdrskin at<BR>
|
||||||
<A HREF="http://www.en.free-shells.com.ar">free-shells.com.ar</A>
|
<A HREF="http://www.en.free-shells.com.ar">free-shells.com.ar</A>
|
||||||
</P>
|
</P>
|
||||||
-->
|
|
||||||
|
|
||||||
</FONT></CENTER>
|
</FONT></CENTER>
|
||||||
<HR>
|
<HR>
|
||||||
<DL>
|
<DL>
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
#define Cdrskin_timestamP "2024.04.27.162735"
|
#define Cdrskin_timestamP "2011.09.27.060001"
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,14 +1,14 @@
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
# compile_cdrskin.sh
|
# compile_cdrskin.sh
|
||||||
# Copyright 2005 - 2023 Thomas Schmitt, scdbackup@gmx.net, GPL v2 or later
|
# Copyright 2005 - 2011 Thomas Schmitt, scdbackup@gmx.net, GPL
|
||||||
# to be executed within ./libburn-* or./cdrskin-*
|
# to be executed within ./libburn-* resp ./cdrskin-*
|
||||||
|
|
||||||
debug_opts="-O2"
|
debug_opts="-O2"
|
||||||
def_opts=
|
def_opts=
|
||||||
largefile_opts="-D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE=1"
|
largefile_opts="-D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE=1"
|
||||||
fifo_opts=""
|
fifo_opts=""
|
||||||
libvers="-DCdrskin_libburn_1_5_6"
|
libvers="-DCdrskin_libburn_1_1_6"
|
||||||
|
|
||||||
# To be used if Makefile.am uses libburn_libburn_la_CFLAGS
|
# To be used if Makefile.am uses libburn_libburn_la_CFLAGS
|
||||||
# burn="libburn/libburn_libburn_la-"
|
# burn="libburn/libburn_libburn_la-"
|
||||||
|
@ -41,21 +41,31 @@ do
|
||||||
elif test "$i" = "-compile_dewav"
|
elif test "$i" = "-compile_dewav"
|
||||||
then
|
then
|
||||||
compile_dewav=1
|
compile_dewav=1
|
||||||
elif test "$i" = "-libburn_1_5_6"
|
elif test "$i" = "-cvs_A60220"
|
||||||
then
|
then
|
||||||
libvers="-DCdrskin_libburn_1_5_6"
|
libvers="-DCdrskin_libburn_cvs_A60220_tS"
|
||||||
|
libdax_audioxtr_o=
|
||||||
|
libdax_msgs_o="$burn"message.o
|
||||||
|
cleanup_src_or_obj="-DCleanup_has_no_libburn_os_H cdrskin/cleanup.c"
|
||||||
|
elif test "$i" = "-libburn_1_1_6"
|
||||||
|
then
|
||||||
|
libvers="-DCdrskin_libburn_1_1_6"
|
||||||
libdax_audioxtr_o="$burn"libdax_audioxtr.o
|
libdax_audioxtr_o="$burn"libdax_audioxtr.o
|
||||||
libdax_msgs_o="$burn"libdax_msgs.o
|
libdax_msgs_o="$burn"libdax_msgs.o
|
||||||
cleanup_src_or_obj="$burn"cleanup.o
|
cleanup_src_or_obj="$burn"cleanup.o
|
||||||
elif test "$i" = "-libburn_svn"
|
elif test "$i" = "-libburn_svn"
|
||||||
then
|
then
|
||||||
libvers="-DCdrskin_libburn_1_5_7"
|
libvers="-DCdrskin_libburn_1_1_7"
|
||||||
libdax_audioxtr_o="$burn"libdax_audioxtr.o
|
libdax_audioxtr_o="$burn"libdax_audioxtr.o
|
||||||
libdax_msgs_o="$burn"libdax_msgs.o
|
libdax_msgs_o="$burn"libdax_msgs.o
|
||||||
cleanup_src_or_obj="$burn"cleanup.o
|
cleanup_src_or_obj="$burn"cleanup.o
|
||||||
elif test "$i" = "-newapi" -o "$i" = "-experimental"
|
elif test "$i" = "-newapi" -o "$i" = "-experimental"
|
||||||
then
|
then
|
||||||
def_opts="$def_opts -DCdrskin_new_api_tesT"
|
def_opts="$def_opts -DCdrskin_new_api_tesT"
|
||||||
|
elif test "$i" = "-oldfashioned"
|
||||||
|
then
|
||||||
|
def_opts="$def_opts -DCdrskin_oldfashioned_api_usE"
|
||||||
|
cleanup_src_or_obj="-DCleanup_has_no_libburn_os_H cdrskin/cleanup.c"
|
||||||
elif test "$i" = "-no_largefile"
|
elif test "$i" = "-no_largefile"
|
||||||
then
|
then
|
||||||
largefile_opts=
|
largefile_opts=
|
||||||
|
@ -99,14 +109,15 @@ do
|
||||||
echo "Options:"
|
echo "Options:"
|
||||||
echo " -compile_cdrfifo compile program cdrskin/cdrfifo."
|
echo " -compile_cdrfifo compile program cdrskin/cdrfifo."
|
||||||
echo " -compile_dewav compile program test/dewav without libburn."
|
echo " -compile_dewav compile program test/dewav without libburn."
|
||||||
echo " -libburn_1_5_6 set macro to match libburn-1.5.6"
|
echo " -libburn_1_1_6 set macro to match libburn-1.1.6"
|
||||||
echo " -libburn_svn set macro to match current libburn git."
|
echo " -libburn_svn set macro to match current libburn-SVN."
|
||||||
echo " -dvd_obs_64k 64 KB default size for DVD/BD writing."
|
echo " -dvd_obs_64k 64 KB default size for DVD/BD writing."
|
||||||
echo " -use_libcdio link with -lcdio because libburn uses it."
|
echo " -use_libcdio link with -lcdio because libburn uses it."
|
||||||
echo " -do_not_compile_cdrskin omit compilation of cdrskin/cdrskin."
|
echo " -do_not_compile_cdrskin omit compilation of cdrskin/cdrskin."
|
||||||
echo " -use_no_libburn_fifo use cdrfifo even for single track non-CD"
|
echo " -use_no_libburn_fifo use cdrfifo even for single track non-CD"
|
||||||
echo " -use_no_cdrfifo always use fifo of libburn and never cdrfifo"
|
echo " -use_no_cdrfifo always use fifo of libburn and never cdrfifo"
|
||||||
echo " -experimental use newly introduced libburn features."
|
echo " -experimental use newly introduced libburn features."
|
||||||
|
echo " -oldfashioned use pre-0.2.2 libburn features only."
|
||||||
echo " -do_diet produce capability reduced lean version."
|
echo " -do_diet produce capability reduced lean version."
|
||||||
echo " -do_strip apply program strip to compiled programs."
|
echo " -do_strip apply program strip to compiled programs."
|
||||||
echo " -g produce debuggable programm."
|
echo " -g produce debuggable programm."
|
||||||
|
@ -145,7 +156,6 @@ then
|
||||||
$cleanup_src_or_obj \
|
$cleanup_src_or_obj \
|
||||||
\
|
\
|
||||||
"$burn"async.o \
|
"$burn"async.o \
|
||||||
"$burn"cdtext.o \
|
|
||||||
"$burn"debug.o \
|
"$burn"debug.o \
|
||||||
"$burn"drive.o \
|
"$burn"drive.o \
|
||||||
"$burn"file.o \
|
"$burn"file.o \
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/bin/sh
|
#!/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
|
# Generates a HTML version of man page cdrskin.1
|
||||||
#
|
#
|
||||||
|
@ -38,29 +38,27 @@ then
|
||||||
|
|
||||||
sed \
|
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="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/<title>CDRSKIN<\/title>/<title>man 1 cdrskin<\/title>/' \
|
||||||
-e 's/<h1 align=center>CDRSKIN<\/h1>/<h1 align=center>man 1 cdrskin<\/h1>/' \
|
-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/<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>Overview of features:<\/b>/\ <BR><b>Overview of features:<\/b>/' \
|
||||||
-e 's/<b>General information paragraphs:<\/b>/<b>General information paragraphs:<\/b><BR>/' \
|
-e 's/<b>General information paragraphs:<\/b>/\ <BR><b>General information paragraphs:<\/b>/' \
|
||||||
-e 's/<b>Track recording model:<\/b>/\ <BR><b>Track recording model:<\/b><BR>/' \
|
-e 's/<b>Track recording model:<\/b>/\ <BR><b>Track recording model:<\/b>/' \
|
||||||
-e 's/^In general there are two types of tracks: data and audio./\ <BR>In general there are two types of tracks: data and audio./' \
|
-e 's/^In general there are two types of tracks: data and audio./\ <BR>In general there are two types of tracks: data and audio./' \
|
||||||
-e 's/^While audio tracks just contain a given/\ <BR>While audio tracks just contain a given/' \
|
-e 's/^While audio tracks just contain a given/\ <BR>While audio tracks just contain a given/' \
|
||||||
-e 's/<b>Write mode selection:<\/b>/<b>Write mode selection:<\/b><BR>/' \
|
-e 's/<b>Write mode selection:<\/b>/\ <BR><b>Write mode selection:<\/b>/' \
|
||||||
-e 's/<b>Recordable CD Media:<\/b>/<b>Recordable CD Media:<\/b><BR>/' \
|
-e 's/<b>Recordable CD Media:<\/b>/\ <BR><b>Recordable CD Media:<\/b>/' \
|
||||||
-e 's/<b>Overwriteable DVD or BD Media:<\/b>/<b>Overwriteable DVD or BD Media:<\/b><BR>/' \
|
-e 's/<b>Overwriteable DVD Media:<\/b>/\ <BR><b>Overwriteable DVD Media:<\/b>/' \
|
||||||
-e 's/<b>Sequentially Recordable DVD or BD Media:<\/b>/<b>Sequentially Recordable DVD or BD Media:<\/b><BR>/' \
|
-e 's/<b>Sequentially Recordable DVD Media:<\/b>/\ <BR><b>Sequentially Recordable DVD Media:<\/b>/' \
|
||||||
-e 's/^The write modes for DVD+R/\ <BR>The write modes for DVD+R/' \
|
-e 's/^The write modes for DVD+R/\ <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>/\ <BR><b>Drive preparation and addressing:<\/b>/' \
|
||||||
-e 's/^If you only got one CD capable drive/\ <BR>If you only got one CD capable drive/' \
|
-e 's/^If you only got one CD capable drive/\ <BR>If you only got one CD capable drive/' \
|
||||||
-e 's/<b>Emulated drives:<\/b>/<b>Emulated drives:<\/b><BR>/' \
|
-e 's/<b>Emulated drives:<\/b>/\ <BR><b>Emulated drives:<\/b>/' \
|
||||||
-e 's/for normal use: <b><br>/for normal use: <b><br><BR>/' \
|
-e 's/^Alphabetical list of options/\ <BR>Alphabetical list of options/' \
|
||||||
-e 's/original cdrecord by Joerg Schilling:<\/p>/original cdrecord by Joerg Schilling:<\/p><BR>/' \
|
|
||||||
-e 's/<\/body>/<BR><HR><FONT SIZE=-1><CENTER>(HTML generated from '"$manpage"'.1 on '"$(date)"' by '$(basename "$0")' )<\/CENTER><\/FONT><\/body>/' \
|
-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 FILES/See section <A HREF="#FILES">FILES<\/A>/' \
|
||||||
-e 's/See section EXAMPLES/See section <A HREF="#EXAMPLES">EXAMPLES<\/A>/' \
|
-e 's/See section EXAMPLES/See section <A HREF="#EXAMPLES">EXAMPLES<\/A>/' \
|
||||||
-e 's/−/-/g' \
|
|
||||||
<"$2" >"$htmlpage"
|
<"$2" >"$htmlpage"
|
||||||
|
|
||||||
set +x
|
set +x
|
||||||
|
@ -71,10 +69,8 @@ then
|
||||||
|
|
||||||
else
|
else
|
||||||
|
|
||||||
# export BROWSER='cp "%s" '"$raw_html"
|
export BROWSER='cp "%s" '"$raw_html"
|
||||||
export BROWSER=$(pwd)/'cdrskin/unite_html_b_line "%s" '"$raw_html"
|
|
||||||
man -H "$manpage"
|
man -H "$manpage"
|
||||||
# cp "$raw_html" /tmp/x.html
|
|
||||||
"$0" -work_as_filter "$raw_html"
|
"$0" -work_as_filter "$raw_html"
|
||||||
rm "$raw_html"
|
rm "$raw_html"
|
||||||
rm "$man_dir"/man1
|
rm "$man_dir"/man1
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
# Create version timestamp cdrskin/cdrskin_timestamp.h
|
# 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')"
|
timestamp="$(date -u '+%Y.%m.%d.%H%M%S')"
|
||||||
echo "Version timestamp : $timestamp"
|
echo "Version timestamp : $timestamp"
|
||||||
|
|
|
@ -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);
|
|
||||||
}
|
|
||||||
|
|
|
@ -19,7 +19,12 @@ Many bytes have been copied from the message output of cdrecord
|
||||||
runs, though. The most comprehensive technical overview of cdrskin
|
runs, though. The most comprehensive technical overview of cdrskin
|
||||||
can be found in [http://libburnia-project.org/browser/libburn/trunk/cdrskin/README?format=txt cdrskin/README].
|
can be found in [http://libburnia-project.org/browser/libburn/trunk/cdrskin/README?format=txt cdrskin/README].
|
||||||
|
|
||||||
About libburn API for burning CD, DVD, and BD: http://api.libburnia-project.org
|
About libburn API for burning CD and DVD: http://api.libburnia-project.org
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
|
||||||
|
For yet unsupported media types see the advice to use dvd+rw-tools at
|
||||||
|
the end of this text.
|
||||||
|
|
||||||
--------------------------------------------------------------------------
|
--------------------------------------------------------------------------
|
||||||
|
|
||||||
|
@ -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.
|
and displays their detected properties.
|
||||||
The drives are listed one per line, with fields:
|
The drives are listed one per line, with fields:
|
||||||
libburn-drive-number, sysadmin-device-file, permissions, vendor, type
|
libburn-drive-number, sysadmin-device-file, permissions, vendor, type
|
||||||
|
@ -85,7 +90,7 @@ Option blank= offers several specialized blanking and formatting types,
|
||||||
which one may use for particular purposes on DVD-RW, DVD-RAM and BD-RE.
|
which one may use for particular purposes on DVD-RW, DVD-RAM and BD-RE.
|
||||||
(See also below: blank=format_overwrite)
|
(See also below: blank=format_overwrite)
|
||||||
The drive offers a list of possible formats by cdrskin option --list_formats.
|
The drive offers a list of possible formats by cdrskin option --list_formats.
|
||||||
One should acquire MMC background information before making use of them.
|
One should aquire MMC background information before making use of them.
|
||||||
|
|
||||||
--------------------------------------------------------------------------
|
--------------------------------------------------------------------------
|
||||||
|
|
||||||
|
@ -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
|
was used with the formatter program (e.g. mkisofs -C) matches the start block
|
||||||
address which will be used by the upcoming burn.
|
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.
|
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
|
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
|
stream to end. It risks a few drive buffer underruns at the beginning of burn
|
||||||
- but modern drives stand this.
|
- but modern drives stand this.
|
||||||
|
|
||||||
|
@ -263,7 +268,7 @@ would be the appropriate translation:
|
||||||
{{{
|
{{{
|
||||||
dev_translation=+0,0,0+/dev/hdc
|
dev_translation=+0,0,0+/dev/hdc
|
||||||
}}}
|
}}}
|
||||||
The "+" character is a separator to be chosen by you.
|
The "+" character is a separator to be choosen by you.
|
||||||
Currently i am not aware of the need to choose any other than "+"
|
Currently i am not aware of the need to choose any other than "+"
|
||||||
unless you get playful with custom translations like
|
unless you get playful with custom translations like
|
||||||
{{{
|
{{{
|
||||||
|
@ -274,7 +279,23 @@ for an illustrated example with K3b 0.10 .
|
||||||
|
|
||||||
--------------------------------------------------------------------------
|
--------------------------------------------------------------------------
|
||||||
|
|
||||||
Advanced multi-session use cases as of dvd+rw-tools:
|
DVD advise:
|
||||||
|
|
||||||
|
For burning of DVD/BD media other than DVD-RAM, DVD+RW, DVD+R, DVD+R DL,
|
||||||
|
DVD-RW, DVD-R, BD-RE, the cdrskin project currently advises to use
|
||||||
|
Andy Polyakov's dvd+rw-tools which despite their historic name are
|
||||||
|
capable of all the media above and more, including BD discs.
|
||||||
|
|
||||||
|
http://fy.chalmers.se/~appro/linux/DVD+RW/tools
|
||||||
|
|
||||||
|
They are not compatible or related to cdrecord resp. cdrecord-ProDVD
|
||||||
|
(now obsoleted by original source cdrtools cdrecord with identical
|
||||||
|
capabilities besides the license key).
|
||||||
|
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Advanced multi-session use cases:
|
||||||
|
|
||||||
A special feature of dvd+rw-tools is growing of ISO-9660 filesystems on
|
A special feature of dvd+rw-tools is growing of ISO-9660 filesystems on
|
||||||
overwriteable media. This is not the same as multi-session writing of cdrskin
|
overwriteable media. This is not the same as multi-session writing of cdrskin
|
||||||
|
|
114
configure.ac
114
configure.ac
|
@ -1,4 +1,4 @@
|
||||||
AC_INIT([libburn], [1.5.7], [http://libburnia-project.org])
|
AC_INIT([libburn], [1.1.6], [http://libburnia-project.org])
|
||||||
AC_PREREQ([2.50])
|
AC_PREREQ([2.50])
|
||||||
dnl AC_CONFIG_HEADER([config.h])
|
dnl AC_CONFIG_HEADER([config.h])
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@ LIBBURNIA_SET_FLAGS
|
||||||
AM_INIT_AUTOMAKE([subdir-objects])
|
AM_INIT_AUTOMAKE([subdir-objects])
|
||||||
AC_CONFIG_MACRO_DIR([./])
|
AC_CONFIG_MACRO_DIR([./])
|
||||||
|
|
||||||
dnl Notes about version numbers and .so numbers:
|
dnl Notes by ts A71207 - B10409 :
|
||||||
dnl
|
dnl
|
||||||
dnl Regrettably the meaning of the various version types was misunderstood
|
dnl Regrettably the meaning of the various version types was misunderstood
|
||||||
dnl before version 0.4.1.
|
dnl before version 0.4.1.
|
||||||
|
@ -94,26 +94,6 @@ dnl 1.0.6 = libburn.so.4.63.0
|
||||||
dnl 1.1.0 = libburn.so.4.65.0
|
dnl 1.1.0 = libburn.so.4.65.0
|
||||||
dnl 1.1.4 = libburn.so.4.67.0
|
dnl 1.1.4 = libburn.so.4.67.0
|
||||||
dnl 1.1.6 = libburn.so.4.69.0
|
dnl 1.1.6 = libburn.so.4.69.0
|
||||||
dnl 1.1.8 = libburn.so.4.71.0
|
|
||||||
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 1.4.6 = libburn.so.4.99.0
|
|
||||||
dnl 1.4.8 = libburn.so.4.101.0
|
|
||||||
dnl 1.5.0 = libburn.so.4.103.0
|
|
||||||
dnl 1.5.2 = libburn.so.4.105.0
|
|
||||||
dnl 1.5.4 = libburn.so.4.107.0
|
|
||||||
dnl 1.5.6 = libburn.so.4.109.0
|
|
||||||
dnl
|
dnl
|
||||||
dnl So LT_CURRENT, LT_REVISION and LT_AGE get set directly here.
|
dnl So LT_CURRENT, LT_REVISION and LT_AGE get set directly here.
|
||||||
dnl SONAME of the emerging library is LT_CURRENT - LT_AGE.
|
dnl SONAME of the emerging library is LT_CURRENT - LT_AGE.
|
||||||
|
@ -138,8 +118,8 @@ dnl If BURN_*_VERSION changes, be sure to change AC_INIT above to match.
|
||||||
dnl
|
dnl
|
||||||
dnl As said: Only copies. Original in libburn/libburn.h : burn_header_version_*
|
dnl As said: Only copies. Original in libburn/libburn.h : burn_header_version_*
|
||||||
BURN_MAJOR_VERSION=1
|
BURN_MAJOR_VERSION=1
|
||||||
BURN_MINOR_VERSION=5
|
BURN_MINOR_VERSION=1
|
||||||
BURN_MICRO_VERSION=7
|
BURN_MICRO_VERSION=6
|
||||||
BURN_VERSION=$BURN_MAJOR_VERSION.$BURN_MINOR_VERSION.$BURN_MICRO_VERSION
|
BURN_VERSION=$BURN_MAJOR_VERSION.$BURN_MINOR_VERSION.$BURN_MICRO_VERSION
|
||||||
|
|
||||||
AC_SUBST(BURN_MAJOR_VERSION)
|
AC_SUBST(BURN_MAJOR_VERSION)
|
||||||
|
@ -150,14 +130,14 @@ AC_SUBST(BURN_VERSION)
|
||||||
dnl Libtool versioning
|
dnl Libtool versioning
|
||||||
LT_RELEASE=$BURN_MAJOR_VERSION.$BURN_MINOR_VERSION.$BURN_MICRO_VERSION
|
LT_RELEASE=$BURN_MAJOR_VERSION.$BURN_MINOR_VERSION.$BURN_MICRO_VERSION
|
||||||
dnl
|
dnl
|
||||||
dnl ### This is the release version libburn-1.5.6
|
dnl This is the release version libburn-1.1.6
|
||||||
dnl This is the development version after above release version
|
dnl ### This is the development version after above release version
|
||||||
dnl ### LT_CURRENT++, LT_AGE++ has not yet happened.
|
dnl LT_CURRENT++, LT_AGE++ has not yet happened.
|
||||||
dnl LT_CURRENT++, LT_AGE++ has happened meanwhile.
|
dnl ### LT_CURRENT++, LT_AGE++ has happened meanwhile.
|
||||||
dnl
|
dnl
|
||||||
dnl SONAME = 114 - 110 = 4 . Linux library name = libburn.so.4.110.0
|
dnl SONAME = 73 - 69 = 4 . Linux library name = libburn.so.4.69.0
|
||||||
LT_CURRENT=114
|
LT_CURRENT=73
|
||||||
LT_AGE=110
|
LT_AGE=69
|
||||||
LT_REVISION=0
|
LT_REVISION=0
|
||||||
LT_CURRENT_MINUS_AGE=`expr $LT_CURRENT - $LT_AGE`
|
LT_CURRENT_MINUS_AGE=`expr $LT_CURRENT - $LT_AGE`
|
||||||
|
|
||||||
|
@ -176,12 +156,12 @@ AC_SUBST(BURN_BINARY_AGE)
|
||||||
AC_PREFIX_DEFAULT([/usr/local])
|
AC_PREFIX_DEFAULT([/usr/local])
|
||||||
test "$prefix" = "NONE" && prefix=$ac_default_prefix
|
test "$prefix" = "NONE" && prefix=$ac_default_prefix
|
||||||
|
|
||||||
dnl ts B90405 : Disabled on advise of Ross Burton
|
AM_MAINTAINER_MODE
|
||||||
dnl AM_MAINTAINER_MODE
|
|
||||||
|
|
||||||
AM_PROG_CC_C_O
|
AM_PROG_CC_C_O
|
||||||
AC_C_CONST
|
AC_C_CONST
|
||||||
AC_C_INLINE
|
AC_C_INLINE
|
||||||
|
AC_C_BIGENDIAN
|
||||||
|
|
||||||
dnl Large file support
|
dnl Large file support
|
||||||
AC_SYS_LARGEFILE
|
AC_SYS_LARGEFILE
|
||||||
|
@ -193,7 +173,7 @@ fi
|
||||||
|
|
||||||
AC_PROG_LIBTOOL
|
AC_PROG_LIBTOOL
|
||||||
AC_SUBST(LIBTOOL_DEPS)
|
AC_SUBST(LIBTOOL_DEPS)
|
||||||
# LIBTOOL="$LIBTOOL --silent"
|
LIBTOOL="$LIBTOOL --silent"
|
||||||
|
|
||||||
AC_PROG_INSTALL
|
AC_PROG_INSTALL
|
||||||
|
|
||||||
|
@ -219,12 +199,11 @@ CFLAGS="$STATVFS_DEF $CFLAGS"
|
||||||
|
|
||||||
dnl ts A91122
|
dnl ts A91122
|
||||||
AC_ARG_ENABLE(track-src-odirect,
|
AC_ARG_ENABLE(track-src-odirect,
|
||||||
[ --enable-track-src-odirect Banned for now: (Enable use of O_DIRECT with track input, default=no)],
|
[ --enable-track-src-odirect Enable use of O_DIRECT with track input, default=no],
|
||||||
, enable_track_src_odirect=no)
|
, enable_track_src_odirect=no)
|
||||||
if test x$enable_track_src_odirect = xyes; then
|
if test x$enable_track_src_odirect = xyes; then
|
||||||
# LIBBURN_O_DIRECT_DEF="-DLibburn_read_o_direcT"
|
LIBBURN_O_DIRECT_DEF="-DLibburn_read_o_direcT"
|
||||||
# echo "enabled use of O_DIRECT with track input"
|
echo "enabled use of O_DIRECT with track input"
|
||||||
echo "REFUSED to enable use of O_DIRECT with track input because of cdrskin multi-track bug"
|
|
||||||
else
|
else
|
||||||
LIBBURN_O_DIRECT_DEF=
|
LIBBURN_O_DIRECT_DEF=
|
||||||
echo "disabled use of O_DIRECT with track input"
|
echo "disabled use of O_DIRECT with track input"
|
||||||
|
@ -235,48 +214,21 @@ CFLAGS="$LIBBURN_O_DIRECT_DEF $CFLAGS"
|
||||||
|
|
||||||
dnl ts A91116
|
dnl ts A91116
|
||||||
AC_ARG_ENABLE(dvd-obs-64k,
|
AC_ARG_ENABLE(dvd-obs-64k,
|
||||||
[ --enable-dvd-obs-64k 64 KB default size for DVD writing, default=no],
|
[ --enable-dvd-obs-64k 64 KB default size for DVD/BD writing, default=no],
|
||||||
, enable_dvd_obs_64k=no)
|
, enable_dvd_obs_64k=no)
|
||||||
if test x$enable_dvd_obs_64k = xyes; then
|
if test x$enable_dvd_obs_64k = xyes; then
|
||||||
LIBBURN_DVD_OBS_64K="-DLibburn_dvd_obs_default_64K"
|
LIBBURN_DVD_OBS_64K="-DLibburn_dvd_obs_default_64K"
|
||||||
echo "enabled write size default 64 KB on DVD"
|
echo "enabled write size default 64 KB on DVD and BD"
|
||||||
else
|
else
|
||||||
LIBBURN_DVD_OBS_64K=
|
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
|
fi
|
||||||
CFLAGS="$LIBBURN_DVD_OBS_64K $CFLAGS"
|
CFLAGS="$LIBBURN_DVD_OBS_64K $CFLAGS"
|
||||||
|
|
||||||
dnl ts B20413
|
dnl ts A91218
|
||||||
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=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"
|
|
||||||
else
|
|
||||||
LIBBURN_DVD_OBS_64K=
|
|
||||||
echo "disabled padding of DVD DAO sessions to 32 or 64 KB"
|
|
||||||
fi
|
|
||||||
CFLAGS="$LIBBURN_DVD_OBS_PAD $CFLAGS"
|
|
||||||
|
|
||||||
dnl ts A91218 - B21002
|
|
||||||
case $host_os in
|
|
||||||
cygwin*|mingw*)
|
|
||||||
default_libcdio=yes
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
default_libcdio=no
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
# Check for proper library versions if this is desired.
|
|
||||||
# (It fails too often on too many systems.)
|
|
||||||
AC_ARG_ENABLE(pkg-check-modules,
|
|
||||||
[ --enable-pkg-check-modules Enable pkg-config check for libcdio , default=no],
|
|
||||||
, enable_pkg_check_modules=no)
|
|
||||||
AC_ARG_ENABLE(libcdio,
|
AC_ARG_ENABLE(libcdio,
|
||||||
[ --enable-libcdio Enable use of libcdio as system adapter, default=no (except on MSWindows)],
|
[ --enable-libcdio Enable EXPERIMENTAL use of libcdio as system adapter, default=no],
|
||||||
, enable_libcdio=$default_libcdio)
|
, enable_libcdio=no)
|
||||||
PKG_PROG_PKG_CONFIG
|
|
||||||
if test x$enable_libcdio = xyes; then
|
if test x$enable_libcdio = xyes; then
|
||||||
dnl Check whether there is libcdio-devel and libcdio-runtime.
|
dnl Check whether there is libcdio-devel and libcdio-runtime.
|
||||||
dnl If not, erase this macro
|
dnl If not, erase this macro
|
||||||
|
@ -293,20 +245,13 @@ then
|
||||||
echo "WARNING: could not enable use of libcdio as system adapter"
|
echo "WARNING: could not enable use of libcdio as system adapter"
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
echo "enabled use of libcdio as system adapter"
|
echo "enabled EXPERIMENTAL use of libcdio as system adapter"
|
||||||
CFLAGS="$LIBCDIO_DEF $CFLAGS"
|
CFLAGS="$LIBCDIO_DEF $CFLAGS"
|
||||||
|
|
||||||
if test x$enable_pkg_check_modules = xyes; then
|
LIBCDIO_REQUIRED=0.83
|
||||||
LIBCDIO_REQUIRED=0.83
|
PKG_CHECK_MODULES(LIBCDIO, libcdio >= $LIBCDIO_REQUIRED)
|
||||||
PKG_CHECK_MODULES(LIBCDIO, libcdio >= $LIBCDIO_REQUIRED)
|
|
||||||
else
|
|
||||||
echo "checking for LIBCDIO... skipped, no --enable-pkg-check-modules"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
dnl ts B70127
|
fi
|
||||||
# There are Linuxes with no public generic SCSI interface
|
|
||||||
LIBBURNIA_CHECK_LINUX_SCSI
|
|
||||||
|
|
||||||
dnl ts B00704
|
dnl ts B00704
|
||||||
# Library versioning normally serves a complex purpose.
|
# Library versioning normally serves a complex purpose.
|
||||||
|
@ -329,9 +274,6 @@ else
|
||||||
echo "disabled strict symbol encapsulation"
|
echo "disabled strict symbol encapsulation"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Check for system dependent mandatory libraries (LIBBURN_ARCH_LIBS)
|
|
||||||
LIBBURNIA_CHECK_ARCH_LIBS(mandatory)
|
|
||||||
|
|
||||||
AC_ARG_ENABLE(ldconfig-at-install,
|
AC_ARG_ENABLE(ldconfig-at-install,
|
||||||
[ --enable-ldconfig-at-install On GNU/Linux run ldconfig, default=yes],
|
[ --enable-ldconfig-at-install On GNU/Linux run ldconfig, default=yes],
|
||||||
, ldconfig_at_install=yes)
|
, ldconfig_at_install=yes)
|
||||||
|
@ -358,7 +300,7 @@ if test x$enable_debug != xyes; then
|
||||||
CFLAGS="-DNDEBUG $CFLAGS"
|
CFLAGS="-DNDEBUG $CFLAGS"
|
||||||
else
|
else
|
||||||
if test x$GCC = xyes; then
|
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
|
fi
|
||||||
CFLAGS="-DDEBUG $CFLAGS"
|
CFLAGS="-DDEBUG $CFLAGS"
|
||||||
fi
|
fi
|
||||||
|
|
736
doc/cdtext.txt
736
doc/cdtext.txt
|
@ -1,736 +0,0 @@
|
||||||
|
|
||||||
Description of CD-TEXT
|
|
||||||
|
|
||||||
Guided by Leon Merten Lohse via libcdio-devel@gnu.org
|
|
||||||
by reading mmc3r10g.pdf from http://www.t10.org/ftp/t10/drafts/mmc3/
|
|
||||||
by docs and results of cdtext.zip from http://www.sonydadc.com/file/
|
|
||||||
by reading http://digitalx.org/cue-sheet/syntax
|
|
||||||
by reading source of libcdio from http://www.gnu.org/s/libcdio
|
|
||||||
which quotes source of cdrecord from ftp://ftp.berlios.de/pub/cdrecord/alpha
|
|
||||||
by reading cdrecord.1 from ftp://ftp.berlios.de/pub/cdrecord/alpha
|
|
||||||
|
|
||||||
Language codes were learned from http://tech.ebu.ch/docs/tech/tech3264.pdf
|
|
||||||
Genre codes were learned from libcdio and confirmed by
|
|
||||||
http://helpdesk.audiofile-engineering.com/index.php?pg=kb.page&id=123
|
|
||||||
|
|
||||||
For libburnia-project.org by Thomas Schmitt <scdbackup@gmx.net>
|
|
||||||
|
|
||||||
Content:
|
|
||||||
- CD-TEXT from the view of the user
|
|
||||||
- Content specifications of particular pack types
|
|
||||||
- Format of a CD-TEXT packs array
|
|
||||||
- Overview of libburn API calls for CD-TEXT
|
|
||||||
- Sony Text File Format (Input Sheet Version 0.7T)
|
|
||||||
- CDRWIN cue sheet files
|
|
||||||
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
CD-TEXT from the view of the user:
|
|
||||||
|
|
||||||
CD-TEXT records attributes of disc and tracks on audio CD.
|
|
||||||
|
|
||||||
The attributes are grouped into blocks which represent particular languages.
|
|
||||||
Up to 8 blocks are possible.
|
|
||||||
|
|
||||||
There are 13 defined attribute categories, which are called Pack Types and are
|
|
||||||
identified by a single-byte code:
|
|
||||||
0x80 = Title
|
|
||||||
0x81 = Names of Performers
|
|
||||||
0x82 = Names of Songwriters
|
|
||||||
0x83 = Names of Composers
|
|
||||||
0x84 = Names of Arrangers
|
|
||||||
0x85 = Messages
|
|
||||||
0x86 = text-and-binary: Disc Identification
|
|
||||||
0x87 = text-and-binary: Genre Identification
|
|
||||||
0x88 = binary: Table of Content information
|
|
||||||
0x89 = binary: Second Table of Content information
|
|
||||||
(0x8a to 0x8c are reserved.)
|
|
||||||
0x8d = Closed Information
|
|
||||||
0x8e = UPC/EAN code of the album and ISRC code of each track
|
|
||||||
0x8f = binary: Size Information of the Block
|
|
||||||
|
|
||||||
Some of these categories apply to the whole disc only:
|
|
||||||
0x86, 0x87, 0x88, 0x89, 0x8d
|
|
||||||
Some have to be additionally attributed to each track, if they are present for
|
|
||||||
the whole disc:
|
|
||||||
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x8e
|
|
||||||
One describes the overall content of a block and in part of all other blocks:
|
|
||||||
0x8f
|
|
||||||
|
|
||||||
The total size of a block's attribute set is restricted by the fact that it
|
|
||||||
has to be stored in at most 253 records with 12 bytes of payload. These records
|
|
||||||
are called Text Packs.
|
|
||||||
A shortcut for repeated identical track texts is provided, so that a text
|
|
||||||
that is identical to the one of the previous track occupies only 2 or 4 bytes.
|
|
||||||
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
Content specification of particular pack types:
|
|
||||||
|
|
||||||
Pack types 0x80 to 0x85 and 0x8e contain 0-terminated cleartext. If double byte
|
|
||||||
characters are used, then two 0-bytes terminate the cleartext.
|
|
||||||
The meaning of 0x80 to 0x85 should be clear by above list. They are encoded
|
|
||||||
according to the Character Code of their block. Either as ISO-8859-1 single
|
|
||||||
byte characters, or as 7-bit ASCII single byte characters, or as MS-JIS double
|
|
||||||
byte characters.
|
|
||||||
More info to 0x8e is given below.
|
|
||||||
|
|
||||||
Pack type 0x86 (Disc Identification) is documented by Sony as "Catalog Number:
|
|
||||||
(use ASCII Code) Catalog Number of the album". So it is not really binary
|
|
||||||
but might be non-printable, and should contain only bytes with bit7 = 0.
|
|
||||||
|
|
||||||
Pack type 0x87 contains 2 binary bytes, followed by 0-terminated cleartext.
|
|
||||||
The two binary bytes form a big-endian index to the following list.
|
|
||||||
0x0000 = "Not Used" (Sony prescribes to use this if no genre applies)
|
|
||||||
0x0001 = "Not Defined"
|
|
||||||
0x0002 = "Adult Contemporary"
|
|
||||||
0x0003 = "Alternative Rock"
|
|
||||||
0x0004 = "Childrens Music"
|
|
||||||
0x0005 = "Classical"
|
|
||||||
0x0006 = "Contemporary Christian"
|
|
||||||
0x0007 = "Country"
|
|
||||||
0x0008 = "Dance"
|
|
||||||
0x0009 = "Easy Listening"
|
|
||||||
0x000a = "Erotic"
|
|
||||||
0x000b = "Folk"
|
|
||||||
0x000c = "Gospel"
|
|
||||||
0x000d = "Hip Hop"
|
|
||||||
0x000e = "Jazz"
|
|
||||||
0x000f = "Latin"
|
|
||||||
0x0010 = "Musical"
|
|
||||||
0x0011 = "New Age"
|
|
||||||
0x0012 = "Opera"
|
|
||||||
0x0013 = "Operetta"
|
|
||||||
0x0014 = "Pop Music"
|
|
||||||
0x0015 = "Rap"
|
|
||||||
0x0016 = "Reggae"
|
|
||||||
0x0017 = "Rock Music"
|
|
||||||
0x0018 = "Rhythm & Blues"
|
|
||||||
0x0019 = "Sound Effects"
|
|
||||||
0x001a = "Spoken Word"
|
|
||||||
0x001b = "World Music"
|
|
||||||
Sony documents the cleartext part as "Genre information that would supplement
|
|
||||||
the Genre Code, such as 'USA Rock music in the 60s'". Always ASCII encoded.
|
|
||||||
|
|
||||||
Pack type 0x88 records information from the CD's Table of Content, as of
|
|
||||||
READ PMA/TOC/ATIP Format 0010b (mmc3r10g.pdf, table 237 TOC Track Descriptor
|
|
||||||
Format, Q Sub-channel).
|
|
||||||
See below, Format of a CD-TEXT packs array, for more details about the content
|
|
||||||
of pack type 0x88.
|
|
||||||
|
|
||||||
Pack type 0x89 is yet quite unclear. It might be a representation of Playback
|
|
||||||
Skip Interval, Mode-5 Q sub-channel, POINT 01 to 40 (mmc3r10g.pdf 4.2.3.6.3).
|
|
||||||
If so, then this seems not to apply to write type SAO, because the CUE SHEET
|
|
||||||
format offers no way to express Mode-5 Q.
|
|
||||||
See below, Format of a CD-TEXT packs array, for an example of this pack type.
|
|
||||||
|
|
||||||
Pack type 0x8d is documented by Sony as "Closed Information: (use 8859-1 Code)
|
|
||||||
Any information can be recorded on disc as memorandum. Information in this
|
|
||||||
field will not be read by CD TEXT players available to the public."
|
|
||||||
Always ISO-8859-1 encoded.
|
|
||||||
|
|
||||||
Pack type 0x8e is documented by Sony as "UPC/EAN Code (POS Code) of the album.
|
|
||||||
This field typically consists of 13 characters." Always ASCII encoded.
|
|
||||||
It applies to tracks as "ISRC code [which] typically consists of 12 characters"
|
|
||||||
and is always ISO-8859-1 encoded.
|
|
||||||
MMC calls these information entities Media Catalog Number and ISRC.
|
|
||||||
The catalog number consists of 13 decimal digits.
|
|
||||||
ISRC consists of 12 characters: 2 country code [0-9A-Z], 3 owner code [0-9A-Z],
|
|
||||||
2 year digits (00 to 99), 5 serial number digits (00000 to 99999).
|
|
||||||
|
|
||||||
Pack type 0x8f summarizes the whole list of text packs of a block.
|
|
||||||
See below, Format of a CD-TEXT packs array, for details.
|
|
||||||
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
Format of a CD-TEXT packs array:
|
|
||||||
|
|
||||||
The attributes are represented on CD as Text Packs in the sub-channel of
|
|
||||||
the Lead-in of the disc. See doc/cookbook.txt for a description how to write
|
|
||||||
the readily formatted CD-TEXT pack array to CD, and how to read CD-TEXT packs
|
|
||||||
from CD.
|
|
||||||
|
|
||||||
The format is explained in part in MMC-3 (mmc3r10g.pdf, Annex J) and in part by
|
|
||||||
the documentation in Sony's cdtext.zip :
|
|
||||||
|
|
||||||
Each pack consists of a 4-byte header, 12 bytes of payload, and 2 bytes of CRC.
|
|
||||||
|
|
||||||
The first byte of each pack tells the pack type. See above for a list of types.
|
|
||||||
|
|
||||||
The second byte tells the track number to which the first text piece in
|
|
||||||
a pack is associated. Number 0 means the whole album. Higher numbers are
|
|
||||||
valid for types 0x80 to 0x85, and 0x8e. With these types, there should be
|
|
||||||
one text for the disc and one for each track.
|
|
||||||
With types 0x88 and 0x89, the second byte bears a track number, too.
|
|
||||||
With type 0x8f, the second byte counts the record parts from 0 to 2.
|
|
||||||
|
|
||||||
The third byte is a sequential counter.
|
|
||||||
|
|
||||||
The fourth byte is the Block Number and Character Position Indicator.
|
|
||||||
It consists of three bit fields:
|
|
||||||
bit7 = Double Bytes Character Code (0= single byte characters)
|
|
||||||
bit4-6 = Block Number (groups text packs in language blocks)
|
|
||||||
bit0-3 = Character position. Either the number of characters which
|
|
||||||
the current text inherited from the previous pack, or
|
|
||||||
15 if the current text started before the previous pack.
|
|
||||||
|
|
||||||
The 12 payload bytes contain pieces of 0-terminated texts or binary data.
|
|
||||||
A text may span over several packs. Unused characters in a pack are used for
|
|
||||||
the next text of the same pack type. If no text of the same type follows,
|
|
||||||
then the remaining text bytes are set to 0.
|
|
||||||
|
|
||||||
The CRC algorithm uses divisor 0x11021. The resulting 16-bit residue of the
|
|
||||||
polynomial division gets inverted and written as big-endian number to bytes
|
|
||||||
16 and 17 of the pack.
|
|
||||||
|
|
||||||
|
|
||||||
The text packs are grouped in up to 8 blocks of at most 256 packs. Each block
|
|
||||||
is in charge for one language. Sequence numbers of each block are counted
|
|
||||||
separately. All packs of block 0 come before the packs of block 1.
|
|
||||||
|
|
||||||
The limitation of block number and sequence numbers imply that there are at
|
|
||||||
most 2048 text packs possible. (READ TOC/PMA/ATIP could retrieve 3640 packs,
|
|
||||||
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.
|
|
||||||
(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
|
|
||||||
a block. They may or may not be repeated at the start of the follow-up packs
|
|
||||||
of type 0x87.
|
|
||||||
|
|
||||||
The first pack of type 0x88 in a block records in its payload bytes:
|
|
||||||
0 : PMIN of POINT A1 = First Track Number
|
|
||||||
1 : PMIN of POINT A2 = Last Track Number
|
|
||||||
2 : unknown, 0 in Sony example
|
|
||||||
3 : PMIN of POINT A2 = Start position of Lead-Out
|
|
||||||
4 : PSEC of POINT A2 = Start position of Lead-Out
|
|
||||||
5 : PFRAME of POINT A2 = Start position of Lead-Out
|
|
||||||
6 to 11 : unknown, 0 in Sony example
|
|
||||||
The following packs record PMIN, PSEC, PFRAME of the POINTs between the
|
|
||||||
lowest track number (min 01h) and the highest track number (max 63h).
|
|
||||||
The payload of the last pack is padded by 0s.
|
|
||||||
The Sony .TOC example:
|
|
||||||
A0 01
|
|
||||||
A1 14
|
|
||||||
A2 63:02:18
|
|
||||||
01 00:02:00
|
|
||||||
02 04:11:25
|
|
||||||
03 08:02:50
|
|
||||||
04 11:47:62
|
|
||||||
...
|
|
||||||
13 53:24:25
|
|
||||||
14 57:03:25
|
|
||||||
yields
|
|
||||||
88 00 23 00 01 0e 00 3f 02 12 00 00 00 00 00 00 12 00
|
|
||||||
88 01 24 00 00 02 00 04 0b 19 08 02 32 0b 2f 3e 67 2d
|
|
||||||
...
|
|
||||||
88 0d 27 00 35 18 19 39 03 19 00 00 00 00 00 00 ea af
|
|
||||||
|
|
||||||
Pack type 0x89 is yet quite unclear. Especially what the information shall
|
|
||||||
mean to the user of the CD. The time points in the Sony example are in the
|
|
||||||
time range of the tracks numbers that are given before the time points:
|
|
||||||
01 02:41:48 01 02:52:58
|
|
||||||
06 23:14:25 06 23:29:60
|
|
||||||
07 28:30:39 07 28:42:30
|
|
||||||
13 55:13:26 13 55:31:50
|
|
||||||
yields
|
|
||||||
89 01 28 00 01 04 00 00 00 00 02 29 30 02 34 3a f3 0c
|
|
||||||
89 06 29 00 02 04 00 00 00 00 17 0e 19 17 1d 3c 73 92
|
|
||||||
89 07 2a 00 03 04 00 00 00 00 1c 1e 27 1c 2a 1e 72 20
|
|
||||||
89 0d 2b 00 04 04 00 00 00 00 37 0d 1a 37 1f 32 0b 62
|
|
||||||
The track numbers are stored in the track number byte of the packs. The two
|
|
||||||
time points are stored in byte 6 to 11 of the payload. Byte 0 of the payload
|
|
||||||
seems to be a sequential counter. Byte 1 always 4 ? Byte 2 to 5 always 0 ?
|
|
||||||
|
|
||||||
Pack type 0x8f summarizes the whole list of text packs of a block.
|
|
||||||
So there is one group of three 0x8f packs per block.
|
|
||||||
Nevertheless each 0x8f group tells the highest sequence number and the
|
|
||||||
language code of all blocks.
|
|
||||||
The payload bytes of three 0x8f packs form a 36 byte record. The track number
|
|
||||||
bytes of the three packs have the values 0, 1, 2.
|
|
||||||
Byte :
|
|
||||||
0 : Character code for pack types 0x80 to 0x85:
|
|
||||||
0x00 = ISO-8859-1
|
|
||||||
0x01 = 7 bit ASCII
|
|
||||||
0x80 = MS-JIS (japanese Kanji, double byte characters)
|
|
||||||
1 : Number of first track
|
|
||||||
2 : Number of last track
|
|
||||||
3 : libcdio source states: "cd-text information copyright byte"
|
|
||||||
Probably 3 means "copyrighted", 0 means "not copyrighted".
|
|
||||||
4 - 19 : Pack count of the various types 0x80 to 0x8f.
|
|
||||||
Byte number N tells the count of packs of type 0x80 + (N - 4).
|
|
||||||
I.e. the first byte in this field of 16 counts packs of type 0x80.
|
|
||||||
20 - 27 : Highest sequence byte number of blocks 0 to 7.
|
|
||||||
28 - 36 : Language code for blocks 0 to 7 (tech3264.pdf appendix 3)
|
|
||||||
Not all of these Codes have ever been seen with CD-TEXT, though.
|
|
||||||
0x00 = Unknown
|
|
||||||
0x01 = Albanian
|
|
||||||
0x02 = Breton
|
|
||||||
0x03 = Catalan
|
|
||||||
0x04 = Croatian
|
|
||||||
0x05 = Welsh
|
|
||||||
0x06 = Czech
|
|
||||||
0x07 = Danish
|
|
||||||
0x08 = German
|
|
||||||
0x09 = English
|
|
||||||
0x0a = Spanish
|
|
||||||
0x0b = Esperanto
|
|
||||||
0x0c = Estonian
|
|
||||||
0x0d = Basque
|
|
||||||
0x0e = Faroese
|
|
||||||
0x0f = French
|
|
||||||
0x10 = Frisian
|
|
||||||
0x11 = Irish
|
|
||||||
0x12 = Gaelic
|
|
||||||
0x13 = Galician
|
|
||||||
0x14 = Icelandic
|
|
||||||
0x15 = Italian
|
|
||||||
0x16 = Lappish
|
|
||||||
0x17 = Latin
|
|
||||||
0x18 = Latvian
|
|
||||||
0x19 = Luxembourgian
|
|
||||||
0x1a = Lithuanian
|
|
||||||
0x1b = Hungarian
|
|
||||||
0x1c = Maltese
|
|
||||||
0x1d = Dutch
|
|
||||||
0x1e = Norwegian
|
|
||||||
0x1f = Occitan
|
|
||||||
0x20 = Polish
|
|
||||||
0x21 = Portuguese
|
|
||||||
0x22 = Romanian
|
|
||||||
0x23 = Romansh
|
|
||||||
0x24 = Serbian
|
|
||||||
0x25 = Slovak
|
|
||||||
0x26 = Slovenian
|
|
||||||
0x27 = Finnish
|
|
||||||
0x28 = Swedish
|
|
||||||
0x29 = Turkish
|
|
||||||
0x2a = Flemish
|
|
||||||
0x2b = Wallon
|
|
||||||
0x45 = Zulu
|
|
||||||
0x46 = Vietnamese
|
|
||||||
0x47 = Uzbek
|
|
||||||
0x48 = Urdu
|
|
||||||
0x49 = Ukrainian
|
|
||||||
0x4a = Thai
|
|
||||||
0x4b = Telugu
|
|
||||||
0x4c = Tatar
|
|
||||||
0x4d = Tamil
|
|
||||||
0x4e = Tadzhik
|
|
||||||
0x4f = Swahili
|
|
||||||
0x50 = Sranan Tongo
|
|
||||||
0x51 = Somali
|
|
||||||
0x52 = Sinhalese
|
|
||||||
0x53 = Shona
|
|
||||||
0x54 = Serbo-croat
|
|
||||||
0x55 = Ruthenian
|
|
||||||
0x56 = Russian
|
|
||||||
0x57 = Quechua
|
|
||||||
0x58 = Pushtu
|
|
||||||
0x59 = Punjabi
|
|
||||||
0x5a = Persian
|
|
||||||
0x5b = Papamiento
|
|
||||||
0x5c = Oriya
|
|
||||||
0x5d = Nepali
|
|
||||||
0x5e = Ndebele
|
|
||||||
0x5f = Marathi
|
|
||||||
0x60 = Moldavian
|
|
||||||
0x61 = Malaysian
|
|
||||||
0x62 = Malagasay
|
|
||||||
0x63 = Macedonian
|
|
||||||
0x64 = Laotian
|
|
||||||
0x65 = Korean
|
|
||||||
0x66 = Khmer
|
|
||||||
0x67 = Kazakh
|
|
||||||
0x68 = Kannada
|
|
||||||
0x69 = Japanese
|
|
||||||
0x6a = Indonesian
|
|
||||||
0x6b = Hindi
|
|
||||||
0x6c = Hebrew
|
|
||||||
0x6d = Hausa
|
|
||||||
0x6e = Gurani
|
|
||||||
0x6f = Gujurati
|
|
||||||
0x70 = Greek
|
|
||||||
0x71 = Georgian
|
|
||||||
0x72 = Fulani
|
|
||||||
0x73 = Dari
|
|
||||||
0x74 = Churash
|
|
||||||
0x75 = Chinese
|
|
||||||
0x76 = Burmese
|
|
||||||
0x77 = Bulgarian
|
|
||||||
0x78 = Bengali
|
|
||||||
0x79 = Bielorussian
|
|
||||||
0x7a = Bambora
|
|
||||||
0x7b = Azerbaijani
|
|
||||||
0x7c = Assamese
|
|
||||||
0x7d = Armenian
|
|
||||||
0x7e = Arabic
|
|
||||||
0x7f = Amharic
|
|
||||||
E.g. these three packs
|
|
||||||
42 : 8f 00 2a 00 01 01 03 00 06 05 04 05 07 06 01 02 48 65
|
|
||||||
43 : 8f 01 2b 00 00 00 00 00 00 00 06 03 2c 00 00 00 c0 20
|
|
||||||
44 : 8f 02 2c 00 00 00 00 00 09 00 00 00 00 00 00 00 11 45
|
|
||||||
decode to
|
|
||||||
Byte :Value Meaning
|
|
||||||
0 : 01 = ASCII 7-bit
|
|
||||||
1 : 01 = first track is 1
|
|
||||||
2 : 03 = last track is 3
|
|
||||||
3 : 00 = copyright (0 = public domain, 3 = copyrighted ?)
|
|
||||||
4 : 06 = 6 packs of type 0x80
|
|
||||||
5 : 05 = 5 packs of type 0x81
|
|
||||||
6 : 04 = 4 packs of type 0x82
|
|
||||||
7 : 05 = 5 packs of type 0x83
|
|
||||||
8 : 07 = 7 packs of type 0x84
|
|
||||||
9 : 06 = 6 packs of type 0x85
|
|
||||||
10 : 01 = 1 pack of type 0x86
|
|
||||||
11 : 02 = 2 packs of type 0x87
|
|
||||||
12 : 00 = 0 packs of type 0x88
|
|
||||||
13 : 00 = 0 packs of type 0x89
|
|
||||||
14 : 00 00 00 00 = 0 packs of types 0x8a to 0x8d
|
|
||||||
18 : 06 = 6 packs of type 0x8e
|
|
||||||
19 : 03 = 3 packs of type 0x8f
|
|
||||||
20 : 2c = last sequence for block 0
|
|
||||||
This matches the sequence number of the last text pack (0x2c = 44)
|
|
||||||
21 : 00 00 00 00 00 00 00 = last sequence numbers for block 1..7 (none)
|
|
||||||
28 : 09 = language code for block 0: English
|
|
||||||
29 : 00 00 00 00 00 00 00 = language codes for block 1..7 (none)
|
|
||||||
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
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:
|
|
||||||
|
|
||||||
int burn_disc_get_leadin_text(struct burn_drive *d,
|
|
||||||
unsigned char **text_packs, int *num_packs,
|
|
||||||
int flag);
|
|
||||||
|
|
||||||
|
|
||||||
It can write a text pack set with a CD SAO session.
|
|
||||||
|
|
||||||
This set may be attached as array of readily formatted text packs by:
|
|
||||||
|
|
||||||
int burn_write_opts_set_leadin_text(struct burn_write_opts *opts,
|
|
||||||
unsigned char *text_packs,
|
|
||||||
int num_packs, int flag);
|
|
||||||
|
|
||||||
The array of text packs may be read from a file by
|
|
||||||
|
|
||||||
int burn_cdtext_from_packfile(char *path, unsigned char **text_packs,
|
|
||||||
int *num_packs, int flag);
|
|
||||||
|
|
||||||
|
|
||||||
Alternatively the pack set may be defined by attaching CD-TEXT attributes
|
|
||||||
to burn_session and burn_track:
|
|
||||||
|
|
||||||
int burn_session_set_cdtext_par(struct burn_session *s,
|
|
||||||
int char_codes[8], int copyrights[8],
|
|
||||||
int languages[8], int flag);
|
|
||||||
|
|
||||||
int burn_session_set_cdtext(struct burn_session *s, int block,
|
|
||||||
int pack_type, char *pack_type_name,
|
|
||||||
unsigned char *payload, int length, int flag);
|
|
||||||
|
|
||||||
int burn_track_set_cdtext(struct burn_track *t, int block,
|
|
||||||
int pack_type, char *pack_type_name,
|
|
||||||
unsigned char *payload, int length, int flag);
|
|
||||||
|
|
||||||
Macros list the texts for genre and language codes:
|
|
||||||
|
|
||||||
BURN_CDTEXT_LANGUAGES_0X00
|
|
||||||
BURN_CDTEXT_FILLER
|
|
||||||
BURN_CDTEXT_LANGUAGES_0X45
|
|
||||||
|
|
||||||
BURN_CDTEXT_GENRE_LIST
|
|
||||||
BURN_CDTEXT_NUM_GENRES
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
int burn_session_by_cue_file(struct burn_session *session,
|
|
||||||
char *path, int fifo_size, struct burn_source **fifo,
|
|
||||||
unsigned char **text_packs, int *num_packs, int flag);
|
|
||||||
|
|
||||||
|
|
||||||
The session and track attributes can then be converted into an array of
|
|
||||||
text packs by:
|
|
||||||
|
|
||||||
int burn_cdtext_from_session(struct burn_session *s,
|
|
||||||
unsigned char **text_packs, int *num_packs,
|
|
||||||
int flag);
|
|
||||||
|
|
||||||
or they can be written as array of text packs to CD when burning begins and
|
|
||||||
no array of pre-formatted packs was attached to the write options by
|
|
||||||
burn_write_opts_set_leadin_text().
|
|
||||||
|
|
||||||
There are calls for inspecting the attached attributes:
|
|
||||||
|
|
||||||
int burn_session_get_cdtext_par(struct burn_session *s,
|
|
||||||
int char_codes[8], int copyrights[8],
|
|
||||||
int block_languages[8], int flag);
|
|
||||||
|
|
||||||
int burn_session_get_cdtext(struct burn_session *s, int block,
|
|
||||||
int pack_type, char *pack_type_name,
|
|
||||||
unsigned char **payload, int *length, int flag);
|
|
||||||
|
|
||||||
int burn_track_get_cdtext(struct burn_track *t, int block,
|
|
||||||
int pack_type, char *pack_type_name,
|
|
||||||
unsigned char **payload, int *length, int flag);
|
|
||||||
|
|
||||||
and for removing attached attributes:
|
|
||||||
|
|
||||||
int burn_session_dispose_cdtext(struct burn_session *s, int block);
|
|
||||||
|
|
||||||
int burn_track_dispose_cdtext(struct burn_track *t, int block);
|
|
||||||
|
|
||||||
|
|
||||||
UPC/EAN and ISRC not only affect CD-TEXT but also information that is written
|
|
||||||
along with the tracks in Q sub-channel. These can be influenced by
|
|
||||||
burn_session_input_sheet_v07t(), burn_session_by_cue_file() and by
|
|
||||||
|
|
||||||
void burn_write_opts_set_mediacatalog(struct burn_write_opts *opts,
|
|
||||||
unsigned char mediacatalog[13]);
|
|
||||||
|
|
||||||
void burn_write_opts_set_has_mediacatalog(struct burn_write_opts *opts,
|
|
||||||
int has_mediacatalog);
|
|
||||||
|
|
||||||
void burn_track_set_isrc(struct burn_track *t, char *country, char *owner,
|
|
||||||
unsigned char year, unsigned int serial);
|
|
||||||
|
|
||||||
int burn_track_set_isrc_string(struct burn_track *t, char isrc[13],
|
|
||||||
int flag);
|
|
||||||
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
Sony Text File Format (Input Sheet Version 0.7T):
|
|
||||||
|
|
||||||
This text file format provides comprehensive means to define the text
|
|
||||||
attributes of session and tracks for a single block. More than one
|
|
||||||
such file has to be read to form an attribute set with multiple blocks.
|
|
||||||
|
|
||||||
The information is given by text lines of the following form:
|
|
||||||
purpose specifier [whitespace] = [whitespace] content text
|
|
||||||
[whitespace] is zero or more ASCII 32 (space) or ASCII 9 (tab) characters.
|
|
||||||
The purpose specifier tells the meaning of the content text.
|
|
||||||
Empty content text does not cause a CD-TEXT attribute to be attached.
|
|
||||||
|
|
||||||
The following purpose specifiers apply to the session as a whole:
|
|
||||||
Specifier = Meaning
|
|
||||||
-------------------------------------------------------------------------
|
|
||||||
Text Code = Character code for pack type 0x8f
|
|
||||||
"ASCII", "8859"
|
|
||||||
Language Code = One of the language names for pack type 0x8f
|
|
||||||
Album Title = Content of pack type 0x80
|
|
||||||
Artist Name = Content of pack type 0x81
|
|
||||||
Songwriter = Content of pack type 0x82
|
|
||||||
Composer = Content of pack type 0x83
|
|
||||||
Arranger = Content of pack type 0x84
|
|
||||||
Album Message = Content of pack type 0x85
|
|
||||||
Catalog Number = Content of pack type 0x86
|
|
||||||
Genre Code = One of the genre names for pack type 0x87
|
|
||||||
Genre Information = Cleartext part of pack type 0x87
|
|
||||||
Closed Information = Content of pack type 0x8d
|
|
||||||
UPC / EAN = Content of pack type 0x8e
|
|
||||||
Text Data Copy Protection = Copyright value for pack type 0x8f
|
|
||||||
"ON" = 0x03, "OFF" = 0x00
|
|
||||||
First Track Number = The lowest track number used in the file
|
|
||||||
Last Track Number = The highest track number used in the file
|
|
||||||
|
|
||||||
The following purpose specifiers apply to particular tracks:
|
|
||||||
Track NN Title = Content of pack type 0x80
|
|
||||||
Track NN Artist = Content of pack type 0x81
|
|
||||||
Track NN Songwriter = Content of pack type 0x82
|
|
||||||
Track NN Composer = Content of pack type 0x83
|
|
||||||
Track NN Arranger = Content of pack type 0x84
|
|
||||||
Track NN Message = Content of pack type 0x85
|
|
||||||
ISRC NN = Content of pack type 0x8e
|
|
||||||
|
|
||||||
The following purpose specifiers have no effect on CD-TEXT:
|
|
||||||
Remarks = Comments with no influence on CD-TEXT
|
|
||||||
Disc Information NN = Supplementary information for use by record companies.
|
|
||||||
ISO-8859-1 encoded. NN ranges from 01 to 04.
|
|
||||||
Input Sheet Version = "0.7T"
|
|
||||||
|
|
||||||
|
|
||||||
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()
|
|
||||||
|
|
||||||
The following purpose specifiers accept byte values of the form 0xXY.
|
|
||||||
Text Code , Language Code , Genre Code , Text Data Copy Protection
|
|
||||||
E.g. to indicate MS-JIS character code (of which the exact name is unknown):
|
|
||||||
Text Code = 0x80
|
|
||||||
Genre Code is settable by 0xXY or 0xXYZT or 0xXY 0xZT.
|
|
||||||
Genre Code = 0x001b
|
|
||||||
|
|
||||||
Purpose specifiers which have the meaning "Content of pack type 0xXY"
|
|
||||||
may be replaced by the pack type codes. E.g.:
|
|
||||||
0x80 = Session content of pack type 0x80
|
|
||||||
Track 02 0x80 = Track content of pack type 0x80 for track 2.
|
|
||||||
Applicable are pack types 0x80 to 0x86, 0x8d, 0x8e.
|
|
||||||
|
|
||||||
Text Code may be specified only once. It gets speficied to "ISO-8850-1"
|
|
||||||
automatically as soon as content is defined which depends on the text
|
|
||||||
encoding of the block. I.e with pack types 0x80 to 0x85.
|
|
||||||
|
|
||||||
If a track attribute is set, but the corresponding session attribute is not
|
|
||||||
defined or defined with empty text, then the session attribute gets attached
|
|
||||||
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
|
|
||||||
|
|
||||||
----------------------------------------------------------
|
|
||||||
Content of file NIGHTCATS.TXT :
|
|
||||||
----------------------------------------------------------
|
|
||||||
Input Sheet Version = 0.7T
|
|
||||||
Text Code = 8859
|
|
||||||
Language Code = English
|
|
||||||
Album Title = Joyful Nights
|
|
||||||
Artist Name = United Cat Orchestra
|
|
||||||
Songwriter = Various Songwriters
|
|
||||||
Composer = Various Composers
|
|
||||||
Arranger = Tom Cat
|
|
||||||
Album Message = For all our fans
|
|
||||||
Catalog Number = 1234567890
|
|
||||||
Genre Code = Classical
|
|
||||||
Genre Information = Feline classic music
|
|
||||||
Closed Information = This is not to be shown by CD players
|
|
||||||
UPC / EAN = 1234567890123
|
|
||||||
Text Data Copy Protection = OFF
|
|
||||||
First Track Number = 1
|
|
||||||
Last Track Number = 3
|
|
||||||
Track 01 Title = Song of Joy
|
|
||||||
Track 01 Artist = Felix and The Purrs
|
|
||||||
Track 01 Songwriter = Friedrich Schiller
|
|
||||||
Track 01 Composer = Ludwig van Beethoven
|
|
||||||
Track 01 Arranger = Tom Cat
|
|
||||||
Track 01 Message = Fritz and Louie once were punks
|
|
||||||
ISRC 01 = XYBLG1101234
|
|
||||||
Track 02 Title = Humpty Dumpty
|
|
||||||
Track 02 Artist = Catwalk Beauties
|
|
||||||
Track 02 Songwriter = Mother Goose
|
|
||||||
Track 02 Composer = unknown
|
|
||||||
Track 02 Arranger = Tom Cat
|
|
||||||
Track 02 Message = Pluck the goose
|
|
||||||
ISRC 02 = XYBLG1100005
|
|
||||||
Track 03 Title = Mee Owwww
|
|
||||||
Track 03 Artist = Mia Kitten
|
|
||||||
Track 03 Songwriter = Mia Kitten
|
|
||||||
Track 03 Composer = Mia Kitten
|
|
||||||
Track 03 Arranger = Mia Kitten
|
|
||||||
Track 03 Message =
|
|
||||||
ISRC 03 = XYBLG1100006
|
|
||||||
----------------------------------------------------------
|
|
||||||
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
CDRWIN cue sheet files:
|
|
||||||
|
|
||||||
A CDRWIN cue sheet file defines the track data source (FILE), various text
|
|
||||||
attributes (CATALOG, TITLE, PERFORMER, SONGWRITER, ISRC), track block types
|
|
||||||
(TRACK), track start addresses (INDEX).
|
|
||||||
The rules for CDRWIN cue sheet files are described at
|
|
||||||
http://digitalx.org/cue-sheet/syntax/
|
|
||||||
There are three more text attributes mentioned in man cdrecord for defining
|
|
||||||
the corresponding CD-TEXT attributes: ARRANGER, COMPOSER, MESSAGE.
|
|
||||||
|
|
||||||
|
|
||||||
--------------------------------------------------------
|
|
||||||
Example of a CDRWIN cue sheet file named NIGHTCATS.CUE :
|
|
||||||
--------------------------------------------------------
|
|
||||||
|
|
||||||
CATALOG 1234567890123
|
|
||||||
FILE "audiodata.bin" BINARY
|
|
||||||
TITLE "Joyful Nights"
|
|
||||||
TRACK 01 AUDIO
|
|
||||||
FLAGS DCP
|
|
||||||
TITLE "Song of Joy"
|
|
||||||
PERFORMER "Felix and The Purrs"
|
|
||||||
SONGWRITER "Friedrich Schiller"
|
|
||||||
ISRC XYBLG1101234
|
|
||||||
INDEX 01 00:00:00
|
|
||||||
TRACK 02 AUDIO
|
|
||||||
FLAGS DCP
|
|
||||||
TITLE "Humpty Dumpty"
|
|
||||||
PERFORMER "Catwalk Beauties"
|
|
||||||
SONGWRITER "Mother Goose"
|
|
||||||
ISRC XYBLG1100005
|
|
||||||
INDEX 01 08:20:12
|
|
||||||
TRACK 03 AUDIO
|
|
||||||
FLAGS DCP
|
|
||||||
TITLE "Mee Owwww"
|
|
||||||
PERFORMER "Mia Kitten"
|
|
||||||
SONGWRITER "Mia Kitten"
|
|
||||||
ISRC XYBLG1100006
|
|
||||||
INDEX 01 13:20:33
|
|
||||||
|
|
||||||
By
|
|
||||||
|
|
||||||
$ cdrskin -v dev=/dev/sr0 -text cuefile=NIGHTCATS.CUE
|
|
||||||
|
|
||||||
this yields as text packs:
|
|
||||||
|
|
||||||
0 : 80 00 00 00 J o y f u l N i g h t f0 f7
|
|
||||||
1 : 80 00 01 0c s 00 S o n g o f J o 43 1c
|
|
||||||
2 : 80 01 02 0a y 00 H u m p t y D u m 43 f9
|
|
||||||
3 : 80 02 03 0a p t y 00 M e e O w w w 24 72
|
|
||||||
4 : 80 03 04 08 w 00 00 00 00 00 00 00 00 00 00 00 6e af
|
|
||||||
5 : 81 00 05 00 00 F e l i x a n d T 4d 51
|
|
||||||
6 : 81 01 06 0b h e P u r r s 00 C a t a7 40
|
|
||||||
7 : 81 02 07 03 w a l k B e a u t i e 59 80
|
|
||||||
8 : 81 02 08 0f s 00 M i a K i t t e n 30 c9
|
|
||||||
9 : 81 03 09 0a 00 00 00 00 00 00 00 00 00 00 00 00 ad 19
|
|
||||||
10 : 82 00 0a 00 00 F r i e d r i c h S 70 8f
|
|
||||||
11 : 82 01 0b 0b c h i l l e r 00 M o t h 33 43
|
|
||||||
12 : 82 02 0c 04 e r G o o s e 00 M i a d6 f5
|
|
||||||
13 : 82 03 0d 03 K i t t e n 00 00 00 00 00 f5 83
|
|
||||||
14 : 8e 00 0e 00 1 2 3 4 5 6 7 8 9 0 1 2 92 3e
|
|
||||||
15 : 8e 00 0f 0c 3 00 X Y B L G 1 1 0 1 2 c0 2b
|
|
||||||
16 : 8e 01 10 0a 3 4 00 X Y B L G 1 1 0 0 bb b3
|
|
||||||
17 : 8e 02 11 09 0 0 5 00 X Y B L G 1 1 0 f3 bf
|
|
||||||
18 : 8e 03 12 08 0 0 0 6 00 00 00 00 00 00 00 00 5b 5c
|
|
||||||
19 : 8f 00 13 00 00 01 03 00 05 05 04 00 00 00 00 00 9b fe
|
|
||||||
20 : 8f 01 14 00 00 00 00 00 00 00 05 03 15 00 00 00 11 0b
|
|
||||||
21 : 8f 02 15 00 00 00 00 00 09 00 00 00 00 00 00 00 da 77
|
|
||||||
|
|
||||||
--------------------------------------
|
|
||||||
|
|
||||||
Some restrictions apply in the libburn call burn_session_by_cue_file():
|
|
||||||
|
|
||||||
Only FILE types BINARY, MOTOROLA, WAVE are allowed.
|
|
||||||
Only TRACK datatypes AUDIO, MODE1/2048 are allowed. They may not be mixed in
|
|
||||||
the same session.
|
|
||||||
|
|
||||||
On the other hand, ARRANGER, COMPOSER, MESSAGE are supported unconditionally.
|
|
||||||
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
This text is copyright 2011 - 2012 Thomas Schmitt <scdbackup@gmx.net>.
|
|
||||||
Permission is granted to copy, modify, and distribute it, as long as the
|
|
||||||
references to the original information sources are maintained.
|
|
||||||
There is NO WARRANTY, to the extent permitted by law.
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
|
|
|
@ -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,
|
For now this means CD-R, CD-RW, DVD-RAM, DVD+RW, DVD+R, DVD+R/DL, DVD-RW,
|
||||||
DVD-R, DVD-R/DL, BD-R, BD-RE.
|
DVD-R, DVD-R/DL, BD-R, BD-RE.
|
||||||
|
|
||||||
Our scope is currently Linux 2.4 and 2.6, FreeBSD, OpenSolaris, or NetBSD.
|
Our scope is currently Linux 2.4 and 2.6, or FreeBSD, or Solaris . For ports
|
||||||
For ports to other systems we would need : login on a development machine or
|
to other systems we would need : login on a development machine resp.
|
||||||
an OS that is installable on an AMD 64-bit PC, advise from a system person
|
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
|
about the equivalent of Linux sg or FreeBSD CAM, volunteers for testing of
|
||||||
realistic use cases.
|
realistic use cases.
|
||||||
|
|
||||||
|
@ -52,7 +52,7 @@ and execute
|
||||||
|
|
||||||
- make
|
- make
|
||||||
|
|
||||||
To make the libraries accessible for running and developing applications
|
To make the libraries accessible for running resp. developing applications
|
||||||
|
|
||||||
- make install
|
- make install
|
||||||
|
|
||||||
|
|
199
doc/cookbook.txt
199
doc/cookbook.txt
|
@ -4,7 +4,7 @@ Note: This is about how libburn operates optical drives. Not about how to
|
||||||
operate libburn. The libburn API is described in libburn/libburn.h
|
operate libburn. The libburn API is described in libburn/libburn.h
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
|
|
||||||
libburnia-project.org Optical Media Rotisserie Recipes as of December 2011
|
libburnia-project.org Optical Media Rotisserie Recipes as of January 2010
|
||||||
|
|
||||||
Content:
|
Content:
|
||||||
- TAO Multi-Session CD Cookbook (CD-R, CD-RW)
|
- TAO Multi-Session CD Cookbook (CD-R, CD-RW)
|
||||||
|
@ -94,15 +94,10 @@ parameters:
|
||||||
Write Type Packet/TAO/SAO/RAW 01h = TAO
|
Write Type Packet/TAO/SAO/RAW 01h = TAO
|
||||||
Multi-session Whether to keep appendable 00b = finalize
|
Multi-session Whether to keep appendable 00b = finalize
|
||||||
11b = keep appendable
|
11b = keep appendable
|
||||||
Copy Whether to deny copying 1 = deny by SCMS , 0 = allow
|
|
||||||
Track Mode Describes frame type 4 for data , 0 for audio
|
Track Mode Describes frame type 4 for data , 0 for audio
|
||||||
Data Block Type Layout of payload blocks 8 for 2048 byte data blocks
|
Data Block Type Layout of payload blocks 8 for 2048 byte data blocks
|
||||||
0 for 2352 byte audio blocks
|
0 for 2352 byte audio blocks
|
||||||
Audio Pause Length 150 = 2 seconds
|
Audio Pause Length 150 = 2 seconds
|
||||||
Media Catalog Number A property of the disc 0x80 if valid
|
|
||||||
13 decimal digits as ASCII
|
|
||||||
ISRC A property of the track 0x80 if valid
|
|
||||||
12 letters and digits, ASCII
|
|
||||||
Any other parameters may be set to 0.
|
Any other parameters may be set to 0.
|
||||||
Mode page data as of MMC-5 table 644 are preceded by a Mode Parameter Header
|
Mode page data as of MMC-5 table 644 are preceded by a Mode Parameter Header
|
||||||
as of SPC-3 table 240. This 8-byte header may be filled with zeros.
|
as of SPC-3 table 240. This 8-byte header may be filled with zeros.
|
||||||
|
@ -198,9 +193,7 @@ If POINT is >= 1 and <= 99 (63h) then the descriptor is about the track of
|
||||||
which POINT tells the number.
|
which POINT tells the number.
|
||||||
The start address of this track can be read from PMIN, PSEC, PFRAME where
|
The start address of this track can be read from PMIN, PSEC, PFRAME where
|
||||||
it is encoded in MSF format:
|
it is encoded in MSF format:
|
||||||
If M is smaller than 90: LBA = (M * 60 + S) * 75 + F - 150
|
blocks = frames - 150, 75 frames = 1 sec , 60 sec = 1 min.
|
||||||
Else : LBA = (M * 60 + S) * 75 + F - 450150
|
|
||||||
|
|
||||||
The length of the track is given by MIN,SEC,FRAME in the same format.
|
The length of the track is given by MIN,SEC,FRAME in the same format.
|
||||||
|
|
||||||
If POINT = A0h then the descriptor tells in PMIN the first track number of its
|
If POINT = A0h then the descriptor tells in PMIN the first track number of its
|
||||||
|
@ -227,12 +220,10 @@ sync. libburn uses the info provided by 52h READ TRACK INFORMATION.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
SAO CD Cookbook
|
SAO CD Cookbook
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Guided by reading libburn/* from http://icculus.org/burn
|
Guided by reading libburn/* from http://icculus.org/burn
|
||||||
backed by reading mmc5r03c.pdf from http://www.t10.org/ftp/t10/drafts/mmc5/
|
backed by reading mmc5r03c.pdf from http://www.t10.org/ftp/t10/drafts/mmc5/
|
||||||
backed by reading scms.html from
|
and by experiments with drives NEC ND-4570A, LG GSA-4082B, LITE-ON LTR48125S
|
||||||
http://www.barrel-of-monkeys.com/graphics/prod/dvdplayers/
|
which used in part code from http://icculus.org/burn.
|
||||||
and by experiments with drives NEC ND-4570A, LG GSA-4082B, LITE-ON LTR48125S,
|
|
||||||
Optiarc BD RW BD-5300S, LG BDDVDRW GGC-H20L
|
|
||||||
|
|
||||||
For libburnia-project.org by Thomas Schmitt <scdbackup@gmx.net>
|
For libburnia-project.org by Thomas Schmitt <scdbackup@gmx.net>
|
||||||
|
|
||||||
|
@ -269,96 +260,46 @@ Each entry of the sheet is of 8 bytes size. Its fields are named
|
||||||
CTL|ADR, TNO, INDEX, DATA FORM, SCMS, MIN, SEC, FRAME .
|
CTL|ADR, TNO, INDEX, DATA FORM, SCMS, MIN, SEC, FRAME .
|
||||||
(mmc5r03c.pdf 6.33)
|
(mmc5r03c.pdf 6.33)
|
||||||
|
|
||||||
CTL is comprised of four bits:
|
CTL is 40h for data and 00h for audio.
|
||||||
bit4 = Pre-emphasis (audio only)
|
|
||||||
bit5 = Digital copy permission:
|
|
||||||
0 = prohibited (one-time copy is permitted if SCMS is 00h)
|
|
||||||
1 = permitted (unlimited)
|
|
||||||
bit6 = Data track indicator (bit4 and bit7 shall be 0)
|
|
||||||
bit7 = 4-channel audio
|
|
||||||
Usually CTL is 40h for data and 00h for audio.
|
|
||||||
(mmc5r03c.pdf 6.33.3.4)
|
(mmc5r03c.pdf 6.33.3.4)
|
||||||
ADR is 01h for entries which define time points. It is 02h for media catalog
|
ADR is always 01h.
|
||||||
entries and it is 03h for track ISRC entries.
|
TNO is the track number (1 to 99).
|
||||||
The bits of CTL and ADR are combined in the CTL|ADR byte.
|
INDEX is a subaddress within tracks. This recipe uses only INDEX 01h within
|
||||||
|
tracks.
|
||||||
TNO is the track number. The TNO of the first track may be chosen in the range
|
|
||||||
of 1 to 99. The TNO of following tracks must be the TNO of their predecessor
|
|
||||||
plus 1. The last track must not have a TNO larger than 99.
|
|
||||||
|
|
||||||
INDEX is a subaddress within tracks. INDEX 1 is mandatory and marks the start
|
|
||||||
of the payload area of a track. The range between INDEX 0 and 1 is called
|
|
||||||
pre-gap. It should contain zeros if it exists. Further cue sheet entries with
|
|
||||||
consecutive INDEX numbers mark ranges within the track. The range of the last
|
|
||||||
index may contain a post-gap with zeros.
|
|
||||||
(mmc5r03c.pdf 4.2.3.5.2)
|
(mmc5r03c.pdf 4.2.3.5.2)
|
||||||
A pre-gap of 2 seconds is mandatory only for the first track. Pre-gap and
|
DATA FORM is 00h for audio payload , 10h for data. (01h for audio pause is not
|
||||||
post-gap may be needed with further tracks if they have neighbors with
|
used in libburn).
|
||||||
different DATA FORM values. (Such mixing is not yet supported by libburn.)
|
|
||||||
|
|
||||||
DATA FORM is 00h for audio payload, 01h for audio pause (Lead-in and Lead-out),
|
|
||||||
10h for data, 14h for data pause (Lead-in and Lead-out).
|
|
||||||
This shall be ored with 40h for CD-TEXT in Lead-in.
|
|
||||||
(mmc5r03c.pdf 6.33.3.11 CD-DA Data Form, 6.33.3.12 CD-ROM mode 1 Form)
|
(mmc5r03c.pdf 6.33.3.11 CD-DA Data Form, 6.33.3.12 CD-ROM mode 1 Form)
|
||||||
|
SCMS is always 00h.
|
||||||
SCMS value 80h in conjunction with bit5 of CTL is an indicator for exhausted
|
|
||||||
one-time-copy permission. If this permission is still intact, then SCMS is 00h.
|
|
||||||
|
|
||||||
MIN, SEC, FRAME give the MSF address where the described data entity starts.
|
MIN, SEC, FRAME give the MSF address where the described data entity starts.
|
||||||
LBA = frames - 150, 75 frames = 1 sec , 60 sec = 1 min.
|
LBA = frames - 150, 75 frames = 1 sec , 60 sec = 1 min.
|
||||||
This address must increase from entry to entry (or at least stay equal).
|
This address must increase from entry to entry (or at least stay equal).
|
||||||
|
|
||||||
|
|
||||||
The first two entries in a Cue Sheet may describe the Media Catalog Number,
|
The first entry describes the Lead-in. Its content is
|
||||||
a string of 13 characters, also known with CD-TEXT as "UPC/EAN".
|
(CTL|ADR ,00h,00h,01h,00h,00h,00h,00h)
|
||||||
(02h, catalog characters 1 to 7)
|
|
||||||
(02h, catalog characters 8 to 13, 00h)
|
|
||||||
These two entries shall be omitted if no catalog number is given.
|
|
||||||
|
|
||||||
The next entry (eventually being the first one) describes the Lead-in.
|
|
||||||
Its content is
|
|
||||||
(CTL|ADR ,00h,00h, DATA FORM ,00h,00h,00h,00h)
|
|
||||||
With the CTL|ADR for the first track: 41h for data, 01h for audio.
|
With the CTL|ADR for the first track: 41h for data, 01h for audio.
|
||||||
DATA FORM is pause (audio=01h, data=14h). Ored with 40h if CD-TEXT shall
|
|
||||||
be stored in Lean-in.
|
|
||||||
|
|
||||||
The LBA for the first write is negative: -150. This corresponds to MSF address
|
The LBA for the first write is negative: -150. This corresponds to MSF address
|
||||||
00h:00h:00h. All addresses are to be given in MSF format.
|
00h:00h:00h. All addresses are to be given in MSF format.
|
||||||
|
The first information track on disc is preceded by a pause encoding of 2 sec:
|
||||||
Each track may be preceded by two entries describing an ISRC string of 12
|
|
||||||
characters.
|
|
||||||
(CTL | 03h, TNO, characters 1 to 6)
|
|
||||||
(CTL | 03h, TNO, characters 7 to 12)
|
|
||||||
These entries shall be omitted if no ISRC is given for the track.
|
|
||||||
CTL shall be the same as with the track.
|
|
||||||
|
|
||||||
The first information track on disc is preceded by a pause encoding or pre-gap
|
|
||||||
of at least 2 seconds:
|
|
||||||
(CTL|ADR,01h,00h, DATA FORM ,00h,00h,00h,00h)
|
(CTL|ADR,01h,00h, DATA FORM ,00h,00h,00h,00h)
|
||||||
with DATA FORM = 00h for audio and 10h for data. By those 2 seconds the MSF
|
with DATA FORM = 00h for audio and 10h for data. By those 2 seconds the MSF
|
||||||
address increases to 00h:02h:00h = LBA 0. Optional further sectors may occupy
|
address increases to 00h:02h:00h = LBA 0.
|
||||||
addresses larger than 0. This entry has to come after ISRC, if ISRC is given
|
|
||||||
for the track. INDEX has to be 0.
|
|
||||||
|
|
||||||
Each track is represented by one or more entries, with increasing index number.
|
Each track is represented by an entry
|
||||||
At least the entry for INDEX 1 has to exist:
|
|
||||||
(CTL|ADR, TNO ,01h,DATA FORM,00h, MIN , SEC , FRAME)
|
(CTL|ADR, TNO ,01h,DATA FORM,00h, MIN , SEC , FRAME)
|
||||||
TNO gives the track number. MIN, SEC, FRAME give the MSF address which becomes
|
TNO gives the track number. MIN, SEC, FRAME give the MSF address which becomes
|
||||||
the start address of the track. The MSF address is then increased by the size
|
the start address of the track. The MSF address is then increased by the size
|
||||||
of the track (to be used with next track or with lead-out).
|
of the track (to be used with next track or with lead-out).
|
||||||
There may be more entries with INDEX 2 to 99. Their MSF address tells the
|
|
||||||
sector where their range starts. This range ends at the MSF of the next entry
|
|
||||||
in the cue sheet. INDEX information is stored in the sub-channel of the sectors
|
|
||||||
but not in the Table-of-Content of the disc.
|
|
||||||
|
|
||||||
A track must at least contain 300 payload blocks: 4 seconds of audio or
|
A track must at least contain 300 payload blocks: 4 seconds of audio or
|
||||||
600 KiB of data.
|
600 KiB of data.
|
||||||
(mmc5r03c.pdf 6.33.3.6)
|
(mmc5r03c.pdf 6.33.3.6)
|
||||||
|
|
||||||
At the end of the session there is a lead-out entry
|
At the end of the session there is a lead-out entry
|
||||||
(CTL|ADR,AAh,01h,DATA FORM,00h,MIN,SEC,FRAME)
|
(CTL|ADR,AAh,01h,01h,00h,MIN,SEC,FRAME)
|
||||||
marking the end of the last track. (With libburn CTL is as of the last track.)
|
marking the end of the last track. (With libburn CTL is as of the last track.)
|
||||||
DATA FORM is 01h for audio, 14h for data.
|
|
||||||
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
|
@ -371,12 +312,6 @@ next lower possible value by the drive. So it is helpful to add a few
|
||||||
kbytes/sec just in case the drive has rounding problems.
|
kbytes/sec just in case the drive has rounding problems.
|
||||||
(mmc5r03c.pdf 6.37)
|
(mmc5r03c.pdf 6.37)
|
||||||
|
|
||||||
If CD-TEXT shall be written into Lead-in, then it is necessary to obtain the
|
|
||||||
Start Time of Lead-in by 43h READ TOC/PMA/ATIP Format 0100b. It is an MFS
|
|
||||||
address which varies from media manufacturer to media manufacturer.
|
|
||||||
Minute will be >= 90. Therefore this conversion applies:
|
|
||||||
LBA = (M * 60 + S) * 75 + F - 450150
|
|
||||||
|
|
||||||
A Write Parameters mode page 05h has to be composed and transmitted via
|
A Write Parameters mode page 05h has to be composed and transmitted via
|
||||||
55h MODE SELECT. This page describes the following parameters:
|
55h MODE SELECT. This page describes the following parameters:
|
||||||
BUFE Buffer Underrun protection 0=off, 1=on
|
BUFE Buffer Underrun protection 0=off, 1=on
|
||||||
|
@ -387,10 +322,6 @@ A Write Parameters mode page 05h has to be composed and transmitted via
|
||||||
Track Mode Describes frame type 0 (is ignored)
|
Track Mode Describes frame type 0 (is ignored)
|
||||||
Data Block Type Layout of payload blocks 0 (is ignored)
|
Data Block Type Layout of payload blocks 0 (is ignored)
|
||||||
Audio Pause Length 150 = 2 seconds (ignored ?)
|
Audio Pause Length 150 = 2 seconds (ignored ?)
|
||||||
Media Catalog Number 0x80 if valid
|
|
||||||
See also Cue Sheet ADR 02h 13 decimal digits as ASCII
|
|
||||||
(With SAO, ISRC is transmitted only by the Cue Sheet.)
|
|
||||||
|
|
||||||
Any other parameters may be set to 0.
|
Any other parameters may be set to 0.
|
||||||
Mode page data as of MMC-5 table 644 are preceded by a Mode Parameter Header
|
Mode page data as of MMC-5 table 644 are preceded by a Mode Parameter Header
|
||||||
as of SPC-3 table 240. This 8-byte header may be filled with zeros.
|
as of SPC-3 table 240. This 8-byte header may be filled with zeros.
|
||||||
|
@ -407,32 +338,15 @@ blocks written. I.e the Transfer Length of the previous 2Ah WRITE has to be
|
||||||
added to the Logical Block Address for the next 2Ah WRITE. Only full blocks
|
added to the Logical Block Address for the next 2Ah WRITE. Only full blocks
|
||||||
can be written.
|
can be written.
|
||||||
(mmc5r03c.pdf, 6.44)
|
(mmc5r03c.pdf, 6.44)
|
||||||
Block addresses may be negative for areas before the normally readable
|
Writing begins at LBA -150 which is to be transmitted as 4-byte, Big-endian,
|
||||||
data. Data representation of addresses is 4-byte, big-endian, two's-complement.
|
two's-complement. E.g: -150 = FFh FFh FFh 6Ah. This is the natural form found
|
||||||
E.g: -150 = FFh FFh FFh 6Ah.
|
with about any 32-bit processor, so only the endianness has to be taken into
|
||||||
This is the natural form found with about any 32-bit processor, so only
|
respect when converting a 32-bit integer into a LBA for command 2Ah WRITE.
|
||||||
the endianness has to be taken into respect when converting a 32-bit
|
|
||||||
integer into a LBA for command 2Ah WRITE.
|
|
||||||
|
|
||||||
If CD-TEXT shall be written into Lead-in, then writing begins at the start
|
|
||||||
address of Lead-in, which was obtained above.
|
|
||||||
The 18 bytes of each text pack have to be split up to 24 bytes with only the
|
|
||||||
lowest six bits used in each byte. E.g. text pack
|
|
||||||
8F 00 2A 00 01 01 03 00 06 05 04 05 07 06 01 02 48 65
|
|
||||||
becomes
|
|
||||||
23 30 00 2A 00 00 04 01 00 30 00 06 01 10 10 05 01 30 18 01 00 24 21 25
|
|
||||||
4 of these 24 byte packs form a block of DATA FORM 41h. I.e. only 96 bytes
|
|
||||||
payload per block. The whole range from Lead-in start to LBA -150 has to be
|
|
||||||
filled with blocks of this form. Therefore it is necessary to write the
|
|
||||||
list of given packs in repeated cycles.
|
|
||||||
A typical Lead-in start address is -11635 = FFh FFh D2h 8Dh.
|
|
||||||
A description of the CD-TEXT pack format is given in file doc/cdtext.txt .
|
|
||||||
|
|
||||||
Writing without CD-TEXT begins at LBA -150 = FFh FFh FFh 6Ah.
|
At first the mandatory pause preceding the first track has to be written as
|
||||||
|
150 blocks of the matching sector size: 2048 for data, 2352 for audio.
|
||||||
In both cases, the mandatory pause preceding the first track has to be
|
By this, the LBA increases from -150 to 0.
|
||||||
written as 150 blocks of the matching sector size: 2048 for data,
|
|
||||||
2352 for audio. By this, the LBA increases from -150 to 0.
|
|
||||||
|
|
||||||
Next the tracks' payload is sent. For each track exactly the number of blocks
|
Next the tracks' payload is sent. For each track exactly the number of blocks
|
||||||
has to be transmitted as is announced in the Cue Sheet by the difference
|
has to be transmitted as is announced in the Cue Sheet by the difference
|
||||||
|
@ -456,21 +370,6 @@ to media by 35h SYNCHRONIZE CACHE.
|
||||||
No further finalization is necessary. (I.e. no 5Bh CLOSE TRACK SESSION.)
|
No further finalization is necessary. (I.e. no 5Bh CLOSE TRACK SESSION.)
|
||||||
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
Obtaining CD-TEXT from Lead-in :
|
|
||||||
|
|
||||||
Audio CDs may contain CD-TEXT information in their Lead-in. It is gained by
|
|
||||||
43h READ TOC/PMA/ATIP, Format 0101b. The reply consists of 4 bytes header,
|
|
||||||
of which the first two bytes give the number of following bytes as big-endian
|
|
||||||
16 bit number. The other two bytes are 0.
|
|
||||||
Following are text packs of 18 bytes each.
|
|
||||||
(mmc5r03c.pdf 6.26.3.7.1 table 495)
|
|
||||||
|
|
||||||
|
|
||||||
A description of CD-TEXT packs and of the applicable libburn API calls is
|
|
||||||
given in file doc/cdtext.txt .
|
|
||||||
|
|
||||||
|
|
||||||
----------------------------------------------------------------------------
|
----------------------------------------------------------------------------
|
||||||
What is known about mixed mode sessions :
|
What is known about mixed mode sessions :
|
||||||
|
|
||||||
|
@ -618,7 +517,7 @@ BG Format 3 indicates fully formatted media.
|
||||||
|
|
||||||
DVD-RW reaches this state either by Format Type 00h (or 10h) with maximum
|
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
|
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)
|
(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
|
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
|
Descriptor Type of the Current/Maximum Capacity Descriptor is 10b ("Formatted
|
||||||
|
@ -647,7 +546,7 @@ In the reply, BG Format 0 indicates unformatted media (or unsuitable media).
|
||||||
(mmc5r03c.pdf 6.22.3.1.13)
|
(mmc5r03c.pdf 6.22.3.1.13)
|
||||||
|
|
||||||
Formatting has to be started by command 04h FORMAT UNIT, Format Type 26h.
|
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
|
0xffffffff blocks and does not require the caller to know the exact maximum
|
||||||
size offered with that format.
|
size offered with that format.
|
||||||
(mmc5r03c.pdf, 6.5 FORMAT UNIT, 6.5.4.2.14 Format Type = 26h)
|
(mmc5r03c.pdf, 6.5 FORMAT UNIT, 6.5.4.2.14 Format Type = 26h)
|
||||||
|
@ -744,7 +643,7 @@ Elsewise the media is in Intermediate state. See below.
|
||||||
A partly formatted DVD-RW can be recognized by 23h READ FORMAT CAPACITIES. The
|
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
|
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
|
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.
|
Types 13h or 11h.
|
||||||
(mmc5r03c.pdf, 6.24.3.2.1, 6.24.3.3)
|
(mmc5r03c.pdf, 6.24.3.2.1, 6.24.3.3)
|
||||||
|
|
||||||
|
@ -753,7 +652,7 @@ be unnecessary to do any further formatting.
|
||||||
But in order to make the DVD-RW surely accept its maximum number of bytes,
|
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,
|
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
|
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
|
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.
|
no fixed size formatting work is done and writing can begin soon after.
|
||||||
(mmc5r03c.pdf, 6.5.4.2.8 Format Type = 13h)
|
(mmc5r03c.pdf, 6.5.4.2.8 Format Type = 13h)
|
||||||
|
@ -803,8 +702,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.
|
00h offers the default size format and usually a maximum payload size format.
|
||||||
Even with that maximum size payload there is hardware defect management.
|
Even with that maximum size payload there is hardware defect management.
|
||||||
(mmc5r03c.pdf 6.5.4.2.1.2)
|
(mmc5r03c.pdf 6.5.4.2.1.2)
|
||||||
01h can convert payload capacity into spare blocks for defect management.
|
01h allows to convert payload capacity into spare blocks for defect
|
||||||
There is no way to increase payload capacity by format 01h.
|
managment. There is no way to increase payload capacity by format 01h.
|
||||||
(mmc5r03c.pdf 6.5.4.2.2.1)
|
(mmc5r03c.pdf 6.5.4.2.2.1)
|
||||||
|
|
||||||
With BD-RE there are three format types : 00h, 30h and 31h.
|
With BD-RE there are three format types : 00h, 30h and 31h.
|
||||||
|
@ -895,8 +794,7 @@ The term "superblock" shall depict the first 64 KiB after the sbsector address.
|
||||||
|
|
||||||
ISO 9660 multi-session depends on typical TOC information in two ways:
|
ISO 9660 multi-session depends on typical TOC information in two ways:
|
||||||
It needs the superblock address MSC1 of the most recently recorded session and
|
It needs the superblock address MSC1 of the most recently recorded session and
|
||||||
it needs the Next Writeable Address NWA for which to prepare the address
|
it needs the Next Writeable Address NWA for which to prepare the adress offset.
|
||||||
offset.
|
|
||||||
|
|
||||||
The following is learned from growisofs and from ECMA-119:
|
The following is learned from growisofs and from ECMA-119:
|
||||||
http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-119.pdf
|
http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-119.pdf
|
||||||
|
@ -914,8 +812,7 @@ To support CD, DVD and BD media alike, it is advisable to round the NWA
|
||||||
to the next multiple of 32 (= 64 KiB).
|
to the next multiple of 32 (= 64 KiB).
|
||||||
|
|
||||||
So one can use 0 as MSC1 and prepare a new ISO session for the computed NWA.
|
So one can use 0 as MSC1 and prepare a new ISO session for the computed NWA.
|
||||||
After writing the session it is necessary to copy the PVD from session start
|
After writing the session it is necessary to patch the PVD at LBA 16.
|
||||||
plus 16 to LBA 16 and to adjust it to its new location.
|
|
||||||
The minimal change would be to update the number of image sectors.
|
The minimal change would be to update the number of image sectors.
|
||||||
It is stored in both notations LSB and MSB:
|
It is stored in both notations LSB and MSB:
|
||||||
for(i= 0; i < 4; i++)
|
for(i= 0; i < 4; i++)
|
||||||
|
@ -976,13 +873,13 @@ Media type can be recognized by Current Profile from 46h GET CONFIGURATION.
|
||||||
DVD-R 0011h
|
DVD-R 0011h
|
||||||
DVD-RW Restricted Overwrite 0013h
|
DVD-RW Restricted Overwrite 0013h
|
||||||
DVD-RW Sequential Recording 0014h
|
DVD-RW Sequential Recording 0014h
|
||||||
DVD-R/DL Sequential Recording 0015h (can only do single-session)
|
(DVD-R/DL Sequential Recording 0015h untested, might be single-session only)
|
||||||
|
|
||||||
There are two approaches for writing to sequential DVD-R[W]: DAO and
|
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.
|
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
|
DAO seems to be the older method. It allows only one single session and
|
||||||
track, and it demands an exactly predicted track size.
|
track and it demands an exactly predicted track size.
|
||||||
|
|
||||||
- About overwriteable, blank, appendable and finalized DVD-R[W] media
|
- About overwriteable, blank, appendable and finalized DVD-R[W] media
|
||||||
- Incremental writing
|
- Incremental writing
|
||||||
|
@ -1026,7 +923,7 @@ brings back this feature.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Incremental writing :
|
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.
|
by feature 0021h being marked current in the reply of 46h GET CONFIGURATION.
|
||||||
growisofs inquires 0021h by setting Starting Feature Number to 0x21 and
|
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
|
Allocation Length to 16 in order to get only this one. The feature descriptor
|
||||||
|
@ -1043,8 +940,8 @@ which are returned by ACh.
|
||||||
|
|
||||||
growisofs fetches a mode page 05h template by MODE SENSE and inserts its own
|
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.
|
parameters. It sets Multi-session to 11b, unless dvd_compat is nonzero.
|
||||||
libburn composes its mode page 05h from zero and enables the application
|
libburn composes its mode page 05h from zero and allows control of
|
||||||
to control Multi-Session.
|
Multi-Session by the application.
|
||||||
BUFE Buffer Underrun protection 0=off, 1=on
|
BUFE Buffer Underrun protection 0=off, 1=on
|
||||||
LS_V Link size valid 1=true
|
LS_V Link size valid 1=true
|
||||||
Test Write -dummy mode for writing 0=off, 1=on
|
Test Write -dummy mode for writing 0=off, 1=on
|
||||||
|
@ -1258,13 +1155,11 @@ track of the session.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Hearsay about DVD-R/DL (Dual Layer) :
|
Hearsay about DVD-R/DL (Dual Layer) :
|
||||||
|
|
||||||
Meanwhile confirmed by one user:
|
|
||||||
|
|
||||||
DVD-R/DL can assume profile 0015h DVD-R Dual Layer Sequential which is supposed
|
DVD-R/DL can assume profile 0015h DVD-R Dual Layer Sequential which is supposed
|
||||||
to behave like DVD-R or 0016h DVD-R Dual Layer Jump which has no counterpart
|
to behave like DVD-R or 0016h DVD-R Dual Layer Jump which has no counterpart
|
||||||
with DVD-R.
|
with DVD-R.
|
||||||
|
|
||||||
A half-sentence in mmc5r03c.pdf 6.3.3.3.3 indicates that closing a session
|
A half-sentence in mmc5r03c.pdf 6.3.3.3.3 might indicate that closing a session
|
||||||
by 5Bh CLOSE TRACK SESSION Close Function 010b overrides the multi-session bits
|
by 5Bh CLOSE TRACK SESSION Close Function 010b overrides the multi-session bits
|
||||||
in mode page 05h.
|
in mode page 05h.
|
||||||
growisofs applies this function in case of not DAO, though. A comment in
|
growisofs applies this function in case of not DAO, though. A comment in
|
||||||
|
@ -1457,7 +1352,7 @@ eventually RRM) chosen by the format sub-type:
|
||||||
10b = (RRM)
|
10b = (RRM)
|
||||||
(mmc5r03c.pdf 6.5.4.2.1.6)
|
(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
|
amounts of spares. Similar to BD-RE format 31h, three format descriptors are
|
||||||
offered: #1: default size, #2: maximum spare area, #3: minimal spare.
|
offered: #1: default size, #2: maximum spare area, #3: minimal spare.
|
||||||
The size may be chosen within that range.
|
The size may be chosen within that range.
|
||||||
|
@ -1510,11 +1405,5 @@ written as rLBA nor as vLBA yet. So one should begin the vLBA of new sessions
|
||||||
at the NWA of a sufficiently sized track.
|
at the NWA of a sufficiently sized track.
|
||||||
(mmc5r03c.pdf 4.5.3.5.4.2 , 4.5.3.6.9)
|
(mmc5r03c.pdf 4.5.3.5.4.2 , 4.5.3.6.9)
|
||||||
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
This text is copyright 2011 - 2012 Thomas Schmitt <scdbackup@gmx.net>.
|
|
||||||
Permission is granted to copy, modify, and distribute it, as long as the
|
|
||||||
references to the original information sources are maintained.
|
|
||||||
There is NO WARRANTY, to the extent permitted by law.
|
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
|
@ -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
|
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
|
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
|
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.
|
immediate close(2) of an already opened device file.
|
||||||
|
|
||||||
The vulnerable programs shall not start their operation before they locked a
|
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
|
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.
|
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
|
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.
|
This attempt you see above: DDLP-A and DDLP-B.
|
||||||
|
|
||||||
|
|
||||||
|
|
1782
doc/doxygen.conf.in
1782
doc/doxygen.conf.in
File diff suppressed because it is too large
Load Diff
|
@ -34,7 +34,7 @@ CD-ROM media (0x08) cannot be inquired by command 43h READ TOC/PMA/ATIP.
|
||||||
in 6.26.3.6 Response Format 0100b: ATIP.
|
in 6.26.3.6 Response Format 0100b: ATIP.
|
||||||
The minute, second, and frame number of lead-in can be read from byte 4 to 6
|
The minute, second, and frame number of lead-in can be read from byte 4 to 6
|
||||||
of the ATIP descriptor. The lead-out bytes are at position 8 to 10. The ATIP
|
of the ATIP descriptor. The lead-out bytes are at position 8 to 10. The ATIP
|
||||||
descriptor is preceded by a four byte header.
|
descriptor is preceeded by a four byte header.
|
||||||
|
|
||||||
I could not find out yet whether (lead-in,lead-out) is mandatorily unique for
|
I could not find out yet whether (lead-in,lead-out) is mandatorily unique for
|
||||||
each particular media product.
|
each particular media product.
|
||||||
|
@ -176,7 +176,7 @@ BD-R and BD-RE:
|
||||||
printf (" Media ID: %6.6s/%-3.3s\n",di+4+100,di+4+106);
|
printf (" Media ID: %6.6s/%-3.3s\n",di+4+100,di+4+106);
|
||||||
= MMC-5 6.23.3.3.1 Format Code 00h: Disc Information (DI)
|
= MMC-5 6.23.3.3.1 Format Code 00h: Disc Information (DI)
|
||||||
Table 288 says that Media Type Code (byte 1 of CDB) for BD media is 1.
|
Table 288 says that Media Type Code (byte 1 of CDB) for BD media is 1.
|
||||||
Table 446 says that Disc Information is preceded by 4 bytes of header.
|
Table 446 says that Disc Information is preceeded by 4 bytes of header.
|
||||||
Table 448 says that bytes 0 to 1 are Disc Information Identifier "DI".
|
Table 448 says that bytes 0 to 1 are Disc Information Identifier "DI".
|
||||||
that bytes 8 to 10 are Disc Type Identifier
|
that bytes 8 to 10 are Disc Type Identifier
|
||||||
BDO for BD-ROM, BDW for BD-RE,
|
BDO for BD-ROM, BDW for BD-RE,
|
||||||
|
@ -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
|
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
|
printable words media_code1, media_code2. The latter can be translated into
|
||||||
a manufacturer company name by API call burn_guess_manufacturer().
|
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().)
|
burn_disc_read_atip().)
|
||||||
|
|
||||||
|
|
||||||
|
@ -1036,9 +1036,6 @@ MEI T02 Panasonic Corporation 1-4X HTL 12cm [Blu]
|
||||||
MEI 00V001 MATSUSHITA EI 2X [Hij]
|
MEI 00V001 MATSUSHITA EI 2X [Hij]
|
||||||
MEI 00V002 MATSUSHITA EI 4X [Hij]
|
MEI 00V002 MATSUSHITA EI 4X [Hij]
|
||||||
|
|
||||||
"Millenniata Inc."
|
|
||||||
MILLENMR MR1 Verbatim M-DISC 4x 25 GB (user reported)
|
|
||||||
|
|
||||||
"Mitsubishi Kagaku Media Co."
|
"Mitsubishi Kagaku Media Co."
|
||||||
MKM 001 MKM 6X [Hij]
|
MKM 001 MKM 6X [Hij]
|
||||||
MKM 003 MKM 8X [Hij]
|
MKM 003 MKM 8X [Hij]
|
||||||
|
@ -1080,7 +1077,6 @@ OTCBRE 001 Optodisc Technology Corporation 1-2X HTL 25GB (12cm) [Blu]
|
||||||
"Moser Baer India Limited"
|
"Moser Baer India Limited"
|
||||||
PHILIP R02 Moser Baer India Ltd 1-2X HTL 25GB [Blu]
|
PHILIP R02 Moser Baer India Ltd 1-2X HTL 25GB [Blu]
|
||||||
PHILIP R04 Moser Baer India Ltd 1-4X HTL 25GB [Blu]
|
PHILIP R04 Moser Baer India Ltd 1-4X HTL 25GB [Blu]
|
||||||
PHILIPR0 R04 TDK 4x 25 GB (own buy)
|
|
||||||
PHILIP W02 Moser Baer India Ltd 1-2X HTL 25GB [Blu]
|
PHILIP W02 Moser Baer India Ltd 1-2X HTL 25GB [Blu]
|
||||||
|
|
||||||
"Philips"
|
"Philips"
|
||||||
|
@ -1190,9 +1186,6 @@ TYG11 TAIYO YUDEN DVD-R DL 8x
|
||||||
TYG-BD Y01 TAIYO YUDEN Co., Ltd. 1-2X LTH [Blu]
|
TYG-BD Y01 TAIYO YUDEN Co., Ltd. 1-2X LTH [Blu]
|
||||||
TYG-BD Y03 TAIYO YUDEN Co., Ltd. 1-4X LTH [Blu]
|
TYG-BD Y03 TAIYO YUDEN Co., Ltd. 1-4X LTH [Blu]
|
||||||
|
|
||||||
"UmeDisc Limited"
|
|
||||||
UMEDISC DL1 Elite DVD+R DL [User report feb 2012]
|
|
||||||
|
|
||||||
"Unifino Inc."
|
"Unifino Inc."
|
||||||
UTJR001001 UNIFINO 4X [Hij]
|
UTJR001001 UNIFINO 4X [Hij]
|
||||||
|
|
||||||
|
|
|
@ -1,84 +0,0 @@
|
||||||
|
|
||||||
Sound extraction for CD-DA burning from .WAV audio file format
|
|
||||||
|
|
||||||
Using information and text snippets
|
|
||||||
from https://ccrma.stanford.edu/courses/422/projects/WaveFormat/
|
|
||||||
in may 2013. The link is now dead. An apparent copy of the page
|
|
||||||
is 2017 at: http://soundfile.sapp.org/doc/WaveFormat/
|
|
||||||
from https://en.wikipedia.org/wiki/WAV
|
|
||||||
|
|
||||||
For libburnia-project.org by Thomas Schmitt <scdbackup@gmx.net>
|
|
||||||
December 2017
|
|
||||||
|
|
||||||
|
|
||||||
The WAVE file format is an application of the Microsoft RIFF container format
|
|
||||||
for multimedia files. A RIFF file consists of Chunks which contain Subchunks.
|
|
||||||
The Chunks form a linked list within the file, the Subchunks form a linked
|
|
||||||
list inside their Chunk.
|
|
||||||
All numbers are stored in little-endian byte order.
|
|
||||||
|
|
||||||
A .WAV file consists at least of one Chunk with id "RIFF", which contains
|
|
||||||
one Subchunk with id "fmt " and one with id "data":
|
|
||||||
|
|
||||||
Offset Size Name Description
|
|
||||||
|
|
||||||
0 4 ChunkID Contains the letters "RIFF"
|
|
||||||
4 4 ChunkSize The size of the rest of the chunk following
|
|
||||||
this field. I.e. the two fields ChunkID and
|
|
||||||
ChunkSize are not included in this count.
|
|
||||||
8 4 Format Contains the letters "WAVE"
|
|
||||||
|
|
||||||
|
|
||||||
The "fmt " subchunk describes the sound data's format:
|
|
||||||
|
|
||||||
Offset Size Name Description
|
|
||||||
|
|
||||||
0 4 Subchunk1ID Contains the letters "fmt "
|
|
||||||
|
|
||||||
4 4 Subchunk1Size The size of the rest of the Subchunk following
|
|
||||||
this field. I.e. Subchunk1ID and Subchunk1Size
|
|
||||||
are not included in this count.
|
|
||||||
8 2 AudioFormat PCM = 1 (i.e. Linear quantization)
|
|
||||||
Values other than 1 indicate some
|
|
||||||
form of compression.
|
|
||||||
10 2 NumChannels Mono = 1, Stereo = 2, etc.
|
|
||||||
12 4 SampleRate 8000, 44100, etc.
|
|
||||||
16 4 ByteRate == SampleRate * NumChannels * BitsPerSample/8
|
|
||||||
20 2 BlockAlign == NumChannels * BitsPerSample/8
|
|
||||||
The number of bytes for one sample including
|
|
||||||
all channels.
|
|
||||||
22 2 BitsPerSample 8 bits = 8, 16 bits = 16, etc.
|
|
||||||
More data may follow in this Subchunk if AudioFormat is not PCM.
|
|
||||||
|
|
||||||
|
|
||||||
The "data" subchunk contains the size of the data and the actual sound:
|
|
||||||
|
|
||||||
Offset Size Name Description
|
|
||||||
|
|
||||||
0 4 Subchunk2ID Contains the letters "data"
|
|
||||||
|
|
||||||
4 4 Subchunk2Size == NumSamples * NumChannels * BitsPerSample/8
|
|
||||||
The number of audio data bytes.
|
|
||||||
8 * Data The audio data bytes.
|
|
||||||
|
|
||||||
|
|
||||||
CD-DA prescribes these "fmt " parameters:
|
|
||||||
AudioFormat == 1
|
|
||||||
SampleRate == 44100
|
|
||||||
BitsPerSample == 16
|
|
||||||
NumChannels == 2 (stereo)
|
|
||||||
(little-endian byte order)
|
|
||||||
|
|
||||||
If matching parameters are given in the .WAV file, one can directly use the
|
|
||||||
data bytes of Subchunk "data" as payload for burning a CD-DA track.
|
|
||||||
|
|
||||||
|
|
||||||
Above simple form can be expanded by other Chunks or Subchunks of Chunk "RIFF".
|
|
||||||
A .wav file appeared which beared a Subchunk "LIST" inside Chunk "RIFF".
|
|
||||||
Wikipedia mentions Chunks "INFO", "CSET", "JUNK", "PAD ".
|
|
||||||
|
|
||||||
Therefore one should expect such Chunks before Chunk "RIFF" and Subchunks
|
|
||||||
other than "fmt " and "data" inside the "RIFF" Chunk.
|
|
||||||
Multiple Chunks "RIFF" and Subchunks "fmt " or "data" per file have not been
|
|
||||||
seen yet. They would make extraction more cumbersome.
|
|
||||||
|
|
174
libburn/async.c
174
libburn/async.c
|
@ -1,7 +1,7 @@
|
||||||
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||||
|
|
||||||
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
|
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
|
||||||
Copyright (c) 2006 - 2024 Thomas Schmitt <scdbackup@gmx.net>
|
Copyright (c) 2006 - 2011 Thomas Schmitt <scdbackup@gmx.net>
|
||||||
Provided under GPL version 2 or later.
|
Provided under GPL version 2 or later.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -98,14 +98,6 @@ struct fifo_opts
|
||||||
int flag;
|
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
|
struct w_list
|
||||||
{
|
{
|
||||||
|
@ -117,49 +109,18 @@ struct w_list
|
||||||
|
|
||||||
struct w_list *next;
|
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;
|
static struct w_list *workers = NULL;
|
||||||
|
|
||||||
static void *fifo_worker_func(struct w_list *w);
|
|
||||||
|
|
||||||
|
|
||||||
int burn_async_manage_lock(int mode)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
static pthread_mutex_t access_lock;
|
|
||||||
static int mutex_initialized = 0;
|
|
||||||
static int mutex_locked = 0;
|
|
||||||
|
|
||||||
if (mode == BURN_ASYNC_LOCK_INIT) {
|
|
||||||
if (mutex_initialized)
|
|
||||||
return 2;
|
|
||||||
ret = pthread_mutex_init(&access_lock, NULL);
|
|
||||||
if (ret != 0)
|
|
||||||
return 0;
|
|
||||||
mutex_initialized = 1;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
if (!mutex_initialized)
|
|
||||||
return 0;
|
|
||||||
if (mode == BURN_ASYNC_LOCK_OBTAIN) {
|
|
||||||
ret = pthread_mutex_lock(&access_lock);
|
|
||||||
if (ret != 0)
|
|
||||||
return 0;
|
|
||||||
mutex_locked = 1;
|
|
||||||
} else if (mode == BURN_ASYNC_LOCK_RELEASE) {
|
|
||||||
if (!mutex_locked)
|
|
||||||
return 2;
|
|
||||||
ret = pthread_mutex_unlock(&access_lock);
|
|
||||||
if (ret != 0)
|
|
||||||
return 0;
|
|
||||||
mutex_locked = 0;
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static struct w_list *find_worker(struct burn_drive *d)
|
static struct w_list *find_worker(struct burn_drive *d)
|
||||||
{
|
{
|
||||||
|
@ -172,7 +133,7 @@ static struct w_list *find_worker(struct burn_drive *d)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void add_worker(int w_type, 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 *a;
|
||||||
struct w_list *tmp;
|
struct w_list *tmp;
|
||||||
|
@ -185,10 +146,7 @@ static void add_worker(int w_type, struct burn_drive *d,
|
||||||
a = calloc(1, sizeof(struct w_list));
|
a = calloc(1, sizeof(struct w_list));
|
||||||
a->w_type = w_type;
|
a->w_type = w_type;
|
||||||
a->drive = d;
|
a->drive = d;
|
||||||
|
a->u = *(union w_list_data *)data;
|
||||||
a->u = *data;
|
|
||||||
|
|
||||||
burn_async_manage_lock(BURN_ASYNC_LOCK_INIT);
|
|
||||||
|
|
||||||
/* insert at front of the list */
|
/* insert at front of the list */
|
||||||
a->next = workers;
|
a->next = workers;
|
||||||
|
@ -199,7 +157,6 @@ static void add_worker(int w_type, struct burn_drive *d,
|
||||||
d->busy = BURN_DRIVE_SPAWNING;
|
d->busy = BURN_DRIVE_SPAWNING;
|
||||||
|
|
||||||
#ifdef Libburn_create_detached_threadS
|
#ifdef Libburn_create_detached_threadS
|
||||||
|
|
||||||
/* ts A71019 :
|
/* ts A71019 :
|
||||||
Trying to start the threads detached to get rid of the zombies
|
Trying to start the threads detached to get rid of the zombies
|
||||||
which do neither react on pthread_join() nor on pthread_detach().
|
which do neither react on pthread_join() nor on pthread_detach().
|
||||||
|
@ -207,12 +164,12 @@ static void add_worker(int w_type, struct burn_drive *d,
|
||||||
pthread_attr_init(&attr);
|
pthread_attr_init(&attr);
|
||||||
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
|
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
|
||||||
attr_pt= &attr;
|
attr_pt= &attr;
|
||||||
|
/*
|
||||||
#endif /* Libburn_create_detached_threadS */
|
libdax_msgs_submit(libdax_messenger, -1, 0x00020158,
|
||||||
|
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_LOW,
|
||||||
/* Worker specific locks are to be released early by the worker */
|
"add_worker(): Creating detached thread.", 0, 0);
|
||||||
if (f == (WorkerFunc) fifo_worker_func)
|
*/
|
||||||
burn_async_manage_lock(BURN_ASYNC_LOCK_OBTAIN);
|
#endif
|
||||||
|
|
||||||
if (pthread_create(&a->thread, attr_pt, f, a)) {
|
if (pthread_create(&a->thread, attr_pt, f, a)) {
|
||||||
free(a);
|
free(a);
|
||||||
|
@ -279,7 +236,7 @@ static void *scan_worker_func(struct w_list *w)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void reset_progress(struct burn_drive *d, int sessions, int tracks,
|
static void reset_progress(struct burn_drive *d, int sessions, int tracks,
|
||||||
int indices, off_t sectors, int flag)
|
int indices, int sectors, int flag)
|
||||||
{
|
{
|
||||||
/* reset the progress indicator */
|
/* reset the progress indicator */
|
||||||
d->progress.session = 0;
|
d->progress.session = 0;
|
||||||
|
@ -296,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)
|
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;
|
int ret = 0;
|
||||||
|
|
||||||
/* ts A61006 : moved up from burn_drive_scan_sync , former Assert */
|
/* ts A61006 : moved up from burn_drive_scan_sync , former Assert */
|
||||||
|
@ -309,7 +266,7 @@ int burn_drive_scan(struct burn_drive_info *drives[], unsigned int *n_drives)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* cannot be anything working! */
|
/* cant be anything working! */
|
||||||
|
|
||||||
/* ts A61006 */
|
/* ts A61006 */
|
||||||
/* a ssert(!(workers && workers->drive)); */
|
/* a ssert(!(workers && workers->drive)); */
|
||||||
|
@ -335,9 +292,9 @@ drive_is_active:;
|
||||||
*drives = NULL;
|
*drives = NULL;
|
||||||
*n_drives = 0;
|
*n_drives = 0;
|
||||||
|
|
||||||
o.scan.drives = drives;
|
o.drives = drives;
|
||||||
o.scan.n_drives = n_drives;
|
o.n_drives = n_drives;
|
||||||
o.scan.done = 0;
|
o.done = 0;
|
||||||
add_worker(Burnworker_type_scaN, NULL,
|
add_worker(Burnworker_type_scaN, NULL,
|
||||||
(WorkerFunc) scan_worker_func, &o);
|
(WorkerFunc) scan_worker_func, &o);
|
||||||
} else if (workers->u.scan.done) {
|
} else if (workers->u.scan.done) {
|
||||||
|
@ -389,14 +346,14 @@ static void *erase_worker_func(struct w_list *w)
|
||||||
|
|
||||||
void burn_disc_erase(struct burn_drive *drive, int fast)
|
void burn_disc_erase(struct burn_drive *drive, int fast)
|
||||||
{
|
{
|
||||||
union w_list_data o;
|
struct erase_opts o;
|
||||||
|
|
||||||
/* ts A61006 */
|
/* ts A61006 */
|
||||||
/* a ssert(drive); */
|
/* a ssert(drive); */
|
||||||
/* a ssert(!SCAN_GOING()); */
|
/* a ssert(!SCAN_GOING()); */
|
||||||
/* a ssert(!find_worker(drive)); */
|
/* a ssert(!find_worker(drive)); */
|
||||||
|
|
||||||
if(drive == NULL) {
|
if((drive == NULL)) {
|
||||||
libdax_msgs_submit(libdax_messenger, -1,
|
libdax_msgs_submit(libdax_messenger, -1,
|
||||||
0x00020104,
|
0x00020104,
|
||||||
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
|
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
|
@ -412,14 +369,14 @@ void burn_disc_erase(struct burn_drive *drive, int fast)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
reset_progress(drive, 1, 1, 1, (off_t) 0x10000, 0);
|
reset_progress(drive, 1, 1, 1, 0x10000, 0);
|
||||||
|
|
||||||
/* A70103 : will be set to 0 by burn_disc_erase_sync() */
|
/* A70103 : will be set to 0 by burn_disc_erase_sync() */
|
||||||
drive->cancel = 1;
|
drive->cancel = 1;
|
||||||
|
|
||||||
/* ts A70103 moved up from burn_disc_erase_sync() */
|
/* ts A70103 moved up from burn_disc_erase_sync() */
|
||||||
/* ts A60825 : allow on parole to blank appendable CDs */
|
/* ts A60825 : allow on parole to blank appendable CDs */
|
||||||
/* ts A70131 : allow blanking of overwritable DVD-RW (profile 0x13) */
|
/* ts A70131 : allow blanking of overwriteable DVD-RW (profile 0x13) */
|
||||||
/* ts A70216 : allow blanking of CD-RW or DVD-RW in any regular state
|
/* ts A70216 : allow blanking of CD-RW or DVD-RW in any regular state
|
||||||
and of any kind of full media */
|
and of any kind of full media */
|
||||||
/* ts A70909 : the willingness to burn any BURN_DISC_FULL media is
|
/* ts A70909 : the willingness to burn any BURN_DISC_FULL media is
|
||||||
|
@ -438,21 +395,16 @@ void burn_disc_erase(struct burn_drive *drive, int fast)
|
||||||
||
|
||
|
||||||
(drive->drive_role != 1 && drive->drive_role != 5)
|
(drive->drive_role != 1 && drive->drive_role != 5)
|
||||||
) {
|
) {
|
||||||
char msg[160];
|
|
||||||
|
|
||||||
sprintf(msg, "Drive and media state unsuitable for blanking. (role= %d , profile= 0x%x , status= %d)",
|
|
||||||
drive->drive_role,
|
|
||||||
(unsigned int) drive->current_profile,
|
|
||||||
drive->status);
|
|
||||||
libdax_msgs_submit(libdax_messenger, drive->global_index,
|
libdax_msgs_submit(libdax_messenger, drive->global_index,
|
||||||
0x00020130,
|
0x00020130,
|
||||||
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
|
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
msg, 0, 0);
|
"Drive and media state unsuitable for blanking",
|
||||||
|
0, 0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
o.erase.drive = drive;
|
o.drive = drive;
|
||||||
o.erase.fast = fast;
|
o.fast = fast;
|
||||||
add_worker(Burnworker_type_erasE, drive,
|
add_worker(Burnworker_type_erasE, drive,
|
||||||
(WorkerFunc) erase_worker_func, &o);
|
(WorkerFunc) erase_worker_func, &o);
|
||||||
}
|
}
|
||||||
|
@ -490,11 +442,11 @@ static void *format_worker_func(struct w_list *w)
|
||||||
/* ts A61230 */
|
/* ts A61230 */
|
||||||
void burn_disc_format(struct burn_drive *drive, off_t size, int flag)
|
void burn_disc_format(struct burn_drive *drive, off_t size, int flag)
|
||||||
{
|
{
|
||||||
union w_list_data o;
|
struct format_opts o;
|
||||||
int ok = 0, ret;
|
int ok = 0, ret;
|
||||||
char msg[40];
|
char msg[40];
|
||||||
|
|
||||||
reset_progress(drive, 1, 1, 1, (off_t) 0x10000, 0);
|
reset_progress(drive, 1, 1, 1, 0x10000, 0);
|
||||||
|
|
||||||
if ((SCAN_GOING()) || find_worker(drive) != NULL) {
|
if ((SCAN_GOING()) || find_worker(drive) != NULL) {
|
||||||
libdax_msgs_submit(libdax_messenger, drive->global_index,
|
libdax_msgs_submit(libdax_messenger, drive->global_index,
|
||||||
|
@ -578,9 +530,9 @@ void burn_disc_format(struct burn_drive *drive, off_t size, int flag)
|
||||||
drive->cancel = 1;
|
drive->cancel = 1;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
o.format.drive = drive;
|
o.drive = drive;
|
||||||
o.format.size = size;
|
o.size = size;
|
||||||
o.format.flag = flag;
|
o.flag = flag;
|
||||||
add_worker(Burnworker_type_formaT, drive,
|
add_worker(Burnworker_type_formaT, drive,
|
||||||
(WorkerFunc) format_worker_func, &o);
|
(WorkerFunc) format_worker_func, &o);
|
||||||
}
|
}
|
||||||
|
@ -632,10 +584,9 @@ static void *write_disc_worker_func(struct w_list *w)
|
||||||
|
|
||||||
void burn_disc_write(struct burn_write_opts *opts, struct burn_disc *disc)
|
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;
|
char *reasons= NULL;
|
||||||
struct burn_drive *d;
|
struct burn_drive *d;
|
||||||
int mvalid;
|
|
||||||
|
|
||||||
d = opts->drive;
|
d = opts->drive;
|
||||||
|
|
||||||
|
@ -652,7 +603,7 @@ void burn_disc_write(struct burn_write_opts *opts, struct burn_disc *disc)
|
||||||
}
|
}
|
||||||
|
|
||||||
reset_progress(d, disc->sessions, disc->session[0]->tracks,
|
reset_progress(d, disc->sessions, disc->session[0]->tracks,
|
||||||
disc->session[0]->track[0]->indices, (off_t) 0, 0);
|
disc->session[0]->track[0]->indices, 0, 0);
|
||||||
|
|
||||||
/* For the next lines any return indicates failure */
|
/* For the next lines any return indicates failure */
|
||||||
d->cancel = 1;
|
d->cancel = 1;
|
||||||
|
@ -683,17 +634,12 @@ void burn_disc_write(struct burn_write_opts *opts, struct burn_disc *disc)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ts A61007 : obsolete Assert in spc_select_write_params() */
|
/* ts A61007 : obsolete Assert in spc_select_write_params() */
|
||||||
if (d->drive_role == 1) {
|
if (d->drive_role == 1 && d->mdata->valid <= 0) {
|
||||||
mvalid = 0;
|
libdax_msgs_submit(libdax_messenger,
|
||||||
if (d->mdata != NULL)
|
|
||||||
mvalid = 1;
|
|
||||||
if (!mvalid) {
|
|
||||||
libdax_msgs_submit(libdax_messenger,
|
|
||||||
d->global_index, 0x00020113,
|
d->global_index, 0x00020113,
|
||||||
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
|
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
"Drive capabilities not inquired yet", 0, 0);
|
"Drive capabilities not inquired yet", 0, 0);
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ts A70219 : intended to replace all further tests here and many
|
/* ts A70219 : intended to replace all further tests here and many
|
||||||
|
@ -726,9 +672,9 @@ void burn_disc_write(struct burn_write_opts *opts, struct burn_disc *disc)
|
||||||
|
|
||||||
d->cancel = 0; /* End of the return = failure area */
|
d->cancel = 0; /* End of the return = failure area */
|
||||||
|
|
||||||
o.write.drive = d;
|
o.drive = d;
|
||||||
o.write.opts = opts;
|
o.opts = opts;
|
||||||
o.write.disc = disc;
|
o.disc = disc;
|
||||||
|
|
||||||
opts->refcount++;
|
opts->refcount++;
|
||||||
|
|
||||||
|
@ -742,6 +688,7 @@ ex:;
|
||||||
|
|
||||||
static void *fifo_worker_func(struct w_list *w)
|
static void *fifo_worker_func(struct w_list *w)
|
||||||
{
|
{
|
||||||
|
int old;
|
||||||
|
|
||||||
#define Libburn_protect_fifo_threaD 1
|
#define Libburn_protect_fifo_threaD 1
|
||||||
|
|
||||||
|
@ -755,6 +702,10 @@ static void *fifo_worker_func(struct w_list *w)
|
||||||
pthread_sigmask(SIG_SETMASK, &sigset, &oldset);
|
pthread_sigmask(SIG_SETMASK, &sigset, &oldset);
|
||||||
#endif /* Libburn_protect_fifo_threaD */
|
#endif /* Libburn_protect_fifo_threaD */
|
||||||
|
|
||||||
|
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &old);
|
||||||
|
pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &old);
|
||||||
|
/* Note: Only burn_fifo_abort() shall cancel the fifo thread */
|
||||||
|
|
||||||
burn_fifo_source_shoveller(w->u.fifo.source, w->u.fifo.flag);
|
burn_fifo_source_shoveller(w->u.fifo.source, w->u.fifo.flag);
|
||||||
remove_worker(pthread_self());
|
remove_worker(pthread_self());
|
||||||
|
|
||||||
|
@ -769,7 +720,7 @@ static void *fifo_worker_func(struct w_list *w)
|
||||||
|
|
||||||
int burn_fifo_start(struct burn_source *source, int flag)
|
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;
|
struct burn_source_fifo *fs = source->data;
|
||||||
|
|
||||||
fs->is_started = -1;
|
fs->is_started = -1;
|
||||||
|
@ -782,8 +733,8 @@ int burn_fifo_start(struct burn_source *source, int flag)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
o.fifo.source = source;
|
o.source = source;
|
||||||
o.fifo.flag = flag;
|
o.flag = flag;
|
||||||
add_worker(Burnworker_type_fifO, NULL,
|
add_worker(Burnworker_type_fifO, NULL,
|
||||||
(WorkerFunc) fifo_worker_func, &o);
|
(WorkerFunc) fifo_worker_func, &o);
|
||||||
fs->is_started = 1;
|
fs->is_started = 1;
|
||||||
|
@ -797,19 +748,18 @@ int burn_fifo_abort(struct burn_source_fifo *fs, int flag)
|
||||||
int ret;
|
int ret;
|
||||||
pthread_t pt;
|
pthread_t pt;
|
||||||
|
|
||||||
burn_async_manage_lock(BURN_ASYNC_LOCK_OBTAIN);
|
if (fs->thread_is_valid <= 0 || fs->thread_handle == NULL)
|
||||||
|
return(2);
|
||||||
|
|
||||||
if (fs->thread_is_valid <= 0 || fs->thread_handle == NULL) {
|
#ifdef NIX
|
||||||
burn_async_manage_lock(BURN_ASYNC_LOCK_RELEASE);
|
libdax_msgs_submit(libdax_messenger, -1, 0x00000002,
|
||||||
return 2;
|
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
}
|
"Aborting running burn_source_fifo thread", 0, 0);
|
||||||
pt = *((pthread_t *) fs->thread_handle);
|
#endif /* NIX */
|
||||||
|
|
||||||
burn_async_manage_lock(BURN_ASYNC_LOCK_RELEASE);
|
|
||||||
|
|
||||||
fs->do_abort = 1;
|
|
||||||
ret = pthread_join(pt, NULL);
|
|
||||||
|
|
||||||
|
pt= *((pthread_t *) fs->thread_handle);
|
||||||
|
remove_worker(pt);
|
||||||
|
ret = pthread_cancel(pt);
|
||||||
return (ret == 0);
|
return (ret == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,5 @@
|
||||||
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||||
|
|
||||||
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
|
|
||||||
Copyright (c) 2006 - 2017 Thomas Schmitt <scdbackup@gmx.net>
|
|
||||||
Provided under GPL version 2 or later.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef BURN__ASYNC_H
|
#ifndef BURN__ASYNC_H
|
||||||
#define BURN__ASYNC_H
|
#define BURN__ASYNC_H
|
||||||
|
|
||||||
|
@ -19,10 +14,5 @@ int burn_fifo_start(struct burn_source *source, int flag);
|
||||||
/* To abort a running fifo thread before the fifo object gets deleted */
|
/* To abort a running fifo thread before the fifo object gets deleted */
|
||||||
int burn_fifo_abort(struct burn_source_fifo *fs, int flag);
|
int burn_fifo_abort(struct burn_source_fifo *fs, int flag);
|
||||||
|
|
||||||
/* ts B70126 */
|
|
||||||
#define BURN_ASYNC_LOCK_RELEASE 0
|
|
||||||
#define BURN_ASYNC_LOCK_OBTAIN 1
|
|
||||||
#define BURN_ASYNC_LOCK_INIT 2
|
|
||||||
int burn_async_manage_lock(int mode);
|
|
||||||
|
|
||||||
#endif /* BURN__ASYNC_H */
|
#endif /* BURN__ASYNC_H */
|
||||||
|
|
1737
libburn/cdtext.c
1737
libburn/cdtext.c
File diff suppressed because it is too large
Load Diff
|
@ -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)
|
int Cleanup_set_handlers(void *handle, Cleanup_app_handler_T handler, int flag)
|
||||||
/*
|
/*
|
||||||
bit0= set to default handlers
|
bit0= set to default handlers
|
||||||
bit1= set to ignore
|
bit1= set to ignore
|
||||||
bit2= set cleanup_perform_app_handler_first
|
bit2= set cleanup_perform_app_handler_first
|
||||||
bit3= set SIGABRT to handler (makes sense with bits 0 or 1)
|
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;
|
int i,j,max_sig= -1,min_sig= 0x7fffffff;
|
||||||
char *sig_name;
|
|
||||||
sighandler_t sig_handler;
|
sighandler_t sig_handler;
|
||||||
|
|
||||||
cleanup_msg[0]= 0;
|
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])
|
if(i==non_signal_list[j])
|
||||||
break;
|
break;
|
||||||
if(j>=non_signal_list_count) {
|
if(j>=non_signal_list_count) {
|
||||||
/* Avoid to use particular SIG macros which might not be defined.
|
if(i==SIGABRT && (flag&8))
|
||||||
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)
|
|
||||||
signal(i,Cleanup_handler_generic);
|
signal(i,Cleanup_handler_generic);
|
||||||
else if((flag & 256) && strcmp(sig_name, "SIGPIPE") == 0)
|
|
||||||
signal(i, SIG_IGN);
|
|
||||||
else
|
else
|
||||||
signal(i,sig_handler);
|
signal(i,sig_handler);
|
||||||
}
|
}
|
||||||
|
|
635
libburn/crc.c
635
libburn/crc.c
|
@ -1,568 +1,47 @@
|
||||||
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||||
|
|
||||||
/* Copyright (c) 2012 Thomas Schmitt <scdbackup@gmx.net>
|
|
||||||
Provided under GPL version 2 or later.
|
|
||||||
|
|
||||||
Containing disabled code pieces from other GPL programs.
|
|
||||||
They are just quotes for reference.
|
|
||||||
|
|
||||||
The activated code uses plain polynomial division and other primitve
|
|
||||||
algorithms to build tables of pre-computed CRC values. It then computes
|
|
||||||
the CRCs by algorithms which are derived from mathematical considerations
|
|
||||||
and from analysing the mathematical meaning of the disabled code pieces.
|
|
||||||
|
|
||||||
The comments here are quite detailed in order to prove my own understanding
|
|
||||||
of the topic.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
#include "../config.h"
|
#include "../config.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "crc.h"
|
#include "crc.h"
|
||||||
|
|
||||||
|
static unsigned short ccitt_table[256] = {
|
||||||
/* Exploration ts B00214 :
|
0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7,
|
||||||
ECMA-130, 22.3.6 "CRC field"
|
0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF,
|
||||||
"This field contains the inverted parity bits. The CRC code word must be
|
0x1231, 0x0210, 0x3273, 0x2252, 0x52B5, 0x4294, 0x72F7, 0x62D6,
|
||||||
divisible by the check polynomial. [...]
|
0x9339, 0x8318, 0xB37B, 0xA35A, 0xD3BD, 0xC39C, 0xF3FF, 0xE3DE,
|
||||||
The generating polynomial shall be
|
0x2462, 0x3443, 0x0420, 0x1401, 0x64E6, 0x74C7, 0x44A4, 0x5485,
|
||||||
G(x) = x^16 + x^12 + x^5 + 1
|
0xA56A, 0xB54B, 0x8528, 0x9509, 0xE5EE, 0xF5CF, 0xC5AC, 0xD58D,
|
||||||
"
|
0x3653, 0x2672, 0x1611, 0x0630, 0x76D7, 0x66F6, 0x5695, 0x46B4,
|
||||||
Also known as CRC-16-CCITT, CRC-CCITT
|
0xB75B, 0xA77A, 0x9719, 0x8738, 0xF7DF, 0xE7FE, 0xD79D, 0xC7BC,
|
||||||
|
0x48C4, 0x58E5, 0x6886, 0x78A7, 0x0840, 0x1861, 0x2802, 0x3823,
|
||||||
Used in libburn for raw write modes in sector.c.
|
0xC9CC, 0xD9ED, 0xE98E, 0xF9AF, 0x8948, 0x9969, 0xA90A, 0xB92B,
|
||||||
There is also disabled code in read.c which would use it.
|
0x5AF5, 0x4AD4, 0x7AB7, 0x6A96, 0x1A71, 0x0A50, 0x3A33, 0x2A12,
|
||||||
|
0xDBFD, 0xCBDC, 0xFBBF, 0xEB9E, 0x9B79, 0x8B58, 0xBB3B, 0xAB1A,
|
||||||
ts B11222:
|
0x6CA6, 0x7C87, 0x4CE4, 0x5CC5, 0x2C22, 0x3C03, 0x0C60, 0x1C41,
|
||||||
The same algorithm is prescribed for CD-TEXT in MMC-3 Annex J.
|
0xEDAE, 0xFD8F, 0xCDEC, 0xDDCD, 0xAD2A, 0xBD0B, 0x8D68, 0x9D49,
|
||||||
"CRC Field consists of 2 bytes. Initiator system may use these bytes
|
0x7E97, 0x6EB6, 0x5ED5, 0x4EF4, 0x3E13, 0x2E32, 0x1E51, 0x0E70,
|
||||||
to check errors in the Pack. The polynomial is x^16 + x^12 + x^5 + 1.
|
0xFF9F, 0xEFBE, 0xDFDD, 0xCFFC, 0xBF1B, 0xAF3A, 0x9F59, 0x8F78,
|
||||||
All bits shall be inverted."
|
0x9188, 0x81A9, 0xB1CA, 0xA1EB, 0xD10C, 0xC12D, 0xF14E, 0xE16F,
|
||||||
|
0x1080, 0x00A1, 0x30C2, 0x20E3, 0x5004, 0x4025, 0x7046, 0x6067,
|
||||||
libburn/cdtext.c uses a simple bit shifting function : crc_11021()
|
0x83B9, 0x9398, 0xA3FB, 0xB3DA, 0xC33D, 0xD31C, 0xE37F, 0xF35E,
|
||||||
|
0x02B1, 0x1290, 0x22F3, 0x32D2, 0x4235, 0x5214, 0x6277, 0x7256,
|
||||||
|
0xB5EA, 0xA5CB, 0x95A8, 0x8589, 0xF56E, 0xE54F, 0xD52C, 0xC50D,
|
||||||
ts B20211:
|
0x34E2, 0x24C3, 0x14A0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
|
||||||
Discussion why both are equivalent in respect to their result:
|
0xA7DB, 0xB7FA, 0x8799, 0x97B8, 0xE75F, 0xF77E, 0xC71D, 0xD73C,
|
||||||
|
0x26D3, 0x36F2, 0x0691, 0x16B0, 0x6657, 0x7676, 0x4615, 0x5634,
|
||||||
Both map the bits of the given bytes to a polynomial over the finite field
|
0xD94C, 0xC96D, 0xF90E, 0xE92F, 0x99C8, 0x89E9, 0xB98A, 0xA9AB,
|
||||||
of two elements "GF(2)". If bytes 0 .. M are given, then bit n of byte m
|
0x5844, 0x4865, 0x7806, 0x6827, 0x18C0, 0x08E1, 0x3882, 0x28A3,
|
||||||
is mapped to the coefficient of x exponent (n + ((M - m) * 8) + 16).
|
0xCB7D, 0xDB5C, 0xEB3F, 0xFB1E, 0x8BF9, 0x9BD8, 0xABBB, 0xBB9A,
|
||||||
I.e. they translate the bits into a polynomial with the highest bit
|
0x4A75, 0x5A54, 0x6A37, 0x7A16, 0x0AF1, 0x1AD0, 0x2AB3, 0x3A92,
|
||||||
becoming the coefficient of the highest power of x. Then this polynomial
|
0xFD2E, 0xED0F, 0xDD6C, 0xCD4D, 0xBDAA, 0xAD8B, 0x9DE8, 0x8DC9,
|
||||||
is multiplied by (x exp 16).
|
0x7C26, 0x6C07, 0x5C64, 0x4C45, 0x3CA2, 0x2C83, 0x1CE0, 0x0CC1,
|
||||||
|
0xEF1F, 0xFF3E, 0xCF5D, 0xDF7C, 0xAF9B, 0xBFBA, 0x8FD9, 0x9FF8,
|
||||||
The set of all such polynomials forms a commutative ring. Its addition
|
0x6E17, 0x7E36, 0x4E55, 0x5E74, 0x2E93, 0x3EB2, 0x0ED1, 0x1EF0
|
||||||
corresponds to bitwise exclusive or. Addition and subtraction are identical.
|
};
|
||||||
Multiplication with polynomials of only one single non-zero coefficient
|
|
||||||
corresponds to leftward bit shifting by the exponent of that coefficient.
|
unsigned long crc32_table[256] = {
|
||||||
The same rules apply as with elementary school arithmetics on integer
|
|
||||||
numbers, but with surprising results due to the finite nature of the
|
|
||||||
coefficient number space.
|
|
||||||
Note that multiplication is _not_ an iteration of addition here.
|
|
||||||
|
|
||||||
Function crc_11021() performs a division with residue by the euclidian
|
|
||||||
algorithm. I.e. it splits polynomial d into quotient q(d) and residue r(d)
|
|
||||||
in respect to the polynomial p = x exp 16 + x exp 12 + x exp 5 + x exp 0
|
|
||||||
d = p * q(d) + r(d)
|
|
||||||
where r(d) is of a polynomial degree lower than p, i.e. only x exp 15
|
|
||||||
or lower have non-zero coefficients.
|
|
||||||
The checksum crc(D) is derived by reverse mapping (r(d) * (x exp 16)).
|
|
||||||
I.e. by mapping the coefficient of (x exp n) to bit n of the 16 bit word
|
|
||||||
crc(D).
|
|
||||||
The function result is the bit-wise complement of crc(D).
|
|
||||||
|
|
||||||
Function crc_ccitt uses a table ccitt_table of r(d) values for the
|
|
||||||
polynomials d which represent the single byte values 0x00 to 0xff.
|
|
||||||
It computes r(d) by computing the residues of an iteratively expanded
|
|
||||||
polynomial. The expansion of the processed byte string A by the next byte B
|
|
||||||
from the input byte string happens by shifting the string 8 bits to the
|
|
||||||
left, and by oring B onto bits 0 to 7.
|
|
||||||
In the space of polynomials, the already processed polynomial "a" (image of
|
|
||||||
byte string A) gets expanded by polynomial b (the image of byte B) like this
|
|
||||||
a * X + b
|
|
||||||
where X is (x exp 8), i.e. the single coefficient polynomial of degree 8.
|
|
||||||
|
|
||||||
The following argumentation uses algebra with commutative, associative
|
|
||||||
and distributive laws.
|
|
||||||
Valid especially with polynomials is this rule:
|
|
||||||
(1): r(a + b) = r(a) + r(b)
|
|
||||||
because r(a) and r(b) are of degree lower than degree(p) and
|
|
||||||
degree(a + b) <= max(degree(a), degree(b))
|
|
||||||
Further valid are:
|
|
||||||
(2): r(a) = r(r(a))
|
|
||||||
(3): r(p * a) = 0
|
|
||||||
|
|
||||||
The residue of this expanded polynomial can be expressed by means of the
|
|
||||||
residue r(a) which is known from the previous iteration step, and the
|
|
||||||
residue r(b) which may be looked up in ccitt_table.
|
|
||||||
r(a * X + b)
|
|
||||||
= r(p * q(a) * X + r(a) * X + p * q(b) + r(b))
|
|
||||||
|
|
||||||
Applying rule (1):
|
|
||||||
= r(p * q(a) * X) + r(r(a) * X) + r(p * q(b)) + r(r(b))
|
|
||||||
|
|
||||||
Rule (3) and rule (2):
|
|
||||||
= r(r(a) * X) + r(b)
|
|
||||||
|
|
||||||
Be h(a) and l(a) chosen so that: r(a) = h(a) * X + l(a),
|
|
||||||
and l(a) has zero coefficients above (x exp 7), and h(a) * X has zero
|
|
||||||
coefficients below (x exp 8). (They correspond to the high and low byte
|
|
||||||
of the 16 bit word crc(A).)
|
|
||||||
So the previous statement can be written as:
|
|
||||||
= r(h(a) * X * X) + r(l(a) * X) + r(b)
|
|
||||||
|
|
||||||
Since the degree of l(a) is lower than 8, the degree of l(a) * X is lower
|
|
||||||
than 16. Thus it cannot be divisible by p which has degree 16.
|
|
||||||
So: r(l(a) * X) = l(a) * X
|
|
||||||
This yields
|
|
||||||
= l(a) * X + r(h(a) * X * X + b)
|
|
||||||
|
|
||||||
h(a) * X * X is the polynomial representation of the high byte of 16 bit
|
|
||||||
word crc(A).
|
|
||||||
So in the world of bit patterns the iteration step is:
|
|
||||||
|
|
||||||
crc(byte string A expanded by byte B)
|
|
||||||
= (low_byte(crc(A)) << 8) ^ crc(high_byte(crc(A)) ^ B)
|
|
||||||
|
|
||||||
And this is what function crc_ccitt() does, modulo swapping the exor
|
|
||||||
operants and the final bit inversion which is prescribed by ECMA-130
|
|
||||||
and MMC-3 Annex J.
|
|
||||||
|
|
||||||
The start value of the table driven byte shifting algorithm may be
|
|
||||||
different from the start value of an equivalent bit shifting algorithm.
|
|
||||||
This is because the final flushing by zero bits is already pre-computed
|
|
||||||
in the table. So the start value of the table driven algorithm must be
|
|
||||||
the CRC of the 0-polynomial under the start value of the bit shifting
|
|
||||||
algorithm.
|
|
||||||
This fact is not of much importance here, because the start value of
|
|
||||||
the bit shifter is 0x0000 which leads to CRC 0x0000 and thus to start
|
|
||||||
value 0x0000 with the table driven byte shifter.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
/* Plain implementation of polynomial division on a Galois field, where
|
|
||||||
addition and subtraction both are binary exor. Euclidian algorithm.
|
|
||||||
Divisor is x^16 + x^12 + x^5 + 1 = 0x11021.
|
|
||||||
|
|
||||||
This is about ten times slower than the table driven algorithm.
|
|
||||||
*/
|
|
||||||
static int crc_11021(unsigned char *data, int count, int flag)
|
|
||||||
{
|
|
||||||
int acc = 0, i;
|
|
||||||
|
|
||||||
for (i = 0; i < count * 8 + 16; i++) {
|
|
||||||
acc = (acc << 1);
|
|
||||||
if (i < count * 8)
|
|
||||||
acc |= ((data[i / 8] >> (7 - (i % 8))) & 1);
|
|
||||||
if (acc & 0x10000)
|
|
||||||
acc ^= 0x11021;
|
|
||||||
}
|
|
||||||
return acc;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* This is my own table driven implementation for which i claim copyright.
|
|
||||||
|
|
||||||
Copyright (c) 2012 Thomas Schmitt <scdbackup@gmx.net>
|
|
||||||
*/
|
|
||||||
unsigned short crc_ccitt(unsigned char *data, int count)
|
|
||||||
{
|
|
||||||
static unsigned short crc_tab[256], tab_initialized = 0;
|
|
||||||
unsigned short acc = 0;
|
|
||||||
unsigned char b[1];
|
|
||||||
int i;
|
|
||||||
|
|
||||||
if (!tab_initialized) {
|
|
||||||
/* Create table of byte residues */
|
|
||||||
for (i = 0; i < 256; i++) {
|
|
||||||
b[0] = i;
|
|
||||||
crc_tab[i] = crc_11021(b, 1, 0);
|
|
||||||
}
|
|
||||||
tab_initialized = 1;
|
|
||||||
}
|
|
||||||
/* There seems to be a speed advantage on amd64 if (acc << 8) is the
|
|
||||||
second operant of exor, and *(data++) seems faster than data[i].
|
|
||||||
*/
|
|
||||||
for (i = 0; i < count; i++)
|
|
||||||
acc = crc_tab[(acc >> 8) ^ *(data++)] ^ (acc << 8);
|
|
||||||
|
|
||||||
/* ECMA-130 22.3.6 and MMC-3 Annex J (CD-TEXT) want the result with
|
|
||||||
inverted bits
|
|
||||||
*/
|
|
||||||
return ~acc;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
This was the function inherited with libburn-0.2.
|
|
||||||
|
|
||||||
static unsigned short ccitt_table[256] = {
|
|
||||||
0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7,
|
|
||||||
0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF,
|
|
||||||
0x1231, 0x0210, 0x3273, 0x2252, 0x52B5, 0x4294, 0x72F7, 0x62D6,
|
|
||||||
0x9339, 0x8318, 0xB37B, 0xA35A, 0xD3BD, 0xC39C, 0xF3FF, 0xE3DE,
|
|
||||||
0x2462, 0x3443, 0x0420, 0x1401, 0x64E6, 0x74C7, 0x44A4, 0x5485,
|
|
||||||
0xA56A, 0xB54B, 0x8528, 0x9509, 0xE5EE, 0xF5CF, 0xC5AC, 0xD58D,
|
|
||||||
0x3653, 0x2672, 0x1611, 0x0630, 0x76D7, 0x66F6, 0x5695, 0x46B4,
|
|
||||||
0xB75B, 0xA77A, 0x9719, 0x8738, 0xF7DF, 0xE7FE, 0xD79D, 0xC7BC,
|
|
||||||
0x48C4, 0x58E5, 0x6886, 0x78A7, 0x0840, 0x1861, 0x2802, 0x3823,
|
|
||||||
0xC9CC, 0xD9ED, 0xE98E, 0xF9AF, 0x8948, 0x9969, 0xA90A, 0xB92B,
|
|
||||||
0x5AF5, 0x4AD4, 0x7AB7, 0x6A96, 0x1A71, 0x0A50, 0x3A33, 0x2A12,
|
|
||||||
0xDBFD, 0xCBDC, 0xFBBF, 0xEB9E, 0x9B79, 0x8B58, 0xBB3B, 0xAB1A,
|
|
||||||
0x6CA6, 0x7C87, 0x4CE4, 0x5CC5, 0x2C22, 0x3C03, 0x0C60, 0x1C41,
|
|
||||||
0xEDAE, 0xFD8F, 0xCDEC, 0xDDCD, 0xAD2A, 0xBD0B, 0x8D68, 0x9D49,
|
|
||||||
0x7E97, 0x6EB6, 0x5ED5, 0x4EF4, 0x3E13, 0x2E32, 0x1E51, 0x0E70,
|
|
||||||
0xFF9F, 0xEFBE, 0xDFDD, 0xCFFC, 0xBF1B, 0xAF3A, 0x9F59, 0x8F78,
|
|
||||||
0x9188, 0x81A9, 0xB1CA, 0xA1EB, 0xD10C, 0xC12D, 0xF14E, 0xE16F,
|
|
||||||
0x1080, 0x00A1, 0x30C2, 0x20E3, 0x5004, 0x4025, 0x7046, 0x6067,
|
|
||||||
0x83B9, 0x9398, 0xA3FB, 0xB3DA, 0xC33D, 0xD31C, 0xE37F, 0xF35E,
|
|
||||||
0x02B1, 0x1290, 0x22F3, 0x32D2, 0x4235, 0x5214, 0x6277, 0x7256,
|
|
||||||
0xB5EA, 0xA5CB, 0x95A8, 0x8589, 0xF56E, 0xE54F, 0xD52C, 0xC50D,
|
|
||||||
0x34E2, 0x24C3, 0x14A0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
|
|
||||||
0xA7DB, 0xB7FA, 0x8799, 0x97B8, 0xE75F, 0xF77E, 0xC71D, 0xD73C,
|
|
||||||
0x26D3, 0x36F2, 0x0691, 0x16B0, 0x6657, 0x7676, 0x4615, 0x5634,
|
|
||||||
0xD94C, 0xC96D, 0xF90E, 0xE92F, 0x99C8, 0x89E9, 0xB98A, 0xA9AB,
|
|
||||||
0x5844, 0x4865, 0x7806, 0x6827, 0x18C0, 0x08E1, 0x3882, 0x28A3,
|
|
||||||
0xCB7D, 0xDB5C, 0xEB3F, 0xFB1E, 0x8BF9, 0x9BD8, 0xABBB, 0xBB9A,
|
|
||||||
0x4A75, 0x5A54, 0x6A37, 0x7A16, 0x0AF1, 0x1AD0, 0x2AB3, 0x3A92,
|
|
||||||
0xFD2E, 0xED0F, 0xDD6C, 0xCD4D, 0xBDAA, 0xAD8B, 0x9DE8, 0x8DC9,
|
|
||||||
0x7C26, 0x6C07, 0x5C64, 0x4C45, 0x3CA2, 0x2C83, 0x1CE0, 0x0CC1,
|
|
||||||
0xEF1F, 0xFF3E, 0xCF5D, 0xDF7C, 0xAF9B, 0xBFBA, 0x8FD9, 0x9FF8,
|
|
||||||
0x6E17, 0x7E36, 0x4E55, 0x5E74, 0x2E93, 0x3EB2, 0x0ED1, 0x1EF0
|
|
||||||
};
|
|
||||||
|
|
||||||
unsigned short crc_ccitt(unsigned char *q, int len)
|
|
||||||
{
|
|
||||||
unsigned short crc = 0;
|
|
||||||
|
|
||||||
while (len-- > 0)
|
|
||||||
crc = ccitt_table[(crc >> 8 ^ *q++) & 0xff] ^ (crc << 8);
|
|
||||||
return ~crc;
|
|
||||||
}
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
/* Exploration ts B00214 :
|
|
||||||
ECMA-130, 14.3 "EDC field"
|
|
||||||
"The EDC field shall consist of 4 bytes recorded in positions 2064 to 2067.
|
|
||||||
The error detection code shall be a 32-bit CRC applied on bytes 0 to 2063.
|
|
||||||
The least significant bit of a data byte is used first. The EDC codeword
|
|
||||||
must be divisible by the check polynomial:
|
|
||||||
P(x) = (x^16 + x^15 + x^2 + 1) . (x^16 + x^2 + x + 1)
|
|
||||||
The least significant parity bit (x^0) is stored in the most significant
|
|
||||||
bit position of byte 2067.
|
|
||||||
"
|
|
||||||
|
|
||||||
Used for raw writing in sector.c
|
|
||||||
|
|
||||||
|
|
||||||
ts B20211:
|
|
||||||
Discussion why function crc_32() implements above prescription of ECMA-130.
|
|
||||||
See end of this file for the ofunction inherited with libburn-0.2.
|
|
||||||
|
|
||||||
The mentioned polynomial product
|
|
||||||
(x^16 + x^15 + x^2 + 1) . (x^16 + x^2 + x + 1)
|
|
||||||
yields this sum of x exponents
|
|
||||||
32 31 18 16
|
|
||||||
18 17 4 2
|
|
||||||
17 16 3 1
|
|
||||||
16 15 2 0
|
|
||||||
======================================
|
|
||||||
32 31 16 15 4 3 1 0
|
|
||||||
(The number of x^18 and x^17 is divisible by two and thus 0 in GF(2).)
|
|
||||||
This yields as 33 bit number:
|
|
||||||
0x18001801b
|
|
||||||
|
|
||||||
If above prescription gets implemented straight forward by function
|
|
||||||
crc_18001801b(), then its results match the ones of crc_32() with all test
|
|
||||||
strings which i could invent.
|
|
||||||
|
|
||||||
The function consists of a conventional polynomial division with reverse
|
|
||||||
input order of bits per byte.
|
|
||||||
|
|
||||||
Further it swaps the bits in the resulting 32 bit word. That is because
|
|
||||||
sector.c:sector_headers writes the 4 bytes of crc_32() as little endian.
|
|
||||||
The ECMA-130 prescription rather demands big endianness and bit swapping
|
|
||||||
towards the normal bit order in bytes:
|
|
||||||
"The EDC field shall consist of 4 bytes recorded in positions 2064 to 2067.
|
|
||||||
[...]
|
|
||||||
The least significant parity bit (x^0) is stored in the most
|
|
||||||
significant bit position of byte 2067."
|
|
||||||
|
|
||||||
-----------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
/* Overall bit mirroring of a 32 bit word */
|
|
||||||
unsigned int rfl32(unsigned int acc)
|
|
||||||
{
|
|
||||||
unsigned int inv_acc;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
inv_acc = 0;
|
|
||||||
for (i = 0; i < 32; i++)
|
|
||||||
if (acc & (1 << i))
|
|
||||||
inv_acc |= 1 << (31 - i);
|
|
||||||
return inv_acc;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Plain implementation of polynomial division on a Galois field, where
|
|
||||||
addition and subtraction both are binary exor. Euclidian algorithm.
|
|
||||||
Divisor is (x^16 + x^15 + x^2 + 1) * (x^16 + x^2 + x + 1).
|
|
||||||
|
|
||||||
This is about ten times slower than the table driven algorithm.
|
|
||||||
|
|
||||||
@param flag bit0= do not mirror bits in input bytes and result word
|
|
||||||
(Useful for building the byte indexed CRC table)
|
|
||||||
*/
|
|
||||||
static unsigned int crc_18001801b(unsigned char *data, int count, int flag)
|
|
||||||
{
|
|
||||||
unsigned int acc = 0, top;
|
|
||||||
long int i;
|
|
||||||
unsigned int inv_acc;
|
|
||||||
|
|
||||||
for (i = 0; i < count * 8 + 32; i++) {
|
|
||||||
top = acc & 0x80000000;
|
|
||||||
acc = (acc << 1);
|
|
||||||
if (i < count * 8) {
|
|
||||||
if (flag & 1)
|
|
||||||
/* Normal bit sequence of input bytes */
|
|
||||||
acc |= ((data[i / 8] >> (7 - (i % 8))) & 1);
|
|
||||||
else
|
|
||||||
/* Bit sequence of input bytes mirrored */
|
|
||||||
acc |= ((data[i / 8] >> (i % 8)) & 1);
|
|
||||||
}
|
|
||||||
if (top)
|
|
||||||
acc ^= 0x8001801b;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (flag & 1)
|
|
||||||
return (unsigned int) (acc & 0xffffffff);
|
|
||||||
|
|
||||||
/* The bits of the whole 32 bit result are mirrored for ECMA-130
|
|
||||||
output compliance and for sector.c habit to store CRC little endian
|
|
||||||
although ECMA-130 prescribes it big endian.
|
|
||||||
*/
|
|
||||||
inv_acc = rfl32((unsigned int) acc);
|
|
||||||
return inv_acc;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
-----------------------------------------------------------------------
|
|
||||||
|
|
||||||
Above discussion why crc_ccitt() and crc_11021() yield identical results
|
|
||||||
can be changed from 16 bit to 32 bit by chosing h(a) and l(a) so that:
|
|
||||||
r(a) = h(a) * X * X * X + l(a)
|
|
||||||
h(a) corresponds to the highest byte of crc(A), whereas l(a) corresponds
|
|
||||||
to the lower three bytes of crc(A).
|
|
||||||
|
|
||||||
This yields
|
|
||||||
r(a * X + b)
|
|
||||||
= l(a) * X + r(h(a) * X * X * X * X + b)
|
|
||||||
|
|
||||||
h(a) * X * X * X * X is the polynomial representation of the high byte of
|
|
||||||
32 bit word crc(A).
|
|
||||||
So in the world of bit patterns we have:
|
|
||||||
|
|
||||||
crc(byte string A expanded by byte B)
|
|
||||||
= (lowest_three_bytes(crc(A)) << 8) ^ crc(high_byte(crc(A)) ^ B)
|
|
||||||
|
|
||||||
|
|
||||||
Regrettably this does not yet account for the byte-internal mirroring of
|
|
||||||
bits during the conversion from bit pattern to polynomial, and during
|
|
||||||
conversion from polynomial residue to bit pattern.
|
|
||||||
|
|
||||||
Be rfl8(D) the result of byte-internal mirroring of bit pattern D,
|
|
||||||
and mirr8(d) its corresponding polynom.
|
|
||||||
|
|
||||||
Be now h(a) and l(a) chosen so that: r(mirr8(a)) = h(a) * X * X * X + l(a)
|
|
||||||
This corresponds to highest byte and lower three bytes of crc(A).
|
|
||||||
|
|
||||||
r(mirr8(a) * X + mirr8(b))
|
|
||||||
= r(h(a) * X * X * X * X) + r(l(a) * X) + r(mirr8(b))
|
|
||||||
= l(a)) * X + r(h(a) * X * X * X * X + mirr8(b))
|
|
||||||
|
|
||||||
The corresponding bit pattern operation is
|
|
||||||
|
|
||||||
crc(mirrored byte string A expanded by mirrored byte B)
|
|
||||||
= (lowest_three_bytes(crc(A)) << 8) ^ crc(high_byte(crc(A)) ^ rfl8(B))
|
|
||||||
|
|
||||||
This demands a final result mirroring to meet the ECMA-130 prescription.
|
|
||||||
|
|
||||||
rfl8() can be implemented as lookup table.
|
|
||||||
|
|
||||||
The start value of the bit shifting iteration is 0x00000000, which leads
|
|
||||||
to the same start value for the table driven byte shifting.
|
|
||||||
|
|
||||||
The following function crc32_by_tab() yields the same results as functions
|
|
||||||
crc_18001801b() and crc_32():
|
|
||||||
|
|
||||||
-----------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
/* Byte-internal bit mirroring function.
|
|
||||||
*/
|
|
||||||
unsigned int rfl8(unsigned int acc)
|
|
||||||
{
|
|
||||||
unsigned int inv_acc;
|
|
||||||
int i, j;
|
|
||||||
|
|
||||||
inv_acc = 0;
|
|
||||||
for (j = 0; j < 4; j++)
|
|
||||||
for (i = 0; i < 8; i++)
|
|
||||||
if (acc & (1 << (i + 8 * j)))
|
|
||||||
inv_acc |= 1 << ((7 - i) + 8 * j);
|
|
||||||
return inv_acc;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef Libburn_with_crc_illustratioN
|
|
||||||
/* Not needed for libburn. The new implementation of function crc_32() is the
|
|
||||||
one that is used.
|
|
||||||
*/
|
|
||||||
|
|
||||||
unsigned int crc32_by_tab(unsigned char *data, int count, int flag)
|
|
||||||
{
|
|
||||||
static unsigned int crc_tab[256], tab_initialized = 0;
|
|
||||||
static unsigned char mirr_tab[256];
|
|
||||||
unsigned int acc, inv_acc;
|
|
||||||
unsigned char b[1];
|
|
||||||
int i;
|
|
||||||
|
|
||||||
if (!tab_initialized) {
|
|
||||||
for (i = 0; i < 256; i++) {
|
|
||||||
b[0] = i;
|
|
||||||
/* Create table of non-mirrored 0x18001801b residues */
|
|
||||||
crc_tab[i] = crc_18001801b(b, 1, 1);
|
|
||||||
/* Create table of mirrored byte values */
|
|
||||||
mirr_tab[i] = rfl8(i);
|
|
||||||
}
|
|
||||||
tab_initialized = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
acc = 0;
|
|
||||||
for (i = 0; i < count; i++)
|
|
||||||
acc = (acc << 8) ^ crc_tab[(acc >> 24) ^ mirr_tab[data[i]]];
|
|
||||||
|
|
||||||
/* The bits of the whole 32 bit result are mirrored for ECMA-130
|
|
||||||
output compliance and for sector.c habit to store CRC little endian
|
|
||||||
although ECMA-130 prescribes it big endian.
|
|
||||||
*/
|
|
||||||
inv_acc = rfl32((unsigned int) acc);
|
|
||||||
return inv_acc;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* Libburn_with_crc_illustratioN */
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
-----------------------------------------------------------------------
|
|
||||||
|
|
||||||
Above function yields sufficient performance, nevertheless the old function
|
|
||||||
crc_32() (see below) is faster by avoiding the additional mirror table
|
|
||||||
lookup.
|
|
||||||
A test with 10 times 650 MB on 3000 MHz amd64:
|
|
||||||
crc_18001801b : 187 s
|
|
||||||
crc32_by_tab : 27 s
|
|
||||||
crc_32 : 16 s
|
|
||||||
|
|
||||||
So how does crc_32() avoid the application of bit mirroring to B ?.
|
|
||||||
|
|
||||||
Inherited crc_32() performs
|
|
||||||
crc = crc32_table[(crc ^ *data++) & 0xffL] ^ (crc >> 8);
|
|
||||||
|
|
||||||
Above function crc32_by_tab() would be
|
|
||||||
crc = crc_tab[(crc >> 24) ^ mirr_tab[*data++]] ^ (crc << 8);
|
|
||||||
|
|
||||||
The shortcut does not change the polynomial representation of the algorithm
|
|
||||||
or the mapping from and to bit patterns. It only mirrors the bit direction
|
|
||||||
in the bytes and in the 32-bit words which are involved in the bit pattern
|
|
||||||
computation. This affects input (which is desired), intermediate state
|
|
||||||
(which is as good as unmirrored), and final output (which would be slightly
|
|
||||||
undesirable if libburn could not use the mirrored result anyway).
|
|
||||||
|
|
||||||
Instead of the high byte (crc >> 24), the abbreviated algorithm uses
|
|
||||||
the low byte of the mirrored intermediate checksum (crc & 0xffL).
|
|
||||||
Instead of shifting the other three intermediate bytes to the left
|
|
||||||
(crc << 8), the abbreviated algorithm shifts them to the right (crc >> 8).
|
|
||||||
In both cases they overwrite the single byte that was used for computing
|
|
||||||
the table index.
|
|
||||||
|
|
||||||
The byte indexed table of CRC values needs to hold mirrored 32 bit values.
|
|
||||||
The byte index [(crc ^ *data++) & 0xffL] would need to be mirrored, which
|
|
||||||
would eat up the gain of not mirroring the input bytes. But this mirroring
|
|
||||||
can be pre-computed into the table by exchanging each value with the value
|
|
||||||
of its mirrored index.
|
|
||||||
|
|
||||||
So this relation exists between the CRC table crc_tab[] of crc32_by_tab()
|
|
||||||
and the table crc32_table[] of the abbreviated algorithm crc_32():
|
|
||||||
|
|
||||||
crc_tab[i] == rfl32(crc32_table[rfl8(i)])
|
|
||||||
|
|
||||||
for i={0..255}.
|
|
||||||
|
|
||||||
I compared the generated table in crc32_by_tab() by this test
|
|
||||||
for (i = 0; i < 256; i++) {
|
|
||||||
if (rfl32(crc_tab[rfl8(i)]) != crc32_table[i] ||
|
|
||||||
crc_tab[i] != rfl32(crc32_table[rfl8(i)])) {
|
|
||||||
printf("DEVIATION : i = %d\n", i);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
No screaming abort happened.
|
|
||||||
|
|
||||||
-----------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* This is my own mirrored table implementation for which i claim copyright.
|
|
||||||
With gcc -O2 it shows the same efficiency as the inherited implementation
|
|
||||||
below. With -O3, -O1, or -O0 it is only slightly slower.
|
|
||||||
|
|
||||||
Copyright (c) 2012 Thomas Schmitt <scdbackup@gmx.net>
|
|
||||||
*/
|
|
||||||
unsigned int crc_32(unsigned char *data, int count)
|
|
||||||
{
|
|
||||||
static unsigned int crc_tab[256], tab_initialized = 0;
|
|
||||||
unsigned int acc = 0;
|
|
||||||
unsigned char b[1];
|
|
||||||
int i;
|
|
||||||
|
|
||||||
if (!tab_initialized) {
|
|
||||||
/* Create table of mirrored 0x18001801b residues in
|
|
||||||
bit-mirrored index positions.
|
|
||||||
*/
|
|
||||||
for (i = 0; i < 256; i++) {
|
|
||||||
b[0] = i;
|
|
||||||
crc_tab[rfl8(i)] = rfl32(crc_18001801b(b, 1, 1));
|
|
||||||
}
|
|
||||||
tab_initialized = 1;
|
|
||||||
}
|
|
||||||
for (i = 0; i < count; i++)
|
|
||||||
acc = (acc >> 8) ^ crc_tab[(acc & 0xff) ^ data[i]];
|
|
||||||
|
|
||||||
/* The bits of the whole 32 bit result stay mirrored for ECMA-130
|
|
||||||
output 8-bit mirroring and for sector.c habit to store the CRC
|
|
||||||
little endian although ECMA-130 prescribes it big endian.
|
|
||||||
*/
|
|
||||||
return acc;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
-----------------------------------------------------------------------
|
|
||||||
|
|
||||||
This was the function inherited with libburn-0.2 which implements the
|
|
||||||
abbreviated algorithm. Its obscure existence led me to above insights.
|
|
||||||
My compliments to the (unknown) people who invented this.
|
|
||||||
|
|
||||||
unsigned long crc32_table[256] = {
|
|
||||||
0x00000000L, 0x90910101L, 0x91210201L, 0x01B00300L,
|
0x00000000L, 0x90910101L, 0x91210201L, 0x01B00300L,
|
||||||
0x92410401L, 0x02D00500L, 0x03600600L, 0x93F10701L,
|
0x92410401L, 0x02D00500L, 0x03600600L, 0x93F10701L,
|
||||||
0x94810801L, 0x04100900L, 0x05A00A00L, 0x95310B01L,
|
0x94810801L, 0x04100900L, 0x05A00A00L, 0x95310B01L,
|
||||||
|
@ -627,16 +106,44 @@ unsigned int crc_32(unsigned char *data, int count)
|
||||||
0xE541F401L, 0x75D0F500L, 0x7460F600L, 0xE4F1F701L,
|
0xE541F401L, 0x75D0F500L, 0x7460F600L, 0xE4F1F701L,
|
||||||
0xE381F801L, 0x7310F900L, 0x72A0FA00L, 0xE231FB01L,
|
0xE381F801L, 0x7310F900L, 0x72A0FA00L, 0xE231FB01L,
|
||||||
0x71C0FC00L, 0xE151FD01L, 0xE0E1FE01L, 0x7070FF00L
|
0x71C0FC00L, 0xE151FD01L, 0xE0E1FE01L, 0x7070FF00L
|
||||||
};
|
};
|
||||||
|
|
||||||
unsigned int crc_32(unsigned char *data, int len)
|
|
||||||
{
|
/* Exploration ts B00214 :
|
||||||
|
ECMA-130, 22.3.6 "CRC field"
|
||||||
|
Generating polynomial: x^16 + x^12 + x^5 + 1
|
||||||
|
Also known as CRC-16-CCITT, CRC-CCITT
|
||||||
|
|
||||||
|
Use in libburn for raw write modes in sector.c.
|
||||||
|
There is also disabled code in read.c which would use it.
|
||||||
|
*/
|
||||||
|
unsigned short crc_ccitt(unsigned char *q, int len)
|
||||||
|
{
|
||||||
|
unsigned short crc = 0;
|
||||||
|
|
||||||
|
while (len-- > 0)
|
||||||
|
crc = ccitt_table[(crc >> 8 ^ *q++) & 0xff] ^ (crc << 8);
|
||||||
|
return ~crc;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Exploration ts B00214 :
|
||||||
|
ECMA-130, 14.3 "EDC field"
|
||||||
|
"The EDC codeword must be divisible by the check polynomial:
|
||||||
|
P(x) = (x^16 + x^15 + x^2 + 1) . (x^16 + x^2 + x + 1)
|
||||||
|
"
|
||||||
|
|
||||||
|
>>> Test whether this coincides with CRC-32 IEEE 802.3
|
||||||
|
x^32 + x^26 + x^23 + x^22 + x^16 + x^12 + x^11 + x^10
|
||||||
|
+ x^8 + x^7 + x^5 + x^4 + x^2 + x + 1
|
||||||
|
|
||||||
|
Used for raw writing in sector.c
|
||||||
|
*/
|
||||||
|
unsigned int crc_32(unsigned char *data, int len)
|
||||||
|
{
|
||||||
unsigned int crc = 0;
|
unsigned int crc = 0;
|
||||||
|
|
||||||
while (len-- > 0)
|
while (len-- > 0)
|
||||||
crc = crc32_table[(crc ^ *data++) & 0xffL] ^ (crc >> 8);
|
crc = crc32_table[(crc ^ *data++) & 0xffL] ^ (crc >> 8);
|
||||||
return crc;
|
return crc;
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,21 +1,11 @@
|
||||||
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||||
|
|
||||||
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
|
|
||||||
Copyright (c) 2012 Thomas Schmitt <scdbackup@gmx.net>
|
|
||||||
Provided under GPL version 2 or later.
|
|
||||||
*/
|
|
||||||
#ifndef BURN__CRC_H
|
#ifndef BURN__CRC_H
|
||||||
#define BURN__CRC_H
|
#define BURN__CRC_H
|
||||||
|
|
||||||
|
|
||||||
#ifdef Xorriso_standalonE
|
#ifdef Xorriso_standalonE
|
||||||
/* Source module crc.c of yet unclear ancestry is excluded from GNU xorriso */
|
/* Source module crc.c of yet unclear ancestry is excluded from GNU xorriso */
|
||||||
/* ts B20219 : The functions have been re-implemented from scratch after
|
|
||||||
studying texts about CRC computation and understanding the
|
|
||||||
meaning of the underlying ECMA-130 specs.
|
|
||||||
Nevertheless, there is no need to include them into xorriso
|
|
||||||
because it does neither CD-TEXT nor raw CD writing.
|
|
||||||
*/
|
|
||||||
#ifndef Libburn_no_crc_C
|
#ifndef Libburn_no_crc_C
|
||||||
#define Libburn_no_crc_C 1
|
#define Libburn_no_crc_C 1
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
-DDDLPA_C_STANDALONE -o ddlpa ddlpa.c
|
-DDDLPA_C_STANDALONE -o ddlpa ddlpa.c
|
||||||
|
|
||||||
The system macros enable 64-bit off_t and open(2) flag O_LARGEFILE, which
|
The system macros enable 64-bit off_t and open(2) flag O_LARGEFILE, which
|
||||||
are not absolutely necessary but explicitly take into respect that
|
are not absolutely necessary but explicitely take into respect that
|
||||||
our devices can offer more than 2 GB of addressable data.
|
our devices can offer more than 2 GB of addressable data.
|
||||||
|
|
||||||
Run test program:
|
Run test program:
|
||||||
|
@ -50,9 +50,7 @@ static int ddlpa_debug_mode = 1;
|
||||||
#ifndef O_LARGEFILE
|
#ifndef O_LARGEFILE
|
||||||
#define O_LARGEFILE 0
|
#define O_LARGEFILE 0
|
||||||
#endif
|
#endif
|
||||||
#ifndef O_BINARY
|
|
||||||
#define O_BINARY 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* ----------------------- private -------------------- */
|
/* ----------------------- 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;
|
int ret, o_flags, o_rw, l_type;
|
||||||
char *o_rwtext;
|
char *o_rwtext;
|
||||||
|
|
||||||
o_flags = o->o_flags | O_NDELAY | O_BINARY;
|
o_flags = o->o_flags | O_NDELAY;
|
||||||
if(!no_o_excl)
|
if(!no_o_excl)
|
||||||
o_flags |= O_EXCL;
|
o_flags |= O_EXCL;
|
||||||
o_rw = (o_flags) & (O_RDONLY | O_WRONLY | O_RDWR);
|
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,
|
static int ddlpa_obtain_scsi_adr(struct ddlpa_lock *o, char *path,
|
||||||
int *bus, int *host, int *channel, int *id, int *lun)
|
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 {
|
struct my_scsi_idlun {
|
||||||
int x;
|
int x;
|
||||||
int host_unique_id;
|
int host_unique_id;
|
||||||
|
@ -552,8 +550,7 @@ usage:;
|
||||||
} else {
|
} else {
|
||||||
/*
|
/*
|
||||||
This substitutes for:
|
This substitutes for:
|
||||||
fd = open(my_path,
|
fd = open(my_path, O_RDWR | O_EXCL | O_LARGEFILE);
|
||||||
O_RDWR | O_EXCL | O_LARGEFILE | O_BINARY);
|
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
|
@ -25,4 +25,20 @@ void burn_set_verbosity(int v)
|
||||||
burn_verbosity = v;
|
burn_verbosity = v;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void burn_print(int level, const char *a, ...)
|
||||||
|
{
|
||||||
|
#ifdef WIN32
|
||||||
|
char debug_string_data[256];
|
||||||
|
#endif
|
||||||
|
va_list vl;
|
||||||
|
|
||||||
|
if (level <= burn_verbosity) {
|
||||||
|
va_start(vl, a);
|
||||||
|
#ifdef WIN32
|
||||||
|
vsprintf(debug_string_data, a, vl);
|
||||||
|
OutputDebugString(debug_string_data);
|
||||||
|
#else
|
||||||
|
vfprintf(stderr, a, vl);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
1214
libburn/drive.c
1214
libburn/drive.c
File diff suppressed because it is too large
Load Diff
|
@ -1,7 +1,7 @@
|
||||||
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||||
|
|
||||||
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
|
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
|
||||||
Copyright (c) 2006 - 2024 Thomas Schmitt <scdbackup@gmx.net>
|
Copyright (c) 2006 - 2010 Thomas Schmitt <scdbackup@gmx.net>
|
||||||
Provided under GPL version 2 or later.
|
Provided under GPL version 2 or later.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -19,7 +19,6 @@ struct command;
|
||||||
struct mempage;
|
struct mempage;
|
||||||
struct scsi_mode_data;
|
struct scsi_mode_data;
|
||||||
struct burn_speed_descriptor;
|
struct burn_speed_descriptor;
|
||||||
struct burn_feature_descr;
|
|
||||||
|
|
||||||
#define LEAD_IN 1
|
#define LEAD_IN 1
|
||||||
#define GAP 2
|
#define GAP 2
|
||||||
|
@ -86,7 +85,7 @@ struct burn_drive *burn_drive_finish_enum(struct burn_drive *d);
|
||||||
int burn_drive_inquire_media(struct burn_drive *d);
|
int burn_drive_inquire_media(struct burn_drive *d);
|
||||||
|
|
||||||
/* ts A61125 : model aspects of burn_drive_release */
|
/* ts A61125 : model aspects of burn_drive_release */
|
||||||
int burn_drive_mark_unready(struct burn_drive *d, int flag);
|
int burn_drive_mark_unready(struct burn_drive *d);
|
||||||
|
|
||||||
|
|
||||||
/* ts A61226 */
|
/* ts A61226 */
|
||||||
|
@ -156,26 +155,4 @@ int burn_abort_5(int patience,
|
||||||
/* Send a default mode page 05 to CD and DVD-R-oids */
|
/* 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);
|
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);
|
|
||||||
|
|
||||||
/* ts C10213 */
|
|
||||||
/* The size of limitless or oversized devices as pseudo drives */
|
|
||||||
/* Do not lightheartedly change this value because of its meaning to
|
|
||||||
burn_drive.media_read_capacity in libburn/transport.h
|
|
||||||
64 TiB = 2 exp 46 = 2 exp 35 blocks
|
|
||||||
*/
|
|
||||||
#define BURN_DRIVE_MAX_BYTES ((off_t) (0x800000000) * (off_t) 2048)
|
|
||||||
|
|
||||||
#endif /* __DRIVE */
|
#endif /* __DRIVE */
|
||||||
|
|
|
@ -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
|
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
|
Q-diagonals by RSPC based on a Galois Field GF(2^8) with enumerating
|
||||||
|
@ -75,12 +75,12 @@
|
||||||
>>> See correctness reservation below.
|
>>> See correctness reservation below.
|
||||||
|
|
||||||
Algebra on Galois fields is the same as on Rational Numbers.
|
Algebra on Galois fields is the same as on Rational Numbers.
|
||||||
But arithmetics on its polynomials differ from usual integer arithmetics
|
But arithmetics is defined by operations on polynomials rather than the
|
||||||
on binary numbers.
|
usual integer arithmetics on binary numbers.
|
||||||
Addition and subtraction are identical with the binary exor operator.
|
Addition and subtraction are identical with the binary exor operator.
|
||||||
Multiplication and division would demand polynomial division, e.g. by the
|
Multiplication and division would demand polynomial division, e.g. by the
|
||||||
euclidean algorithm. The computing path over logarithms and powers follows
|
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
|
modulo 255, and exor operations. Note that the logarithms are natural
|
||||||
numbers, not polynomials. They get added or subtracted by the usual addition
|
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.
|
(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
|
#ifdef Libburn_use_h_matriceS
|
||||||
|
|
||||||
/* On my AMD 2x64 bit 3000 MHz processor h[i] costs about 7 % more time
|
/* 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
|
condensed data representation which slightly increases the rate of cache
|
||||||
hits.
|
hits.
|
||||||
Nevertheless this effect is very likely depending on the exact cache
|
Nevertheless this effect is very likely depending on the exact cache
|
||||||
|
|
256
libburn/file.c
256
libburn/file.c
|
@ -1,7 +1,7 @@
|
||||||
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||||
|
|
||||||
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
|
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
|
||||||
Copyright (c) 2006 - 2017 Thomas Schmitt <scdbackup@gmx.net>
|
Copyright (c) 2006 - 2010 Thomas Schmitt <scdbackup@gmx.net>
|
||||||
Provided under GPL version 2 or later.
|
Provided under GPL version 2 or later.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -22,17 +22,10 @@
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <pthread.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 "source.h"
|
||||||
#include "libburn.h"
|
#include "libburn.h"
|
||||||
#include "file.h"
|
#include "file.h"
|
||||||
#include "async.h"
|
#include "async.h"
|
||||||
#include "init.h"
|
|
||||||
#include "util.h"
|
|
||||||
|
|
||||||
#include "libdax_msgs.h"
|
#include "libdax_msgs.h"
|
||||||
extern struct libdax_msgs *libdax_messenger;
|
extern struct libdax_msgs *libdax_messenger;
|
||||||
|
@ -43,7 +36,7 @@ an unreadable disc */
|
||||||
|
|
||||||
|
|
||||||
/* This is a generic OS oriented function wrapper which compensates
|
/* This is a generic OS oriented function wrapper which compensates
|
||||||
shortcomings of read() in respect to a guaranteed amount of return data.
|
shortcommings of read() in respect to a guaranteed amount of return data.
|
||||||
See man 2 read , paragraph "RETURN VALUE".
|
See man 2 read , paragraph "RETURN VALUE".
|
||||||
*/
|
*/
|
||||||
static int read_full_buffer(int fd, unsigned char *buffer, int size)
|
static int read_full_buffer(int fd, unsigned char *buffer, int size)
|
||||||
|
@ -126,11 +119,11 @@ struct burn_source *burn_file_source_new(const char *path, const char *subpath)
|
||||||
|
|
||||||
if (!path)
|
if (!path)
|
||||||
return NULL;
|
return NULL;
|
||||||
fd1 = open(path, O_RDONLY | O_BINARY);
|
fd1 = open(path, O_RDONLY);
|
||||||
if (fd1 == -1)
|
if (fd1 == -1)
|
||||||
return NULL;
|
return NULL;
|
||||||
if (subpath != NULL) {
|
if (subpath != NULL) {
|
||||||
fd2 = open(subpath, O_RDONLY | O_BINARY);
|
fd2 = open(subpath, O_RDONLY);
|
||||||
if (fd2 == -1) {
|
if (fd2 == -1) {
|
||||||
close(fd1);
|
close(fd1);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -182,7 +175,7 @@ struct burn_source *burn_fd_source_new(int datafd, int subfd, off_t size)
|
||||||
|
|
||||||
if (datafd == -1)
|
if (datafd == -1)
|
||||||
return NULL;
|
return NULL;
|
||||||
fs = burn_alloc_mem(sizeof(struct burn_source_file), 1, 0);
|
fs = calloc(1, sizeof(struct burn_source_file));
|
||||||
if (fs == NULL) /* ts A70825 */
|
if (fs == NULL) /* ts A70825 */
|
||||||
return NULL;
|
return NULL;
|
||||||
fs->datafd = datafd;
|
fs->datafd = datafd;
|
||||||
|
@ -331,31 +324,8 @@ static int fifo_set_size(struct burn_source *source, off_t size)
|
||||||
static void fifo_free(struct burn_source *source)
|
static void fifo_free(struct burn_source *source)
|
||||||
{
|
{
|
||||||
struct burn_source_fifo *fs = source->data;
|
struct burn_source_fifo *fs = source->data;
|
||||||
int wait_count;
|
|
||||||
static int wait_max = 30, wait_usleep = 100000;
|
|
||||||
|
|
||||||
burn_fifo_abort(fs, 0);
|
burn_fifo_abort(fs, 0);
|
||||||
for (wait_count = 0; wait_count <= wait_max; wait_count++) {
|
|
||||||
if (fs->thread_is_valid <= 0)
|
|
||||||
break;
|
|
||||||
if (wait_count < wait_max)
|
|
||||||
usleep(wait_usleep);
|
|
||||||
}
|
|
||||||
if (wait_count > wait_max) {
|
|
||||||
/* The shoveler thread might still be active. If so, it would
|
|
||||||
use invalid or inappropriate memory if the fifo would be
|
|
||||||
disposed now. A memory and resource leak is the better
|
|
||||||
option here.
|
|
||||||
*/
|
|
||||||
libdax_msgs_submit(libdax_messenger, -1,
|
|
||||||
0x000201ab,
|
|
||||||
LIBDAX_MSGS_SEV_WARNING,
|
|
||||||
LIBDAX_MSGS_PRIO_HIGH,
|
|
||||||
"Leaving burn_source_fifo object undisposed because it is possibly stuck but alive",
|
|
||||||
0, 0);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fs->inp != NULL)
|
if (fs->inp != NULL)
|
||||||
burn_source_free(fs->inp);
|
burn_source_free(fs->inp);
|
||||||
|
|
||||||
|
@ -379,20 +349,13 @@ int burn_fifo_source_shoveller(struct burn_source *source, int flag)
|
||||||
fs->thread_pid = getpid();
|
fs->thread_pid = getpid();
|
||||||
fs->thread_is_valid = 1;
|
fs->thread_is_valid = 1;
|
||||||
|
|
||||||
/* Lock was obtained by async.c:add_worker() */
|
|
||||||
burn_async_manage_lock(BURN_ASYNC_LOCK_RELEASE);
|
|
||||||
|
|
||||||
bufsize = fs->chunksize * fs->chunks;
|
bufsize = fs->chunksize * fs->chunks;
|
||||||
while (!fs->end_of_consumption) {
|
while (!fs->end_of_consumption) {
|
||||||
if (fs->do_abort)
|
|
||||||
goto emergency_exit;
|
|
||||||
|
|
||||||
/* wait for enough buffer space available */
|
/* wait for enough buffer space available */
|
||||||
wpos = fs->buf_writepos;
|
wpos = fs->buf_writepos;
|
||||||
counted = 0;
|
counted = 0;
|
||||||
while (1) {
|
while (1) {
|
||||||
if (fs->do_abort)
|
|
||||||
goto emergency_exit;
|
|
||||||
rpos = fs->buf_readpos;
|
rpos = fs->buf_readpos;
|
||||||
diff = rpos - wpos;
|
diff = rpos - wpos;
|
||||||
trans_end = 0;
|
trans_end = 0;
|
||||||
|
@ -435,8 +398,6 @@ int burn_fifo_source_shoveller(struct burn_source *source, int flag)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Obtain next chunk */
|
/* Obtain next chunk */
|
||||||
if (fs->do_abort)
|
|
||||||
goto emergency_exit;
|
|
||||||
if (fs->inp->read != NULL)
|
if (fs->inp->read != NULL)
|
||||||
ret = fs->inp->read(fs->inp,
|
ret = fs->inp->read(fs->inp,
|
||||||
(unsigned char *) bufpt, fs->inp_read_size);
|
(unsigned char *) bufpt, fs->inp_read_size);
|
||||||
|
@ -462,8 +423,6 @@ int burn_fifo_source_shoveller(struct burn_source *source, int flag)
|
||||||
fs->put_counter++;
|
fs->put_counter++;
|
||||||
|
|
||||||
/* activate read chunk */
|
/* activate read chunk */
|
||||||
if (fs->do_abort)
|
|
||||||
goto emergency_exit;
|
|
||||||
if (ret > fs->inp_read_size)
|
if (ret > fs->inp_read_size)
|
||||||
/* beware of ill custom burn_source */
|
/* beware of ill custom burn_source */
|
||||||
ret = fs->inp_read_size;
|
ret = fs->inp_read_size;
|
||||||
|
@ -497,11 +456,8 @@ int burn_fifo_source_shoveller(struct burn_source *source, int flag)
|
||||||
fs->end_of_input = 1;
|
fs->end_of_input = 1;
|
||||||
|
|
||||||
/* wait for end of reading by consumer */;
|
/* wait for end of reading by consumer */;
|
||||||
while (fs->buf_readpos != fs->buf_writepos && !fs->end_of_consumption) {
|
while (fs->buf_readpos != fs->buf_writepos && !fs->end_of_consumption)
|
||||||
if (fs->do_abort)
|
fifo_sleep(0);
|
||||||
goto emergency_exit;
|
|
||||||
fifo_sleep(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* destroy ring buffer */;
|
/* destroy ring buffer */;
|
||||||
if (!fs->end_of_consumption)
|
if (!fs->end_of_consumption)
|
||||||
|
@ -518,11 +474,8 @@ int burn_fifo_source_shoveller(struct burn_source *source, int flag)
|
||||||
((size_t) fs->chunksize) * (size_t) fs->chunks, 0);
|
((size_t) fs->chunksize) * (size_t) fs->chunks, 0);
|
||||||
fs->buf = NULL;
|
fs->buf = NULL;
|
||||||
|
|
||||||
emergency_exit:;
|
|
||||||
burn_async_manage_lock(BURN_ASYNC_LOCK_OBTAIN);
|
|
||||||
fs->thread_handle= NULL;
|
fs->thread_handle= NULL;
|
||||||
fs->thread_is_valid = 0;
|
fs->thread_is_valid = 0;
|
||||||
burn_async_manage_lock(BURN_ASYNC_LOCK_RELEASE);
|
|
||||||
return (fs->input_error == 0);
|
return (fs->input_error == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -557,14 +510,13 @@ struct burn_source *burn_fifo_source_new(struct burn_source *inp,
|
||||||
"Desired fifo buffer too small", 0, 0);
|
"Desired fifo buffer too small", 0, 0);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
fs = burn_alloc_mem(sizeof(struct burn_source_fifo), 1, 0);
|
fs = calloc(1, sizeof(struct burn_source_fifo));
|
||||||
if (fs == NULL)
|
if (fs == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
fs->is_started = 0;
|
fs->is_started = 0;
|
||||||
fs->thread_handle = NULL;
|
fs->thread_handle = NULL;
|
||||||
fs->thread_pid = 0;
|
fs->thread_pid = 0;
|
||||||
fs->thread_is_valid = 0;
|
fs->thread_is_valid = 0;
|
||||||
fs->do_abort = 0;
|
|
||||||
fs->inp = NULL; /* set later */
|
fs->inp = NULL; /* set later */
|
||||||
if (flag & 1)
|
if (flag & 1)
|
||||||
fs->inp_read_size = 32 * 1024;
|
fs->inp_read_size = 32 * 1024;
|
||||||
|
@ -805,12 +757,9 @@ int burn_fifo_fill(struct burn_source *source, int bufsize, int flag)
|
||||||
|
|
||||||
static void offst_free(struct burn_source *source);
|
static void offst_free(struct burn_source *source);
|
||||||
|
|
||||||
/* @param flag bit0 = do not check for burn_source_offst, do not return NULL
|
static struct burn_source_offst *offst_auth(struct burn_source *source)
|
||||||
*/
|
|
||||||
static struct burn_source_offst *offst_auth(struct burn_source *source,
|
|
||||||
int flag)
|
|
||||||
{
|
{
|
||||||
if (source->free_data != offst_free && !(flag & 1)) {
|
if (source->free_data != offst_free) {
|
||||||
libdax_msgs_submit(libdax_messenger, -1, 0x0002017a,
|
libdax_msgs_submit(libdax_messenger, -1, 0x0002017a,
|
||||||
LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH,
|
LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
"Expected offset source object as parameter",
|
"Expected offset source object as parameter",
|
||||||
|
@ -824,21 +773,18 @@ static off_t offst_get_size(struct burn_source *source)
|
||||||
{
|
{
|
||||||
struct burn_source_offst *fs;
|
struct burn_source_offst *fs;
|
||||||
|
|
||||||
if ((fs = offst_auth(source, 0)) == NULL)
|
if ((fs = offst_auth(source)) == NULL)
|
||||||
return (off_t) 0;
|
return (off_t) 0;
|
||||||
return fs->nominal_size;
|
return fs->size;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int offst_set_size(struct burn_source *source, off_t size)
|
static int offst_set_size(struct burn_source *source, off_t size)
|
||||||
{
|
{
|
||||||
struct burn_source_offst *fs;
|
struct burn_source_offst *fs;
|
||||||
|
|
||||||
if ((fs = offst_auth(source, 0)) == NULL)
|
if ((fs = offst_auth(source)) == NULL)
|
||||||
return 0;
|
return 0;
|
||||||
|
fs->size = size;
|
||||||
fs->nominal_size = size;
|
|
||||||
if (fs->size <= 0 || fs->size_adjustable)
|
|
||||||
fs->size = size;
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -846,12 +792,12 @@ static void offst_free(struct burn_source *source)
|
||||||
{
|
{
|
||||||
struct burn_source_offst *fs;
|
struct burn_source_offst *fs;
|
||||||
|
|
||||||
if ((fs = offst_auth(source, 0)) == NULL)
|
if ((fs = offst_auth(source)) == NULL)
|
||||||
return;
|
return;
|
||||||
if (fs->prev != NULL)
|
if (fs->prev != NULL)
|
||||||
offst_auth(fs->prev, 1)->next = fs->next;
|
offst_auth(fs->prev)->next = fs->next;
|
||||||
if (fs->next != NULL)
|
if (fs->next != NULL)
|
||||||
offst_auth(fs->next, 1)->prev = fs->prev;
|
offst_auth(fs->next)->prev = fs->prev;
|
||||||
if (fs->inp != NULL)
|
if (fs->inp != NULL)
|
||||||
burn_source_free(fs->inp); /* i.e. decrement refcount */
|
burn_source_free(fs->inp); /* i.e. decrement refcount */
|
||||||
free(source->data);
|
free(source->data);
|
||||||
|
@ -863,13 +809,13 @@ static int offst_read(struct burn_source *source, unsigned char *buffer,
|
||||||
int ret, to_read, todo;
|
int ret, to_read, todo;
|
||||||
struct burn_source_offst *fs;
|
struct burn_source_offst *fs;
|
||||||
|
|
||||||
if ((fs = offst_auth(source, 0)) == NULL)
|
if ((fs = offst_auth(source)) == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
/* Eventually skip bytes up to start position */;
|
/* Eventually skip bytes up to start position */;
|
||||||
if (!fs->running) {
|
if (!fs->running) {
|
||||||
if (fs->prev != NULL)
|
if (fs->prev != NULL)
|
||||||
fs->pos = offst_auth(fs->prev, 1)->pos;
|
fs->pos = offst_auth(fs->prev)->pos;
|
||||||
fs->running= 1;
|
fs->running= 1;
|
||||||
}
|
}
|
||||||
if(fs->pos < fs->start) {
|
if(fs->pos < fs->start) {
|
||||||
|
@ -904,7 +850,7 @@ static int offst_cancel(struct burn_source *source)
|
||||||
int ret;
|
int ret;
|
||||||
struct burn_source_offst *fs;
|
struct burn_source_offst *fs;
|
||||||
|
|
||||||
if ((fs = offst_auth(source, 0)) == NULL)
|
if ((fs = offst_auth(source)) == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
ret = burn_source_cancel(fs->inp);
|
ret = burn_source_cancel(fs->inp);
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -918,7 +864,7 @@ struct burn_source *burn_offst_source_new(
|
||||||
struct burn_source_offst *fs, *prev_fs = NULL;
|
struct burn_source_offst *fs, *prev_fs = NULL;
|
||||||
|
|
||||||
if (prev != NULL)
|
if (prev != NULL)
|
||||||
if ((prev_fs = offst_auth(prev, 0)) == NULL)
|
if ((prev_fs = offst_auth(prev)) == NULL)
|
||||||
return NULL; /* Not type burn_source_offst */
|
return NULL; /* Not type burn_source_offst */
|
||||||
|
|
||||||
fs = calloc(1, sizeof(struct burn_source_offst));
|
fs = calloc(1, sizeof(struct burn_source_offst));
|
||||||
|
@ -943,7 +889,7 @@ struct burn_source *burn_offst_source_new(
|
||||||
fs->next = NULL;
|
fs->next = NULL;
|
||||||
if (prev != NULL) {
|
if (prev != NULL) {
|
||||||
if (prev_fs->next != NULL) {
|
if (prev_fs->next != NULL) {
|
||||||
offst_auth(prev_fs->next, 1)->prev = src;
|
offst_auth(prev_fs->next)->prev = src;
|
||||||
fs->next = prev_fs->next;
|
fs->next = prev_fs->next;
|
||||||
}
|
}
|
||||||
prev_fs->next = src;
|
prev_fs->next = src;
|
||||||
|
@ -957,8 +903,6 @@ struct burn_source *burn_offst_source_new(
|
||||||
}
|
}
|
||||||
fs->start = start;
|
fs->start = start;
|
||||||
fs->size = size;
|
fs->size = size;
|
||||||
fs->size_adjustable = !(flag & 1);
|
|
||||||
fs->nominal_size = size;
|
|
||||||
fs->running = 0;
|
fs->running = 0;
|
||||||
fs->pos = 0;
|
fs->pos = 0;
|
||||||
inp->refcount++; /* make sure inp lives longer than src */
|
inp->refcount++; /* make sure inp lives longer than src */
|
||||||
|
@ -966,159 +910,3 @@ struct burn_source *burn_offst_source_new(
|
||||||
return src;
|
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||||
|
|
||||||
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
|
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
|
||||||
Copyright (c) 2006 - 2017 Thomas Schmitt <scdbackup@gmx.net>
|
Copyright (c) 2006 - 2010 Thomas Schmitt <scdbackup@gmx.net>
|
||||||
Provided under GPL version 2 or later.
|
Provided under GPL version 2 or later.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -27,8 +27,8 @@ struct burn_source_fifo {
|
||||||
/* The fifo stays inactive and unequipped with eventual resources
|
/* The fifo stays inactive and unequipped with eventual resources
|
||||||
until its read() method is called for the first time.
|
until its read() method is called for the first time.
|
||||||
Only then burn_fifo_start() gets called, allocates the complete
|
Only then burn_fifo_start() gets called, allocates the complete
|
||||||
resources, starts a thread with burn_fifo_source_shoveller()
|
resources, starts a thread with burn_fifo_source_shuffler()
|
||||||
which shovels data and finally destroys the resources.
|
which shuffles data and finally destroys the resources.
|
||||||
This late start is to stay modest in case of multiple tracks
|
This late start is to stay modest in case of multiple tracks
|
||||||
in one disc.
|
in one disc.
|
||||||
*/
|
*/
|
||||||
|
@ -38,9 +38,6 @@ struct burn_source_fifo {
|
||||||
int thread_pid;
|
int thread_pid;
|
||||||
int thread_is_valid;
|
int thread_is_valid;
|
||||||
|
|
||||||
/* The shoveller aborts if this is 1. Resource leaks are possible. */
|
|
||||||
volatile int do_abort;
|
|
||||||
|
|
||||||
/* the burn_source for which this fifo is acting as proxy */
|
/* the burn_source for which this fifo is acting as proxy */
|
||||||
struct burn_source *inp;
|
struct burn_source *inp;
|
||||||
int inp_read_size;
|
int inp_read_size;
|
||||||
|
@ -85,10 +82,6 @@ struct burn_source_offst {
|
||||||
struct burn_source *prev;
|
struct burn_source *prev;
|
||||||
off_t start;
|
off_t start;
|
||||||
off_t size;
|
off_t size;
|
||||||
int size_adjustable;
|
|
||||||
|
|
||||||
/* for set_size/get_size */
|
|
||||||
off_t nominal_size;
|
|
||||||
|
|
||||||
/* To help offst_free() */
|
/* To help offst_free() */
|
||||||
struct burn_source *next;
|
struct burn_source *next;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||||
|
|
||||||
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
|
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
|
||||||
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.
|
Provided under GPL version 2 or later.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -31,7 +31,6 @@
|
||||||
#include "libburn.h"
|
#include "libburn.h"
|
||||||
#include "drive.h"
|
#include "drive.h"
|
||||||
#include "transport.h"
|
#include "transport.h"
|
||||||
#include "util.h"
|
|
||||||
|
|
||||||
/* ts A60825 : The storage location for back_hacks.h variables. */
|
/* ts A60825 : The storage location for back_hacks.h variables. */
|
||||||
#define BURN_BACK_HACKS_INIT 1
|
#define BURN_BACK_HACKS_INIT 1
|
||||||
|
@ -44,15 +43,12 @@ struct libdax_msgs *libdax_messenger= NULL;
|
||||||
|
|
||||||
int burn_running = 0;
|
int burn_running = 0;
|
||||||
|
|
||||||
double lib_start_time;
|
|
||||||
|
|
||||||
|
|
||||||
/* ts A60813 : GNU/Linux: whether to use O_EXCL on open() of device files
|
/* ts A60813 : GNU/Linux: whether to use O_EXCL on open() of device files
|
||||||
ts B00212 : FreeBSD: whether to use flock(LOCK_EX) after open()
|
ts B00212 : FreeBSD: whether to use flock(LOCK_EX) after open()
|
||||||
*/
|
*/
|
||||||
int burn_sg_open_o_excl = 1;
|
int burn_sg_open_o_excl = 1;
|
||||||
|
|
||||||
/* ts A70403 : GNU/Linux: whether to use fcntl(,F_SETLK,)
|
/* ts A70403 : GNU/Linux: wether to use fcntl(,F_SETLK,)
|
||||||
after open() of device files */
|
after open() of device files */
|
||||||
int burn_sg_fcntl_f_setlk = 1;
|
int burn_sg_fcntl_f_setlk = 1;
|
||||||
|
|
||||||
|
@ -71,7 +67,7 @@ int burn_sg_use_family = 0;
|
||||||
has been thoroughly tested. */
|
has been thoroughly tested. */
|
||||||
int burn_sg_open_o_nonblock = 1;
|
int burn_sg_open_o_nonblock = 1;
|
||||||
|
|
||||||
/* whether to take a busy drive as an error */
|
/* wether to take a busy drive as an error */
|
||||||
/* Caution: this is implemented by a rough hack and eventually leads
|
/* Caution: this is implemented by a rough hack and eventually leads
|
||||||
to unconditional abort of the process */
|
to unconditional abort of the process */
|
||||||
int burn_sg_open_abort_busy = 0;
|
int burn_sg_open_abort_busy = 0;
|
||||||
|
@ -98,7 +94,7 @@ int burn_builtin_signal_action = 0; /* burn_set_signal_handling() */
|
||||||
volatile int burn_builtin_triggered_action = 0; /* burn_is_aborting() */
|
volatile int burn_builtin_triggered_action = 0; /* burn_is_aborting() */
|
||||||
|
|
||||||
|
|
||||||
/* ts A70223 : whether implemented untested profiles are supported */
|
/* ts A70223 : wether implemented untested profiles are supported */
|
||||||
int burn_support_untested_profiles = 0;
|
int burn_support_untested_profiles = 0;
|
||||||
|
|
||||||
/* ts A91111 :
|
/* ts A91111 :
|
||||||
|
@ -112,7 +108,7 @@ int burn_sg_log_scsi = 0;
|
||||||
|
|
||||||
/* ts B10312 :
|
/* ts B10312 :
|
||||||
Whether to map random-access readonly files to drive role 4.
|
Whether to map random-access readonly files to drive role 4.
|
||||||
Else it is role 2 overwritable drive
|
Else it is role 2 overwriteable drive
|
||||||
*/
|
*/
|
||||||
int burn_drive_role_4_allowed = 0;
|
int burn_drive_role_4_allowed = 0;
|
||||||
|
|
||||||
|
@ -140,8 +136,6 @@ int burn_initialize(void)
|
||||||
|
|
||||||
if (burn_running)
|
if (burn_running)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
lib_start_time = burn_get_time(0);
|
|
||||||
burn_support_untested_profiles = 0;
|
burn_support_untested_profiles = 0;
|
||||||
ret = burn_msgs_initialize();
|
ret = burn_msgs_initialize();
|
||||||
if (ret <= 0)
|
if (ret <= 0)
|
||||||
|
@ -353,17 +347,6 @@ int burn_sev_to_text(int severity_number, char **severity_name, int flag)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ts B21214 API */
|
|
||||||
char *burn_list_sev_texts(int flag)
|
|
||||||
{
|
|
||||||
char *sev_list;
|
|
||||||
|
|
||||||
libdax_msgs__sev_to_text(0, &sev_list, 1);
|
|
||||||
return sev_list;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* ts B00224 */
|
/* ts B00224 */
|
||||||
char *burn_util_thread_id(pid_t pid, pthread_t tid, char text[80])
|
char *burn_util_thread_id(pid_t pid, pthread_t tid, char text[80])
|
||||||
{
|
{
|
||||||
|
@ -379,23 +362,6 @@ char *burn_util_thread_id(pid_t pid, pthread_t tid, char text[80])
|
||||||
return text;
|
return text;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ts B20122 */
|
|
||||||
/* @param value 0=return rather than exit(value)
|
|
||||||
*/
|
|
||||||
int burn_abort_exit(int value)
|
|
||||||
{
|
|
||||||
burn_abort(4440, burn_abort_pacifier, abort_message_prefix);
|
|
||||||
fprintf(stderr,
|
|
||||||
"\n%sABORT : Program done. Even if you do not see a shell prompt.\n\n",
|
|
||||||
abort_message_prefix);
|
|
||||||
if (value)
|
|
||||||
exit(value);
|
|
||||||
burn_global_abort_level = -2;
|
|
||||||
return(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int burn_builtin_abort_handler(void *handle, int signum, int flag)
|
int burn_builtin_abort_handler(void *handle, int signum, int flag)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -510,9 +476,13 @@ int burn_builtin_abort_handler(void *handle, int signum, int flag)
|
||||||
"%sABORT : Wait the normal burning time before any kill -9\n",
|
"%sABORT : Wait the normal burning time before any kill -9\n",
|
||||||
abort_message_prefix);
|
abort_message_prefix);
|
||||||
close(0); /* somehow stdin as input blocks abort until EOF */
|
close(0); /* somehow stdin as input blocks abort until EOF */
|
||||||
|
burn_abort(4440, burn_abort_pacifier, abort_message_prefix);
|
||||||
|
|
||||||
burn_abort_exit(0);
|
fprintf(stderr,
|
||||||
return (1);
|
"\n%sABORT : Program done. Even if you do not see a shell prompt.\n\n",
|
||||||
|
abort_message_prefix);
|
||||||
|
burn_global_abort_level = -2;
|
||||||
|
return(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -549,7 +519,7 @@ void burn_set_signal_handling(void *handle, burn_abort_handler_t handler,
|
||||||
if(burn_builtin_signal_action == 0)
|
if(burn_builtin_signal_action == 0)
|
||||||
burn_builtin_signal_action = 1;
|
burn_builtin_signal_action = 1;
|
||||||
Cleanup_set_handlers(handle, (Cleanup_app_handler_T) handler,
|
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_handle = handle;
|
||||||
burn_global_signal_handler = handler;
|
burn_global_signal_handler = handler;
|
||||||
}
|
}
|
||||||
|
@ -580,41 +550,6 @@ int burn_init_catch_on_abort(int flag)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* B20122 */
|
|
||||||
/* Temporarily disable builtin actions 0,1,2 to avoid that burn_abort()
|
|
||||||
waits for its own thread to end grabbing.
|
|
||||||
*/
|
|
||||||
int burn_grab_prepare_sig_action(int *signal_action_mem, int flag)
|
|
||||||
{
|
|
||||||
*signal_action_mem = -1;
|
|
||||||
if (burn_global_signal_handler == burn_builtin_abort_handler &&
|
|
||||||
burn_builtin_signal_action >= 0 &&
|
|
||||||
burn_builtin_signal_action <= 2) {
|
|
||||||
*signal_action_mem = burn_builtin_signal_action;
|
|
||||||
burn_builtin_signal_action = 3;
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* B20122 */
|
|
||||||
/* Re-enable builtin actions 0,1,2 and perform delayed signal reactions
|
|
||||||
*/
|
|
||||||
int burn_grab_restore_sig_action(int signal_action_mem, int flag)
|
|
||||||
{
|
|
||||||
if (signal_action_mem >= 0)
|
|
||||||
burn_builtin_signal_action = signal_action_mem;
|
|
||||||
if (burn_is_aborting(0) && signal_action_mem >= 0) {
|
|
||||||
if (signal_action_mem == 0 || signal_action_mem == 1) {
|
|
||||||
burn_abort_exit(1); /* Never comes back */
|
|
||||||
} else if (signal_action_mem == 2) {
|
|
||||||
burn_builtin_triggered_action = signal_action_mem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* ts A70223 : API */
|
/* ts A70223 : API */
|
||||||
void burn_allow_untested_profiles(int yes)
|
void burn_allow_untested_profiles(int yes)
|
||||||
{
|
{
|
||||||
|
@ -654,7 +589,7 @@ void *burn_alloc_mem(size_t size, size_t count, int flag)
|
||||||
{
|
{
|
||||||
void *pt;
|
void *pt;
|
||||||
|
|
||||||
pt = calloc(count, size);
|
pt = calloc(size, count);
|
||||||
if(pt == NULL)
|
if(pt == NULL)
|
||||||
libdax_msgs_submit(libdax_messenger, -1, 0x00000003,
|
libdax_msgs_submit(libdax_messenger, -1, 0x00000003,
|
||||||
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
|
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
|
|
|
@ -1,18 +1,11 @@
|
||||||
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||||
|
|
||||||
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
|
|
||||||
Copyright (c) 2006 - 2013 Thomas Schmitt <scdbackup@gmx.net>
|
|
||||||
Provided under GPL version 2 or later.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef BURN__INIT_H
|
#ifndef BURN__INIT_H
|
||||||
#define BURN__INIT_H
|
#define BURN__INIT_H
|
||||||
|
|
||||||
extern int burn_running;
|
extern int burn_running;
|
||||||
|
|
||||||
extern double lib_start_time;
|
/** Indicator for burn_drive_get_status() wether a signal hit parts of the
|
||||||
|
|
||||||
/** Indicator for burn_drive_get_status() whether a signal hit parts of the
|
|
||||||
thread team.
|
thread team.
|
||||||
0= all works well ,
|
0= all works well ,
|
||||||
1 to 5 = waiting for eventual signal on control thread
|
1 to 5 = waiting for eventual signal on control thread
|
||||||
|
@ -55,9 +48,4 @@ void *burn_alloc_mem(size_t size, size_t count, int flag);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* B20122 */
|
|
||||||
int burn_grab_prepare_sig_action(int *signal_action_mem, int flag);
|
|
||||||
int burn_grab_restore_sig_action(int signal_action_mem, int flag);
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* BURN__INIT_H */
|
#endif /* BURN__INIT_H */
|
||||||
|
|
1608
libburn/libburn.h
1608
libburn/libburn.h
File diff suppressed because it is too large
Load Diff
|
@ -4,8 +4,6 @@ burn_abort;
|
||||||
burn_abort_pacifier;
|
burn_abort_pacifier;
|
||||||
burn_allow_drive_role_4;
|
burn_allow_drive_role_4;
|
||||||
burn_allow_untested_profiles;
|
burn_allow_untested_profiles;
|
||||||
burn_cdtext_from_session;
|
|
||||||
burn_cdtext_from_packfile;
|
|
||||||
burn_disc_add_session;
|
burn_disc_add_session;
|
||||||
burn_disc_available_space;
|
burn_disc_available_space;
|
||||||
burn_disc_close_damaged;
|
burn_disc_close_damaged;
|
||||||
|
@ -19,8 +17,6 @@ burn_disc_get_bd_spare_info;
|
||||||
burn_disc_get_cd_info;
|
burn_disc_get_cd_info;
|
||||||
burn_disc_get_format_descr;
|
burn_disc_get_format_descr;
|
||||||
burn_disc_get_formats;
|
burn_disc_get_formats;
|
||||||
burn_disc_get_incomplete_sessions;
|
|
||||||
burn_disc_get_leadin_text;
|
|
||||||
burn_disc_get_media_id;
|
burn_disc_get_media_id;
|
||||||
burn_disc_get_msc1;
|
burn_disc_get_msc1;
|
||||||
burn_disc_get_multi_caps;
|
burn_disc_get_multi_caps;
|
||||||
|
@ -32,7 +28,6 @@ burn_disc_get_status;
|
||||||
burn_disc_next_track_is_damaged;
|
burn_disc_next_track_is_damaged;
|
||||||
burn_disc_pretend_blank;
|
burn_disc_pretend_blank;
|
||||||
burn_disc_pretend_full;
|
burn_disc_pretend_full;
|
||||||
burn_disc_pretend_full_uncond;
|
|
||||||
burn_disc_read;
|
burn_disc_read;
|
||||||
burn_disc_read_atip;
|
burn_disc_read_atip;
|
||||||
burn_disc_remove_session;
|
burn_disc_remove_session;
|
||||||
|
@ -45,22 +40,14 @@ burn_drive_convert_fs_adr;
|
||||||
burn_drive_convert_scsi_adr;
|
burn_drive_convert_scsi_adr;
|
||||||
burn_drive_d_get_adr;
|
burn_drive_d_get_adr;
|
||||||
burn_drive_equals_adr;
|
burn_drive_equals_adr;
|
||||||
burn_drive_extract_audio;
|
|
||||||
burn_drive_extract_audio_track;
|
|
||||||
burn_drive_free_speedlist;
|
burn_drive_free_speedlist;
|
||||||
burn_drive_get_adr;
|
burn_drive_get_adr;
|
||||||
burn_drive_get_all_profiles;
|
burn_drive_get_all_profiles;
|
||||||
burn_drive_get_bd_r_pow;
|
|
||||||
burn_drive_get_best_speed;
|
burn_drive_get_best_speed;
|
||||||
burn_drive_get_disc;
|
burn_drive_get_disc;
|
||||||
burn_drive_get_drive_role;
|
burn_drive_get_drive_role;
|
||||||
burn_drive_get_feature;
|
|
||||||
burn_drive_get_feature_codes;
|
|
||||||
burn_drive_get_immed;
|
|
||||||
burn_drive_get_media_sno;
|
|
||||||
burn_drive_get_min_write_speed;
|
burn_drive_get_min_write_speed;
|
||||||
burn_drive_get_read_speed;
|
burn_drive_get_read_speed;
|
||||||
burn_drive_get_serial_no;
|
|
||||||
burn_drive_get_speedlist;
|
burn_drive_get_speedlist;
|
||||||
burn_drive_get_start_end_lba;
|
burn_drive_get_start_end_lba;
|
||||||
burn_drive_get_status;
|
burn_drive_get_status;
|
||||||
|
@ -72,18 +59,13 @@ burn_drive_is_enumerable_adr;
|
||||||
burn_drive_leave_locked;
|
burn_drive_leave_locked;
|
||||||
burn_drive_obtain_scsi_adr;
|
burn_drive_obtain_scsi_adr;
|
||||||
burn_drive_probe_cd_write_modes;
|
burn_drive_probe_cd_write_modes;
|
||||||
burn_drive_re_assess;
|
|
||||||
burn_drive_release;
|
burn_drive_release;
|
||||||
burn_drive_reset_simulate;
|
|
||||||
burn_drive_scan;
|
burn_drive_scan;
|
||||||
burn_drive_scan_and_grab;
|
burn_drive_scan_and_grab;
|
||||||
burn_drive_set_buffer_waiting;
|
burn_drive_set_buffer_waiting;
|
||||||
burn_drive_set_immed;
|
|
||||||
burn_drive_set_speed;
|
burn_drive_set_speed;
|
||||||
burn_drive_set_speed_exact;
|
|
||||||
burn_drive_set_stream_recording;
|
burn_drive_set_stream_recording;
|
||||||
burn_drive_snooze;
|
burn_drive_snooze;
|
||||||
burn_drive_was_feat21_failure;
|
|
||||||
burn_drive_wrote_well;
|
burn_drive_wrote_well;
|
||||||
burn_fd_source_new;
|
burn_fd_source_new;
|
||||||
burn_fifo_fill;
|
burn_fifo_fill;
|
||||||
|
@ -100,15 +82,12 @@ burn_guess_manufacturer;
|
||||||
burn_initialize;
|
burn_initialize;
|
||||||
burn_is_aborting;
|
burn_is_aborting;
|
||||||
burn_lba_to_msf;
|
burn_lba_to_msf;
|
||||||
burn_list_sev_texts;
|
|
||||||
burn_lookup_device_link;
|
burn_lookup_device_link;
|
||||||
burn_make_input_sheet_v07t;
|
|
||||||
burn_msf_to_lba;
|
burn_msf_to_lba;
|
||||||
burn_msf_to_sectors;
|
burn_msf_to_sectors;
|
||||||
burn_msgs_obtain;
|
burn_msgs_obtain;
|
||||||
burn_msgs_set_severities;
|
burn_msgs_set_severities;
|
||||||
burn_msgs_submit;
|
burn_msgs_submit;
|
||||||
burn_nominal_slowdown;
|
|
||||||
burn_obtain_profile_name;
|
burn_obtain_profile_name;
|
||||||
burn_offst_source_new;
|
burn_offst_source_new;
|
||||||
burn_os_alloc_buffer;
|
burn_os_alloc_buffer;
|
||||||
|
@ -117,7 +96,6 @@ burn_os_open_track_src;
|
||||||
burn_precheck_write;
|
burn_precheck_write;
|
||||||
burn_preset_device_open;
|
burn_preset_device_open;
|
||||||
burn_random_access_write;
|
burn_random_access_write;
|
||||||
burn_read_audio;
|
|
||||||
burn_read_data;
|
burn_read_data;
|
||||||
burn_read_opts_free;
|
burn_read_opts_free;
|
||||||
burn_read_opts_new;
|
burn_read_opts_new;
|
||||||
|
@ -132,23 +110,14 @@ burn_read_opts_transfer_damaged_blocks;
|
||||||
burn_scsi_transport_id;
|
burn_scsi_transport_id;
|
||||||
burn_sectors_to_msf;
|
burn_sectors_to_msf;
|
||||||
burn_session_add_track;
|
burn_session_add_track;
|
||||||
burn_session_by_cue_file;
|
|
||||||
burn_session_create;
|
burn_session_create;
|
||||||
burn_session_dispose_cdtext;
|
|
||||||
burn_session_free;
|
burn_session_free;
|
||||||
burn_session_get_cdtext;
|
|
||||||
burn_session_get_cdtext_par;
|
|
||||||
burn_session_get_hidefirst;
|
burn_session_get_hidefirst;
|
||||||
burn_session_get_leadout_entry;
|
burn_session_get_leadout_entry;
|
||||||
burn_session_get_sectors;
|
burn_session_get_sectors;
|
||||||
burn_session_get_start_tno;
|
|
||||||
burn_session_get_tracks;
|
burn_session_get_tracks;
|
||||||
burn_session_hide_first_track;
|
burn_session_hide_first_track;
|
||||||
burn_session_input_sheet_v07t;
|
|
||||||
burn_session_remove_track;
|
burn_session_remove_track;
|
||||||
burn_session_set_cdtext;
|
|
||||||
burn_session_set_cdtext_par;
|
|
||||||
burn_session_set_start_tno;
|
|
||||||
burn_set_messenger;
|
burn_set_messenger;
|
||||||
burn_set_scsi_logging;
|
burn_set_scsi_logging;
|
||||||
burn_set_signal_handling;
|
burn_set_signal_handling;
|
||||||
|
@ -159,26 +128,18 @@ burn_structure_print_disc;
|
||||||
burn_structure_print_session;
|
burn_structure_print_session;
|
||||||
burn_structure_print_track;
|
burn_structure_print_track;
|
||||||
burn_text_to_sev;
|
burn_text_to_sev;
|
||||||
burn_track_clear_indice;
|
|
||||||
burn_track_clear_isrc;
|
burn_track_clear_isrc;
|
||||||
burn_track_create;
|
burn_track_create;
|
||||||
burn_track_define_data;
|
burn_track_define_data;
|
||||||
burn_track_dispose_cdtext;
|
|
||||||
burn_track_free;
|
burn_track_free;
|
||||||
burn_track_get_cdtext;
|
|
||||||
burn_track_get_counters;
|
burn_track_get_counters;
|
||||||
burn_track_get_entry;
|
burn_track_get_entry;
|
||||||
burn_track_get_mode;
|
burn_track_get_mode;
|
||||||
burn_track_get_sectors;
|
burn_track_get_sectors;
|
||||||
burn_track_set_byte_swap;
|
burn_track_set_byte_swap;
|
||||||
burn_track_set_cdxa_conv;
|
burn_track_set_cdxa_conv;
|
||||||
burn_track_set_cdtext;
|
|
||||||
burn_track_set_default_size;
|
burn_track_set_default_size;
|
||||||
burn_track_set_index;
|
|
||||||
burn_track_set_isrc;
|
burn_track_set_isrc;
|
||||||
burn_track_set_isrc_string;
|
|
||||||
burn_track_set_postgap_size;
|
|
||||||
burn_track_set_pregap_size;
|
|
||||||
burn_track_set_size;
|
burn_track_set_size;
|
||||||
burn_track_set_source;
|
burn_track_set_source;
|
||||||
burn_version;
|
burn_version;
|
||||||
|
@ -186,17 +147,13 @@ burn_write_opts_auto_write_type;
|
||||||
burn_write_opts_free;
|
burn_write_opts_free;
|
||||||
burn_write_opts_get_drive;
|
burn_write_opts_get_drive;
|
||||||
burn_write_opts_new;
|
burn_write_opts_new;
|
||||||
burn_write_opts_set_bdr_obs_exempt;
|
|
||||||
burn_write_opts_set_dvd_obs;
|
burn_write_opts_set_dvd_obs;
|
||||||
burn_write_opts_set_fail21h_sev;
|
|
||||||
burn_write_opts_set_fillup;
|
burn_write_opts_set_fillup;
|
||||||
burn_write_opts_set_force;
|
burn_write_opts_set_force;
|
||||||
burn_write_opts_set_format;
|
burn_write_opts_set_format;
|
||||||
burn_write_opts_set_has_mediacatalog;
|
burn_write_opts_set_has_mediacatalog;
|
||||||
burn_write_opts_set_leadin_text;
|
|
||||||
burn_write_opts_set_mediacatalog;
|
burn_write_opts_set_mediacatalog;
|
||||||
burn_write_opts_set_multi;
|
burn_write_opts_set_multi;
|
||||||
burn_write_opts_set_obs_pad;
|
|
||||||
burn_write_opts_set_perform_opc;
|
burn_write_opts_set_perform_opc;
|
||||||
burn_write_opts_set_simulate;
|
burn_write_opts_set_simulate;
|
||||||
burn_write_opts_set_start_byte;
|
burn_write_opts_set_start_byte;
|
||||||
|
@ -213,13 +170,3 @@ libdax_audioxtr_new;
|
||||||
libdax_audioxtr_read;
|
libdax_audioxtr_read;
|
||||||
local: *;
|
local: *;
|
||||||
};
|
};
|
||||||
|
|
||||||
LIBBURN4_1.5.8 {
|
|
||||||
burn_disc_get_sectors_v2;
|
|
||||||
burn_disc_track_lba_nwa_v2;
|
|
||||||
burn_drive_get_status_v2;
|
|
||||||
burn_get_read_capacity_v2;
|
|
||||||
burn_session_get_sectors_v2;
|
|
||||||
burn_track_get_sectors_v2;
|
|
||||||
} LIBBURN4;
|
|
||||||
|
|
||||||
|
|
|
@ -17,10 +17,6 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <errno.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"
|
#include "libdax_msgs.h"
|
||||||
extern struct libdax_msgs *libdax_messenger;
|
extern struct libdax_msgs *libdax_messenger;
|
||||||
|
@ -55,7 +51,6 @@ int libdax_audioxtr_new(struct libdax_audioxtr **xtr, char *path, int flag)
|
||||||
o->bits_per_sample= 0;
|
o->bits_per_sample= 0;
|
||||||
o->msb_first= 0;
|
o->msb_first= 0;
|
||||||
|
|
||||||
o->wav_data_location= 44;
|
|
||||||
o->wav_subchunk2_size= 0;
|
o->wav_subchunk2_size= 0;
|
||||||
|
|
||||||
o->au_data_location= 0;
|
o->au_data_location= 0;
|
||||||
|
@ -95,7 +90,7 @@ static int libdax_audioxtr_open(struct libdax_audioxtr *o, int flag)
|
||||||
if(strcmp(o->path,"-")==0)
|
if(strcmp(o->path,"-")==0)
|
||||||
o->fd= 0;
|
o->fd= 0;
|
||||||
else
|
else
|
||||||
o->fd= open(o->path, O_RDONLY | O_BINARY);
|
o->fd= open(o->path, O_RDONLY);
|
||||||
if(o->fd<0) {
|
if(o->fd<0) {
|
||||||
sprintf(msg,"Cannot open audio source file : %s",o->path);
|
sprintf(msg,"Cannot open audio source file : %s",o->path);
|
||||||
libdax_msgs_submit(libdax_messenger,-1,0x00020200,
|
libdax_msgs_submit(libdax_messenger,-1,0x00020200,
|
||||||
|
@ -122,123 +117,47 @@ static int libdax_audioxtr_open(struct libdax_audioxtr *o, int flag)
|
||||||
return(1);
|
return(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* @param flag: bit0= sequential file, skip by reading data
|
|
||||||
*/
|
|
||||||
static int libdax_audioxtr_skip(struct libdax_audioxtr *o,
|
|
||||||
off_t *old_pos,
|
|
||||||
off_t pos, int flag)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
size_t to_read;
|
|
||||||
static char buf[256]; /* Thread safe because the content does not matter */
|
|
||||||
|
|
||||||
if((flag & 1) || o->fd == 0) { /* stdin */
|
|
||||||
while(pos - *old_pos > 0) {
|
|
||||||
to_read= pos - *old_pos;
|
|
||||||
if(to_read > sizeof(buf))
|
|
||||||
to_read= sizeof(buf);
|
|
||||||
ret= read(o->fd, buf, to_read);
|
|
||||||
if(ret < (int) to_read)
|
|
||||||
return(0);
|
|
||||||
*old_pos+= to_read;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
ret= lseek(o->fd, pos, SEEK_SET);
|
|
||||||
if(ret == -1)
|
|
||||||
return(0);
|
|
||||||
*old_pos= pos;
|
|
||||||
}
|
|
||||||
return(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int libdax_audioxtr_identify_wav(struct libdax_audioxtr *o, int flag)
|
static int libdax_audioxtr_identify_wav(struct libdax_audioxtr *o, int flag)
|
||||||
{
|
{
|
||||||
int ret, fmt_seen= 0, data_seen= 0;
|
int ret;
|
||||||
off_t pos= 0, old_pos= 0, riff_end= 0;
|
char buf[45];
|
||||||
char buf[16];
|
|
||||||
unsigned char *ubuf;
|
|
||||||
|
|
||||||
/* check whether this is a MS WAVE file .wav */
|
/* check wether this is a MS WAVE file .wav */
|
||||||
/* info used: http://ccrma.stanford.edu/courses/422/projects/WaveFormat/
|
/* info used: http://ccrma.stanford.edu/courses/422/projects/WaveFormat/ */
|
||||||
https://en.wikipedia.org/wiki/WAV
|
|
||||||
see summary in: doc/waveformat.txt
|
|
||||||
*/
|
|
||||||
ubuf= (unsigned char *) buf;
|
|
||||||
|
|
||||||
/* Look for ChunkID "RIFF" , tolerate other known chunks */
|
if(o->fd!=0) {
|
||||||
while(1) {
|
ret= lseek(o->fd,0,SEEK_SET);
|
||||||
ret= libdax_audioxtr_skip(o, &old_pos, pos, 0);
|
if(ret==-1)
|
||||||
if(ret <= 0)
|
|
||||||
return(0);
|
return(0);
|
||||||
ret= read(o->fd, buf, 8);
|
|
||||||
if(ret < 8)
|
|
||||||
return(0);
|
|
||||||
old_pos+= 8;
|
|
||||||
pos= old_pos + libdax_audioxtr_to_int(o, ubuf + 4, 4, 0);
|
|
||||||
if(pos > 0xffffffff || pos - old_pos < 4) /* Too large or no Format word */
|
|
||||||
return(0);
|
|
||||||
if(strncmp(buf, "RIFF", 4) == 0)
|
|
||||||
break;
|
|
||||||
/* Wikipedia mentions these known ChunkId values */
|
|
||||||
if(strncmp(buf, "INFO", 4) == 0 ||
|
|
||||||
strncmp(buf, "CSET", 4) == 0 ||
|
|
||||||
strncmp(buf, "JUNK", 4) == 0 ||
|
|
||||||
strncmp(buf, "PAD ", 4) == 0)
|
|
||||||
continue;
|
|
||||||
return(0);
|
|
||||||
}
|
}
|
||||||
|
ret= read(o->fd, buf, 44);
|
||||||
/* Read RIFF Format header */
|
if(ret<44)
|
||||||
ret= read(o->fd, buf, 4);
|
|
||||||
if(ret < 4)
|
|
||||||
return(0);
|
return(0);
|
||||||
old_pos+= 4;
|
buf[44]= 0; /* as stopper for any string operations */
|
||||||
if(strncmp(buf, "WAVE", 4) != 0) /* Format */
|
|
||||||
|
if(strncmp(buf,"RIFF",4)!=0) /* ChunkID */
|
||||||
|
return(0);
|
||||||
|
if(strncmp(buf+8,"WAVE",4)!=0) /* Format */
|
||||||
|
return(0);
|
||||||
|
if(strncmp(buf+12,"fmt ",4)!=0) /* Subchunk1ID */
|
||||||
|
return(0);
|
||||||
|
if(buf[16]!=16 || buf[17]!=0 || buf[18]!=0 || buf[19]!=0) /* Subchunk1Size */
|
||||||
|
return(0);
|
||||||
|
if(buf[20]!=1 || buf[21]!=0) /* AudioFormat must be 1 (Linear quantization) */
|
||||||
return(0);
|
return(0);
|
||||||
riff_end= pos;
|
|
||||||
|
|
||||||
/* Look for SubchunkID "fmt " and "data" */
|
strcpy(o->fmt,".wav");
|
||||||
pos= old_pos;
|
o->msb_first= 0;
|
||||||
while(old_pos < riff_end) {
|
o->num_channels= libdax_audioxtr_to_int(o,(unsigned char *) buf+22,2,0);
|
||||||
ret= libdax_audioxtr_skip(o, &old_pos, pos, 0);
|
o->sample_rate= libdax_audioxtr_to_int(o,(unsigned char *) buf+24,4,0);
|
||||||
if(ret <= 0)
|
o->bits_per_sample= libdax_audioxtr_to_int(o,(unsigned char *)buf+34,2,0);
|
||||||
return(0);
|
sprintf(o->fmt_info,
|
||||||
ret= read(o->fd, buf, 8);
|
".wav , num_channels=%d , sample_rate=%d , bits_per_sample=%d",
|
||||||
if(ret < 8)
|
o->num_channels,o->sample_rate,o->bits_per_sample);
|
||||||
return(0);
|
o->wav_subchunk2_size= libdax_audioxtr_to_int(o,(unsigned char *)buf+40,4,0);
|
||||||
old_pos= pos + 8;
|
o->data_size= o->wav_subchunk2_size;
|
||||||
pos= old_pos + libdax_audioxtr_to_int(o, ubuf + 4, 4, 0); /* SubchunkSize */
|
return(1);
|
||||||
|
|
||||||
if(strncmp(buf,"fmt ", 4) == 0) {
|
|
||||||
if(pos - old_pos < 16)
|
|
||||||
return(0);
|
|
||||||
ret= read(o->fd, buf, 16);
|
|
||||||
if(ret < 16)
|
|
||||||
return(0);
|
|
||||||
old_pos+= 16;
|
|
||||||
if(buf[0]!=1 || buf[1]!=0) /* AudioFormat (1 = Linear quantization) */
|
|
||||||
return(0);
|
|
||||||
o->msb_first= 0;
|
|
||||||
o->num_channels= libdax_audioxtr_to_int(o, ubuf + 2 , 2, 0);
|
|
||||||
o->sample_rate= libdax_audioxtr_to_int(o, ubuf + 4, 4, 0);
|
|
||||||
o->bits_per_sample= libdax_audioxtr_to_int(o, ubuf + 14, 2, 0);
|
|
||||||
sprintf(o->fmt_info,
|
|
||||||
".wav , num_channels=%d , sample_rate=%d , bits_per_sample=%d",
|
|
||||||
o->num_channels, o->sample_rate, o->bits_per_sample);
|
|
||||||
fmt_seen= 1;
|
|
||||||
|
|
||||||
} else if(strncmp(buf,"data", 4) == 0) {
|
|
||||||
o->wav_data_location= old_pos;
|
|
||||||
o->wav_subchunk2_size= pos - old_pos;
|
|
||||||
o->data_size= o->wav_subchunk2_size;
|
|
||||||
data_seen= 1;
|
|
||||||
}
|
|
||||||
if(fmt_seen && data_seen) {
|
|
||||||
strcpy(o->fmt,".wav");
|
|
||||||
return(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return(0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -247,7 +166,7 @@ static int libdax_audioxtr_identify_au(struct libdax_audioxtr *o, int flag)
|
||||||
int ret,encoding;
|
int ret,encoding;
|
||||||
char buf[24];
|
char buf[24];
|
||||||
|
|
||||||
/* Check whether this is a Sun Audio, .au file */
|
/* Check wether this is a Sun Audio, .au file */
|
||||||
/* info used: http://ccrma.stanford.edu/courses/422/projects/WaveFormat/ */
|
/* info used: http://ccrma.stanford.edu/courses/422/projects/WaveFormat/ */
|
||||||
|
|
||||||
if(o->fd!=0) {
|
if(o->fd!=0) {
|
||||||
|
@ -285,6 +204,10 @@ static int libdax_audioxtr_identify_au(struct libdax_audioxtr *o, int flag)
|
||||||
sprintf(o->fmt_info,
|
sprintf(o->fmt_info,
|
||||||
".au , num_channels=%d , sample_rate=%d , bits_per_sample=%d",
|
".au , num_channels=%d , sample_rate=%d , bits_per_sample=%d",
|
||||||
o->num_channels,o->sample_rate,o->bits_per_sample);
|
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 */
|
return(o->bits_per_sample>0); /* Audio format must be linear PCM */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -333,7 +256,7 @@ static int libdax_audioxtr_init_reading(struct libdax_audioxtr *o, int flag)
|
||||||
|
|
||||||
o->extract_count= 0;
|
o->extract_count= 0;
|
||||||
if(strcmp(o->fmt,".wav")==0)
|
if(strcmp(o->fmt,".wav")==0)
|
||||||
ret= lseek(o->fd, o->wav_data_location, SEEK_SET);
|
ret= lseek(o->fd,44,SEEK_SET);
|
||||||
else if(strcmp(o->fmt,".au")==0)
|
else if(strcmp(o->fmt,".au")==0)
|
||||||
ret= lseek(o->fd,o->au_data_location,SEEK_SET);
|
ret= lseek(o->fd,o->au_data_location,SEEK_SET);
|
||||||
else
|
else
|
||||||
|
|
|
@ -38,7 +38,7 @@ struct libdax_audioxtr;
|
||||||
/* Calls from applications (to be forwarded by libdax/libburn) */
|
/* Calls from applications (to be forwarded by libdax/libburn) */
|
||||||
|
|
||||||
|
|
||||||
/** Open an audio file, check whether suitable, create extractor object.
|
/** Open an audio file, check wether suitable, create extractor object.
|
||||||
@param xtr Opaque handle to extractor. Gets attached extractor object.
|
@param xtr Opaque handle to extractor. Gets attached extractor object.
|
||||||
@param path Address of the audio file to extract. "-" is stdin (but might
|
@param path Address of the audio file to extract. "-" is stdin (but might
|
||||||
be not suitable for all futurely supported formats).
|
be not suitable for all futurely supported formats).
|
||||||
|
@ -176,10 +176,7 @@ struct libdax_audioxtr {
|
||||||
/* Format dependent parameters */
|
/* Format dependent parameters */
|
||||||
|
|
||||||
/* MS WAVE Format */
|
/* MS WAVE Format */
|
||||||
/* see description in: doc/waveformat.txt */
|
/* info used: http://ccrma.stanford.edu/courses/422/projects/WaveFormat/ */
|
||||||
|
|
||||||
/* Offset to "data" subchunk */
|
|
||||||
unsigned int wav_data_location;
|
|
||||||
|
|
||||||
/* == NumSamples * NumChannels * BitsPerSample/8
|
/* == NumSamples * NumChannels * BitsPerSample/8
|
||||||
This is the number of bytes in the data. */
|
This is the number of bytes in the data. */
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
|
|
||||||
/* libdax_msgs
|
/* libdax_msgs
|
||||||
Message handling facility of libdax.
|
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.
|
provided under GPL version 2 or later.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -34,13 +34,14 @@ static int libdax_msgs_item_new(struct libdax_msgs_item **item,
|
||||||
int ret;
|
int ret;
|
||||||
struct libdax_msgs_item *o;
|
struct libdax_msgs_item *o;
|
||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
|
struct timezone tz;
|
||||||
|
|
||||||
(*item)= o=
|
(*item)= o=
|
||||||
(struct libdax_msgs_item *) calloc(1, sizeof(struct libdax_msgs_item));
|
(struct libdax_msgs_item *) calloc(1, sizeof(struct libdax_msgs_item));
|
||||||
if(o==NULL)
|
if(o==NULL)
|
||||||
return(-1);
|
return(-1);
|
||||||
o->timestamp= 0.0;
|
o->timestamp= 0.0;
|
||||||
ret= gettimeofday(&tv, NULL);
|
ret= gettimeofday(&tv,&tz);
|
||||||
if(ret==0)
|
if(ret==0)
|
||||||
o->timestamp= tv.tv_sec+0.000001*tv.tv_usec;
|
o->timestamp= tv.tv_sec+0.000001*tv.tv_usec;
|
||||||
o->process_id= getpid();
|
o->process_id= getpid();
|
||||||
|
@ -288,7 +289,7 @@ int libdax_msgs__sev_to_text(int severity, char **severity_name,
|
||||||
int flag)
|
int flag)
|
||||||
{
|
{
|
||||||
if(flag&1) {
|
if(flag&1) {
|
||||||
*severity_name= "ALL ERRFILE DEBUG UPDATE NOTE HINT WARNING SORRY MISHAP FAILURE FATAL ABORT NEVER";
|
*severity_name= "NEVER\nABORT\nFATAL\nFAILURE\nMISHAP\nSORRY\nWARNING\nHINT\nNOTE\nUPDATE\nDEBUG\nERRFILE\nALL";
|
||||||
return(1);
|
return(1);
|
||||||
}
|
}
|
||||||
*severity_name= "";
|
*severity_name= "";
|
||||||
|
@ -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 libdax_msgs_submit(struct libdax_msgs *m, int origin, int error_code,
|
||||||
int severity, int priority, char *msg_text,
|
int severity, int priority, char *msg_text,
|
||||||
int os_errno, int flag)
|
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)
|
if(ret>0)
|
||||||
sprintf(sev_text,"%s : ",sev_name);
|
sprintf(sev_text,"%s : ",sev_name);
|
||||||
|
|
||||||
fprintf(stderr, "%s%s%s%c", m->print_id, sev_text, textpt,
|
fprintf(stderr,"%s%s%s\n",m->print_id,sev_text,textpt);
|
||||||
(flag & 1) ? '\r' : '\n');
|
|
||||||
if(os_errno!=0) {
|
if(os_errno!=0) {
|
||||||
ret= libdax_msgs_lock(m,0);
|
ret= libdax_msgs_lock(m,0);
|
||||||
if(ret<=0)
|
if(ret<=0)
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
|
|
||||||
/* libdax_msgs
|
/* libdax_msgs
|
||||||
Message handling facility of libburn and libisofs.
|
Message handling facility of libdax.
|
||||||
Copyright (C) 2006-2021 Thomas Schmitt <scdbackup@gmx.net>,
|
Copyright (C) 2006-2011 Thomas Schmitt <scdbackup@gmx.net>,
|
||||||
provided under GPL version 2 or later.
|
provided under GPL version 2 or later.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -266,9 +266,8 @@ int libdax_msgs_new(struct libdax_msgs **m, int flag);
|
||||||
|
|
||||||
/** Destroy a message handling facility and all its eventual messages.
|
/** Destroy a message handling facility and all its eventual messages.
|
||||||
The submitted pointer gets set to NULL.
|
The submitted pointer gets set to NULL.
|
||||||
Actually only the last destroy call of all official references to the
|
Actually only the last destroy call of all offical references to the object
|
||||||
object will really dispose it. All others just decrement the reference
|
will really dispose it. All others just decrement the reference counter.
|
||||||
counter.
|
|
||||||
Call this function only with official reference pointers obtained by
|
Call this function only with official reference pointers obtained by
|
||||||
libdax_msgs_new() or libdax_msgs_refer(), and only once per such pointer.
|
libdax_msgs_new() or libdax_msgs_refer(), and only once per such pointer.
|
||||||
@param flag Bitfield for control purposes (unused yet, submit 0)
|
@param flag Bitfield for control purposes (unused yet, submit 0)
|
||||||
|
@ -303,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 priority The LIBDAX_MSGS_PRIO_* number of the event.
|
||||||
@param msg_text Printable and human readable message text.
|
@param msg_text Printable and human readable message text.
|
||||||
@param os_errno Eventual error code from operating system (0 if none)
|
@param os_errno Eventual error code from operating system (0 if none)
|
||||||
@param flag Bitfield for control purposes
|
@param flag Bitfield for control purposes (unused yet, submit 0)
|
||||||
bit0= If direct output to stderr:
|
|
||||||
CarriageReturn rather than LineFeed
|
|
||||||
@return 1 on success, 0 on rejection, <0 for severe errors
|
@return 1 on success, 0 on rejection, <0 for severe errors
|
||||||
*/
|
*/
|
||||||
int libdax_msgs_submit(struct libdax_msgs *m, int origin, int error_code,
|
int libdax_msgs_submit(struct libdax_msgs *m, int origin, int error_code,
|
||||||
|
@ -319,7 +316,7 @@ int libdax_msgs_submit(struct libdax_msgs *m, int origin, int error_code,
|
||||||
|
|
||||||
/** Convert a registered severity number into a severity name
|
/** Convert a registered severity number into a severity name
|
||||||
@param flag Bitfield for control purposes:
|
@param flag Bitfield for control purposes:
|
||||||
bit0= list all severity names in a blank separated string
|
bit0= list all severity names in a newline separated string
|
||||||
@return >0 success, <=0 failure
|
@return >0 success, <=0 failure
|
||||||
*/
|
*/
|
||||||
int libdax_msgs__sev_to_text(int severity, char **severity_name,
|
int libdax_msgs__sev_to_text(int severity, char **severity_name,
|
||||||
|
@ -414,7 +411,6 @@ Range "libdax_msgs" : 0x00000000 to 0x0000ffff
|
||||||
0x00000001 (DEBUG,ZERO) = Test error message
|
0x00000001 (DEBUG,ZERO) = Test error message
|
||||||
0x00000002 (DEBUG,ZERO) = Debugging message
|
0x00000002 (DEBUG,ZERO) = Debugging message
|
||||||
0x00000003 (FATAL,HIGH) = Out of virtual memory
|
0x00000003 (FATAL,HIGH) = Out of virtual memory
|
||||||
0x00000004 (FATAL,HIGH) = Generic fatal error
|
|
||||||
|
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
|
@ -425,7 +421,7 @@ Range "elmom" : 0x00010000 to 0x0001ffff
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
Range "scdbackup" : 0x00020000 to 0x0002ffff
|
Range "scdbackup" : 0x00020000 to 0x0002ffff
|
||||||
|
|
||||||
Accessing and defending drives:
|
Acessing and defending drives:
|
||||||
|
|
||||||
0x00020001 (SORRY,LOW) = Cannot open busy device
|
0x00020001 (SORRY,LOW) = Cannot open busy device
|
||||||
0x00020002 (SORRY,HIGH) = Encountered error when closing drive
|
0x00020002 (SORRY,HIGH) = Encountered error when closing drive
|
||||||
|
@ -440,7 +436,6 @@ Range "scdbackup" : 0x00020000 to 0x0002ffff
|
||||||
0x0002000b (FAILURE,HIGH) = File object '...' not found
|
0x0002000b (FAILURE,HIGH) = File object '...' not found
|
||||||
0x0002000c (FAILURE,HIGH) = Cannot start device file enumeration
|
0x0002000c (FAILURE,HIGH) = Cannot start device file enumeration
|
||||||
0x0002000d (FAILURE,HIGH) = Cannot enumerate next device
|
0x0002000d (FAILURE,HIGH) = Cannot enumerate next device
|
||||||
0x0002000e (NOTE,HIGH) = Failed to open device during
|
|
||||||
|
|
||||||
General library operations:
|
General library operations:
|
||||||
|
|
||||||
|
@ -478,7 +473,7 @@ Range "scdbackup" : 0x00020000 to 0x0002ffff
|
||||||
0x0002011f (SORRY,HIGH) = Burning is restricted to a single track
|
0x0002011f (SORRY,HIGH) = Burning is restricted to a single track
|
||||||
0x00020120 (NOTE,HIGH) = FORMAT UNIT ignored
|
0x00020120 (NOTE,HIGH) = FORMAT UNIT ignored
|
||||||
0x00020121 (FATAL,HIGH) = Write preparation setup failed
|
0x00020121 (FATAL,HIGH) = Write preparation setup failed
|
||||||
0x00020122 (FAILURE,HIGH) = SCSI error on format_unit
|
0x00020122 (FATAL,HIGH) = SCSI error on format_unit
|
||||||
0x00020123 (SORRY,HIGH) = DVD Media are unsuitable for desired track type
|
0x00020123 (SORRY,HIGH) = DVD Media are unsuitable for desired track type
|
||||||
0x00020124 (SORRY,HIGH) = SCSI error on set_streaming
|
0x00020124 (SORRY,HIGH) = SCSI error on set_streaming
|
||||||
0x00020125 (SORRY,HIGH) = Write start address not supported
|
0x00020125 (SORRY,HIGH) = Write start address not supported
|
||||||
|
@ -521,8 +516,8 @@ Range "scdbackup" : 0x00020000 to 0x0002ffff
|
||||||
0x0002014a (SORRY,HIGH) = Cannot read desired amount of data
|
0x0002014a (SORRY,HIGH) = Cannot read desired amount of data
|
||||||
0x0002014b (SORRY,HIGH) = Drive is already registered resp. scanned
|
0x0002014b (SORRY,HIGH) = Drive is already registered resp. scanned
|
||||||
0x0002014c (FATAL,HIGH) = Emulated drive caught in SCSI function
|
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
|
0x0002014f (SORRY,HIGH) = Timeout with asynchromous SCSI command
|
||||||
0x00020150 (DEBUG,LOW) = Reporting asynchronous waiting time
|
0x00020150 (DEBUG,LOW) = Reporting asynchronous waiting time
|
||||||
0x00020151 (FAILURE,HIGH) = Read attempt on write-only drive
|
0x00020151 (FAILURE,HIGH) = Read attempt on write-only drive
|
||||||
0x00020152 (FATAL,HIGH) = Cannot start fifo thread
|
0x00020152 (FATAL,HIGH) = Cannot start fifo thread
|
||||||
|
@ -555,7 +550,7 @@ Range "scdbackup" : 0x00020000 to 0x0002ffff
|
||||||
0x0002016e (DEBUG,HIGH) = MODE SENSE page 2A too short
|
0x0002016e (DEBUG,HIGH) = MODE SENSE page 2A too short
|
||||||
0x0002016f (DEBUG,HIGH) = Unable to grab scanned drive
|
0x0002016f (DEBUG,HIGH) = Unable to grab scanned drive
|
||||||
0x00020170 (NOTE,HIGH) = Closing open session before writing new one
|
0x00020170 (NOTE,HIGH) = Closing open session before writing new one
|
||||||
0x00020171 (NOTE,HIGH) = Closing BD-R with accidentally open session
|
0x00020171 (NOTE,HIGH) = Closing BD-R with accidently open session
|
||||||
0x00020172 (SORRY,HIGH) = Read start address larger than number of readable blocks
|
0x00020172 (SORRY,HIGH) = Read start address larger than number of readable blocks
|
||||||
0x00020173 (FAILURE,HIGH) = Drive tells NWA smaller than last written address
|
0x00020173 (FAILURE,HIGH) = Drive tells NWA smaller than last written address
|
||||||
0x00020174 (SORRY,HIGH) = Fifo alignment does not allow desired read size
|
0x00020174 (SORRY,HIGH) = Fifo alignment does not allow desired read size
|
||||||
|
@ -579,45 +574,6 @@ Range "scdbackup" : 0x00020000 to 0x0002ffff
|
||||||
0x00020186 (WARNING,HIGH) = Track damaged and not closed
|
0x00020186 (WARNING,HIGH) = Track damaged and not closed
|
||||||
0x00020187 (NOTE,HIGH) = Track not marked as damaged. No action taken.
|
0x00020187 (NOTE,HIGH) = Track not marked as damaged. No action taken.
|
||||||
0x00020188 (FAILURE,HIGH) = Cannot close damaged track on given media type
|
0x00020188 (FAILURE,HIGH) = Cannot close damaged track on given media type
|
||||||
0x00020189 (FATAL,HIGH) = Drive is already grabbed by libburn
|
|
||||||
0x0002018a (SORRY,HIGH) = Timeout exceeded. Retry canceled.
|
|
||||||
0x0002018b (FAILURE,HIGH) = Too many CD-TEXT packs
|
|
||||||
0x0002018c (FAILURE,HIGH) = CD-TEXT pack type out of range
|
|
||||||
0x0002018d (FAILURE,HIGH) = CD-TEXT block number out of range
|
|
||||||
0x0002018e (FAILURE,HIGH) = Too many CD-TEXT packs in block
|
|
||||||
0x0002018f (FAILURE,HIGH) = CD-TEXT pack CRC mismatch
|
|
||||||
0x00020190 (WARNING,HIGH) = CD-TEXT pack CRC mismatch had to be corrected
|
|
||||||
0x00020191 (FAILURE,HIGH) = Unknown parameter in text input file
|
|
||||||
0x00020192 (FAILURE,HIGH) = Text input file sequence error
|
|
||||||
0x00020193 (FAILURE,HIGH) = Text input file readability problem
|
|
||||||
0x00020194 (FAILURE,HIGH) = Text input file syntax error or specs violation
|
|
||||||
0x00020195 (WARNING,HIGH) = Text input file warning
|
|
||||||
0x00020196 (FAILURE,HIGH) = Session has already defined tracks
|
|
||||||
0x00020197 (FAILURE,HIGH) = Unsupported text input file feature
|
|
||||||
0x00020198 (FAILURE,HIGH) = CD-TEXT pack file readability problem
|
|
||||||
0x00020199 (SORRY,HIGH) = Text input file reading aborted
|
|
||||||
0x0002019a (SORRY,HIGH) = Bad track index number
|
|
||||||
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
|
|
||||||
0x000201ab (WARN,HIGH) = Leaving burn_source_fifo object undisposed
|
|
||||||
0x000201ac (NOTE,HIGH) = Drive currently does not offer Stream Recording
|
|
||||||
0x000201ad (NOTE,HIGH) = WRITE commands have been repeated
|
|
||||||
0x000201ae (FAILURE,HIGH) = Track size exceeds 4 TiB - 32 KiB
|
|
||||||
|
|
||||||
|
|
||||||
libdax_audioxtr:
|
libdax_audioxtr:
|
||||||
0x00020200 (SORRY,HIGH) = Cannot open audio source file
|
0x00020200 (SORRY,HIGH) = Cannot open audio source file
|
||||||
|
@ -647,11 +603,11 @@ Range "vreixo" : 0x00030000 to 0x0003ffff
|
||||||
0x0003ffbc (FAILURE,HIGH) = Image already bootable
|
0x0003ffbc (FAILURE,HIGH) = Image already bootable
|
||||||
0x0003ffbb (FAILURE,HIGH) = Trying to use an invalid file as boot image
|
0x0003ffbb (FAILURE,HIGH) = Trying to use an invalid file as boot image
|
||||||
0x0003ff80 (FAILURE,HIGH) = Error on file operation
|
0x0003ff80 (FAILURE,HIGH) = Error on file operation
|
||||||
0x0003ff7f (FAILURE,HIGH) = Trying to open an already opened file
|
0x0003ff7f (FAILURE,HIGH) = Trying to open an already openned file
|
||||||
0x0003ff7e (FAILURE,HIGH) = Access to file is not allowed
|
0x0003ff7e (FAILURE,HIGH) = Access to file is not allowed
|
||||||
0x0003ff7d (FAILURE,HIGH) = Incorrect path to file
|
0x0003ff7d (FAILURE,HIGH) = Incorrect path to file
|
||||||
0x0003ff7c (FAILURE,HIGH) = The file does not exist in the filesystem
|
0x0003ff7c (FAILURE,HIGH) = The file does not exist in the filesystem
|
||||||
0x0003ff7b (FAILURE,HIGH) = Trying to read or close a file not opened
|
0x0003ff7b (FAILURE,HIGH) = Trying to read or close a file not openned
|
||||||
0x0003ff7a (FAILURE,HIGH) = Directory used where no dir is expected
|
0x0003ff7a (FAILURE,HIGH) = Directory used where no dir is expected
|
||||||
0x0003ff79 (FAILURE,HIGH) = File read error
|
0x0003ff79 (FAILURE,HIGH) = File read error
|
||||||
0x0003ff78 (FAILURE,HIGH) = Not dir used where a dir is expected
|
0x0003ff78 (FAILURE,HIGH) = Not dir used where a dir is expected
|
||||||
|
@ -702,7 +658,7 @@ X 0x00030203 (HINT,MEDIUM) = Unsupported El-Torito feature
|
||||||
X 0x00030204 (SORRY,HIGH) = Invalid file to be an El-Torito image
|
X 0x00030204 (SORRY,HIGH) = Invalid file to be an El-Torito image
|
||||||
X 0x00030205 (WARNING,MEDIUM)= Cannot properly patch isolinux image
|
X 0x00030205 (WARNING,MEDIUM)= Cannot properly patch isolinux image
|
||||||
X 0x00030206 (WARNING,MEDIUM)= Copying El-Torito from a previous image without
|
X 0x00030206 (WARNING,MEDIUM)= Copying El-Torito from a previous image without
|
||||||
X enough info about it
|
X enought info about it
|
||||||
X 0x00030301 (NOTE,MEDIUM) = Unsupported file type for Joliet tree
|
X 0x00030301 (NOTE,MEDIUM) = Unsupported file type for Joliet tree
|
||||||
|
|
||||||
|
|
||||||
|
|
2030
libburn/mmc.c
2030
libburn/mmc.c
File diff suppressed because it is too large
Load Diff
|
@ -1,7 +1,7 @@
|
||||||
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||||
|
|
||||||
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
|
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
|
||||||
Copyright (c) 2006 - 2024 Thomas Schmitt <scdbackup@gmx.net>
|
Copyright (c) 2006 - 2010 Thomas Schmitt <scdbackup@gmx.net>
|
||||||
Provided under GPL version 2 or later.
|
Provided under GPL version 2 or later.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -27,7 +27,7 @@ void mmc_close_disc(struct burn_write_opts *o);
|
||||||
|
|
||||||
void mmc_close(struct burn_drive *, int session, int track);
|
void mmc_close(struct burn_drive *, int session, int track);
|
||||||
void mmc_get_event(struct burn_drive *);
|
void mmc_get_event(struct burn_drive *);
|
||||||
int mmc_write(struct burn_drive *, off_t start, struct buffer *buf);
|
int mmc_write(struct burn_drive *, int start, struct buffer *buf);
|
||||||
void mmc_write_12(struct burn_drive *d, int start, struct buffer *buf);
|
void mmc_write_12(struct burn_drive *d, int start, struct buffer *buf);
|
||||||
void mmc_sync_cache(struct burn_drive *);
|
void mmc_sync_cache(struct burn_drive *);
|
||||||
void mmc_load(struct burn_drive *);
|
void mmc_load(struct burn_drive *);
|
||||||
|
@ -36,9 +36,9 @@ void mmc_erase(struct burn_drive *, int);
|
||||||
void mmc_read_toc(struct burn_drive *);
|
void mmc_read_toc(struct burn_drive *);
|
||||||
void mmc_read_disc_info(struct burn_drive *);
|
void mmc_read_disc_info(struct burn_drive *);
|
||||||
void mmc_read_atip(struct burn_drive *);
|
void mmc_read_atip(struct burn_drive *);
|
||||||
int mmc_read_cd(struct burn_drive *d, int start, int len,
|
void mmc_read_sectors(struct burn_drive *,
|
||||||
int sec_type, int main_ch,
|
int,
|
||||||
const struct burn_read_opts *o, struct buffer *buf, int flag);
|
int, const struct burn_read_opts *, struct buffer *);
|
||||||
void mmc_set_speed(struct burn_drive *, int, int);
|
void mmc_set_speed(struct burn_drive *, int, int);
|
||||||
void mmc_read_lead_in(struct burn_drive *, struct buffer *);
|
void mmc_read_lead_in(struct burn_drive *, struct buffer *);
|
||||||
void mmc_perform_opc(struct burn_drive *);
|
void mmc_perform_opc(struct burn_drive *);
|
||||||
|
@ -48,8 +48,7 @@ void mmc_get_configuration(struct burn_drive *);
|
||||||
@return 1=nwa is valid , 0=nwa is not valid , -1=error */
|
@return 1=nwa is valid , 0=nwa is not valid , -1=error */
|
||||||
int mmc_get_nwa(struct burn_drive *d, int trackno, int *lba, int *nwa);
|
int mmc_get_nwa(struct burn_drive *d, int trackno, int *lba, int *nwa);
|
||||||
|
|
||||||
/* ts B11228 : changed from void to int */
|
void mmc_send_cue_sheet(struct burn_drive *, struct cue_sheet *);
|
||||||
int mmc_send_cue_sheet(struct burn_drive *, struct cue_sheet *);
|
|
||||||
|
|
||||||
/* ts A61023 : get size and free space of drive buffer */
|
/* ts A61023 : get size and free space of drive buffer */
|
||||||
int mmc_read_buffer_capacity(struct burn_drive *d);
|
int mmc_read_buffer_capacity(struct burn_drive *d);
|
||||||
|
@ -72,22 +71,13 @@ int mmc_get_write_performance(struct burn_drive *d);
|
||||||
is the eventual duty of the caller.
|
is the eventual duty of the caller.
|
||||||
*/
|
*/
|
||||||
int mmc_compose_mode_page_5(struct burn_drive *d,
|
int mmc_compose_mode_page_5(struct burn_drive *d,
|
||||||
struct burn_session *s, int tno,
|
|
||||||
const struct burn_write_opts *o,
|
const struct burn_write_opts *o,
|
||||||
unsigned char *pd);
|
unsigned char *pd);
|
||||||
|
|
||||||
/* ts A70201 */
|
/* ts A70201 */
|
||||||
int mmc_four_char_to_int(unsigned char *data);
|
int mmc_four_char_to_int(unsigned char *data);
|
||||||
/* ts C40226 */
|
|
||||||
unsigned int mmc_four_char_to_uint(unsigned char *data);
|
|
||||||
|
|
||||||
/* ts A70201 :
|
/* ts A70812 : return 0 = ok , return BE_CANCELLED = error occured */
|
||||||
Common track info fetcher for mmc_get_nwa() and mmc_fake_toc()
|
|
||||||
*/
|
|
||||||
int mmc_read_track_info(struct burn_drive *d, int trackno, struct buffer *buf,
|
|
||||||
int alloc_len);
|
|
||||||
|
|
||||||
/* ts A70812 : return 0 = ok , return BE_CANCELLED = error occurred */
|
|
||||||
int mmc_read_10(struct burn_drive *d, int start, int amount,
|
int mmc_read_10(struct burn_drive *d, int start, int amount,
|
||||||
struct buffer *buf);
|
struct buffer *buf);
|
||||||
|
|
||||||
|
@ -125,25 +115,4 @@ int mmc_get_phys_format_info(struct burn_drive *d, int *disk_category,
|
||||||
char **book_name, int *part_version, int *num_layers,
|
char **book_name, int *part_version, int *num_layers,
|
||||||
int *num_blocks, int flag);
|
int *num_blocks, int flag);
|
||||||
|
|
||||||
/* ts B11201 */
|
|
||||||
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);
|
|
||||||
|
|
||||||
/* ts B90414 */
|
|
||||||
int burn_make_feature_text(struct burn_drive *d, unsigned int feature_code,
|
|
||||||
unsigned char flags,
|
|
||||||
unsigned char additional_length,
|
|
||||||
unsigned char *feature_data,
|
|
||||||
char **text, int flag);
|
|
||||||
|
|
||||||
#ifdef Libburn_develop_quality_scaN
|
|
||||||
/* B21108 ts */
|
|
||||||
int mmc_nec_optiarc_f3(struct burn_drive *d, int sub_op,
|
|
||||||
int start_lba, int rate_period,
|
|
||||||
int *eba, int *error_rate1, int *error_rate2);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /*__MMC*/
|
#endif /*__MMC*/
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
|
|
||||||
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
|
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
|
||||||
Copyright (c) 2006 - 2017 Thomas Schmitt <scdbackup@gmx.net>
|
Copyright (c) 2006 - 2010 Thomas Schmitt <scdbackup@gmx.net>
|
||||||
Provided under GPL version 2 or later.
|
Provided under GPL version 2 or later.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -12,15 +12,12 @@
|
||||||
#include "options.h"
|
#include "options.h"
|
||||||
#include "drive.h"
|
#include "drive.h"
|
||||||
#include "transport.h"
|
#include "transport.h"
|
||||||
#include "init.h"
|
|
||||||
#include "write.h"
|
|
||||||
|
|
||||||
/* ts A61007 */
|
/* ts A61007 */
|
||||||
/* #include <a ssert.h> */
|
/* #include <a ssert.h> */
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
#include "libdax_msgs.h"
|
#include "libdax_msgs.h"
|
||||||
extern struct libdax_msgs *libdax_messenger;
|
extern struct libdax_msgs *libdax_messenger;
|
||||||
|
@ -44,27 +41,16 @@ struct burn_write_opts *burn_write_opts_new(struct burn_drive *drive)
|
||||||
opts->toc_entry = NULL;
|
opts->toc_entry = NULL;
|
||||||
opts->toc_entries = 0;
|
opts->toc_entries = 0;
|
||||||
opts->simulate = 0;
|
opts->simulate = 0;
|
||||||
opts->underrun_proof = drive->mdata->p2a_valid > 0 &&
|
opts->underrun_proof = drive->mdata->underrun_proof;
|
||||||
drive->mdata->underrun_proof;
|
|
||||||
opts->perform_opc = 1;
|
opts->perform_opc = 1;
|
||||||
opts->obs = -1;
|
opts->obs = -1;
|
||||||
|
|
||||||
#ifdef Libburn_dvd_always_obs_paD
|
|
||||||
opts->obs_pad = 1;
|
|
||||||
#else
|
|
||||||
opts->obs_pad = 0;
|
opts->obs_pad = 0;
|
||||||
#endif
|
|
||||||
|
|
||||||
opts->bdr_obs_exempt = 0;
|
|
||||||
opts->start_byte = -1;
|
opts->start_byte = -1;
|
||||||
opts->fill_up_media = 0;
|
opts->fill_up_media = 0;
|
||||||
opts->force_is_set = 0;
|
opts->force_is_set = 0;
|
||||||
opts->do_stream_recording = 0;
|
opts->do_stream_recording = 0;
|
||||||
opts->dvd_obs_override = 0;
|
opts->dvd_obs_override = 0;
|
||||||
opts->stdio_fsync_size = Libburn_stdio_fsync_limiT;
|
opts->stdio_fsync_size = Libburn_stdio_fsync_limiT;
|
||||||
opts->text_packs = NULL;
|
|
||||||
opts->num_text_packs = 0;
|
|
||||||
opts->no_text_pack_crc_check = 0;
|
|
||||||
opts->has_mediacatalog = 0;
|
opts->has_mediacatalog = 0;
|
||||||
opts->format = BURN_CDROM;
|
opts->format = BURN_CDROM;
|
||||||
opts->multi = 0;
|
opts->multi = 0;
|
||||||
|
@ -74,40 +60,8 @@ struct burn_write_opts *burn_write_opts_new(struct burn_drive *drive)
|
||||||
|
|
||||||
void burn_write_opts_free(struct burn_write_opts *opts)
|
void burn_write_opts_free(struct burn_write_opts *opts)
|
||||||
{
|
{
|
||||||
if (--opts->refcount > 0)
|
if (--opts->refcount <= 0)
|
||||||
return;
|
free(opts);
|
||||||
if (opts->text_packs != NULL)
|
|
||||||
free(opts->text_packs);
|
|
||||||
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 *burn_read_opts_new(struct burn_drive *drive)
|
||||||
|
@ -125,7 +79,6 @@ struct burn_read_opts *burn_read_opts_new(struct burn_drive *drive)
|
||||||
opts->report_recovered_errors = 0;
|
opts->report_recovered_errors = 0;
|
||||||
opts->transfer_damaged_blocks = 0;
|
opts->transfer_damaged_blocks = 0;
|
||||||
opts->hardware_error_retries = 3;
|
opts->hardware_error_retries = 3;
|
||||||
opts->dap_bit = 0;
|
|
||||||
|
|
||||||
return opts;
|
return opts;
|
||||||
}
|
}
|
||||||
|
@ -184,6 +137,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)
|
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;
|
opts->simulate = !!sim;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -191,8 +155,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 burn_write_opts_set_underrun_proof(struct burn_write_opts *opts,
|
||||||
int underrun_proof)
|
int underrun_proof)
|
||||||
{
|
{
|
||||||
if (opts->drive->mdata->p2a_valid <= 0 ||
|
if (opts->drive->mdata->valid <= 0)
|
||||||
opts->drive->mdata->underrun_proof) {
|
return 0;
|
||||||
|
if (opts->drive->mdata->underrun_proof) {
|
||||||
opts->underrun_proof = underrun_proof;
|
opts->underrun_proof = underrun_proof;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -213,7 +178,7 @@ void burn_write_opts_set_has_mediacatalog(struct burn_write_opts *opts,
|
||||||
void burn_write_opts_set_mediacatalog(struct burn_write_opts *opts,
|
void burn_write_opts_set_mediacatalog(struct burn_write_opts *opts,
|
||||||
unsigned char mediacatalog[13])
|
unsigned char mediacatalog[13])
|
||||||
{
|
{
|
||||||
memcpy(opts->mediacatalog, mediacatalog, 13);
|
memcpy(opts->mediacatalog, &mediacatalog, 13);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -224,81 +189,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
|
|
||||||
bit2= repair checksums if they are 00 00 with each pack
|
|
||||||
*/
|
|
||||||
int burn_write_opts_set_leadin_text(struct burn_write_opts *opts,
|
|
||||||
unsigned char *text_packs,
|
|
||||||
int num_packs, int flag)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
unsigned char *pack_buffer = NULL;
|
|
||||||
|
|
||||||
if (num_packs > Libburn_leadin_cdtext_packs_maX ) {
|
|
||||||
libdax_msgs_submit(libdax_messenger, opts->drive->global_index,
|
|
||||||
0x0002018b,
|
|
||||||
LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH,
|
|
||||||
"Too many CD-TEXT packs", 0, 0);
|
|
||||||
ret= 0; goto ex;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (num_packs > 0)
|
|
||||||
BURN_ALLOC_MEM(pack_buffer, unsigned char, num_packs * 18);
|
|
||||||
|
|
||||||
if (opts->text_packs != NULL) {
|
|
||||||
free(opts->text_packs);
|
|
||||||
opts->text_packs = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (flag & 1) {
|
|
||||||
opts->no_text_pack_crc_check = 1;
|
|
||||||
} else {
|
|
||||||
opts->no_text_pack_crc_check = 0;
|
|
||||||
ret = burn_cdtext_crc_mismatches(text_packs, num_packs,
|
|
||||||
(flag >> 1) & 3);
|
|
||||||
if (ret > 0) {
|
|
||||||
libdax_msgs_submit(libdax_messenger, -1, 0x0002018f,
|
|
||||||
LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH,
|
|
||||||
"CD-TEXT pack CRC mismatch", 0, 0);
|
|
||||||
ret = 0; goto ex;
|
|
||||||
} else if (ret < 0) {
|
|
||||||
libdax_msgs_submit(libdax_messenger, -1, 0x00020190,
|
|
||||||
LIBDAX_MSGS_SEV_WARNING, LIBDAX_MSGS_PRIO_HIGH,
|
|
||||||
"CD-TEXT pack CRC mismatch had to be corrected",
|
|
||||||
0, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* ts A61222 */
|
/* ts A61222 */
|
||||||
void burn_write_opts_set_start_byte(struct burn_write_opts *opts, off_t value)
|
void burn_write_opts_set_start_byte(struct burn_write_opts *opts, off_t value)
|
||||||
{
|
{
|
||||||
|
@ -324,11 +214,6 @@ enum burn_write_types burn_write_opts_auto_write_type(
|
||||||
|
|
||||||
reasons[0] = 0;
|
reasons[0] = 0;
|
||||||
|
|
||||||
if (burn_drive_get_bd_r_pow(d)) {
|
|
||||||
strcat(reasons,
|
|
||||||
"MEDIA: unsuitable BD-R Pseudo Overwrite formatting, ");
|
|
||||||
return BURN_WRITE_NONE;
|
|
||||||
}
|
|
||||||
if (d->status != BURN_DISC_BLANK &&
|
if (d->status != BURN_DISC_BLANK &&
|
||||||
d->status != BURN_DISC_APPENDABLE){
|
d->status != BURN_DISC_APPENDABLE){
|
||||||
if (d->status == BURN_DISC_FULL)
|
if (d->status == BURN_DISC_FULL)
|
||||||
|
@ -411,10 +296,6 @@ do_sao:;
|
||||||
{wt = BURN_WRITE_SAO; goto ex;}
|
{wt = BURN_WRITE_SAO; goto ex;}
|
||||||
no_sao:;
|
no_sao:;
|
||||||
try_tao:;
|
try_tao:;
|
||||||
if (opts->num_text_packs > 0) {
|
|
||||||
strcat(reasons, "CD-TEXT: write type SAO required, ");
|
|
||||||
{wt = BURN_WRITE_NONE; goto ex;}
|
|
||||||
}
|
|
||||||
if ((flag & 1) && opts->write_type != BURN_WRITE_TAO)
|
if ((flag & 1) && opts->write_type != BURN_WRITE_TAO)
|
||||||
goto try_raw;
|
goto try_raw;
|
||||||
reason_pt = reasons + strlen(reasons);
|
reason_pt = reasons + strlen(reasons);
|
||||||
|
@ -529,32 +410,15 @@ void burn_write_opts_set_dvd_obs(struct burn_write_opts *opts, int obs)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ts B20406: API */
|
|
||||||
void burn_write_opts_set_obs_pad(struct burn_write_opts *opts, int pad)
|
|
||||||
{
|
|
||||||
opts->obs_pad = 2 * !!pad;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* ts C10909: API */
|
|
||||||
void burn_write_opts_set_bdr_obs_exempt(struct burn_write_opts *opts,
|
|
||||||
int value)
|
|
||||||
{
|
|
||||||
opts->bdr_obs_exempt = !!value;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* ts A91115: API */
|
/* ts A91115: API */
|
||||||
void burn_write_opts_set_stdio_fsync(struct burn_write_opts *opts, int rhythm)
|
void burn_write_opts_set_stdio_fsync(struct burn_write_opts *opts, int rythm)
|
||||||
{
|
{
|
||||||
if (rhythm == -1)
|
if (rythm == -1)
|
||||||
opts->stdio_fsync_size = -1; /* never */
|
opts->stdio_fsync_size = 0;
|
||||||
else if (rhythm == 0)
|
else if (rythm == 0)
|
||||||
opts->stdio_fsync_size = Libburn_stdio_fsync_limiT;
|
opts->stdio_fsync_size = Libburn_stdio_fsync_limiT;
|
||||||
else if (rhythm == 1)
|
else if (rythm >= 32)
|
||||||
opts->stdio_fsync_size = 0; /* only at end of writing */
|
opts->stdio_fsync_size = rythm;
|
||||||
else if (rhythm >= 32)
|
|
||||||
opts->stdio_fsync_size = rhythm;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
|
|
||||||
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
|
/* 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.
|
Provided under GPL version 2 or later.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -42,21 +42,16 @@ struct burn_write_opts
|
||||||
/* ts A61219 : Output block size to trigger buffer flush if hit.
|
/* ts A61219 : Output block size to trigger buffer flush if hit.
|
||||||
-1 with CD, 32 kB with DVD */
|
-1 with CD, 32 kB with DVD */
|
||||||
int obs;
|
int obs;
|
||||||
int obs_pad; /* >0 pad up last block to obs, 0 do not
|
int obs_pad; /* 1=pad up last block to obs */
|
||||||
2 indicates burn_write_opts_set_obs_pad(,1)
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* 1= do not apply obs_pad=1 to BD-R if not stream recording. */
|
/* ts A61222 : Start address for media which allow a choice */
|
||||||
int bdr_obs_exempt;
|
|
||||||
|
|
||||||
/* ts A61222 : Start address for media which offer a choice */
|
|
||||||
off_t start_byte;
|
off_t start_byte;
|
||||||
|
|
||||||
/* ts A70213 : Whether to fill up the available space on media */
|
/* ts A70213 : Wether to fill up the available space on media */
|
||||||
int fill_up_media;
|
int fill_up_media;
|
||||||
|
|
||||||
/* ts A70303 : Whether to override conformance checks:
|
/* ts A70303 : Wether to override conformance checks:
|
||||||
- the check whether CD write+block type is supported by the drive
|
- the check wether CD write+block type is supported by the drive
|
||||||
*/
|
*/
|
||||||
int force_is_set;
|
int force_is_set;
|
||||||
|
|
||||||
|
@ -74,42 +69,21 @@ struct burn_write_opts
|
||||||
Values 0 or >= 32 counted in 2 KB blocks. */
|
Values 0 or >= 32 counted in 2 KB blocks. */
|
||||||
int stdio_fsync_size;
|
int stdio_fsync_size;
|
||||||
|
|
||||||
/* ts B11203 : CD-TEXT */
|
|
||||||
unsigned char *text_packs;
|
|
||||||
int num_text_packs;
|
|
||||||
int no_text_pack_crc_check;
|
|
||||||
|
|
||||||
/** A disc can have a media catalog number */
|
/** A disc can have a media catalog number */
|
||||||
int has_mediacatalog;
|
int has_mediacatalog;
|
||||||
unsigned char mediacatalog[13];
|
unsigned char mediacatalog[13];
|
||||||
/** Session format */
|
/** Session format */
|
||||||
int format;
|
int format;
|
||||||
|
|
||||||
/* internal use only */
|
/* internal use only */
|
||||||
unsigned char control;
|
unsigned char control;
|
||||||
|
|
||||||
/* Whether to keep medium appendable */
|
|
||||||
unsigned char multi;
|
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
|
/* Default value for burn_write_opts.stdio_flush_size
|
||||||
*/
|
*/
|
||||||
#define Libburn_stdio_fsync_limiT 8192
|
#define Libburn_stdio_fsync_limiT 8192
|
||||||
|
|
||||||
/* Maximum number of Lead-in text packs.
|
|
||||||
READ TOC/PMA/ATIP can at most return 3640.7 packs.
|
|
||||||
The sequence counters of the packs have 8 bits. There are 8 blocks at most.
|
|
||||||
Thus max 2048 packs.
|
|
||||||
*/
|
|
||||||
#define Libburn_leadin_cdtext_packs_maX 2048
|
|
||||||
|
|
||||||
|
|
||||||
/** Options for disc reading operations. This should be created with
|
/** Options for disc reading operations. This should be created with
|
||||||
burn_read_opts_new() and freed with burn_read_opts_free(). */
|
burn_read_opts_new() and freed with burn_read_opts_free(). */
|
||||||
|
@ -142,19 +116,6 @@ struct burn_read_opts
|
||||||
/** The number of retries the hardware should make to correct
|
/** The number of retries the hardware should make to correct
|
||||||
errors. */
|
errors. */
|
||||||
unsigned char hardware_error_retries;
|
unsigned char hardware_error_retries;
|
||||||
|
|
||||||
/* ts B21119 */
|
|
||||||
/* >>> Needs API access */
|
|
||||||
/** Whether to set DAP bit which allows the 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 */
|
#endif /* BURN__OPTIONS_H */
|
||||||
|
|
|
@ -5,8 +5,7 @@
|
||||||
Unknown POSIX like systems
|
Unknown POSIX like systems
|
||||||
with the dummy MMC transport adapter sg-dummy.c
|
with the dummy MMC transport adapter sg-dummy.c
|
||||||
|
|
||||||
Copyright (C) 2009 - 2013 Thomas Schmitt <scdbackup@gmx.net>
|
Copyright (C) 2009 Thomas Schmitt <scdbackup@gmx.net>, provided under GPLv2+
|
||||||
Provided under GPLv2+
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
@ -17,16 +16,18 @@
|
||||||
#define BURN_OS_SIGNAL_MACRO_LIST \
|
#define BURN_OS_SIGNAL_MACRO_LIST \
|
||||||
SIGHUP, SIGINT, SIGQUIT, SIGILL, SIGABRT, \
|
SIGHUP, SIGINT, SIGQUIT, SIGILL, SIGABRT, \
|
||||||
SIGFPE, SIGSEGV, SIGPIPE, SIGALRM, SIGTERM, \
|
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 */
|
/* Once as text 1:1 list of strings for messages and interpreters */
|
||||||
#define BURN_OS_SIGNAL_NAME_LIST \
|
#define BURN_OS_SIGNAL_NAME_LIST \
|
||||||
"SIGHUP", "SIGINT", "SIGQUIT", "SIGILL", "SIGABRT", \
|
"SIGHUP", "SIGINT", "SIGQUIT", "SIGILL", "SIGABRT", \
|
||||||
"SIGFPE", "SIGSEGV", "SIGPIPE", "SIGALRM", "SIGTERM", \
|
"SIGFPE", "SIGSEGV", "SIGPIPE", "SIGALRM", "SIGTERM", \
|
||||||
"SIGUSR1", "SIGUSR2", "SIGXCPU"
|
"SIGUSR1", "SIGUSR2", "SIGXCPU", "SIGTSTP", "SIGTTIN", \
|
||||||
|
"SIGTTOU"
|
||||||
|
|
||||||
/* The number of above list items */
|
/* 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.
|
/** The list of all signals which shall surely not be caught.
|
||||||
It depends on the particular signal whether it can be ignored or whether
|
It 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.
|
/** The combined list of all signals which shall not be caught.
|
||||||
*/
|
*/
|
||||||
#define BURN_OS_NON_SIGNAL_MACRO_LIST \
|
#define BURN_OS_NON_SIGNAL_MACRO_LIST \
|
||||||
SIGKILL, SIGCHLD, SIGSTOP, SIGTSTP, SIGCONT, SIGTTIN, SIGTTOU \
|
SIGKILL, SIGCHLD, SIGSTOP BURN_OS_SIG_WINCH BURN_OS_SIG_URG
|
||||||
BURN_OS_SIG_WINCH BURN_OS_SIG_URG
|
|
||||||
|
|
||||||
/* The number of above list items */
|
/* The number of above list items */
|
||||||
#define BURN_OS_NON_SIGNAL_COUNT \
|
#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 */
|
/* The maximum size for a (SCSI) i/o transaction */
|
||||||
|
|
|
@ -4,8 +4,8 @@
|
||||||
by os.h in case of compilation for
|
by os.h in case of compilation for
|
||||||
FreeBSD with CAM
|
FreeBSD with CAM
|
||||||
|
|
||||||
Copyright (C) 2006 - 2013 Thomas Schmitt <scdbackup@gmx.net>,
|
Copyright (C) 2006 - 2010 Thomas Schmitt <scdbackup@gmx.net>,
|
||||||
Provided under GPLv2+
|
provided under GPLv2+
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** List of all signals which shall be caught by signal handlers and trigger
|
/** List of all signals which shall be caught by signal handlers and trigger
|
||||||
|
@ -15,25 +15,29 @@
|
||||||
#define BURN_OS_SIGNAL_MACRO_LIST \
|
#define BURN_OS_SIGNAL_MACRO_LIST \
|
||||||
SIGHUP, SIGINT, SIGQUIT, SIGILL, SIGABRT, \
|
SIGHUP, SIGINT, SIGQUIT, SIGILL, SIGABRT, \
|
||||||
SIGFPE, SIGSEGV, SIGPIPE, SIGALRM, SIGTERM, \
|
SIGFPE, SIGSEGV, SIGPIPE, SIGALRM, SIGTERM, \
|
||||||
SIGUSR1, SIGUSR2, SIGXCPU, SIGBUS, SIGPROF, \
|
SIGUSR1, SIGUSR2, SIGXCPU, SIGTSTP, SIGTTIN, \
|
||||||
SIGSYS, SIGTRAP, SIGVTALRM, SIGXCPU, SIGXFSZ
|
SIGTTOU, \
|
||||||
|
SIGBUS, SIGPROF, SIGSYS, SIGTRAP, \
|
||||||
|
SIGVTALRM, SIGXCPU, SIGXFSZ
|
||||||
|
|
||||||
/* Once as text 1:1 list of strings for messages and interpreters */
|
/* Once as text 1:1 list of strings for messages and interpreters */
|
||||||
#define BURN_OS_SIGNAL_NAME_LIST \
|
#define BURN_OS_SIGNAL_NAME_LIST \
|
||||||
"SIGHUP", "SIGINT", "SIGQUIT", "SIGILL", "SIGABRT", \
|
"SIGHUP", "SIGINT", "SIGQUIT", "SIGILL", "SIGABRT", \
|
||||||
"SIGFPE", "SIGSEGV", "SIGPIPE", "SIGALRM", "SIGTERM", \
|
"SIGFPE", "SIGSEGV", "SIGPIPE", "SIGALRM", "SIGTERM", \
|
||||||
"SIGUSR1", "SIGUSR2", "SIGXCPU", "SIGBUS", "SIGPROF", \
|
"SIGUSR1", "SIGUSR2", "SIGXCPU", "SIGTSTP", "SIGTTIN", \
|
||||||
"SIGSYS", "SIGTRAP", "SIGVTALRM", "SIGXCPU", "SIGXFSZ"
|
"SIGTTOU", \
|
||||||
|
"SIGBUS", "SIGPROF", "SIGSYS", "SIGTRAP", \
|
||||||
|
"SIGVTALRM", "SIGXCPU", "SIGXFSZ"
|
||||||
|
|
||||||
/* The number of above list items */
|
/* 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 */
|
/** To list all signals which shall surely not be caught */
|
||||||
#define BURN_OS_NON_SIGNAL_MACRO_LIST \
|
#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 */
|
/* 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 */
|
/* The maximum size for a (SCSI) i/o transaction */
|
||||||
|
|
|
@ -5,8 +5,7 @@
|
||||||
Unknown X/Open-like systems
|
Unknown X/Open-like systems
|
||||||
with GNU libcdio MMC transport adapter sg-libcdio.c
|
with GNU libcdio MMC transport adapter sg-libcdio.c
|
||||||
|
|
||||||
Copyright (C) 2009 - 2013 Thomas Schmitt <scdbackup@gmx.net>
|
Copyright (C) 2009 Thomas Schmitt <scdbackup@gmx.net>, provided under GPLv2+
|
||||||
Provided under GPLv2+
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
@ -17,16 +16,18 @@
|
||||||
#define BURN_OS_SIGNAL_MACRO_LIST \
|
#define BURN_OS_SIGNAL_MACRO_LIST \
|
||||||
SIGHUP, SIGINT, SIGQUIT, SIGILL, SIGABRT, \
|
SIGHUP, SIGINT, SIGQUIT, SIGILL, SIGABRT, \
|
||||||
SIGFPE, SIGSEGV, SIGPIPE, SIGALRM, SIGTERM, \
|
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 */
|
/* Once as text 1:1 list of strings for messages and interpreters */
|
||||||
#define BURN_OS_SIGNAL_NAME_LIST \
|
#define BURN_OS_SIGNAL_NAME_LIST \
|
||||||
"SIGHUP", "SIGINT", "SIGQUIT", "SIGILL", "SIGABRT", \
|
"SIGHUP", "SIGINT", "SIGQUIT", "SIGILL", "SIGABRT", \
|
||||||
"SIGFPE", "SIGSEGV", "SIGPIPE", "SIGALRM", "SIGTERM", \
|
"SIGFPE", "SIGSEGV", "SIGPIPE", "SIGALRM", "SIGTERM", \
|
||||||
"SIGUSR1", "SIGUSR2", "SIGXCPU"
|
"SIGUSR1", "SIGUSR2", "SIGXCPU", "SIGTSTP", "SIGTTIN", \
|
||||||
|
"SIGTTOU"
|
||||||
|
|
||||||
/* The number of above list items */
|
/* 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.
|
/** 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.
|
/** The combined list of all signals which shall not be caught.
|
||||||
*/
|
*/
|
||||||
#define BURN_OS_NON_SIGNAL_MACRO_LIST \
|
#define BURN_OS_NON_SIGNAL_MACRO_LIST \
|
||||||
SIGKILL, SIGCHLD, SIGSTOP, SIGTSTP, SIGCONT, SIGTTIN, SIGTTOU \
|
SIGKILL, SIGCHLD, SIGSTOP BURN_OS_SIG_WINCH BURN_OS_SIG_URG
|
||||||
BURN_OS_SIG_WINCH BURN_OS_SIG_URG
|
|
||||||
|
|
||||||
/* The number of above list items */
|
/* The number of above list items */
|
||||||
#define BURN_OS_NON_SIGNAL_COUNT \
|
#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 */
|
/* The maximum size for a (SCSI) i/o transaction */
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
by os.h in case of compilation for
|
by os.h in case of compilation for
|
||||||
Linux kernels 2.4 and 2.6, GNU/Linux SCSI Generic (sg)
|
Linux kernels 2.4 and 2.6, 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.
|
Provided under GPL version 2 or later.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -16,27 +16,29 @@
|
||||||
#define BURN_OS_SIGNAL_MACRO_LIST \
|
#define BURN_OS_SIGNAL_MACRO_LIST \
|
||||||
SIGHUP, SIGINT, SIGQUIT, SIGILL, SIGABRT, \
|
SIGHUP, SIGINT, SIGQUIT, SIGILL, SIGABRT, \
|
||||||
SIGFPE, SIGSEGV, SIGPIPE, SIGALRM, SIGTERM, \
|
SIGFPE, SIGSEGV, SIGPIPE, SIGALRM, SIGTERM, \
|
||||||
SIGUSR1, SIGUSR2, SIGXCPU, SIGBUS, SIGPOLL, \
|
SIGUSR1, SIGUSR2, SIGXCPU, SIGTSTP, SIGTTIN, \
|
||||||
SIGPROF, SIGSYS, SIGTRAP, SIGVTALRM, SIGXCPU, \
|
SIGTTOU, \
|
||||||
SIGXFSZ
|
SIGBUS, SIGPOLL, SIGPROF, SIGSYS, SIGTRAP, \
|
||||||
|
SIGVTALRM, SIGXCPU, SIGXFSZ
|
||||||
|
|
||||||
/* Once as text 1:1 list of strings for messages and interpreters */
|
/* Once as text 1:1 list of strings for messages and interpreters */
|
||||||
#define BURN_OS_SIGNAL_NAME_LIST \
|
#define BURN_OS_SIGNAL_NAME_LIST \
|
||||||
"SIGHUP", "SIGINT", "SIGQUIT", "SIGILL", "SIGABRT", \
|
"SIGHUP", "SIGINT", "SIGQUIT", "SIGILL", "SIGABRT", \
|
||||||
"SIGFPE", "SIGSEGV", "SIGPIPE", "SIGALRM", "SIGTERM", \
|
"SIGFPE", "SIGSEGV", "SIGPIPE", "SIGALRM", "SIGTERM", \
|
||||||
"SIGUSR1", "SIGUSR2", "SIGXCPU", "SIGBUS", "SIGPOLL", \
|
"SIGUSR1", "SIGUSR2", "SIGXCPU", "SIGTSTP", "SIGTTIN", \
|
||||||
"SIGPROF", "SIGSYS", "SIGTRAP", "SIGVTALRM", "SIGXCPU", \
|
"SIGTTOU", \
|
||||||
"SIGXFSZ"
|
"SIGBUS", "SIGPOLL", "SIGPROF", "SIGSYS", "SIGTRAP", \
|
||||||
|
"SIGVTALRM", "SIGXCPU", "SIGXFSZ"
|
||||||
|
|
||||||
/* The number of above list items */
|
/* 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 */
|
/** To list all signals which shall surely not be caught */
|
||||||
#define BURN_OS_NON_SIGNAL_MACRO_LIST \
|
#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 */
|
/* 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 */
|
/* The maximum size for a (SCSI) i/o transaction */
|
||||||
|
|
|
@ -1,99 +0,0 @@
|
||||||
|
|
||||||
/* os-netbsd.h
|
|
||||||
Operating system specific libburn definitions and declarations. Included
|
|
||||||
by os.h in case of compilation for
|
|
||||||
NetBSD 6 or OpenBSD 5.9
|
|
||||||
with MMC transport adapter sg-netbsd.c
|
|
||||||
|
|
||||||
Copyright (C) 2010 - 2016 Thomas Schmitt <scdbackup@gmx.net>
|
|
||||||
provided under GPLv2+
|
|
||||||
|
|
||||||
Derived 2014 from libburn/os-solaris.c
|
|
||||||
Adapted 2016 to OpenBSD by help of SASANO Takayoshi <uaa@mx5.nisiq.net>
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
/** 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
|
|
||||||
|
|
||||||
#ifdef __OpenBSD__
|
|
||||||
|
|
||||||
/** 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
|
|
||||||
|
|
||||||
/* The number of above list items */
|
|
||||||
#define BURN_OS_NON_SIGNAL_COUNT 11
|
|
||||||
|
|
||||||
/* ts B60730 */
|
|
||||||
/* Either OpenBSD or SASANO Takayoshi's LG BH14NS48 throw 2,0,0
|
|
||||||
on Immed bit with BLANK and SYNCHRONIZE CACHE.
|
|
||||||
Until it is clear that the drive is to blame, the OpenBSD default is
|
|
||||||
not to use Immed.
|
|
||||||
|
|
||||||
This may be overridden at ./configure time by
|
|
||||||
export CFLAGS
|
|
||||||
CFLAGS="$CFLAGS -DLibburn_do_no_immed_defaulT=0"
|
|
||||||
*/
|
|
||||||
#ifndef Libburn_do_no_immed_defaulT
|
|
||||||
#define Libburn_do_no_immed_defaulT 1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#else /* __OpenBSD__ */
|
|
||||||
|
|
||||||
/** 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
|
|
||||||
|
|
||||||
#endif /* ! __OpenBSD__ */
|
|
||||||
|
|
||||||
/* 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;
|
|
||||||
|
|
|
@ -5,8 +5,7 @@
|
||||||
Solaris based systems, e.g. SunOS 5.11
|
Solaris based systems, e.g. SunOS 5.11
|
||||||
with Solaris uscsi MMC transport adapter sg-solaris.c
|
with Solaris uscsi MMC transport adapter sg-solaris.c
|
||||||
|
|
||||||
Copyright (C) 2010 - 2013 Thomas Schmitt <scdbackup@gmx.net>
|
Copyright (C) 2010 Thomas Schmitt <scdbackup@gmx.net>, provided under GPLv2+
|
||||||
provided under GPLv2+
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
@ -17,23 +16,25 @@
|
||||||
#define BURN_OS_SIGNAL_MACRO_LIST \
|
#define BURN_OS_SIGNAL_MACRO_LIST \
|
||||||
SIGHUP, SIGINT, SIGQUIT, SIGILL, SIGABRT, \
|
SIGHUP, SIGINT, SIGQUIT, SIGILL, SIGABRT, \
|
||||||
SIGFPE, SIGSEGV, SIGPIPE, SIGALRM, SIGTERM, \
|
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 */
|
/* Once as text 1:1 list of strings for messages and interpreters */
|
||||||
#define BURN_OS_SIGNAL_NAME_LIST \
|
#define BURN_OS_SIGNAL_NAME_LIST \
|
||||||
"SIGHUP", "SIGINT", "SIGQUIT", "SIGILL", "SIGABRT", \
|
"SIGHUP", "SIGINT", "SIGQUIT", "SIGILL", "SIGABRT", \
|
||||||
"SIGFPE", "SIGSEGV", "SIGPIPE", "SIGALRM", "SIGTERM", \
|
"SIGFPE", "SIGSEGV", "SIGPIPE", "SIGALRM", "SIGTERM", \
|
||||||
"SIGUSR1", "SIGUSR2", "SIGXCPU"
|
"SIGUSR1", "SIGUSR2", "SIGXCPU", "SIGTSTP", "SIGTTIN", \
|
||||||
|
"SIGTTOU"
|
||||||
|
|
||||||
/* The number of above list items */
|
/* 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 */
|
/** To list all signals which shall surely not be caught */
|
||||||
#define BURN_OS_NON_SIGNAL_MACRO_LIST \
|
#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 */
|
/* 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 */
|
/* The maximum size for a (SCSI) i/o transaction */
|
||||||
|
|
22
libburn/os.h
22
libburn/os.h
|
@ -3,8 +3,7 @@
|
||||||
Operating system specific libburn definitions and declarations.
|
Operating system specific libburn definitions and declarations.
|
||||||
The macros defined here are used by libburn modules in order to
|
The macros defined here are used by libburn modules in order to
|
||||||
avoid own system dependent case distinctions.
|
avoid own system dependent case distinctions.
|
||||||
Copyright (C) 2009 - 2016 Thomas Schmitt <scdbackup@gmx.net>,
|
Copyright (C) 2009 Thomas Schmitt <scdbackup@gmx.net>, provided under GPLv2+
|
||||||
provided under GPLv2+
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef BURN_OS_H_INCLUDED
|
#ifndef BURN_OS_H_INCLUDED
|
||||||
|
@ -14,6 +13,7 @@
|
||||||
Operating system case distinction
|
Operating system case distinction
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#ifdef Libburn_use_sg_dummY
|
#ifdef Libburn_use_sg_dummY
|
||||||
|
|
||||||
|
|
||||||
|
@ -29,22 +29,6 @@
|
||||||
#include "os-libcdio.h"
|
#include "os-libcdio.h"
|
||||||
|
|
||||||
|
|
||||||
#else
|
|
||||||
#ifdef __NetBSD__
|
|
||||||
|
|
||||||
|
|
||||||
/* -------------------------- NetBSD with SCIOCCOMMAND --------------------- */
|
|
||||||
#include "os-netbsd.h"
|
|
||||||
|
|
||||||
|
|
||||||
#else
|
|
||||||
#ifdef __OpenBSD__
|
|
||||||
|
|
||||||
|
|
||||||
/* -------------------------- OpenBSD with SCIOCCOMMAND -------------------- */
|
|
||||||
#include "os-netbsd.h"
|
|
||||||
|
|
||||||
|
|
||||||
#else
|
#else
|
||||||
#ifdef __FreeBSD__
|
#ifdef __FreeBSD__
|
||||||
|
|
||||||
|
@ -88,8 +72,6 @@
|
||||||
#endif /* ! __linux */
|
#endif /* ! __linux */
|
||||||
#endif /* ! __FreeBSD__kernel__ */
|
#endif /* ! __FreeBSD__kernel__ */
|
||||||
#endif /* ! __FreeBSD__ */
|
#endif /* ! __FreeBSD__ */
|
||||||
#endif /* ! __OpenBSD__ */
|
|
||||||
#endif /* ! __NetBSD__ */
|
|
||||||
#endif /* ! Libburn_use_libcdiO */
|
#endif /* ! Libburn_use_libcdiO */
|
||||||
#endif /* ! Libburn_use_sg_dummY */
|
#endif /* ! Libburn_use_sg_dummY */
|
||||||
|
|
||||||
|
|
401
libburn/read.c
401
libburn/read.c
|
@ -1,7 +1,7 @@
|
||||||
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||||
|
|
||||||
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
|
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
|
||||||
Copyright (c) 2006 - 2024 Thomas Schmitt <scdbackup@gmx.net>
|
Copyright (c) 2006 - 2011 Thomas Schmitt <scdbackup@gmx.net>
|
||||||
Provided under GPL version 2 or later.
|
Provided under GPL version 2 or later.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -22,11 +22,6 @@
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <errno.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 "sector.h"
|
||||||
#include "libburn.h"
|
#include "libburn.h"
|
||||||
#include "drive.h"
|
#include "drive.h"
|
||||||
|
@ -41,7 +36,6 @@
|
||||||
#include "init.h"
|
#include "init.h"
|
||||||
#include "toc.h"
|
#include "toc.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "mmc.h"
|
|
||||||
#include "sg.h"
|
#include "sg.h"
|
||||||
#include "read.h"
|
#include "read.h"
|
||||||
#include "options.h"
|
#include "options.h"
|
||||||
|
@ -121,6 +115,7 @@ drive, or only store a subset of the _opts structs in drives */
|
||||||
while (1) {
|
while (1) {
|
||||||
seclen = burn_sector_length_read(d, o);
|
seclen = burn_sector_length_read(d, o);
|
||||||
|
|
||||||
|
burn_print(12, "received %d blocks\n", page.sectors);
|
||||||
for (i = 0; i < page.sectors; i++) {
|
for (i = 0; i < page.sectors; i++) {
|
||||||
burn_packet_process(d, page.data + seclen * i, o);
|
burn_packet_process(d, page.data + seclen * i, o);
|
||||||
d->track_end--;
|
d->track_end--;
|
||||||
|
@ -128,6 +123,7 @@ drive, or only store a subset of the _opts structs in drives */
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((d->cancel) || (drive_lba == LAST_SESSION_END(d))) {
|
if ((d->cancel) || (drive_lba == LAST_SESSION_END(d))) {
|
||||||
|
burn_print(1, "finished or cancelled\n");
|
||||||
d->busy = BURN_DRIVE_IDLE;
|
d->busy = BURN_DRIVE_IDLE;
|
||||||
if (!d->cancel)
|
if (!d->cancel)
|
||||||
d->toc->complete = 1;
|
d->toc->complete = 1;
|
||||||
|
@ -141,14 +137,16 @@ drive, or only store a subset of the _opts structs in drives */
|
||||||
if (d->currtrack >
|
if (d->currtrack >
|
||||||
d->toc->session[d->currsession].lasttrack) {
|
d->toc->session[d->currsession].lasttrack) {
|
||||||
d->currsession++;
|
d->currsession++;
|
||||||
/* session switch to d->currsession */
|
burn_print(12, "session switch to %d\n",
|
||||||
/* skipping a lead out */
|
d->currsession);
|
||||||
|
burn_print(12, "skipping a lead out\n");
|
||||||
drive_lba = CURRENT_SESSION_START(d);
|
drive_lba = CURRENT_SESSION_START(d);
|
||||||
|
burn_print(12, "new lba %d\n", drive_lba);
|
||||||
/* XXX more of the same
|
/* XXX more of the same
|
||||||
end = burn_track_end(d, d->currsession,
|
end = burn_track_end(d, d->currsession,
|
||||||
d->currtrack);
|
d->currtrack);
|
||||||
*/
|
*/ }
|
||||||
}
|
burn_print(12, "track switch to %d\n", d->currtrack);
|
||||||
}
|
}
|
||||||
|
|
||||||
page.sectors = 0;
|
page.sectors = 0;
|
||||||
|
@ -164,8 +162,6 @@ drive, or only store a subset of the _opts structs in drives */
|
||||||
drive_lba);
|
drive_lba);
|
||||||
|
|
||||||
/* >>> ts A61009 : ensure page.sectors >= 0 before calling */
|
/* >>> ts A61009 : ensure page.sectors >= 0 before calling */
|
||||||
/* >>> ts B21123 : Would now be d->read_cd() with
|
|
||||||
with sectype = 0 , mainch = 0xf8 */
|
|
||||||
d->r ead_sectors(d, drive_lba, page.sectors, o, &page);
|
d->r ead_sectors(d, drive_lba, page.sectors, o, &page);
|
||||||
|
|
||||||
printf("Read %d\n", page.sectors);
|
printf("Read %d\n", page.sectors);
|
||||||
|
@ -205,7 +201,6 @@ static int bitcount(unsigned char *data, int n)
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void burn_packet_process(struct burn_drive *d, unsigned char *data,
|
void burn_packet_process(struct burn_drive *d, unsigned char *data,
|
||||||
const struct burn_read_opts *o)
|
const struct burn_read_opts *o)
|
||||||
{
|
{
|
||||||
|
@ -219,7 +214,12 @@ void burn_packet_process(struct burn_drive *d, unsigned char *data,
|
||||||
if (o->c2errors) {
|
if (o->c2errors) {
|
||||||
fb = bitcount(data + ptr, 294);
|
fb = bitcount(data + ptr, 294);
|
||||||
if (fb) {
|
if (fb) {
|
||||||
/* bitcount(data + ptr, 294) damaged bits */;
|
burn_print(1, "%d damaged bits\n",
|
||||||
|
bitcount(data + ptr, 294));
|
||||||
|
burn_print(1, "sending error on %s %s\n",
|
||||||
|
d->idata->vendor, d->idata->product);
|
||||||
|
/* XXX send a burn_message! burn_message_error(d,
|
||||||
|
something); */
|
||||||
}
|
}
|
||||||
ptr += 294;
|
ptr += 294;
|
||||||
}
|
}
|
||||||
|
@ -259,13 +259,12 @@ void burn_packet_process(struct burn_drive *d, unsigned char *data,
|
||||||
#ifndef Libburn_no_crc_C
|
#ifndef Libburn_no_crc_C
|
||||||
crc = (*(sub + 22) << 8) + *(sub + 23);
|
crc = (*(sub + 22) << 8) + *(sub + 23);
|
||||||
if (crc != crc_ccitt(sub + 12, 10)) {
|
if (crc != crc_ccitt(sub + 12, 10)) {
|
||||||
/*
|
|
||||||
burn_print(1, "sending error on %s %s\n",
|
burn_print(1, "sending error on %s %s\n",
|
||||||
d->idata->vendor, d->idata->product);
|
d->idata->vendor, d->idata->product);
|
||||||
e = burn_error();
|
/* e = burn_error();
|
||||||
e->drive = d;
|
e->drive = d;
|
||||||
|
*/
|
||||||
burn_print(1, "crc mismatch in Q\n");
|
burn_print(1, "crc mismatch in Q\n");
|
||||||
*/;
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -286,7 +285,7 @@ void burn_packet_process(struct burn_drive *d, unsigned char *data,
|
||||||
*//* write(o->datafd, data, 2352); */
|
*//* write(o->datafd, data, 2352); */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* so yeah, when you uncomment these, make them write zeros instead of crap
|
/* so yeah, when you uncomment these, make them write zeros insted of crap
|
||||||
static void write_empty_sector(int fd)
|
static void write_empty_sector(int fd)
|
||||||
{
|
{
|
||||||
static char sec[2352], initialized = 0;
|
static char sec[2352], initialized = 0;
|
||||||
|
@ -314,33 +313,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 */
|
/* ts A70904 */
|
||||||
/** @param flag bit0= be silent on data shortage
|
/** @param flag bit0=be silent on data shortage */
|
||||||
bit5= report data shortage with severity DEBUG
|
|
||||||
*/
|
|
||||||
int burn_stdio_read(int fd, char *buf, int bufsize, struct burn_drive *d,
|
int burn_stdio_read(int fd, char *buf, int bufsize, struct burn_drive *d,
|
||||||
int flag)
|
int flag)
|
||||||
{
|
{
|
||||||
|
@ -355,9 +329,7 @@ int burn_stdio_read(int fd, char *buf, int bufsize, struct burn_drive *d,
|
||||||
if(todo > 0 && !(flag & 1)) {
|
if(todo > 0 && !(flag & 1)) {
|
||||||
libdax_msgs_submit(libdax_messenger, d->global_index,
|
libdax_msgs_submit(libdax_messenger, d->global_index,
|
||||||
0x0002014a,
|
0x0002014a,
|
||||||
(flag & 32) ?
|
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
LIBDAX_MSGS_SEV_DEBUG : LIBDAX_MSGS_SEV_SORRY,
|
|
||||||
LIBDAX_MSGS_PRIO_HIGH,
|
|
||||||
"Cannot read desired amount of data", errno, 0);
|
"Cannot read desired amount of data", errno, 0);
|
||||||
}
|
}
|
||||||
if (count < 0)
|
if (count < 0)
|
||||||
|
@ -366,82 +338,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 */
|
/* ts A70812 : API function */
|
||||||
int burn_read_data(struct burn_drive *d, off_t byte_address,
|
int burn_read_data(struct burn_drive *d, off_t byte_address,
|
||||||
char data[], off_t data_size, off_t *data_count, int flag)
|
char data[], off_t data_size, off_t *data_count, int flag)
|
||||||
{
|
{
|
||||||
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;
|
int sose_mem = 0, fd = -1, ret;
|
||||||
char msg[81], *wpt;
|
char msg[81], *wpt;
|
||||||
struct buffer *buf = NULL, *buffer_mem = d->buffer;
|
struct buffer *buf = NULL, *buffer_mem = d->buffer;
|
||||||
|
@ -492,17 +393,17 @@ int burn_read_data(struct burn_drive *d, off_t byte_address,
|
||||||
msg, 0, 0);
|
msg, 0, 0);
|
||||||
{ret = 0; goto ex;}
|
{ret = 0; goto ex;}
|
||||||
}
|
}
|
||||||
if (d->media_read_capacity != 0x7fffffffffffffff &&
|
if (d->media_read_capacity != 0x7fffffff && byte_address >=
|
||||||
byte_address >= (d->media_read_capacity + 1) * (off_t) 2048) {
|
((off_t) d->media_read_capacity + (off_t) 1) * (off_t) 2048) {
|
||||||
if (!(flag & 2)) {
|
if (!(flag & 2)) {
|
||||||
sprintf(msg,
|
sprintf(msg,
|
||||||
"Read start address %.fs larger than number of readable blocks %.f",
|
"Read start address %ds larger than number of readable blocks %d",
|
||||||
(double) (byte_address / 2048 + !!(byte_address % 2048)),
|
(int) (byte_address / 2048 + !!(byte_address % 2048)),
|
||||||
(double) (d->media_read_capacity + 1));
|
d->media_read_capacity);
|
||||||
libdax_msgs_submit(libdax_messenger, d->global_index,
|
libdax_msgs_submit(libdax_messenger, d->global_index,
|
||||||
0x00020172, (flag & 32) ?
|
0x00020172,
|
||||||
LIBDAX_MSGS_SEV_DEBUG : LIBDAX_MSGS_SEV_SORRY,
|
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
LIBDAX_MSGS_PRIO_HIGH, msg, 0, 0);
|
msg, 0, 0);
|
||||||
}
|
}
|
||||||
{ret = 0; goto ex;}
|
{ret = 0; goto ex;}
|
||||||
}
|
}
|
||||||
|
@ -526,8 +427,7 @@ int burn_read_data(struct burn_drive *d, off_t byte_address,
|
||||||
fd = d->stdio_fd;
|
fd = d->stdio_fd;
|
||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
d->stdio_fd = fd =
|
d->stdio_fd = fd =
|
||||||
open(d->devname,
|
open(d->devname, O_RDONLY | O_LARGEFILE);
|
||||||
O_RDONLY | O_LARGEFILE | O_BINARY);
|
|
||||||
if (fd == -1) {
|
if (fd == -1) {
|
||||||
if (errno == EACCES && (flag & 2)) {
|
if (errno == EACCES && (flag & 2)) {
|
||||||
if (!(flag & 8))
|
if (!(flag & 8))
|
||||||
|
@ -537,23 +437,29 @@ int burn_read_data(struct burn_drive *d, off_t byte_address,
|
||||||
LIBDAX_MSGS_PRIO_HIGH,
|
LIBDAX_MSGS_PRIO_HIGH,
|
||||||
"Failed to open device (a pseudo-drive) for reading",
|
"Failed to open device (a pseudo-drive) for reading",
|
||||||
errno, 0);
|
errno, 0);
|
||||||
} else if (errno != ENOENT || !(flag & 2))
|
} else if (errno!= ENOENT || !(flag & 2))
|
||||||
libdax_msgs_submit(libdax_messenger,
|
libdax_msgs_submit(libdax_messenger,
|
||||||
d->global_index, 0x00020005,
|
d->global_index, 0x00020005,
|
||||||
(flag & 32) && errno == ENOENT ?
|
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
LIBDAX_MSGS_SEV_DEBUG :
|
|
||||||
LIBDAX_MSGS_SEV_SORRY,
|
|
||||||
LIBDAX_MSGS_PRIO_HIGH,
|
|
||||||
"Failed to open device (a pseudo-drive) for reading",
|
"Failed to open device (a pseudo-drive) for reading",
|
||||||
errno, 0);
|
errno, 0);
|
||||||
ret = 0;
|
ret = 0;
|
||||||
if (errno == EACCES && (flag & 8))
|
if (errno == EACCES && (flag & 8))
|
||||||
ret= -2;
|
ret= -2;
|
||||||
goto ex;
|
goto ex;
|
||||||
}
|
}
|
||||||
ret = burn_stdio_seek(fd, byte_address, d, flag & (2 | 32));
|
if (lseek(fd, byte_address, SEEK_SET) == -1) {
|
||||||
if (ret <= 0)
|
if (!(flag & 2)) {
|
||||||
goto ex;
|
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;
|
d->busy = BURN_DRIVE_READING_SYNC;
|
||||||
|
@ -566,213 +472,66 @@ int burn_read_data(struct burn_drive *d, off_t byte_address,
|
||||||
wpt = data;
|
wpt = data;
|
||||||
for (; start < upto; start += chunksize) {
|
for (; start < upto; start += chunksize) {
|
||||||
chunksize = upto - start;
|
chunksize = upto - start;
|
||||||
if (chunksize > (BUFFER_SIZE / 2048)) {
|
if (chunksize > 16) {
|
||||||
chunksize = (BUFFER_SIZE / 2048);
|
chunksize = 16;
|
||||||
cpy_size = BUFFER_SIZE;
|
cpy_size = 16 * 2048;
|
||||||
} else
|
} else
|
||||||
cpy_size = data_size - *data_count;
|
cpy_size = data_size - *data_count;
|
||||||
if (flag & 2)
|
if (flag & 2)
|
||||||
d->silent_on_scsi_error = 1;
|
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)
|
|
||||||
d->silent_on_scsi_error = 2;
|
|
||||||
}
|
|
||||||
if (d->drive_role == 1) {
|
if (d->drive_role == 1) {
|
||||||
err = d->read_10(d, start, chunksize, d->buffer);
|
err = d->read_10(d, start, chunksize, d->buffer);
|
||||||
} else {
|
} else {
|
||||||
ret = burn_stdio_read(fd, (char *) d->buffer->data,
|
ret = burn_stdio_read(fd, (char *) d->buffer->data,
|
||||||
cpy_size, d,
|
cpy_size, d, !!(flag & 2));
|
||||||
(flag & 32) | !!(flag & 2));
|
|
||||||
err = 0;
|
err = 0;
|
||||||
if (ret <= 0)
|
if (ret <= 0)
|
||||||
err = BE_CANCELLED;
|
err = BE_CANCELLED;
|
||||||
}
|
}
|
||||||
if (flag & (2 | 16 | 32))
|
if (flag & 2)
|
||||||
d->silent_on_scsi_error = sose_mem;
|
d->silent_on_scsi_error = sose_mem;
|
||||||
if (err == BE_CANCELLED) {
|
if (err == BE_CANCELLED) {
|
||||||
if ((flag & 16) && (d->had_particular_error & 1))
|
/* Try to read a smaller part of the chunk */
|
||||||
{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);
|
|
||||||
}
|
|
||||||
if (ret <= 0)
|
|
||||||
goto bad_read;
|
|
||||||
} else {
|
|
||||||
memcpy(wpt, d->buffer->data, cpy_size);
|
|
||||||
wpt += cpy_size;
|
|
||||||
*data_count += cpy_size;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = 1;
|
|
||||||
ex:;
|
|
||||||
BURN_FREE_MEM(buf);
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* ts B21119 : API function*/
|
|
||||||
int burn_read_audio(struct burn_drive *d, int sector_no,
|
|
||||||
char data[], off_t data_size, off_t *data_count, int flag)
|
|
||||||
{
|
|
||||||
int alignment = 2352, start, upto, chunksize = 1, err, cpy_size, i;
|
|
||||||
int sose_mem = 0, ret;
|
|
||||||
char msg[81], *wpt;
|
|
||||||
struct buffer *buf = NULL, *buffer_mem = d->buffer;
|
|
||||||
|
|
||||||
BURN_ALLOC_MEM(buf, struct buffer, 1);
|
|
||||||
*data_count = 0;
|
|
||||||
sose_mem = d->silent_on_scsi_error;
|
|
||||||
|
|
||||||
if (d->released) {
|
|
||||||
libdax_msgs_submit(libdax_messenger,
|
|
||||||
d->global_index, 0x00020142,
|
|
||||||
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
|
|
||||||
"Drive is not grabbed on random access read", 0, 0);
|
|
||||||
{ret = 0; goto ex;}
|
|
||||||
}
|
|
||||||
if (d->drive_role != 1) {
|
|
||||||
libdax_msgs_submit(libdax_messenger, d->global_index,
|
|
||||||
0x00020146,
|
|
||||||
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
|
|
||||||
"Drive is a virtual placeholder (stdio-drive or null-drive)",
|
|
||||||
0, 0);
|
|
||||||
{ret = 0; goto ex;}
|
|
||||||
}
|
|
||||||
if ((data_size % alignment) != 0) {
|
|
||||||
sprintf(msg,
|
|
||||||
"Audio read size not properly aligned (%d bytes)",
|
|
||||||
alignment);
|
|
||||||
libdax_msgs_submit(libdax_messenger, d->global_index,
|
|
||||||
0x0002019d,
|
|
||||||
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
|
|
||||||
msg, 0, 0);
|
|
||||||
{ret = 0; goto ex;}
|
|
||||||
}
|
|
||||||
if (d->busy != BURN_DRIVE_IDLE) {
|
|
||||||
libdax_msgs_submit(libdax_messenger,
|
|
||||||
d->global_index, 0x00020145,
|
|
||||||
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
|
|
||||||
"Drive is busy on attempt to read audio", 0, 0);
|
|
||||||
{ret = 0; goto ex;}
|
|
||||||
}
|
|
||||||
|
|
||||||
d->busy = BURN_DRIVE_READING_SYNC;
|
|
||||||
d->buffer = buf;
|
|
||||||
|
|
||||||
start = sector_no;
|
|
||||||
upto = start + data_size / alignment;
|
|
||||||
wpt = data;
|
|
||||||
for (; start < upto; start += chunksize) {
|
|
||||||
chunksize = upto - start;
|
|
||||||
if (chunksize > (BUFFER_SIZE / alignment))
|
|
||||||
chunksize = (BUFFER_SIZE / alignment);
|
|
||||||
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)
|
|
||||||
d->silent_on_scsi_error = 2;
|
|
||||||
}
|
|
||||||
err = d->read_cd(d, start, chunksize, 1, 0x10, NULL, d->buffer,
|
|
||||||
(flag & 8) >> 3);
|
|
||||||
if (flag & (2 | 16 | 32))
|
|
||||||
d->silent_on_scsi_error = sose_mem;
|
|
||||||
if (err == BE_CANCELLED) {
|
|
||||||
if ((flag & 16) && (d->had_particular_error & 1))
|
|
||||||
{ret = -3; goto ex;}
|
|
||||||
if(!(flag & 4))
|
if(!(flag & 4))
|
||||||
for (i = 0; i < chunksize - 1; i++) {
|
for (i = 0; i < chunksize - 1; i++) {
|
||||||
if (flag & 2)
|
if (flag & 2)
|
||||||
d->silent_on_scsi_error = 1;
|
d->silent_on_scsi_error = 1;
|
||||||
else if (flag & 32)
|
if (d->drive_role == 1) {
|
||||||
d->silent_on_scsi_error = 3;
|
err = d->read_10(d, start + i, 1,
|
||||||
err = d->read_cd(d, start + i, 1, 1, 0x10,
|
d->buffer);
|
||||||
NULL, d->buffer, (flag & 8) >> 3);
|
} else {
|
||||||
if (flag & (2 | 32))
|
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;
|
d->silent_on_scsi_error = sose_mem;
|
||||||
if (err == BE_CANCELLED)
|
if (err == BE_CANCELLED)
|
||||||
break;
|
break;
|
||||||
memcpy(wpt, d->buffer->data, alignment);
|
memcpy(wpt, d->buffer->data, 2048);
|
||||||
wpt += alignment;
|
wpt += 2048;
|
||||||
*data_count += alignment;
|
*data_count += 2048;
|
||||||
}
|
}
|
||||||
|
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;
|
ret = 0; goto ex;
|
||||||
}
|
}
|
||||||
memcpy(wpt, d->buffer->data, cpy_size);
|
memcpy(wpt, d->buffer->data, cpy_size);
|
||||||
wpt += cpy_size;
|
wpt += cpy_size;
|
||||||
*data_count += cpy_size;
|
*data_count += cpy_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = 1;
|
ret = 1;
|
||||||
ex:
|
ex:;
|
||||||
BURN_FREE_MEM(buf);
|
BURN_FREE_MEM(buf);
|
||||||
d->buffer = buffer_mem;
|
d->buffer = buffer_mem;
|
||||||
d->busy = BURN_DRIVE_IDLE;
|
d->busy = BURN_DRIVE_IDLE;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef Libburn_develop_quality_scaN
|
|
||||||
|
|
||||||
/* B21108 ts */
|
|
||||||
int burn_nec_optiarc_rep_err_rate(struct burn_drive *d,
|
|
||||||
int start_lba, int rate_period, int flag)
|
|
||||||
{
|
|
||||||
int ret, lba = 0, error_rate1 = 0, error_rate2 = 0, enabled = 0, dret;
|
|
||||||
|
|
||||||
/* Sub Operation Code 1 : Enable Error Rate reporting function */
|
|
||||||
ret = mmc_nec_optiarc_f3(d, 1, start_lba, rate_period,
|
|
||||||
&lba, &error_rate1, &error_rate2);
|
|
||||||
if (ret <= 0)
|
|
||||||
goto ex;
|
|
||||||
enabled = 1;
|
|
||||||
|
|
||||||
/* >>> Sub Operation Code 2 : Seek to starting address
|
|
||||||
start_lba , rate_period
|
|
||||||
*/;
|
|
||||||
|
|
||||||
/* >>> Loop with Sub Operation Code 3 : Send Error Rate information
|
|
||||||
reply: 4-byte LBA , 2-byte C1/PIE , 2-byte C2/PIF
|
|
||||||
*/;
|
|
||||||
|
|
||||||
ret = 1;
|
|
||||||
ex:;
|
|
||||||
if (enabled) {
|
|
||||||
/* Code F : Disable Error Rate reporting function */
|
|
||||||
dret = mmc_nec_optiarc_f3(d, 0xf, 0, 0,
|
|
||||||
&lba, &error_rate1, &error_rate2);
|
|
||||||
if (dret < ret)
|
|
||||||
ret = dret;
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* Libburn_develop_quality_scaN */
|
|
||||||
|
|
||||||
|
|
|
@ -67,7 +67,6 @@ void sbc_load(struct burn_drive *d)
|
||||||
/* c->opcode[1] |= 1; / * ts A70918 : Immed */
|
/* c->opcode[1] |= 1; / * ts A70918 : Immed */
|
||||||
|
|
||||||
c->dir = NO_TRANSFER;
|
c->dir = NO_TRANSFER;
|
||||||
c->timeout = Libburn_mmc_load_timeouT;
|
|
||||||
d->issue_command(d, c);
|
d->issue_command(d, c);
|
||||||
if (c->error)
|
if (c->error)
|
||||||
return;
|
return;
|
||||||
|
@ -114,15 +113,12 @@ int sbc_start_unit_flag(struct burn_drive *d, int flag)
|
||||||
|
|
||||||
scsi_init_command(c, SBC_START_UNIT, sizeof(SBC_START_UNIT));
|
scsi_init_command(c, SBC_START_UNIT, sizeof(SBC_START_UNIT));
|
||||||
c->retry = 1;
|
c->retry = 1;
|
||||||
if (d->do_no_immed && (flag & 1))
|
c->opcode[1] |= (flag & 1); /* ts A70918 : Immed */
|
||||||
c->timeout = 1800 * 1000;
|
|
||||||
else
|
|
||||||
c->opcode[1] |= (flag & 1); /* ts A70918 : Immed */
|
|
||||||
c->dir = NO_TRANSFER;
|
c->dir = NO_TRANSFER;
|
||||||
d->issue_command(d, c);
|
d->issue_command(d, c);
|
||||||
if (c->error)
|
if (c->error)
|
||||||
return 0;
|
return 0;
|
||||||
if (d->do_no_immed || !(flag & 1))
|
if (!(flag & 1))
|
||||||
return 1;
|
return 1;
|
||||||
/* ts A70918 : asynchronous */
|
/* ts A70918 : asynchronous */
|
||||||
ret = spc_wait_unit_attention(d, 1800, "START UNIT", 0);
|
ret = spc_wait_unit_attention(d, 1800, "START UNIT", 0);
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||||
|
|
||||||
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
|
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
|
||||||
Copyright (c) 2006 - 2021 Thomas Schmitt <scdbackup@gmx.net>
|
Copyright (c) 2006 - 2011 Thomas Schmitt <scdbackup@gmx.net>
|
||||||
Provided under GPL version 2 or later.
|
Provided under GPL version 2 or later.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -40,10 +40,6 @@ extern struct libdax_msgs *libdax_messenger;
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#endif /* Libburn_log_in_and_out_streaM */
|
#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";*/
|
/*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;
|
static int tee_fd= -1;
|
||||||
if(tee_fd==-1)
|
if(tee_fd==-1)
|
||||||
tee_fd= open("/tmp/libburn_sg_readin",
|
tee_fd= open("/tmp/libburn_sg_readin",
|
||||||
O_WRONLY | O_CREAT | O_TRUNC | O_BINARY,
|
O_WRONLY|O_CREAT|O_TRUNC,S_IRUSR|S_IWUSR);
|
||||||
S_IRUSR | S_IWUSR);
|
|
||||||
#endif /* Libburn_log_in_and_out_streaM */
|
#endif /* Libburn_log_in_and_out_streaM */
|
||||||
|
|
||||||
|
|
||||||
|
@ -190,20 +185,13 @@ static void get_bytes(struct burn_track *track, int count, unsigned char *data)
|
||||||
if (track->end_on_premature_eoi && shortage >= count &&
|
if (track->end_on_premature_eoi && shortage >= count &&
|
||||||
!track->open_ended) {
|
!track->open_ended) {
|
||||||
char msg[80];
|
char msg[80];
|
||||||
off_t missing, inp_block_size, track_blocks;
|
/* Memorize that premature end of input happened */
|
||||||
|
|
||||||
inp_block_size = burn_sector_length(track->mode);
|
|
||||||
track_blocks = burn_track_get_sectors_2_v2(track, 1);
|
|
||||||
if (track_blocks < 0)
|
|
||||||
track_blocks = 0;
|
|
||||||
missing = track_blocks * inp_block_size - track->sourcecount;
|
|
||||||
sprintf(msg,
|
sprintf(msg,
|
||||||
"Premature end of input encountered. Missing: %.f bytes",
|
"Premature end of input encountered. Missing: %d bytes",
|
||||||
(double) missing);
|
shortage);
|
||||||
libdax_msgs_submit(libdax_messenger, -1, 0x00020180,
|
libdax_msgs_submit(libdax_messenger, -1, 0x00020180,
|
||||||
LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH,
|
LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
msg, 0,0);
|
msg, 0,0);
|
||||||
/* Memorize that premature end of input happened */
|
|
||||||
track->end_on_premature_eoi = 2;
|
track->end_on_premature_eoi = 2;
|
||||||
}
|
}
|
||||||
if (track->open_ended || track->end_on_premature_eoi)
|
if (track->open_ended || track->end_on_premature_eoi)
|
||||||
|
@ -235,43 +223,6 @@ ex:;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ts B20113 : outsourced from get_sector() */
|
|
||||||
int sector_write_buffer(struct burn_drive *d,
|
|
||||||
struct burn_track *track, int flag)
|
|
||||||
{
|
|
||||||
int err, i;
|
|
||||||
struct buffer *out;
|
|
||||||
|
|
||||||
out = d->buffer;
|
|
||||||
if (out->sectors <= 0)
|
|
||||||
return 2;
|
|
||||||
err = d->write(d, d->nwa, out);
|
|
||||||
if (err == BE_CANCELLED)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
/* ts A61101 */
|
|
||||||
if(track != NULL) {
|
|
||||||
track->writecount += out->bytes;
|
|
||||||
track->written_sectors += out->sectors;
|
|
||||||
|
|
||||||
/* Determine current index */
|
|
||||||
for (i = d->progress.index; i + 1 < track->indices; i++) {
|
|
||||||
if (track->index[i + 1] > d->nwa + out->sectors)
|
|
||||||
break;
|
|
||||||
d->progress.index = i + 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* ts A61119 */
|
|
||||||
d->progress.buffered_bytes += out->bytes;
|
|
||||||
|
|
||||||
d->nwa += out->sectors;
|
|
||||||
out->bytes = 0;
|
|
||||||
out->sectors = 0;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* ts A61009 : seems to hand out sector start pointer in opts->drive->buffer
|
/* ts A61009 : seems to hand out sector start pointer in opts->drive->buffer
|
||||||
and to count hand outs as well as reserved bytes */
|
and to count hand outs as well as reserved bytes */
|
||||||
/* ts A61101 : added parameter track for counting written bytes */
|
/* ts A61101 : added parameter track for counting written bytes */
|
||||||
|
@ -280,7 +231,7 @@ static unsigned char *get_sector(struct burn_write_opts *opts,
|
||||||
{
|
{
|
||||||
struct burn_drive *d = opts->drive;
|
struct burn_drive *d = opts->drive;
|
||||||
struct buffer *out = d->buffer;
|
struct buffer *out = d->buffer;
|
||||||
int outmode, seclen, write_ret;
|
int outmode, seclen;
|
||||||
unsigned char *ret;
|
unsigned char *ret;
|
||||||
|
|
||||||
outmode = get_outmode(opts);
|
outmode = get_outmode(opts);
|
||||||
|
@ -299,9 +250,22 @@ static unsigned char *get_sector(struct burn_write_opts *opts,
|
||||||
/* (there is enough buffer size reserve for track->cdxa_conversion) */
|
/* (there is enough buffer size reserve for track->cdxa_conversion) */
|
||||||
if (out->bytes + seclen > BUFFER_SIZE ||
|
if (out->bytes + seclen > BUFFER_SIZE ||
|
||||||
(opts->obs > 0 && out->bytes + seclen > opts->obs)) {
|
(opts->obs > 0 && out->bytes + seclen > opts->obs)) {
|
||||||
write_ret = sector_write_buffer(d, track, 0);
|
int err;
|
||||||
if (write_ret <= 0)
|
err = d->write(d, d->nwa, out);
|
||||||
|
if (err == BE_CANCELLED)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
/* ts A61101 */
|
||||||
|
if(track != NULL) {
|
||||||
|
track->writecount += out->bytes;
|
||||||
|
track->written_sectors += out->sectors;
|
||||||
|
}
|
||||||
|
/* ts A61119 */
|
||||||
|
d->progress.buffered_bytes += out->bytes;
|
||||||
|
|
||||||
|
d->nwa += out->sectors;
|
||||||
|
out->bytes = 0;
|
||||||
|
out->sectors = 0;
|
||||||
}
|
}
|
||||||
ret = out->data + out->bytes;
|
ret = out->data + out->bytes;
|
||||||
out->bytes += seclen;
|
out->bytes += seclen;
|
||||||
|
@ -355,7 +319,7 @@ static int convert_data(struct burn_write_opts *o, struct burn_track *track,
|
||||||
|
|
||||||
/* ts A61010 */
|
/* ts A61010 */
|
||||||
/* a ssert(outlen >= inlen); */
|
/* a ssert(outlen >= inlen); */
|
||||||
if (outlen < inlen || outlen < 0 || inlen < 0)
|
if (outlen < inlen)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if ((outmode & BURN_MODE_BITS) == (inmode & BURN_MODE_BITS)) {
|
if ((outmode & BURN_MODE_BITS) == (inmode & BURN_MODE_BITS)) {
|
||||||
|
@ -914,7 +878,7 @@ void process_q(struct burn_drive *d, unsigned char *q)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
/* XXX do not ignore these */
|
/* XXX dont ignore these */
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
/* burn_print(12, "ISRC data in mode 3 q\n");*/
|
/* burn_print(12, "ISRC data in mode 3 q\n");*/
|
||||||
|
@ -925,7 +889,7 @@ void process_q(struct burn_drive *d, unsigned char *q)
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|
||||||
/* ts A61009 : if reactivated then without Assert */
|
/* ts A61009 : if reactivated then witout Assert */
|
||||||
a ssert(0);
|
a ssert(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -933,7 +897,7 @@ void process_q(struct burn_drive *d, unsigned char *q)
|
||||||
|
|
||||||
/* this needs more info. subs in the data? control/adr? */
|
/* this needs more info. subs in the data? control/adr? */
|
||||||
|
|
||||||
/* ts A61119 : One should not use unofficial compiler extensions.
|
/* ts A61119 : One should not use inofficial compiler extensions.
|
||||||
>>> Some day this function needs to be implemented. At least for now
|
>>> Some day this function needs to be implemented. At least for now
|
||||||
the result does not match the "mode" of cdrecord -toc.
|
the result does not match the "mode" of cdrecord -toc.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -24,10 +24,6 @@ int sector_postgap(struct burn_write_opts *, unsigned char tno,
|
||||||
int sector_lout(struct burn_write_opts *, unsigned char control, int mode);
|
int sector_lout(struct burn_write_opts *, unsigned char control, int mode);
|
||||||
int sector_data(struct burn_write_opts *, struct burn_track *t, int psub);
|
int sector_data(struct burn_write_opts *, struct burn_track *t, int psub);
|
||||||
|
|
||||||
/* ts B20113 */
|
|
||||||
int sector_write_buffer(struct burn_drive *d,
|
|
||||||
struct burn_track *track, int flag);
|
|
||||||
|
|
||||||
/* ts A61009 */
|
/* ts A61009 */
|
||||||
int sector_headers_is_ok(struct burn_write_opts *o, int mode);
|
int sector_headers_is_ok(struct burn_write_opts *o, int mode);
|
||||||
|
|
||||||
|
|
|
@ -35,11 +35,6 @@ Present implementation: default dummy which enables libburn only to work
|
||||||
#include <sys/statvfs.h>
|
#include <sys/statvfs.h>
|
||||||
#endif /* Libburn_os_has_stavtfS */
|
#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 "transport.h"
|
||||||
#include "drive.h"
|
#include "drive.h"
|
||||||
#include "sg.h"
|
#include "sg.h"
|
||||||
|
@ -85,7 +80,7 @@ int sg_initialize(char msg[1024], int flag)
|
||||||
|
|
||||||
|
|
||||||
/** Performs global finalization of the SCSI transport adapter and eventually
|
/** Performs global finalization of the SCSI transport adapter and eventually
|
||||||
needed operating system facilities. Releases globally acquired resources.
|
needed operating system facilities. Releases globally aquired resources.
|
||||||
@param flag unused yet, submit 0
|
@param flag unused yet, submit 0
|
||||||
@return 1 = success, <=0 = failure
|
@return 1 = success, <=0 = failure
|
||||||
*/
|
*/
|
||||||
|
@ -144,9 +139,9 @@ int scsi_enumerate_drives(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** Tells whether libburn has the given drive in use or exclusively reserved.
|
/** 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
|
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() */
|
/** Published as burn_drive.drive_is_open() */
|
||||||
int sg_drive_is_open(struct burn_drive * d)
|
int sg_drive_is_open(struct burn_drive * d)
|
||||||
|
@ -180,7 +175,7 @@ int sg_release(struct burn_drive *d)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** Sends a SCSI command to the drive, receives reply and evaluates whether
|
/** Sends a SCSI command to the drive, receives reply and evaluates wether
|
||||||
the command succeeded or shall be retried or finally failed.
|
the command succeeded or shall be retried or finally failed.
|
||||||
Returned SCSI errors shall not lead to a return value indicating failure.
|
Returned SCSI errors shall not lead to a return value indicating failure.
|
||||||
The callers get notified by c->error. An SCSI failure which leads not to
|
The callers get notified by c->error. An SCSI failure which leads not to
|
||||||
|
@ -213,7 +208,7 @@ int sg_obtain_scsi_adr(char *path, int *bus_no, int *host_no, int *channel_no,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** Tells whether a text is a persistent address as listed by the enumeration
|
/** Tells wether a text is a persistent address as listed by the enumeration
|
||||||
functions.
|
functions.
|
||||||
*/
|
*/
|
||||||
int sg_is_enumerable_adr(char *adr)
|
int sg_is_enumerable_adr(char *adr)
|
||||||
|
@ -223,7 +218,7 @@ int sg_is_enumerable_adr(char *adr)
|
||||||
|
|
||||||
|
|
||||||
/* Return 1 if the given path leads to a regular file or a device that can be
|
/* Return 1 if the given path leads to a regular file or a device that can be
|
||||||
fseeked, read, and possibly written with 2 kB granularity.
|
seeked, read, and possibly written with 2 kB granularity.
|
||||||
*/
|
*/
|
||||||
int burn_os_is_2k_seekrw(char *path, int flag)
|
int burn_os_is_2k_seekrw(char *path, int flag)
|
||||||
{
|
{
|
||||||
|
@ -249,7 +244,7 @@ int burn_os_is_2k_seekrw(char *path, int flag)
|
||||||
0 = could not estimate size capacity of file object
|
0 = could not estimate size capacity of file object
|
||||||
1 = estimation has been made, bytes was set
|
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 stat stbuf;
|
||||||
|
|
||||||
|
@ -282,7 +277,7 @@ int burn_os_stdio_capacity(char *path, off_t write_start, off_t *bytes)
|
||||||
long blocks;
|
long blocks;
|
||||||
|
|
||||||
blocks = *bytes / 512;
|
blocks = *bytes / 512;
|
||||||
fd = open(path, open_mode | O_BINARY);
|
fd = open(path, open_mode);
|
||||||
if (fd == -1)
|
if (fd == -1)
|
||||||
{ret = -2; goto ex;}
|
{ret = -2; goto ex;}
|
||||||
ret = ioctl(fd, BLKGETSIZE, &blocks);
|
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 */
|
#endif /* Libburn_if_this_was_linuX */
|
||||||
|
|
||||||
} else if(S_ISREG(stbuf.st_mode)) {
|
} 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);
|
strcpy(testpath, path);
|
||||||
} else
|
} else
|
||||||
{ret = 0; goto ex;}
|
{ret = 0; goto ex;}
|
||||||
|
@ -335,7 +330,7 @@ int burn_os_open_track_src(char *path, int open_flags, int flag)
|
||||||
{
|
{
|
||||||
int fd;
|
int fd;
|
||||||
|
|
||||||
fd = open(path, open_flags | O_BINARY);
|
fd = open(path, open_flags);
|
||||||
return fd;
|
return fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -47,8 +47,8 @@ sg_initialize() performs global initialization of the SCSI transport
|
||||||
facilities. Checks for compatibility of supporting
|
facilities. Checks for compatibility of supporting
|
||||||
software components.
|
software components.
|
||||||
|
|
||||||
sg_shutdown() performs global finalizations and releases globally
|
sg_shutdown() performs global finalizations and releases golbally
|
||||||
acquired resources.
|
aquired resources.
|
||||||
|
|
||||||
sg_give_next_adr() iterates over the set of potentially useful drive
|
sg_give_next_adr() iterates over the set of potentially useful drive
|
||||||
address strings.
|
address strings.
|
||||||
|
@ -57,10 +57,10 @@ scsi_enumerate_drives() brings all available, not-whitelist-banned, and
|
||||||
accessible drives into libburn's list of drives.
|
accessible drives into libburn's list of drives.
|
||||||
|
|
||||||
sg_dispose_drive() finalizes adapter specifics of struct burn_drive
|
sg_dispose_drive() finalizes adapter specifics of struct burn_drive
|
||||||
on destruction. Releases resources which were acquired
|
on destruction. Releases resources which were aquired
|
||||||
underneath scsi_enumerate_drives().
|
underneath scsi_enumerate_drives().
|
||||||
|
|
||||||
sg_drive_is_open() tells whether libburn has the given drive in use.
|
sg_drive_is_open() tells wether libburn has the given drive in use.
|
||||||
|
|
||||||
sg_grab() opens the drive for SCSI commands and ensures
|
sg_grab() opens the drive for SCSI commands and ensures
|
||||||
undisturbed access.
|
undisturbed access.
|
||||||
|
@ -68,7 +68,7 @@ sg_grab() opens the drive for SCSI commands and ensures
|
||||||
sg_release() closes a drive opened by sg_grab()
|
sg_release() closes a drive opened by sg_grab()
|
||||||
|
|
||||||
sg_issue_command() sends a SCSI command to the drive, receives reply,
|
sg_issue_command() sends a SCSI command to the drive, receives reply,
|
||||||
and evaluates whether the command succeeded or shall
|
and evaluates wether the command succeeded or shall
|
||||||
be retried or finally failed.
|
be retried or finally failed.
|
||||||
|
|
||||||
sg_obtain_scsi_adr() tries to obtain SCSI address parameters.
|
sg_obtain_scsi_adr() tries to obtain SCSI address parameters.
|
||||||
|
@ -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_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
|
throughput with file reading and/or SCSI write command
|
||||||
transmission.
|
transmission.
|
||||||
|
|
||||||
|
@ -307,7 +307,7 @@ int sg_initialize(char msg[1024], int flag)
|
||||||
|
|
||||||
|
|
||||||
/** Performs global finalization of the SCSI transport adapter and eventually
|
/** Performs global finalization of the SCSI transport adapter and eventually
|
||||||
needed operating system facilities. Releases globally acquired resources.
|
needed operating system facilities. Releases globally aquired resources.
|
||||||
@param flag unused yet, submit 0
|
@param flag unused yet, submit 0
|
||||||
@return 1 = success, <=0 = failure
|
@return 1 = success, <=0 = failure
|
||||||
*/
|
*/
|
||||||
|
@ -444,9 +444,9 @@ int scsi_enumerate_drives(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** Tells whether libburn has the given drive in use or exclusively reserved.
|
/** 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
|
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() */
|
/** Published as burn_drive.drive_is_open() */
|
||||||
int sg_drive_is_open(struct burn_drive * d)
|
int sg_drive_is_open(struct burn_drive * d)
|
||||||
|
@ -485,7 +485,7 @@ int sg_grab(struct burn_drive *d)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** PORTING: Is mainly about the call to sg_close_drive() and whether it
|
/** PORTING: Is mainly about the call to sg_close_drive() and wether it
|
||||||
implements the demanded functionality.
|
implements the demanded functionality.
|
||||||
*/
|
*/
|
||||||
/** Gives up the drive for SCSI commands and releases eventual access locks.
|
/** Gives up the drive for SCSI commands and releases eventual access locks.
|
||||||
|
@ -493,14 +493,16 @@ int sg_grab(struct burn_drive *d)
|
||||||
*/
|
*/
|
||||||
int sg_release(struct burn_drive *d)
|
int sg_release(struct burn_drive *d)
|
||||||
{
|
{
|
||||||
if (d->cam == NULL)
|
if (d->cam == NULL) {
|
||||||
|
burn_print(1, "release an ungrabbed drive. die\n");
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
sg_close_drive(d);
|
sg_close_drive(d);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** Sends a SCSI command to the drive, receives reply and evaluates whether
|
/** Sends a SCSI command to the drive, receives reply and evaluates wether
|
||||||
the command succeeded or shall be retried or finally failed.
|
the command succeeded or shall be retried or finally failed.
|
||||||
Returned SCSI errors shall not lead to a return value indicating failure.
|
Returned SCSI errors shall not lead to a return value indicating failure.
|
||||||
The callers get notified by c->error. An SCSI failure which leads not to
|
The callers get notified by c->error. An SCSI failure which leads not to
|
||||||
|
@ -548,6 +550,8 @@ int sg_issue_command(struct burn_drive *d, struct command *c)
|
||||||
ccb->csio.cdb_len = c->oplen;
|
ccb->csio.cdb_len = c->oplen;
|
||||||
memcpy(&ccb->csio.cdb_io.cdb_bytes, &c->opcode, c->oplen);
|
memcpy(&ccb->csio.cdb_io.cdb_bytes, &c->opcode, c->oplen);
|
||||||
|
|
||||||
|
memset(&ccb->csio.sense_data, 0, sizeof (ccb->csio.sense_data));
|
||||||
|
|
||||||
if (c->page) {
|
if (c->page) {
|
||||||
ccb->csio.data_ptr = c->page->data;
|
ccb->csio.data_ptr = c->page->data;
|
||||||
if (c->dir == FROM_DRIVE) {
|
if (c->dir == FROM_DRIVE) {
|
||||||
|
@ -567,11 +571,7 @@ int sg_issue_command(struct burn_drive *d, struct command *c)
|
||||||
ccb->csio.dxfer_len = 0;
|
ccb->csio.dxfer_len = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ts B90523 : Record effective transfer length request for debugging*/
|
|
||||||
c->dxfer_len = ccb->csio.dxfer_len;
|
|
||||||
|
|
||||||
do {
|
do {
|
||||||
memset(&ccb->csio.sense_data, 0, sizeof(ccb->csio.sense_data));
|
|
||||||
err = cam_send_ccb(d->cam, ccb);
|
err = cam_send_ccb(d->cam, ccb);
|
||||||
if (err == -1) {
|
if (err == -1) {
|
||||||
libdax_msgs_submit(libdax_messenger,
|
libdax_msgs_submit(libdax_messenger,
|
||||||
|
@ -588,7 +588,6 @@ int sg_issue_command(struct burn_drive *d, struct command *c)
|
||||||
}
|
}
|
||||||
/* XXX */
|
/* XXX */
|
||||||
memcpy(c->sense, &ccb->csio.sense_data, ccb->csio.sense_len);
|
memcpy(c->sense, &ccb->csio.sense_data, ccb->csio.sense_len);
|
||||||
c->sense_len = ccb->csio.sense_len;
|
|
||||||
if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
|
if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
|
||||||
if (!c->retry) {
|
if (!c->retry) {
|
||||||
c->error = 1;
|
c->error = 1;
|
||||||
|
@ -607,8 +606,6 @@ int sg_issue_command(struct burn_drive *d, struct command *c)
|
||||||
} else {
|
} else {
|
||||||
done = 1;
|
done = 1;
|
||||||
}
|
}
|
||||||
if (!done)
|
|
||||||
spc_register_retry(c);
|
|
||||||
} while (!done);
|
} while (!done);
|
||||||
cam_freeccb(ccb);
|
cam_freeccb(ccb);
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -647,7 +644,7 @@ int sg_obtain_scsi_adr(char *path, int *bus_no, int *host_no, int *channel_no,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** Tells whether a text is a persistent address as listed by the enumeration
|
/** Tells wether a text is a persistent address as listed by the enumeration
|
||||||
functions.
|
functions.
|
||||||
*/
|
*/
|
||||||
int sg_is_enumerable_adr(char* adr)
|
int sg_is_enumerable_adr(char* adr)
|
||||||
|
@ -722,7 +719,7 @@ int burn_os_is_2k_seekrw(char *path, int flag)
|
||||||
0 = could not estimate size capacity of file object
|
0 = could not estimate size capacity of file object
|
||||||
1 = estimation has been made, bytes was set
|
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 stat stbuf;
|
||||||
struct statvfs vfsbuf;
|
struct statvfs vfsbuf;
|
||||||
|
@ -775,7 +772,7 @@ int burn_os_stdio_capacity(char *path, off_t write_start, off_t *bytes)
|
||||||
{ret = -2; goto ex;}
|
{ret = -2; goto ex;}
|
||||||
*bytes = add_size;
|
*bytes = add_size;
|
||||||
} else if(S_ISREG(stbuf.st_mode)) {
|
} 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);
|
strcpy(testpath, path);
|
||||||
} else
|
} else
|
||||||
{ret = 0; goto ex;}
|
{ret = 0; goto ex;}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Copyright (c) 2006 - 2013 Thomas Schmitt <scdbackup@gmx.net>
|
Copyright (c) 2006 - 2011 Thomas Schmitt <scdbackup@gmx.net>
|
||||||
Provided under GPL version 2 or later
|
Provided under GPL version 2 or later
|
||||||
and under FreeBSD license revised, i.e. without advertising clause.
|
and under FreeBSD license revised, i.e. without advertising clause.
|
||||||
*/
|
*/
|
||||||
|
@ -128,7 +128,7 @@ int sg_initialize(char msg[1024], int flag)
|
||||||
|
|
||||||
/* ts A91227 */
|
/* ts A91227 */
|
||||||
/** Performs global finalization of the SCSI transport adapter and eventually
|
/** Performs global finalization of the SCSI transport adapter and eventually
|
||||||
needed operating system facilities. Releases globally acquired resources.
|
needed operating system facilities. Releases globally aquired resources.
|
||||||
@param flag unused yet, submit 0
|
@param flag unused yet, submit 0
|
||||||
@return 1 = success, <=0 = failure
|
@return 1 = success, <=0 = failure
|
||||||
*/
|
*/
|
||||||
|
@ -441,11 +441,6 @@ static void enumerate_common(char *fname, int bus_no, int host_no,
|
||||||
struct burn_drive *t;
|
struct burn_drive *t;
|
||||||
struct burn_drive out;
|
struct burn_drive out;
|
||||||
|
|
||||||
/* Initialize pointers to managed memory */
|
|
||||||
out.devname = NULL;
|
|
||||||
out.idata = NULL;
|
|
||||||
out.mdata = NULL;
|
|
||||||
|
|
||||||
/* ts A60923 */
|
/* ts A60923 */
|
||||||
out.bus_no = bus_no;
|
out.bus_no = bus_no;
|
||||||
out.host = host_no;
|
out.host = host_no;
|
||||||
|
@ -453,9 +448,7 @@ static void enumerate_common(char *fname, int bus_no, int host_no,
|
||||||
out.channel = channel_no;
|
out.channel = channel_no;
|
||||||
out.lun = lun_no;
|
out.lun = lun_no;
|
||||||
|
|
||||||
out.devname = strdup(fname);
|
out.devname = burn_strdup(fname);
|
||||||
if (out.devname == NULL)
|
|
||||||
goto could_not_allocate;
|
|
||||||
|
|
||||||
out.cam = NULL;
|
out.cam = NULL;
|
||||||
out.lock_fd = -1;
|
out.lock_fd = -1;
|
||||||
|
@ -484,7 +477,7 @@ static void enumerate_common(char *fname, int bus_no, int host_no,
|
||||||
out.read_toc = mmc_read_toc;
|
out.read_toc = mmc_read_toc;
|
||||||
out.write = mmc_write;
|
out.write = mmc_write;
|
||||||
out.erase = mmc_erase;
|
out.erase = mmc_erase;
|
||||||
out.read_cd = mmc_read_cd;
|
out.read_sectors = mmc_read_sectors;
|
||||||
out.perform_opc = mmc_perform_opc;
|
out.perform_opc = mmc_perform_opc;
|
||||||
out.set_speed = mmc_set_speed;
|
out.set_speed = mmc_set_speed;
|
||||||
out.send_parameters = spc_select_error_params;
|
out.send_parameters = spc_select_error_params;
|
||||||
|
@ -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 = calloc(1, sizeof(struct burn_scsi_inquiry_data));
|
||||||
out.idata->valid = 0;
|
out.idata->valid = 0;
|
||||||
out.mdata = calloc(1, sizeof(struct scsi_mode_data));
|
out.mdata = calloc(1, sizeof(struct scsi_mode_data));
|
||||||
|
out.mdata->valid = 0;
|
||||||
if (out.idata == NULL || out.mdata == NULL) {
|
if (out.idata == NULL || out.mdata == NULL) {
|
||||||
could_not_allocate:;
|
|
||||||
libdax_msgs_submit(libdax_messenger, -1, 0x00020108,
|
libdax_msgs_submit(libdax_messenger, -1, 0x00020108,
|
||||||
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
|
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
"Could not allocate new drive object", 0, 0);
|
"Could not allocate new drive object", 0, 0);
|
||||||
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;
|
return;
|
||||||
}
|
}
|
||||||
out.mdata->p2a_valid = 0;
|
|
||||||
memset(&out.params, 0, sizeof(struct params));
|
memset(&out.params, 0, sizeof(struct params));
|
||||||
t = burn_drive_register(&out);
|
t = burn_drive_register(&out);
|
||||||
|
|
||||||
|
@ -525,9 +508,12 @@ could_not_allocate:;
|
||||||
|
|
||||||
/* try to get the drive info */
|
/* try to get the drive info */
|
||||||
if (t->grab(t)) {
|
if (t->grab(t)) {
|
||||||
|
burn_print(2, "getting drive info\n");
|
||||||
t->getcaps(t);
|
t->getcaps(t);
|
||||||
t->unlock(t);
|
t->unlock(t);
|
||||||
t->released = 1;
|
t->released = 1;
|
||||||
|
} else {
|
||||||
|
burn_print(2, "unable to grab new located drive\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ts A60821
|
/* ts A60821
|
||||||
|
@ -765,8 +751,10 @@ int sg_release(struct burn_drive *d)
|
||||||
if (mmc_function_spy(d, "sg_release") <= 0)
|
if (mmc_function_spy(d, "sg_release") <= 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (d->cam == NULL)
|
if (d->cam == NULL) {
|
||||||
|
burn_print(1, "release an ungrabbed drive. die\n");
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
mmc_function_spy(NULL, "sg_release ----------- closing.");
|
mmc_function_spy(NULL, "sg_release ----------- closing.");
|
||||||
|
|
||||||
|
@ -785,11 +773,10 @@ int sg_issue_command(struct burn_drive *d, struct command *c)
|
||||||
|
|
||||||
mmc_function_spy(NULL, "sg_issue_command");
|
mmc_function_spy(NULL, "sg_issue_command");
|
||||||
|
|
||||||
c->error = 0;
|
if (d->cam == NULL) {
|
||||||
memset(c->sense, 0, sizeof(c->sense));
|
c->error = 0;
|
||||||
|
|
||||||
if (d->cam == NULL)
|
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
if (burn_sg_log_scsi & 1) {
|
if (burn_sg_log_scsi & 1) {
|
||||||
if (fp == NULL) {
|
if (fp == NULL) {
|
||||||
fp= fopen("/tmp/libburn_sg_command_log", "a");
|
fp= fopen("/tmp/libburn_sg_command_log", "a");
|
||||||
|
@ -801,10 +788,6 @@ int sg_issue_command(struct burn_drive *d, struct command *c)
|
||||||
scsi_log_cmd(c,fp,0);
|
scsi_log_cmd(c,fp,0);
|
||||||
|
|
||||||
c->error = 0;
|
c->error = 0;
|
||||||
if (c->timeout > 0)
|
|
||||||
timeout_ms = c->timeout;
|
|
||||||
else
|
|
||||||
timeout_ms = 200000;
|
|
||||||
|
|
||||||
ccb = cam_getccb(d->cam);
|
ccb = cam_getccb(d->cam);
|
||||||
cam_fill_csio(&ccb->csio,
|
cam_fill_csio(&ccb->csio,
|
||||||
|
@ -816,7 +799,7 @@ int sg_issue_command(struct burn_drive *d, struct command *c)
|
||||||
0, /* dxfer_len */
|
0, /* dxfer_len */
|
||||||
sizeof (ccb->csio.sense_data), /* sense_len */
|
sizeof (ccb->csio.sense_data), /* sense_len */
|
||||||
0, /* cdb_len */
|
0, /* cdb_len */
|
||||||
timeout_ms); /* timeout */
|
30*1000); /* timeout */
|
||||||
switch (c->dir) {
|
switch (c->dir) {
|
||||||
case TO_DRIVE:
|
case TO_DRIVE:
|
||||||
ccb->csio.ccb_h.flags |= CAM_DIR_OUT;
|
ccb->csio.ccb_h.flags |= CAM_DIR_OUT;
|
||||||
|
@ -849,6 +832,8 @@ int sg_issue_command(struct burn_drive *d, struct command *c)
|
||||||
ccb->csio.cdb_len = c->oplen;
|
ccb->csio.cdb_len = c->oplen;
|
||||||
memcpy(&ccb->csio.cdb_io.cdb_bytes, &c->opcode, c->oplen);
|
memcpy(&ccb->csio.cdb_io.cdb_bytes, &c->opcode, c->oplen);
|
||||||
|
|
||||||
|
memset(&ccb->csio.sense_data, 0, sizeof (ccb->csio.sense_data));
|
||||||
|
|
||||||
if (c->page) {
|
if (c->page) {
|
||||||
ccb->csio.data_ptr = c->page->data;
|
ccb->csio.data_ptr = c->page->data;
|
||||||
if (c->dir == FROM_DRIVE) {
|
if (c->dir == FROM_DRIVE) {
|
||||||
|
@ -873,19 +858,12 @@ int sg_issue_command(struct burn_drive *d, struct command *c)
|
||||||
ccb->csio.dxfer_len = 0;
|
ccb->csio.dxfer_len = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ts B90523 : Record effective transfer length request for debugging*/
|
|
||||||
c->dxfer_len = ccb->csio.dxfer_len;
|
|
||||||
|
|
||||||
start_time = time(NULL);
|
start_time = time(NULL);
|
||||||
|
timeout_ms = 200000;
|
||||||
for (i = 0; !done; i++) {
|
for (i = 0; !done; i++) {
|
||||||
|
|
||||||
memset(&ccb->csio.sense_data, 0, sizeof(ccb->csio.sense_data));
|
|
||||||
memset(c->sense, 0, sizeof(c->sense));
|
memset(c->sense, 0, sizeof(c->sense));
|
||||||
c->start_time = burn_get_time(0);
|
|
||||||
|
|
||||||
err = cam_send_ccb(d->cam, ccb);
|
err = cam_send_ccb(d->cam, ccb);
|
||||||
|
|
||||||
c->end_time = burn_get_time(0);
|
|
||||||
ignore_error = sense_len = 0;
|
ignore_error = sense_len = 0;
|
||||||
/* ts B00325 : CAM_AUTOSNS_VALID advised by Alexander Motin */
|
/* ts B00325 : CAM_AUTOSNS_VALID advised by Alexander Motin */
|
||||||
if (ccb->ccb_h.status & CAM_AUTOSNS_VALID) {
|
if (ccb->ccb_h.status & CAM_AUTOSNS_VALID) {
|
||||||
|
@ -982,14 +960,17 @@ int sg_issue_command(struct burn_drive *d, struct command *c)
|
||||||
c->sense[13] = 0x00;
|
c->sense[13] = 0x00;
|
||||||
done = 1;
|
done = 1;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
done = scsi_eval_cmd_outcome(d, c, fp, c->sense,
|
/* >>> Need own duration time measurement.
|
||||||
sense_len, start_time,
|
Then remove bit1 from flag.
|
||||||
timeout_ms, i, !!ignore_error);
|
*/
|
||||||
if (d->cancel)
|
done = scsi_eval_cmd_outcome(d, c, fp, c->sense,
|
||||||
|
sense_len, 0, start_time,
|
||||||
|
timeout_ms, i,
|
||||||
|
2 | !!ignore_error);
|
||||||
|
} else {
|
||||||
done = 1;
|
done = 1;
|
||||||
if (!done)
|
}
|
||||||
spc_register_retry(c);
|
|
||||||
} while (!done);
|
} while (!done);
|
||||||
ret = 1;
|
ret = 1;
|
||||||
ex:;
|
ex:;
|
||||||
|
@ -1000,7 +981,7 @@ ex:;
|
||||||
|
|
||||||
/* ts B00115 */
|
/* ts B00115 */
|
||||||
/* Return 1 if the given path leads to a regular file or a device that can be
|
/* Return 1 if the given path leads to a regular file or a device that can be
|
||||||
fseeked, read and eventually written with 2 kB granularity.
|
seeked, read and eventually written with 2 kB granularity.
|
||||||
*/
|
*/
|
||||||
int burn_os_is_2k_seekrw(char *path, int flag)
|
int burn_os_is_2k_seekrw(char *path, int flag)
|
||||||
{
|
{
|
||||||
|
@ -1073,7 +1054,7 @@ int burn_os_is_2k_seekrw(char *path, int flag)
|
||||||
0 = could not estimate size capacity of file object
|
0 = could not estimate size capacity of file object
|
||||||
1 = estimation has been made, bytes was set
|
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 stat stbuf;
|
||||||
struct statvfs vfsbuf;
|
struct statvfs vfsbuf;
|
||||||
|
@ -1126,7 +1107,7 @@ int burn_os_stdio_capacity(char *path, off_t write_start, off_t *bytes)
|
||||||
{ret = -2; goto ex;}
|
{ret = -2; goto ex;}
|
||||||
*bytes = add_size;
|
*bytes = add_size;
|
||||||
} else if(S_ISREG(stbuf.st_mode)) {
|
} 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);
|
strcpy(testpath, path);
|
||||||
} else
|
} else
|
||||||
{ret = 0; goto ex;}
|
{ret = 0; goto ex;}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Copyright (c) 2009 - 2016 Thomas Schmitt <scdbackup@gmx.net>
|
Copyright (c) 2009 - 2011 Thomas Schmitt <scdbackup@gmx.net>
|
||||||
Provided under GPL version 2 or later.
|
Provided under GPL version 2 or later.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -44,8 +44,8 @@ sg_initialize() performs global initialization of the SCSI transport
|
||||||
facilities. Checks for compatibility of supporting
|
facilities. Checks for compatibility of supporting
|
||||||
software components.
|
software components.
|
||||||
|
|
||||||
sg_shutdown() performs global finalizations and releases globally
|
sg_shutdown() performs global finalizations and releases golbally
|
||||||
acquired resources.
|
aquired resources.
|
||||||
|
|
||||||
sg_give_next_adr() iterates over the set of potentially useful drive
|
sg_give_next_adr() iterates over the set of potentially useful drive
|
||||||
address strings.
|
address strings.
|
||||||
|
@ -54,10 +54,10 @@ scsi_enumerate_drives() brings all available, not-whitelist-banned, and
|
||||||
accessible drives into libburn's list of drives.
|
accessible drives into libburn's list of drives.
|
||||||
|
|
||||||
sg_dispose_drive() finalizes adapter specifics of struct burn_drive
|
sg_dispose_drive() finalizes adapter specifics of struct burn_drive
|
||||||
on destruction. Releases resources which were acquired
|
on destruction. Releases resources which were aquired
|
||||||
underneath scsi_enumerate_drives().
|
underneath scsi_enumerate_drives().
|
||||||
|
|
||||||
sg_drive_is_open() tells whether libburn has the given drive in use.
|
sg_drive_is_open() tells wether libburn has the given drive in use.
|
||||||
|
|
||||||
sg_grab() opens the drive for SCSI commands and ensures
|
sg_grab() opens the drive for SCSI commands and ensures
|
||||||
undisturbed access.
|
undisturbed access.
|
||||||
|
@ -65,7 +65,7 @@ sg_grab() opens the drive for SCSI commands and ensures
|
||||||
sg_release() closes a drive opened by sg_grab()
|
sg_release() closes a drive opened by sg_grab()
|
||||||
|
|
||||||
sg_issue_command() sends a SCSI command to the drive, receives reply,
|
sg_issue_command() sends a SCSI command to the drive, receives reply,
|
||||||
and evaluates whether the command succeeded or shall
|
and evaluates wether the command succeeded or shall
|
||||||
be retried or finally failed.
|
be retried or finally failed.
|
||||||
|
|
||||||
sg_obtain_scsi_adr() tries to obtain SCSI address parameters.
|
sg_obtain_scsi_adr() tries to obtain SCSI address parameters.
|
||||||
|
@ -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_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
|
throughput with file reading and/or SCSI write command
|
||||||
transmission.
|
transmission.
|
||||||
|
|
||||||
|
@ -142,18 +142,10 @@ Send feedback to libburn-hackers@pykix.org .
|
||||||
#define Libburn_is_on_solariS 1
|
#define Libburn_is_on_solariS 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Proposal by Rocky Bernstein to avoid macro clashes with cdio_config.h */
|
|
||||||
#define __CDIO_CONFIG_H__ 1
|
|
||||||
|
|
||||||
#include <cdio/cdio.h>
|
#include <cdio/cdio.h>
|
||||||
#include <cdio/logging.h>
|
#include <cdio/logging.h>
|
||||||
#include <cdio/mmc.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.
|
/* The waiting time before eventually retrying a failed SCSI command.
|
||||||
Before each retry wait Libburn_sg_linux_retry_incR longer than with
|
Before each retry wait Libburn_sg_linux_retry_incR longer than with
|
||||||
|
@ -395,7 +387,7 @@ int sg_initialize(char msg[1024], int flag)
|
||||||
|
|
||||||
|
|
||||||
/** Performs global finalization of the SCSI transport adapter and eventually
|
/** Performs global finalization of the SCSI transport adapter and eventually
|
||||||
needed operating system facilities. Releases globally acquired resources.
|
needed operating system facilities. Releases globally aquired resources.
|
||||||
@param flag unused yet, submit 0
|
@param flag unused yet, submit 0
|
||||||
@return 1 = success, <=0 = failure
|
@return 1 = success, <=0 = failure
|
||||||
*/
|
*/
|
||||||
|
@ -462,7 +454,7 @@ int sg_give_next_adr(burn_drive_enumerator_t *idx,
|
||||||
|
|
||||||
ret = burn_drive_resolve_link(adr, path, &recursion_count, 2);
|
ret = burn_drive_resolve_link(adr, path, &recursion_count, 2);
|
||||||
if(ret > 0 && (ssize_t) strlen(path) < adr_size)
|
if(ret > 0 && (ssize_t) strlen(path) < adr_size)
|
||||||
strcpy(adr, path);
|
strcpy(path, adr);
|
||||||
ret = (ret >= 0);
|
ret = (ret >= 0);
|
||||||
ex:
|
ex:
|
||||||
BURN_FREE_MEM(path);
|
BURN_FREE_MEM(path);
|
||||||
|
@ -529,7 +521,7 @@ ex:;
|
||||||
|
|
||||||
/** Tells whether libburn has the given drive in use or exclusively reserved.
|
/** 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
|
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() */
|
/** Published as burn_drive.drive_is_open() */
|
||||||
int sg_drive_is_open(struct burn_drive * d)
|
int sg_drive_is_open(struct burn_drive * d)
|
||||||
|
@ -602,14 +594,16 @@ ex:;
|
||||||
*/
|
*/
|
||||||
int sg_release(struct burn_drive *d)
|
int sg_release(struct burn_drive *d)
|
||||||
{
|
{
|
||||||
if (d->p_cdio == NULL)
|
if (d->p_cdio == NULL) {
|
||||||
|
burn_print(1, "release an ungrabbed drive. die\n");
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
sg_close_drive(d);
|
sg_close_drive(d);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** Sends a SCSI command to the drive, receives reply and evaluates whether
|
/** Sends a SCSI command to the drive, receives reply and evaluates wether
|
||||||
the command succeeded or shall be retried or finally failed.
|
the command succeeded or shall be retried or finally failed.
|
||||||
Returned SCSI errors shall not lead to a return value indicating failure.
|
Returned SCSI errors shall not lead to a return value indicating failure.
|
||||||
The callers get notified by c->error. An SCSI failure which leads not to
|
The callers get notified by c->error. An SCSI failure which leads not to
|
||||||
|
@ -620,7 +614,7 @@ int sg_release(struct burn_drive *d)
|
||||||
*/
|
*/
|
||||||
int sg_issue_command(struct burn_drive *d, struct command *c)
|
int sg_issue_command(struct burn_drive *d, struct command *c)
|
||||||
{
|
{
|
||||||
int sense_valid = 0, i, timeout_ms, sense_len;
|
int sense_valid = 0, i, timeout_ms;
|
||||||
int key = 0, asc = 0, ascq = 0, done = 0;
|
int key = 0, asc = 0, ascq = 0, done = 0;
|
||||||
time_t start_time;
|
time_t start_time;
|
||||||
driver_return_code_t i_status;
|
driver_return_code_t i_status;
|
||||||
|
@ -629,11 +623,9 @@ int sg_issue_command(struct burn_drive *d, struct command *c)
|
||||||
mmc_cdb_t cdb = {{0, }};
|
mmc_cdb_t cdb = {{0, }};
|
||||||
cdio_mmc_direction_t e_direction;
|
cdio_mmc_direction_t e_direction;
|
||||||
CdIo_t *p_cdio;
|
CdIo_t *p_cdio;
|
||||||
cdio_mmc_request_sense_t *sense_pt = NULL;
|
unsigned char *sense_pt = NULL;
|
||||||
|
|
||||||
c->error = 0;
|
c->error = 0;
|
||||||
memset(c->sense, 0, sizeof(c->sense));
|
|
||||||
|
|
||||||
if (d->p_cdio == NULL) {
|
if (d->p_cdio == NULL) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -665,27 +657,16 @@ int sg_issue_command(struct burn_drive *d, struct command *c)
|
||||||
e_direction = SCSI_MMC_DATA_NONE;
|
e_direction = SCSI_MMC_DATA_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ts B90523 : Record effective transfer length request for debugging*/
|
|
||||||
c->dxfer_len = dxfer_len;
|
|
||||||
|
|
||||||
/* retry-loop */
|
/* retry-loop */
|
||||||
start_time = time(NULL);
|
start_time = time(NULL);
|
||||||
if (c->timeout > 0)
|
timeout_ms = 200000;
|
||||||
timeout_ms = c->timeout;
|
|
||||||
else
|
|
||||||
timeout_ms = 200000;
|
|
||||||
for(i = 0; !done; i++) {
|
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,
|
i_status = mmc_run_cmd(p_cdio, timeout_ms, &cdb, e_direction,
|
||||||
dxfer_len, c->page->data);
|
dxfer_len, c->page->data);
|
||||||
|
|
||||||
c->end_time = burn_get_time(0);
|
|
||||||
sense_valid = mmc_last_cmd_sense(p_cdio, &sense_pt);
|
sense_valid = mmc_last_cmd_sense(p_cdio, &sense_pt);
|
||||||
if (sense_valid >= 18) {
|
if (sense_valid >= 18) {
|
||||||
memcpy(c->sense, (unsigned char *) sense_pt,
|
memcpy(c->sense, sense_pt,
|
||||||
(size_t) sense_valid >= sizeof(c->sense) ?
|
(size_t) sense_valid >= sizeof(c->sense) ?
|
||||||
sizeof(c->sense) : (size_t) sense_valid );
|
sizeof(c->sense) : (size_t) sense_valid );
|
||||||
spc_decode_sense(c->sense, 0, &key, &asc, &ascq);
|
spc_decode_sense(c->sense, 0, &key, &asc, &ascq);
|
||||||
|
@ -723,16 +704,11 @@ int sg_issue_command(struct burn_drive *d, struct command *c)
|
||||||
done = 1;
|
done = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (key || asc || ascq)
|
if (i_status != 0 || (key || asc || ascq)) {
|
||||||
sense_len = 18;
|
done = scsi_eval_cmd_outcome(d, c, fp, c->sense, 18,
|
||||||
else
|
0, start_time, timeout_ms, i, 2);
|
||||||
sense_len = 0;
|
} else
|
||||||
done = scsi_eval_cmd_outcome(d, c, fp, c->sense, sense_len,
|
|
||||||
start_time, timeout_ms, i, 0);
|
|
||||||
if (d->cancel)
|
|
||||||
done = 1;
|
done = 1;
|
||||||
if (!done)
|
|
||||||
spc_register_retry(c);
|
|
||||||
|
|
||||||
} /* end of retry-loop */
|
} /* end of retry-loop */
|
||||||
|
|
||||||
|
@ -768,7 +744,7 @@ int sg_obtain_scsi_adr(char *path, int *bus_no, int *host_no, int *channel_no,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** Tells whether a text is a persistent address as listed by the enumeration
|
/** Tells wether a text is a persistent address as listed by the enumeration
|
||||||
functions.
|
functions.
|
||||||
*/
|
*/
|
||||||
int sg_is_enumerable_adr(char* adr)
|
int sg_is_enumerable_adr(char* adr)
|
||||||
|
@ -845,7 +821,7 @@ static int freebsd_is_2k_seekrw(char *path, int flag)
|
||||||
|
|
||||||
|
|
||||||
/* Return 1 if the given path leads to a regular file or a device that can be
|
/* Return 1 if the given path leads to a regular file or a device that can be
|
||||||
fseeked, read, and possibly written with 2 kB granularity.
|
seeked, read, and possibly written with 2 kB granularity.
|
||||||
*/
|
*/
|
||||||
int burn_os_is_2k_seekrw(char *path, int flag)
|
int burn_os_is_2k_seekrw(char *path, int flag)
|
||||||
{
|
{
|
||||||
|
@ -875,7 +851,7 @@ int burn_os_is_2k_seekrw(char *path, int flag)
|
||||||
0 = could not estimate size capacity of file object
|
0 = could not estimate size capacity of file object
|
||||||
1 = estimation has been made, bytes was set
|
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 stat stbuf;
|
||||||
|
|
||||||
|
@ -905,7 +881,7 @@ int burn_os_stdio_capacity(char *path, off_t write_start, off_t *bytes)
|
||||||
|
|
||||||
/* GNU/Linux specific determination of block device size */
|
/* GNU/Linux specific determination of block device size */
|
||||||
} else if(S_ISBLK(stbuf.st_mode)) {
|
} else if(S_ISBLK(stbuf.st_mode)) {
|
||||||
int open_mode = O_RDONLY | O_BINARY, fd;
|
int open_mode = O_RDONLY, fd, ret;
|
||||||
long blocks;
|
long blocks;
|
||||||
|
|
||||||
blocks = *bytes / 512;
|
blocks = *bytes / 512;
|
||||||
|
@ -923,9 +899,9 @@ int burn_os_stdio_capacity(char *path, off_t write_start, off_t *bytes)
|
||||||
#ifdef Libburn_is_on_freebsD
|
#ifdef Libburn_is_on_freebsD
|
||||||
|
|
||||||
} else if(S_ISCHR(stbuf.st_mode)) {
|
} else if(S_ISCHR(stbuf.st_mode)) {
|
||||||
int fd;
|
int fd, ret;
|
||||||
|
|
||||||
fd = open(path, O_RDONLY | O_BINARY);
|
fd = open(path, O_RDONLY);
|
||||||
if (fd == -1)
|
if (fd == -1)
|
||||||
{ret = -2; goto ex;}
|
{ret = -2; goto ex;}
|
||||||
ret = ioctl(fd, DIOCGMEDIASIZE, &add_size);
|
ret = ioctl(fd, DIOCGMEDIASIZE, &add_size);
|
||||||
|
@ -939,7 +915,7 @@ int burn_os_stdio_capacity(char *path, off_t write_start, off_t *bytes)
|
||||||
#ifdef Libburn_is_on_solariS
|
#ifdef Libburn_is_on_solariS
|
||||||
|
|
||||||
} else if(S_ISBLK(stbuf.st_mode)) {
|
} 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);
|
fd = open(path, open_mode);
|
||||||
if (fd == -1)
|
if (fd == -1)
|
||||||
|
@ -954,7 +930,7 @@ int burn_os_stdio_capacity(char *path, off_t write_start, off_t *bytes)
|
||||||
#endif /* Libburn_is_on_solariS */
|
#endif /* Libburn_is_on_solariS */
|
||||||
|
|
||||||
} else if(S_ISREG(stbuf.st_mode)) {
|
} 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);
|
strcpy(testpath, path);
|
||||||
} else
|
} else
|
||||||
{ret = 0; goto ex;}
|
{ret = 0; goto ex;}
|
||||||
|
@ -995,7 +971,7 @@ int burn_os_open_track_src(char *path, int open_flags, int flag)
|
||||||
{
|
{
|
||||||
int fd;
|
int fd;
|
||||||
|
|
||||||
fd = open(path, open_flags | O_BINARY);
|
fd = open(path, open_flags);
|
||||||
return fd;
|
return fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,916 +0,0 @@
|
||||||
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
|
||||||
|
|
||||||
/*
|
|
||||||
Copyright (c) 2010 - 2016 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.
|
|
||||||
Adapted 2016 to OpenBSD by help of SASANO Takayoshi <uaa@mx5.nisiq.net>.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
|
|
||||||
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
|
|
||||||
OpenBSD 5.9, ioctl SCIOCCOMMAND
|
|
||||||
|
|
||||||
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 globally
|
|
||||||
acquired 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 acquired
|
|
||||||
underneath scsi_enumerate_drives().
|
|
||||||
|
|
||||||
sg_drive_is_open() tells whether 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 whether 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/OpenBSD ioctl 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)
|
|
||||||
{
|
|
||||||
#ifdef __OpenBSD__
|
|
||||||
sprintf(msg, "internal OpenBSD SCIOCCOMMAND adapter sg-netbsd");
|
|
||||||
#else
|
|
||||||
sprintf(msg, "internal NetBSD SCIOCCOMMAND adapter sg-netbsd");
|
|
||||||
#endif
|
|
||||||
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 acquired 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 whether
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ts B90523 : Record effective transfer length request for debugging*/
|
|
||||||
c->dxfer_len = req.datalen;
|
|
||||||
|
|
||||||
/* 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;
|
|
||||||
if (!done)
|
|
||||||
spc_register_retry(c);
|
|
||||||
} /* 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;}
|
|
||||||
|
|
||||||
#ifdef __OpenBSD__
|
|
||||||
|
|
||||||
*bus_no = *host_no = addr.scbus;
|
|
||||||
*target_no = addr.target;
|
|
||||||
*lun_no = addr.lun;
|
|
||||||
|
|
||||||
#else /* __OpenBSD__ */
|
|
||||||
|
|
||||||
*bus_no = *host_no = addr.addr.scsi.scbus;
|
|
||||||
*target_no = addr.addr.scsi.target;
|
|
||||||
*lun_no = addr.addr.scsi.lun;
|
|
||||||
|
|
||||||
#endif /* ! __OpenBSD__ */
|
|
||||||
|
|
||||||
ret = 1;
|
|
||||||
ex:;
|
|
||||||
if (fd != -1)
|
|
||||||
close(fd);
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/** Tells whether 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
|
|
||||||
fseeked, 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;
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Copyright (c) 2010 - 2016 Thomas Schmitt <scdbackup@gmx.net>
|
Copyright (c) 2010 - 2011 Thomas Schmitt <scdbackup@gmx.net>
|
||||||
Provided under GPL version 2 or later.
|
Provided under GPL version 2 or later.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -44,8 +44,8 @@ sg_initialize() performs global initialization of the SCSI transport
|
||||||
facilities. Checks for compatibility of supporting
|
facilities. Checks for compatibility of supporting
|
||||||
software components.
|
software components.
|
||||||
|
|
||||||
sg_shutdown() performs global finalizations and releases globally
|
sg_shutdown() performs global finalizations and releases golbally
|
||||||
acquired resources.
|
aquired resources.
|
||||||
|
|
||||||
sg_give_next_adr() iterates over the set of potentially useful drive
|
sg_give_next_adr() iterates over the set of potentially useful drive
|
||||||
address strings.
|
address strings.
|
||||||
|
@ -54,10 +54,10 @@ scsi_enumerate_drives() brings all available, not-whitelist-banned, and
|
||||||
accessible drives into libburn's list of drives.
|
accessible drives into libburn's list of drives.
|
||||||
|
|
||||||
sg_dispose_drive() finalizes adapter specifics of struct burn_drive
|
sg_dispose_drive() finalizes adapter specifics of struct burn_drive
|
||||||
on destruction. Releases resources which were acquired
|
on destruction. Releases resources which were aquired
|
||||||
underneath scsi_enumerate_drives().
|
underneath scsi_enumerate_drives().
|
||||||
|
|
||||||
sg_drive_is_open() tells whether libburn has the given drive in use.
|
sg_drive_is_open() tells wether libburn has the given drive in use.
|
||||||
|
|
||||||
sg_grab() opens the drive for SCSI commands and ensures
|
sg_grab() opens the drive for SCSI commands and ensures
|
||||||
undisturbed access.
|
undisturbed access.
|
||||||
|
@ -65,7 +65,7 @@ sg_grab() opens the drive for SCSI commands and ensures
|
||||||
sg_release() closes a drive opened by sg_grab()
|
sg_release() closes a drive opened by sg_grab()
|
||||||
|
|
||||||
sg_issue_command() sends a SCSI command to the drive, receives reply,
|
sg_issue_command() sends a SCSI command to the drive, receives reply,
|
||||||
and evaluates whether the command succeeded or shall
|
and evaluates wether the command succeeded or shall
|
||||||
be retried or finally failed.
|
be retried or finally failed.
|
||||||
|
|
||||||
sg_obtain_scsi_adr() tries to obtain SCSI address parameters.
|
sg_obtain_scsi_adr() tries to obtain SCSI address parameters.
|
||||||
|
@ -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_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
|
throughput with file reading and/or SCSI write command
|
||||||
transmission.
|
transmission.
|
||||||
|
|
||||||
|
@ -116,7 +116,6 @@ Send feedback to libburn-hackers@pykix.org .
|
||||||
#include <sys/statvfs.h>
|
#include <sys/statvfs.h>
|
||||||
#endif /* Libburn_os_has_stavtfS */
|
#endif /* Libburn_os_has_stavtfS */
|
||||||
|
|
||||||
#include <volmgt.h>
|
|
||||||
#include <sys/dkio.h>
|
#include <sys/dkio.h>
|
||||||
#include <sys/vtoc.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.
|
Return 0 if name is not of the desired form.
|
||||||
*/
|
*/
|
||||||
static int decode_btl_solaris(char *name, int *busno, int *tgtno, int *lunno,
|
static int decode_btl_solaris(char *name, int *busno, int *tgtno, int *lunno,
|
||||||
int flag)
|
int flag)
|
||||||
{
|
{
|
||||||
char *cpt, *cpt_mem;
|
char *cpt;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
*busno = *tgtno = *lunno = -1;
|
*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);
|
ret = decode_btl_number(&cpt, 'd', tgtno);
|
||||||
if (ret <= 0)
|
if (ret <= 0)
|
||||||
return ret;
|
return ret;
|
||||||
cpt_mem = cpt;
|
|
||||||
ret = decode_btl_number(&cpt, 's', lunno);
|
ret = decode_btl_number(&cpt, 's', lunno);
|
||||||
if (ret <= 0) {
|
if (ret <= 0)
|
||||||
cpt = cpt_mem;
|
return ret;
|
||||||
ret = decode_btl_number(&cpt, '/', lunno);
|
|
||||||
if (ret <= 0)
|
|
||||||
return ret;
|
|
||||||
return(1);
|
|
||||||
}
|
|
||||||
cpt++;
|
cpt++;
|
||||||
if (*cpt != '2' || *(cpt + 1) != 0)
|
if (*cpt != '2' || *(cpt + 1) != 0)
|
||||||
return 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,
|
static int next_enum_cXtYdZs2(burn_drive_enumerator_t *idx,
|
||||||
char adr[], int adr_size, int flag)
|
char adr[], int adr_size, int flag)
|
||||||
{
|
{
|
||||||
int busno, tgtno, lunno, ret, fd = -1, volpath_size = 160, os_errno;
|
int busno, tgtno, lunno, ret, fd = -1, volpath_size = 160;
|
||||||
char *volpath = NULL, *msg = NULL, *dev_to_open = NULL;
|
char *volpath = NULL;
|
||||||
struct dirent *entry;
|
struct dirent *entry;
|
||||||
struct dk_cinfo cinfo;
|
struct dk_cinfo cinfo;
|
||||||
DIR *dir;
|
DIR *dir;
|
||||||
|
|
||||||
BURN_ALLOC_MEM(volpath, char, volpath_size);
|
BURN_ALLOC_MEM(volpath, char, volpath_size);
|
||||||
BURN_ALLOC_MEM(msg, char, 4096);
|
|
||||||
|
|
||||||
dir = idx->dir;
|
dir = idx->dir;
|
||||||
while (1) {
|
while (1) {
|
||||||
|
@ -337,68 +282,25 @@ static int next_enum_cXtYdZs2(burn_drive_enumerator_t *idx,
|
||||||
|
|
||||||
sprintf(volpath, "/dev/rdsk/%s", entry->d_name);
|
sprintf(volpath, "/dev/rdsk/%s", entry->d_name);
|
||||||
if (burn_drive_is_banned(volpath))
|
if (burn_drive_is_banned(volpath))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
fd = open(volpath, O_RDONLY | O_NDELAY);
|
||||||
|
if (fd < 0)
|
||||||
continue;
|
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 */
|
/* See man dkio */
|
||||||
ret = ioctl(fd, DKIOCINFO, &cinfo);
|
ret = ioctl(fd, DKIOCINFO, &cinfo);
|
||||||
close(fd);
|
close(fd);
|
||||||
if (ret < 0) {
|
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);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
if (cinfo.dki_ctype != DKC_CDROM)
|
||||||
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);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
if (adr_size <= (int) strlen(volpath))
|
||||||
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);
|
|
||||||
{ret = -1; goto ex;}
|
{ret = -1; goto ex;}
|
||||||
}
|
|
||||||
strcpy(adr, volpath);
|
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 = 1; goto ex;}
|
||||||
}
|
}
|
||||||
ret = 0;
|
ret = 0;
|
||||||
ex:;
|
ex:;
|
||||||
BURN_FREE_MEM(dev_to_open);
|
|
||||||
BURN_FREE_MEM(msg);
|
|
||||||
BURN_FREE_MEM(volpath);
|
BURN_FREE_MEM(volpath);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -497,7 +399,7 @@ int sg_initialize(char msg[1024], int flag)
|
||||||
|
|
||||||
|
|
||||||
/** Performs global finalization of the SCSI transport adapter and eventually
|
/** Performs global finalization of the SCSI transport adapter and eventually
|
||||||
needed operating system facilities. Releases globally acquired resources.
|
needed operating system facilities. Releases globally aquired resources.
|
||||||
@param flag unused yet, submit 0
|
@param flag unused yet, submit 0
|
||||||
@return 1 = success, <=0 = failure
|
@return 1 = success, <=0 = failure
|
||||||
*/
|
*/
|
||||||
|
@ -590,7 +492,7 @@ ex:;
|
||||||
|
|
||||||
/** Tells whether libburn has the given drive in use or exclusively reserved.
|
/** 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
|
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() */
|
/** Published as burn_drive.drive_is_open() */
|
||||||
int sg_drive_is_open(struct burn_drive * d)
|
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)
|
int sg_grab(struct burn_drive *d)
|
||||||
{
|
{
|
||||||
char *msg = NULL, *dev_to_open = NULL;
|
char *msg = NULL;
|
||||||
int os_errno, ret;
|
int os_errno, ret;
|
||||||
struct dk_cinfo cinfo;
|
struct dk_cinfo cinfo;
|
||||||
|
|
||||||
|
@ -617,16 +519,10 @@ int sg_grab(struct burn_drive *d)
|
||||||
d->released = 0;
|
d->released = 0;
|
||||||
{ret = 1; goto ex;}
|
{ret = 1; goto ex;}
|
||||||
}
|
}
|
||||||
ret = sg_solaris_convert_devname(d->devname, &dev_to_open, 0);
|
d->fd = open(d->devname, O_RDONLY | O_NDELAY);
|
||||||
if (ret <= 0)
|
|
||||||
goto ex;
|
|
||||||
d->fd = open(dev_to_open, O_RDONLY | O_NDELAY);
|
|
||||||
if (d->fd == -1) {
|
if (d->fd == -1) {
|
||||||
os_errno = errno;
|
os_errno = errno;
|
||||||
sprintf(msg, "Could not grab drive '%s'",
|
sprintf(msg, "Could not grab drive '%s'", d->devname);
|
||||||
d->devname);
|
|
||||||
if (strcmp(d->devname, dev_to_open))
|
|
||||||
sprintf(msg + strlen(msg), " via '%s'", dev_to_open);
|
|
||||||
libdax_msgs_submit(libdax_messenger, d->global_index,
|
libdax_msgs_submit(libdax_messenger, d->global_index,
|
||||||
0x00020003,
|
0x00020003,
|
||||||
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
|
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
|
||||||
|
@ -634,27 +530,10 @@ int sg_grab(struct burn_drive *d)
|
||||||
{ret = 0; goto ex;}
|
{ret = 0; goto ex;}
|
||||||
}
|
}
|
||||||
ret = ioctl(d->fd, DKIOCINFO, &cinfo);
|
ret = ioctl(d->fd, DKIOCINFO, &cinfo);
|
||||||
if (ret < 0) {
|
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);
|
|
||||||
goto revoke;
|
goto revoke;
|
||||||
}
|
if (cinfo.dki_ctype != DKC_CDROM)
|
||||||
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);
|
|
||||||
goto revoke;
|
goto revoke;
|
||||||
}
|
|
||||||
|
|
||||||
/* >>> obtain eventual locks */;
|
/* >>> obtain eventual locks */;
|
||||||
|
|
||||||
|
@ -669,7 +548,6 @@ revoke:;
|
||||||
msg, 0, 0);
|
msg, 0, 0);
|
||||||
ret = 0;
|
ret = 0;
|
||||||
ex:;
|
ex:;
|
||||||
BURN_FREE_MEM(dev_to_open);
|
|
||||||
BURN_FREE_MEM(msg);
|
BURN_FREE_MEM(msg);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -683,14 +561,16 @@ ex:;
|
||||||
*/
|
*/
|
||||||
int sg_release(struct burn_drive *d)
|
int sg_release(struct burn_drive *d)
|
||||||
{
|
{
|
||||||
if (d->fd < 0)
|
if (d->fd < 0) {
|
||||||
|
burn_print(1, "release an ungrabbed drive. die\n");
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
sg_close_drive(d);
|
sg_close_drive(d);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** Sends a SCSI command to the drive, receives reply and evaluates whether
|
/** Sends a SCSI command to the drive, receives reply and evaluates wether
|
||||||
the command succeeded or shall be retried or finally failed.
|
the command succeeded or shall be retried or finally failed.
|
||||||
Returned SCSI errors shall not lead to a return value indicating failure.
|
Returned SCSI errors shall not lead to a return value indicating failure.
|
||||||
The callers get notified by c->error. An SCSI failure which leads not to
|
The callers get notified by c->error. An SCSI failure which leads not to
|
||||||
|
@ -701,7 +581,7 @@ int sg_release(struct burn_drive *d)
|
||||||
*/
|
*/
|
||||||
int sg_issue_command(struct burn_drive *d, struct command *c)
|
int sg_issue_command(struct burn_drive *d, struct command *c)
|
||||||
{
|
{
|
||||||
int i, timeout_ms, ret, key, asc, ascq, done = 0, sense_len;
|
int i, timeout_ms, ret, key, asc, ascq, done = 0;
|
||||||
time_t start_time;
|
time_t start_time;
|
||||||
struct uscsi_cmd cgc;
|
struct uscsi_cmd cgc;
|
||||||
char msg[80];
|
char msg[80];
|
||||||
|
@ -709,7 +589,6 @@ int sg_issue_command(struct burn_drive *d, struct command *c)
|
||||||
|
|
||||||
c->error = 0;
|
c->error = 0;
|
||||||
memset(c->sense, 0, sizeof(c->sense));
|
memset(c->sense, 0, sizeof(c->sense));
|
||||||
|
|
||||||
if (d->fd == -1)
|
if (d->fd == -1)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
@ -723,17 +602,13 @@ int sg_issue_command(struct burn_drive *d, struct command *c)
|
||||||
if (burn_sg_log_scsi & 3)
|
if (burn_sg_log_scsi & 3)
|
||||||
scsi_log_cmd(c,fp,0);
|
scsi_log_cmd(c,fp,0);
|
||||||
|
|
||||||
if (c->timeout > 0)
|
|
||||||
timeout_ms = c->timeout;
|
|
||||||
else
|
|
||||||
timeout_ms = 200000;
|
|
||||||
memset (&cgc, 0, sizeof (struct uscsi_cmd));
|
memset (&cgc, 0, sizeof (struct uscsi_cmd));
|
||||||
/* No error messages, no retries,
|
/* No error messages, no retries,
|
||||||
do not execute with other commands, request sense data
|
do not execute with other commands, request sense data
|
||||||
*/
|
*/
|
||||||
cgc.uscsi_flags = USCSI_SILENT | USCSI_DIAGNOSE | USCSI_ISOLATE
|
cgc.uscsi_flags = USCSI_SILENT | USCSI_DIAGNOSE | USCSI_ISOLATE
|
||||||
| USCSI_RQENABLE;
|
| USCSI_RQENABLE;
|
||||||
cgc.uscsi_timeout = timeout_ms / 1000;
|
cgc.uscsi_timeout = 200;
|
||||||
cgc.uscsi_cdb = (caddr_t) c->opcode;
|
cgc.uscsi_cdb = (caddr_t) c->opcode;
|
||||||
cgc.uscsi_bufaddr = (caddr_t) c->page->data;
|
cgc.uscsi_bufaddr = (caddr_t) c->page->data;
|
||||||
if (c->dir == TO_DRIVE) {
|
if (c->dir == TO_DRIVE) {
|
||||||
|
@ -754,20 +629,13 @@ int sg_issue_command(struct burn_drive *d, struct command *c)
|
||||||
cgc.uscsi_rqlen = sizeof(c->sense);
|
cgc.uscsi_rqlen = sizeof(c->sense);
|
||||||
cgc.uscsi_rqbuf = (caddr_t) c->sense;
|
cgc.uscsi_rqbuf = (caddr_t) c->sense;
|
||||||
|
|
||||||
/* ts B90523 : Record effective transfer length request for debugging*/
|
|
||||||
c->dxfer_len = cgc.uscsi_buflen;
|
|
||||||
|
|
||||||
/* retry-loop */
|
/* retry-loop */
|
||||||
start_time = time(NULL);
|
start_time = time(NULL);
|
||||||
|
timeout_ms = 200000;
|
||||||
for(i = 0; !done; i++) {
|
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);
|
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
|
/* For cgc.uscsi_status see SAM-3 5.3.1, Table 22
|
||||||
0 = GOOD , 2 = CHECK CONDITION : Sense Data are delivered
|
0 = GOOD , 2 = CHECK CONDITION : Sense Data are delivered
|
||||||
8 = BUSY
|
8 = BUSY
|
||||||
|
@ -794,16 +662,11 @@ int sg_issue_command(struct burn_drive *d, struct command *c)
|
||||||
/* >>> valid sense: cgc.uscsi_rqlen - cgc.uscsi_rqresid */;
|
/* >>> valid sense: cgc.uscsi_rqlen - cgc.uscsi_rqresid */;
|
||||||
|
|
||||||
spc_decode_sense(c->sense, 0, &key, &asc, &ascq);
|
spc_decode_sense(c->sense, 0, &key, &asc, &ascq);
|
||||||
if (key || asc || ascq)
|
if (key || asc || ascq) {
|
||||||
sense_len = 18;
|
done = scsi_eval_cmd_outcome(d, c, fp, c->sense, 18, 0,
|
||||||
else
|
start_time, timeout_ms, i, 2);
|
||||||
sense_len = 0;
|
} else
|
||||||
done = scsi_eval_cmd_outcome(d, c, fp, c->sense, sense_len,
|
|
||||||
start_time, timeout_ms, i, 0);
|
|
||||||
if (d->cancel)
|
|
||||||
done = 1;
|
done = 1;
|
||||||
if (!done)
|
|
||||||
spc_register_retry(c);
|
|
||||||
|
|
||||||
} /* end of retry-loop */
|
} /* end of retry-loop */
|
||||||
|
|
||||||
|
@ -837,7 +700,7 @@ int sg_obtain_scsi_adr(char *path, int *bus_no, int *host_no, int *channel_no,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** Tells whether a text is a persistent address as listed by the enumeration
|
/** Tells wether a text is a persistent address as listed by the enumeration
|
||||||
functions.
|
functions.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -886,7 +749,7 @@ int sg_is_enumerable_adr(char* adr)
|
||||||
|
|
||||||
|
|
||||||
/* Return 1 if the given path leads to a regular file or a device that can be
|
/* Return 1 if the given path leads to a regular file or a device that can be
|
||||||
fseeked, read, and possibly written with 2 kB granularity.
|
seeked, read, and possibly written with 2 kB granularity.
|
||||||
*/
|
*/
|
||||||
int burn_os_is_2k_seekrw(char *path, int flag)
|
int burn_os_is_2k_seekrw(char *path, int flag)
|
||||||
{
|
{
|
||||||
|
@ -912,7 +775,7 @@ int burn_os_is_2k_seekrw(char *path, int flag)
|
||||||
0 = could not estimate size capacity of file object
|
0 = could not estimate size capacity of file object
|
||||||
1 = estimation has been made, bytes was set
|
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 stat stbuf;
|
||||||
int ret;
|
int ret;
|
||||||
|
@ -953,7 +816,7 @@ int burn_os_stdio_capacity(char *path, off_t write_start, off_t *bytes)
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if(S_ISREG(stbuf.st_mode)) {
|
} 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);
|
strcpy(testpath, path);
|
||||||
} else
|
} else
|
||||||
{ret = 0; goto ex;}
|
{ret = 0; goto ex;}
|
||||||
|
|
20
libburn/sg.c
20
libburn/sg.c
|
@ -1,7 +1,7 @@
|
||||||
|
|
||||||
/* sg.c
|
/* sg.c
|
||||||
Switcher for operating system dependent transport level modules of libburn.
|
Switcher for operating system dependent transport level modules of libburn.
|
||||||
Copyright (C) 2009 - 2016 Thomas Schmitt <scdbackup@gmx.net>,
|
Copyright (C) 2009 - 2010 Thomas Schmitt <scdbackup@gmx.net>,
|
||||||
provided under GPLv2+
|
provided under GPLv2+
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -20,16 +20,6 @@
|
||||||
|
|
||||||
#include "sg-libcdio.c"
|
#include "sg-libcdio.c"
|
||||||
|
|
||||||
#else
|
|
||||||
#ifdef __NetBSD__
|
|
||||||
|
|
||||||
#include "sg-netbsd.c"
|
|
||||||
|
|
||||||
#else
|
|
||||||
#ifdef __OpenBSD__
|
|
||||||
|
|
||||||
#include "sg-netbsd.c"
|
|
||||||
|
|
||||||
#else
|
#else
|
||||||
#ifdef __FreeBSD__
|
#ifdef __FreeBSD__
|
||||||
|
|
||||||
|
@ -68,13 +58,11 @@
|
||||||
static int intentional_compiler_warning(void)
|
static int intentional_compiler_warning(void)
|
||||||
{
|
{
|
||||||
int INTENTIONAL_COMPILER_WARNING_;
|
int INTENTIONAL_COMPILER_WARNING_;
|
||||||
int Cannot_recognize_supported_operating_system_;
|
int Cannot_recognize_GNU_Linux_nor_FreeBSD_nor_Solaris_;
|
||||||
int Like_GNU_Linux_or_FreeBSD_or_Solaris_or_NetBSD_;
|
|
||||||
int Have_to_use_dummy_MMC_transport_adapter_;
|
int Have_to_use_dummy_MMC_transport_adapter_;
|
||||||
int This_libburn_will_not_be_able_to_operate_on_real_CD_drives;
|
int This_libburn_will_not_be_able_to_operate_on_real_CD_drives;
|
||||||
int Have_to_use_dummy_MMC_transport_adapter;
|
int Have_to_use_dummy_MMC_transport_adapter;
|
||||||
int Like_GNU_Linux_or_FreeBSD_or_Solaris_or_NetBSD;
|
int Cannot_recognize_GNU_Linux_nor_FreeBSD_nor_Solaris;
|
||||||
int Cannot_recognize_supported_operating_system;
|
|
||||||
int INTENTIONAL_COMPILER_WARNING;
|
int INTENTIONAL_COMPILER_WARNING;
|
||||||
|
|
||||||
return(0);
|
return(0);
|
||||||
|
@ -86,8 +74,6 @@ static int intentional_compiler_warning(void)
|
||||||
#endif /* ! __linux */
|
#endif /* ! __linux */
|
||||||
#endif /* ! __FreeBSD_kernel__ */
|
#endif /* ! __FreeBSD_kernel__ */
|
||||||
#endif /* ! __FreeBSD__ */
|
#endif /* ! __FreeBSD__ */
|
||||||
#endif /* ! __OpenBSD__ */
|
|
||||||
#endif /* ! __NetBSD__ */
|
|
||||||
#endif /* ! Libburn_use_libcdiO */
|
#endif /* ! Libburn_use_libcdiO */
|
||||||
#endif /* ! Libburn_use_sg_dummY */
|
#endif /* ! Libburn_use_sg_dummY */
|
||||||
|
|
||||||
|
|
|
@ -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_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 */
|
/* ts A91227 */
|
||||||
/** Returns the id string of the SCSI transport adapter and eventually
|
/** Returns the id string of the SCSI transport adapter and eventually
|
||||||
|
@ -62,7 +62,7 @@ int sg_initialize(char msg[1024], int flag);
|
||||||
|
|
||||||
/* ts A91227 */
|
/* ts A91227 */
|
||||||
/** Performs global finalization of the SCSI transport adapter and eventually
|
/** Performs global finalization of the SCSI transport adapter and eventually
|
||||||
needed operating system facilities. Releases globally acquired resources.
|
needed operating system facilities. Releases globally aquired resources.
|
||||||
@param flag unused yet, submit 0
|
@param flag unused yet, submit 0
|
||||||
@return 1 = success, <=0 = failure
|
@return 1 = success, <=0 = failure
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -15,7 +15,6 @@
|
||||||
#include "libburn.h"
|
#include "libburn.h"
|
||||||
#include "source.h"
|
#include "source.h"
|
||||||
#include "structure.h"
|
#include "structure.h"
|
||||||
#include "init.h"
|
|
||||||
|
|
||||||
void burn_source_free(struct burn_source *src)
|
void burn_source_free(struct burn_source *src)
|
||||||
{
|
{
|
||||||
|
@ -42,10 +41,12 @@ struct burn_source *burn_source_new(void)
|
||||||
{
|
{
|
||||||
struct burn_source *out;
|
struct burn_source *out;
|
||||||
|
|
||||||
/* ts A70825 , B11219 */
|
out = calloc(1, sizeof(struct burn_source));
|
||||||
out = burn_alloc_mem(sizeof(struct burn_source), 1, 0);
|
|
||||||
|
/* ts A70825 */
|
||||||
if (out == NULL)
|
if (out == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
memset((char *) out, 0, sizeof(struct burn_source));
|
||||||
|
|
||||||
out->refcount = 1;
|
out->refcount = 1;
|
||||||
return out;
|
return out;
|
||||||
|
|
1093
libburn/spc.c
1093
libburn/spc.c
File diff suppressed because it is too large
Load Diff
104
libburn/spc.h
104
libburn/spc.h
|
@ -1,7 +1,7 @@
|
||||||
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||||
|
|
||||||
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
|
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
|
||||||
Copyright (c) 2006 - 2019 Thomas Schmitt <scdbackup@gmx.net>
|
Copyright (c) 2006 - 2010 Thomas Schmitt <scdbackup@gmx.net>
|
||||||
Provided under GPL version 2 or later.
|
Provided under GPL version 2 or later.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -21,21 +21,14 @@ void spc_select_error_params(struct burn_drive *,
|
||||||
void spc_getcaps(struct burn_drive *d);
|
void spc_getcaps(struct burn_drive *d);
|
||||||
void spc_sense_write_params(struct burn_drive *);
|
void spc_sense_write_params(struct burn_drive *);
|
||||||
void spc_select_write_params(struct burn_drive *,
|
void spc_select_write_params(struct burn_drive *,
|
||||||
struct burn_session *, int,
|
|
||||||
const struct burn_write_opts *);
|
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_probe_write_modes(struct burn_drive *);
|
||||||
void spc_request_sense(struct burn_drive *d, struct buffer *buf);
|
void spc_request_sense(struct burn_drive *d, struct buffer *buf);
|
||||||
int spc_block_type(enum burn_block_types b);
|
int spc_block_type(enum burn_block_types b);
|
||||||
int spc_get_erase_progress(struct burn_drive *d);
|
int spc_get_erase_progress(struct burn_drive *d);
|
||||||
|
|
||||||
/* ts A70315 : test_unit_ready with result parameters */
|
/* ts A70315 : test_unit_ready with result parameters */
|
||||||
int spc_test_unit_ready_r(struct burn_drive *d, int *key, int *asc, int *ascq,
|
int spc_test_unit_ready_r(struct burn_drive *d, int *key, int *asc, int *ascq);
|
||||||
int *progress);
|
|
||||||
|
|
||||||
int spc_test_unit_ready(struct burn_drive *d);
|
int spc_test_unit_ready(struct burn_drive *d);
|
||||||
|
|
||||||
|
@ -75,55 +68,22 @@ int scsi_init_command(struct command *c, unsigned char *opcode, int oplen);
|
||||||
/* ts A91106 */
|
/* ts A91106 */
|
||||||
int scsi_show_cmd_text(struct command *c, void *fp, int flag);
|
int scsi_show_cmd_text(struct command *c, void *fp, int flag);
|
||||||
|
|
||||||
/* ts B11110 */
|
/* ts A91106 */
|
||||||
/** Logs command (before execution). */
|
int scsi_show_cmd_reply(struct command *c, void *fp, int flag);
|
||||||
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) */
|
/* ts A91218 (former sg_log_cmd ts A70518) */
|
||||||
/** Legacy frontend to scsi_log_command() */
|
/** Logs command (before execution) */
|
||||||
int scsi_log_cmd(struct command *c, void *fp, int flag);
|
int scsi_log_cmd(struct command *c, void *fp, int flag);
|
||||||
|
|
||||||
/* ts B11110 */
|
|
||||||
/** Logs outcome of a sg command.
|
|
||||||
@param flag bit0 causes an error message
|
|
||||||
bit1 do not print duration
|
|
||||||
*/
|
|
||||||
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);
|
|
||||||
|
|
||||||
/* ts A91221 (former sg_log_err ts A91108) */
|
/* ts A91221 (former sg_log_err ts A91108) */
|
||||||
/** Legacy frontend to scsi_log_reply().
|
/** Logs outcome of a sg command. */
|
||||||
@param flag bit0 causes an error message
|
int scsi_log_err(struct command *c, void *fp, unsigned char sense[18],
|
||||||
bit1 do not print duration
|
int sense_len, int duration, int flag);
|
||||||
*/
|
|
||||||
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);
|
|
||||||
|
|
||||||
/* ts B00728 */
|
/* ts B00728 */
|
||||||
int spc_decode_sense(unsigned char *sense, int senselen,
|
int spc_decode_sense(unsigned char *sense, int senselen,
|
||||||
int *key, int *asc, int *ascq);
|
int *key, int *asc, int *ascq);
|
||||||
|
|
||||||
/* ts B90206 */
|
|
||||||
char *spc_command_name(unsigned int c, int flag);
|
|
||||||
|
|
||||||
/* ts B90511 */
|
|
||||||
int spc_human_readable_cmd(struct command *c, char *msg, int msg_max,
|
|
||||||
int flag);
|
|
||||||
|
|
||||||
/* ts B90616 */
|
|
||||||
void spc_register_retry(struct command *c);
|
|
||||||
|
|
||||||
/* ts B00808 */
|
/* ts B00808 */
|
||||||
/** Evaluates outcome of a single SCSI command, eventually logs sense data,
|
/** Evaluates outcome of a single SCSI command, eventually logs sense data,
|
||||||
and issues DEBUG error message in case the command is evaluated as done.
|
and issues DEBUG error message in case the command is evaluated as done.
|
||||||
|
@ -132,59 +92,15 @@ void spc_register_retry(struct command *c);
|
||||||
*/
|
*/
|
||||||
int scsi_eval_cmd_outcome(struct burn_drive *d, struct command *c, void *fp_in,
|
int scsi_eval_cmd_outcome(struct burn_drive *d, struct command *c, void *fp_in,
|
||||||
unsigned char *sense, int sense_len,
|
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);
|
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.
|
/* The waiting time before eventually retrying a failed SCSI command.
|
||||||
Before each retry wait Libburn_scsi_retry_incR longer than with
|
Before each retry wait Libburn_scsi_retry_incR longer than with
|
||||||
the previous one. At most wait for Libburn_scsi_retry_umaX microseconds.
|
the previous one.
|
||||||
*/
|
*/
|
||||||
#define Libburn_scsi_retry_usleeP 100000
|
#define Libburn_scsi_retry_usleeP 100000
|
||||||
#define Libburn_scsi_retry_incR 100000
|
#define Libburn_scsi_retry_incR 100000
|
||||||
#define Libburn_scsi_retry_umaX 500000
|
|
||||||
|
|
||||||
/* The retry waiting time for commands WRITE(10) and WRITE(12).
|
|
||||||
*/
|
|
||||||
#define Libburn_scsi_write_retry_usleeP 0
|
|
||||||
#define Libburn_scsi_write_retry_incR 2000
|
|
||||||
#define Libburn_scsi_write_retry_umaX 25000
|
|
||||||
|
|
||||||
|
|
||||||
/* ts B11124 */
|
|
||||||
/* Millisecond timeout for quickly responding SPC, SBC, and MMC commands */
|
|
||||||
#define Libburn_scsi_default_timeouT 30000
|
|
||||||
|
|
||||||
/* WRITE(10) and WRITE(12) */
|
|
||||||
#define Libburn_scsi_write_timeouT 200000
|
|
||||||
|
|
||||||
/* RESERVE TRACK */
|
|
||||||
#define Libburn_mmc_reserve_timeouT 200000
|
|
||||||
|
|
||||||
/* CLOSE TRACK/SESSION with Immed bit */
|
|
||||||
#define Libburn_mmc_close_timeouT 200000
|
|
||||||
/* CLOSE TRACK/SESSION without Immed bit */
|
|
||||||
#define Libburn_mmc_close_noim_timeouT 3600000
|
|
||||||
|
|
||||||
/* BLANK , FORMAT UNIT with Immed bit */
|
|
||||||
#define Libburn_mmc_blank_timeouT 200000
|
|
||||||
/* BLANK , FORMAT UNIT without Immed bit */
|
|
||||||
#define Libburn_mmc_blank_noim_timeouT 18000000
|
|
||||||
|
|
||||||
/* SEND OPC INFORMATION */
|
|
||||||
#define Libburn_mmc_opc_timeouT 200000
|
|
||||||
|
|
||||||
/* MMC_SYNC_CACHE with Immed bit */
|
|
||||||
#define Libburn_mmc_sync_timeouT 200000
|
|
||||||
/* MMC_SYNC_CACHE without Immed bit */
|
|
||||||
#define Libburn_mmc_sync_noim_timeouT 3600000
|
|
||||||
|
|
||||||
/* START STOP UNIT with Start bit and Load bit set */
|
|
||||||
#define Libburn_mmc_load_timeouT 300000
|
|
||||||
|
|
||||||
#endif /*__SPC*/
|
#endif /*__SPC*/
|
||||||
|
|
1645
libburn/structure.c
1645
libburn/structure.c
File diff suppressed because it is too large
Load Diff
|
@ -16,32 +16,13 @@ struct isrc
|
||||||
unsigned int serial; /* must be 0-99999 */
|
unsigned int serial; /* must be 0-99999 */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* ts B11206 */
|
|
||||||
#define Libburn_pack_type_basE 0x80
|
|
||||||
#define Libburn_pack_num_typeS 0x10
|
|
||||||
#define Libburn_pack_type_nameS \
|
|
||||||
"TITLE", "PERFORMER", "SONGWRITER", "COMPOSER", \
|
|
||||||
"ARRANGER", "MESSAGE", "DISCID", "GENRE", \
|
|
||||||
"TOC", "TOC2", "", "", \
|
|
||||||
"", "CLOSED", "UPC_ISRC", "BLOCKSIZE"
|
|
||||||
|
|
||||||
struct burn_cdtext
|
|
||||||
{
|
|
||||||
unsigned char *(payload[Libburn_pack_num_typeS]);
|
|
||||||
int length[Libburn_pack_num_typeS];
|
|
||||||
int flags; /* bit0 - bit15= double byte characters */
|
|
||||||
};
|
|
||||||
|
|
||||||
struct burn_track
|
struct burn_track
|
||||||
{
|
{
|
||||||
int refcnt;
|
int refcnt;
|
||||||
struct burn_toc_entry *entry;
|
struct burn_toc_entry *entry;
|
||||||
unsigned char indices;
|
unsigned char indices;
|
||||||
/* lba address of the index. CD only. 0x7fffffff means undefined index.
|
/* lba address of the index */
|
||||||
To be programmed relative to track source start before burning,
|
unsigned int index[99];
|
||||||
but to hold absolute addresses after burning or reading.
|
|
||||||
*/
|
|
||||||
int index[100];
|
|
||||||
/** number of 0 bytes to write before data */
|
/** number of 0 bytes to write before data */
|
||||||
int offset;
|
int offset;
|
||||||
/** how much offset has been used */
|
/** how much offset has been used */
|
||||||
|
@ -53,7 +34,7 @@ struct burn_track
|
||||||
/** 1 means Pad with zeros, 0 means start reading the next track */
|
/** 1 means Pad with zeros, 0 means start reading the next track */
|
||||||
int pad;
|
int pad;
|
||||||
|
|
||||||
/* ts A70213 : whether to expand this track to full available media */
|
/* ts A70213 : wether to expand this track to full available media */
|
||||||
int fill_up_media;
|
int fill_up_media;
|
||||||
|
|
||||||
/* ts A70218 : a track size to use if it is mandarory to have some */
|
/* ts A70218 : a track size to use if it is mandarory to have some */
|
||||||
|
@ -90,18 +71,8 @@ struct burn_track
|
||||||
int pregap1;
|
int pregap1;
|
||||||
/** The track contains interval two of a pregap */
|
/** The track contains interval two of a pregap */
|
||||||
int pregap2;
|
int pregap2;
|
||||||
|
|
||||||
/* ts B20110 */
|
|
||||||
/** The number of sectors in pre-gap 2, if .pregap2 is set */
|
|
||||||
int pregap2_size;
|
|
||||||
|
|
||||||
/** The track contains a postgap */
|
/** The track contains a postgap */
|
||||||
int postgap;
|
int postgap;
|
||||||
|
|
||||||
/* ts B20111 */
|
|
||||||
/** The number of sectors in post-gap, if .postgap is set */
|
|
||||||
int postgap_size;
|
|
||||||
|
|
||||||
struct isrc isrc;
|
struct isrc isrc;
|
||||||
|
|
||||||
/* ts A61024 */
|
/* ts A61024 */
|
||||||
|
@ -111,9 +82,6 @@ struct burn_track
|
||||||
/* ts A90910 : conversions from CD XA prepared input */
|
/* ts A90910 : conversions from CD XA prepared input */
|
||||||
int cdxa_conversion; /* 0=none, 1=remove -xa1 headers (first 8 bytes)*/
|
int cdxa_conversion; /* 0=none, 1=remove -xa1 headers (first 8 bytes)*/
|
||||||
|
|
||||||
/* ts B11206 */
|
|
||||||
struct burn_cdtext *cdtext[8];
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct burn_session
|
struct burn_session
|
||||||
|
@ -129,26 +97,12 @@ struct burn_session
|
||||||
int tracks;
|
int tracks;
|
||||||
struct burn_track **track;
|
struct burn_track **track;
|
||||||
int refcnt;
|
int refcnt;
|
||||||
|
|
||||||
/* ts B11206 */
|
|
||||||
struct burn_cdtext *cdtext[8];
|
|
||||||
unsigned char cdtext_char_code[8];
|
|
||||||
unsigned char cdtext_copyright[8];
|
|
||||||
unsigned char cdtext_language[8];
|
|
||||||
|
|
||||||
/* ts B11226 */
|
|
||||||
unsigned char mediacatalog[14]; /* overridable by burn_write_opts */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct burn_disc
|
struct burn_disc
|
||||||
{
|
{
|
||||||
int sessions;
|
int sessions;
|
||||||
struct burn_session **session;
|
struct burn_session **session;
|
||||||
|
|
||||||
#ifdef Libburn_disc_with_incomplete_sessioN
|
|
||||||
int incomplete_sessions;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int refcnt;
|
int refcnt;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -160,7 +114,7 @@ int burn_track_is_open_ended(struct burn_track *t);
|
||||||
int burn_track_is_data_done(struct burn_track *t);
|
int burn_track_is_data_done(struct burn_track *t);
|
||||||
|
|
||||||
/* ts A70125 : sets overall sectors of a track: offset+payload+padding */
|
/* ts A70125 : sets overall sectors of a track: offset+payload+padding */
|
||||||
int burn_track_set_sectors(struct burn_track *t, off_t sectors);
|
int burn_track_set_sectors(struct burn_track *t, int sectors);
|
||||||
|
|
||||||
/* ts A70218 : sets the payload size alone */
|
/* ts A70218 : sets the payload size alone */
|
||||||
int burn_track_set_size(struct burn_track *t, off_t size);
|
int burn_track_set_size(struct burn_track *t, off_t size);
|
||||||
|
@ -174,18 +128,7 @@ off_t burn_track_get_default_size(struct burn_track *t);
|
||||||
|
|
||||||
|
|
||||||
/* ts A80808 : Enhance CD toc to DVD toc */
|
/* ts A80808 : Enhance CD toc to DVD toc */
|
||||||
int burn_disc_cd_toc_extensions(struct burn_drive *drive, int flag);
|
int burn_disc_cd_toc_extensions(struct burn_disc *d, int flag);
|
||||||
|
|
||||||
|
|
||||||
/* ts B11206 */
|
|
||||||
struct burn_cdtext *burn_cdtext_create(void);
|
|
||||||
void burn_cdtext_free(struct burn_cdtext **cdtext);
|
|
||||||
|
|
||||||
/* ts B20119 */
|
|
||||||
/* @param flag bit0= do not add post-gap
|
|
||||||
*/
|
|
||||||
int burn_track_get_sectors_2(struct burn_track *t, int flag);
|
|
||||||
off_t burn_track_get_sectors_2_v2(struct burn_track *t, int flag);
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* BURN__STRUCTURE_H */
|
#endif /* BURN__STRUCTURE_H */
|
||||||
|
|
|
@ -147,11 +147,7 @@ void toc_find_modes(struct burn_drive *d)
|
||||||
lba = burn_msf_to_lba(e->pmin, e->psec,
|
lba = burn_msf_to_lba(e->pmin, e->psec,
|
||||||
e->pframe);
|
e->pframe);
|
||||||
mem->sectors = 1;
|
mem->sectors = 1;
|
||||||
|
|
||||||
ts B21119 : Would now be d->read_cd() with
|
|
||||||
with sectype = 0 , mainch = 0xf8
|
|
||||||
d->read_sectors(d, lba, mem.sectors, &o, mem);
|
d->read_sectors(d, lba, mem.sectors, &o, mem);
|
||||||
|
|
||||||
t->mode = sector_identify(mem->data);
|
t->mode = sector_identify(mem->data);
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||||
|
|
||||||
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
|
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
|
||||||
Copyright (c) 2006 - 2024 Thomas Schmitt <scdbackup@gmx.net>
|
Copyright (c) 2006 - 2010 Thomas Schmitt <scdbackup@gmx.net>
|
||||||
Provided under GPL version 2 or later.
|
Provided under GPL version 2 or later.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -61,40 +61,22 @@ struct command
|
||||||
int dir;
|
int dir;
|
||||||
int dxfer_len;
|
int dxfer_len;
|
||||||
unsigned char sense[128];
|
unsigned char sense[128];
|
||||||
int sense_len;
|
|
||||||
int error;
|
int error;
|
||||||
int retry;
|
int retry;
|
||||||
struct buffer *page;
|
struct buffer *page;
|
||||||
int timeout; /* milliseconds */
|
|
||||||
|
|
||||||
double start_time;
|
|
||||||
double end_time;
|
|
||||||
|
|
||||||
int retry_count;
|
|
||||||
int last_retry_key;
|
|
||||||
int last_retry_asc;
|
|
||||||
int last_retry_ascq;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct burn_scsi_inquiry_data
|
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 vendor[9];
|
||||||
char product[17];
|
char product[17];
|
||||||
char revision[5];
|
char revision[5];
|
||||||
|
|
||||||
int valid;
|
int valid;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct scsi_mode_data
|
struct scsi_mode_data
|
||||||
{
|
{
|
||||||
int p2a_valid;
|
|
||||||
int buffer_size;
|
int buffer_size;
|
||||||
int dvdram_read;
|
int dvdram_read;
|
||||||
int dvdram_write;
|
int dvdram_write;
|
||||||
|
@ -106,13 +88,8 @@ struct scsi_mode_data
|
||||||
int cdr_read;
|
int cdr_read;
|
||||||
int cdr_write;
|
int cdr_write;
|
||||||
int simulate;
|
int simulate;
|
||||||
int c2_pointers;
|
|
||||||
int underrun_proof;
|
|
||||||
|
|
||||||
int max_read_speed;
|
int max_read_speed;
|
||||||
int cur_read_speed;
|
|
||||||
int max_write_speed;
|
int max_write_speed;
|
||||||
int cur_write_speed;
|
|
||||||
|
|
||||||
/* ts A61021 */
|
/* ts A61021 */
|
||||||
int min_write_speed;
|
int min_write_speed;
|
||||||
|
@ -123,10 +100,15 @@ struct scsi_mode_data
|
||||||
int max_end_lba;
|
int max_end_lba;
|
||||||
struct burn_speed_descriptor *speed_descriptors;
|
struct burn_speed_descriptor *speed_descriptors;
|
||||||
|
|
||||||
|
int cur_read_speed;
|
||||||
|
int cur_write_speed;
|
||||||
int retry_page_length;
|
int retry_page_length;
|
||||||
int retry_page_valid;
|
int retry_page_valid;
|
||||||
int write_page_length;
|
int write_page_length;
|
||||||
int write_page_valid;
|
int write_page_valid;
|
||||||
|
int c2_pointers;
|
||||||
|
int valid;
|
||||||
|
int underrun_proof;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -144,26 +126,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() */
|
/** Gets initialized in enumerate_common() and burn_drive_register() */
|
||||||
struct burn_drive
|
struct burn_drive
|
||||||
{
|
{
|
||||||
|
@ -215,24 +177,12 @@ struct burn_drive
|
||||||
unsigned char all_profiles[256];
|
unsigned char all_profiles[256];
|
||||||
int num_profiles;
|
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.
|
/* ts A70128 : MMC-to-MMC feature info from 46h for DVD-RW.
|
||||||
Quite internal. Regard as opaque :)
|
Quite internal. Regard as opaque :)
|
||||||
*/
|
*/
|
||||||
/* 1 = incremental recording available, 0 = not available */
|
/* 1 = incremental recording available, 0 = not available */
|
||||||
int current_has_feat21h;
|
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 */
|
/* Link Size item number 0 from feature 0021h descriptor */
|
||||||
int current_feat21h_link_size;
|
int current_feat21h_link_size;
|
||||||
|
|
||||||
|
@ -258,16 +208,6 @@ struct burn_drive
|
||||||
*/
|
*/
|
||||||
int current_feat2fh_byte4;
|
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.
|
/* ts B10524 : whether the damage bit was set for the future track.
|
||||||
bit0= damage bit , bit1= nwa valid bit
|
bit0= damage bit , bit1= nwa valid bit
|
||||||
*/
|
*/
|
||||||
|
@ -277,7 +217,7 @@ struct burn_drive
|
||||||
(which could need closing after write) */
|
(which could need closing after write) */
|
||||||
int needs_close_session;
|
int needs_close_session;
|
||||||
/* ts A71003 : whether a random write operation was done and no
|
/* ts A71003 : whether a random write operation was done and no
|
||||||
synchronize cache has happened yet */
|
synchronize chache has happened yet */
|
||||||
int needs_sync_cache;
|
int needs_sync_cache;
|
||||||
|
|
||||||
/* ts A80412 : whether to use WRITE12 with Streaming bit set
|
/* ts A80412 : whether to use WRITE12 with Streaming bit set
|
||||||
|
@ -320,41 +260,22 @@ struct burn_drive
|
||||||
volatile int released;
|
volatile int released;
|
||||||
|
|
||||||
/* ts A61106 */
|
/* ts A61106 */
|
||||||
/* 0= report errors
|
|
||||||
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;
|
int silent_on_scsi_error;
|
||||||
|
|
||||||
/* ts B21023 */
|
|
||||||
/* bit0= 5 64 00 occurred with READ10 in mmc_read_10()
|
|
||||||
*/
|
|
||||||
int had_particular_error;
|
|
||||||
|
|
||||||
int stdio_fd;
|
int stdio_fd;
|
||||||
|
|
||||||
off_t nwa; /* next writeable address */
|
int nwa; /* next writeable address */
|
||||||
int alba; /* absolute lba */
|
int alba; /* absolute lba */
|
||||||
int rlba; /* relative lba in section */
|
int rlba; /* relative lba in section */
|
||||||
int start_lba;
|
int start_lba;
|
||||||
int end_lba;
|
int end_lba;
|
||||||
|
|
||||||
/* ts B61116 */
|
|
||||||
int do_simulate;
|
|
||||||
|
|
||||||
/* ts A70131 : from 51h READ DISC INFORMATION Number of Sessions (-1)*/
|
/* ts A70131 : from 51h READ DISC INFORMATION Number of Sessions (-1)*/
|
||||||
int complete_sessions;
|
int complete_sessions;
|
||||||
/* ts A90107 */
|
/* ts A90107 */
|
||||||
int state_of_last_session;
|
int state_of_last_session;
|
||||||
|
|
||||||
#ifdef Libburn_disc_with_incomplete_sessioN
|
|
||||||
/* ts B30112 */
|
|
||||||
int incomplete_sessions;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/* ts A70129 :
|
/* ts A70129 :
|
||||||
from 51h READ DISC INFORMATION Last Track Number in Last Session */
|
from 51h READ DISC INFORMATION Last Track Number in Last Session */
|
||||||
int last_track_no;
|
int last_track_no;
|
||||||
|
@ -371,30 +292,20 @@ struct burn_drive
|
||||||
/* ts A70215 : if > 0 : first lba on media that is too high for write*/
|
/* ts A70215 : if > 0 : first lba on media that is too high for write*/
|
||||||
int media_lba_limit;
|
int media_lba_limit;
|
||||||
|
|
||||||
/* ts A81210 / C40303 : Upper limit of readable data size,
|
/* ts A81210 : Upper limit of readable data size,
|
||||||
0x7fffffffffffffff = unknown
|
0x7fffffff = unknown
|
||||||
BURN_DRIVE_MAX_BYTES / 2048 = possibly truncated
|
0x7ffffff0 = 32 bit overflow, or unknown stdio size
|
||||||
or unknown stdio size
|
|
||||||
*/
|
*/
|
||||||
off_t media_read_capacity;
|
int media_read_capacity;
|
||||||
|
|
||||||
/* ts B60305 : Whether READ CAPACITY of CD is credible:
|
/* ts B10314 : Next Writeable Adress for drive_role == 5 */
|
||||||
-1= no READ CAPACITY yet , 0= untrusted READ CAPACITY
|
int role_5_nwa;
|
||||||
1= READ CAPACITY confirmed or corrected by other commands
|
|
||||||
*/
|
|
||||||
int mr_capacity_trusted;
|
|
||||||
|
|
||||||
/* ts B10314 / C40302 : Next Writeable Address for drive_role == 5 */
|
|
||||||
off_t role_5_nwa;
|
|
||||||
|
|
||||||
/* ts B60730 */
|
|
||||||
int do_no_immed;
|
|
||||||
|
|
||||||
int toc_temp;
|
int toc_temp;
|
||||||
struct burn_disc *disc; /* disc structure */
|
struct burn_disc *disc; /* disc structure */
|
||||||
int block_types[4];
|
int block_types[4];
|
||||||
struct buffer *buffer;
|
struct buffer *buffer;
|
||||||
struct burn_progress_v2 progress;
|
struct burn_progress progress;
|
||||||
|
|
||||||
/* To be used by mmc.c, sbc.c, spc.c for SCSI commands where the struct
|
/* To be used by mmc.c, sbc.c, spc.c for SCSI commands where the struct
|
||||||
content surely does not have to persist while another command gets
|
content surely does not have to persist while another command gets
|
||||||
|
@ -424,32 +335,12 @@ struct burn_drive
|
||||||
volatile int cancel;
|
volatile int cancel;
|
||||||
volatile enum burn_drive_status busy;
|
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 */
|
/* ts A70929 */
|
||||||
pid_t thread_pid;
|
pid_t thread_pid;
|
||||||
int thread_pid_valid;
|
int thread_pid_valid;
|
||||||
/* ts B00225 */
|
/* ts B00225 */
|
||||||
pthread_t thread_tid;
|
pthread_t thread_tid;
|
||||||
|
|
||||||
/* ts B90513 */
|
|
||||||
unsigned int write_retry_count;
|
|
||||||
|
|
||||||
/* ts C00806 */
|
|
||||||
/* 0=no change, 1=change, -1=already urged OS to revalidate medium */
|
|
||||||
int medium_state_changed;
|
|
||||||
|
|
||||||
/* ts C00822 */
|
|
||||||
/* If set, use Exact bit with SET STREAMING and use SET STREAMING
|
|
||||||
even if the medium is a CD.
|
|
||||||
*/
|
|
||||||
int set_streaming_exact_bit;
|
|
||||||
int set_streaming_err;
|
|
||||||
|
|
||||||
/* transport functions */
|
/* transport functions */
|
||||||
int (*grab) (struct burn_drive *);
|
int (*grab) (struct burn_drive *);
|
||||||
|
@ -467,7 +358,7 @@ struct burn_drive
|
||||||
/* ts A61021 */
|
/* ts A61021 */
|
||||||
void (*read_atip) (struct burn_drive *);
|
void (*read_atip) (struct burn_drive *);
|
||||||
|
|
||||||
int (*write) (struct burn_drive *, off_t, struct buffer *);
|
int (*write) (struct burn_drive *, int, struct buffer *);
|
||||||
void (*read_toc) (struct burn_drive *);
|
void (*read_toc) (struct burn_drive *);
|
||||||
void (*lock) (struct burn_drive *);
|
void (*lock) (struct burn_drive *);
|
||||||
void (*unlock) (struct burn_drive *);
|
void (*unlock) (struct burn_drive *);
|
||||||
|
@ -480,18 +371,17 @@ struct burn_drive
|
||||||
int is_stopped;
|
int is_stopped;
|
||||||
|
|
||||||
void (*read_disc_info) (struct burn_drive *);
|
void (*read_disc_info) (struct burn_drive *);
|
||||||
int (*read_cd) (struct burn_drive *, int start, int len,
|
void (*read_sectors) (struct burn_drive *,
|
||||||
int sec_type, int main_ch,
|
int start,
|
||||||
const struct burn_read_opts *, struct buffer *,
|
int len,
|
||||||
int flag);
|
const struct burn_read_opts *, struct buffer *);
|
||||||
void (*perform_opc) (struct burn_drive *);
|
void (*perform_opc) (struct burn_drive *);
|
||||||
void (*set_speed) (struct burn_drive *, int, int);
|
void (*set_speed) (struct burn_drive *, int, int);
|
||||||
void (*send_parameters) (struct burn_drive *,
|
void (*send_parameters) (struct burn_drive *,
|
||||||
const struct burn_read_opts *);
|
const struct burn_read_opts *);
|
||||||
void (*send_write_parameters) (struct burn_drive *,
|
void (*send_write_parameters) (struct burn_drive *,
|
||||||
struct burn_session *, int tno,
|
|
||||||
const struct burn_write_opts *);
|
const struct burn_write_opts *);
|
||||||
int (*send_cue_sheet) (struct burn_drive *, struct cue_sheet *);
|
void (*send_cue_sheet) (struct burn_drive *, struct cue_sheet *);
|
||||||
|
|
||||||
/* ts A70205 : Announce size of a DVD-R[W] DAO session. */
|
/* ts A70205 : Announce size of a DVD-R[W] DAO session. */
|
||||||
int (*reserve_track) (struct burn_drive *d, off_t size);
|
int (*reserve_track) (struct burn_drive *d, off_t size);
|
||||||
|
|
149
libburn/util.c
149
libburn/util.c
|
@ -1,6 +1,6 @@
|
||||||
|
|
||||||
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
|
/* 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.
|
Provided under GPL version 2 or later.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -15,12 +15,6 @@
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.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.
|
/* ts A80914 : This is unneeded. Version info comes from libburn.h.
|
||||||
#include "v ersion.h"
|
#include "v ersion.h"
|
||||||
|
@ -29,6 +23,42 @@
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "libburn.h"
|
#include "libburn.h"
|
||||||
|
|
||||||
|
char *burn_strdup(char *s)
|
||||||
|
{
|
||||||
|
char *ret;
|
||||||
|
int l;
|
||||||
|
|
||||||
|
/* ts A61008 */
|
||||||
|
/* a ssert(s); */
|
||||||
|
if (s == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
l = strlen(s) + 1;
|
||||||
|
ret = calloc(1, l);
|
||||||
|
memcpy(ret, s, l);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *burn_strndup(char *s, int n)
|
||||||
|
{
|
||||||
|
char *ret;
|
||||||
|
int l;
|
||||||
|
|
||||||
|
/* ts A61008 */
|
||||||
|
/* a ssert(s); */
|
||||||
|
/* a ssert(n > 0); */
|
||||||
|
if (s == NULL || n <= 0)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
l = strlen(s);
|
||||||
|
ret = calloc(1, l < n ? l : n);
|
||||||
|
|
||||||
|
memcpy(ret, s, l < n - 1 ? l : n - 1);
|
||||||
|
ret[n - 1] = '\0';
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
void burn_version(int *major, int *minor, int *micro)
|
void burn_version(int *major, int *minor, int *micro)
|
||||||
{
|
{
|
||||||
|
@ -177,7 +207,6 @@ char *burn_guess_manufacturer(int prf,
|
||||||
{"MCC", 8, "Mitsubishi Chemical Corporation"},
|
{"MCC", 8, "Mitsubishi Chemical Corporation"},
|
||||||
{"MCI", 8, "Mitsui Chemicals Inc."},
|
{"MCI", 8, "Mitsui Chemicals Inc."},
|
||||||
{"MEI", 3, "Panasonic Corporation"},
|
{"MEI", 3, "Panasonic Corporation"},
|
||||||
{"MILLEN", 8, "Millenniata Inc."},
|
|
||||||
{"MKM", 3, "Mitsubishi Kagaku Media Co."},
|
{"MKM", 3, "Mitsubishi Kagaku Media Co."},
|
||||||
{"MMC", 8, "Mitsubishi Kagaku Media Co."},
|
{"MMC", 8, "Mitsubishi Kagaku Media Co."},
|
||||||
{"MXL", 8, "Hitachi Maxell Ltd."},
|
{"MXL", 8, "Hitachi Maxell Ltd."},
|
||||||
|
@ -195,11 +224,9 @@ char *burn_guess_manufacturer(int prf,
|
||||||
{"RITEK", 5, "Ritek Corp"},
|
{"RITEK", 5, "Ritek Corp"},
|
||||||
{"SONY", 4, "Sony Corporation"},
|
{"SONY", 4, "Sony Corporation"},
|
||||||
{"TDK", 3, "TDK Corporation"},
|
{"TDK", 3, "TDK Corporation"},
|
||||||
{"TTG", 3, "TDK Corporation"},
|
{"TT", 8, "TDK Corporation"},
|
||||||
{"TTH", 3, "TDK Corporation"},
|
|
||||||
{"TY", 8, "Taiyo Yuden Company Limited"},
|
{"TY", 8, "Taiyo Yuden Company Limited"},
|
||||||
{"TYG", 3, "Taiyo Yuden Company Limited"},
|
{"TYG", 3, "Taiyo Yuden Company Limited"},
|
||||||
{"UME", 3, "UmeDisc Limited"},
|
|
||||||
{"UTJR001", 7, "Unifino Inc."},
|
{"UTJR001", 7, "Unifino Inc."},
|
||||||
{"VERBAT", 5, "Mitsubishi Kagaku Media Co."},
|
{"VERBAT", 5, "Mitsubishi Kagaku Media Co."},
|
||||||
{"YUDEN", 5, "Taiyo Yuden Company Limited"},
|
{"YUDEN", 5, "Taiyo Yuden Company Limited"},
|
||||||
|
@ -301,103 +328,3 @@ ex:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ts B11216 */
|
|
||||||
/** Read a line from fp and strip LF or CRLF */
|
|
||||||
char *burn_sfile_fgets(char *line, int maxl, FILE *fp)
|
|
||||||
{
|
|
||||||
int l;
|
|
||||||
char *ret;
|
|
||||||
|
|
||||||
ret = fgets(line, maxl, fp);
|
|
||||||
if (ret == NULL)
|
|
||||||
return NULL;
|
|
||||||
l = strlen(line);
|
|
||||||
if (l > 0)
|
|
||||||
if (line[l - 1] == '\r')
|
|
||||||
line[--l] = 0;
|
|
||||||
if (l > 0)
|
|
||||||
if (line[l - 1] == '\n')
|
|
||||||
line[--l] = 0;
|
|
||||||
if(l > 0)
|
|
||||||
if(line[l - 1] == '\r')
|
|
||||||
line[--l] = 0;
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
char *burn_printify(char *msg)
|
|
||||||
{
|
|
||||||
char *cpt;
|
|
||||||
|
|
||||||
for (cpt = msg; *cpt != 0; cpt++)
|
|
||||||
if (*cpt < 32 || *cpt > 126)
|
|
||||||
*cpt = '#';
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
|
@ -1,25 +1,11 @@
|
||||||
#ifndef __UTIL
|
#ifndef __UTIL
|
||||||
#define __UTIL
|
#define __UTIL
|
||||||
|
|
||||||
/* for struct stat */
|
char *burn_strdup(char *s);
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/stat.h>
|
char *burn_strndup(char *s, int n);
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
/* ts A90905 */
|
/* ts A90905 */
|
||||||
int burn_util_make_printable_word(char **text, int flag);
|
int burn_util_make_printable_word(char **text, int flag);
|
||||||
|
|
||||||
/* ts B11216 */
|
|
||||||
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
|
#endif
|
||||||
|
|
1132
libburn/write.c
1132
libburn/write.c
File diff suppressed because it is too large
Load Diff
|
@ -39,13 +39,6 @@ int burn_write_close_track(struct burn_write_opts *o, struct burn_session *s,
|
||||||
int tnum);
|
int tnum);
|
||||||
int burn_write_close_session(struct burn_write_opts *o);
|
int burn_write_close_session(struct burn_write_opts *o);
|
||||||
|
|
||||||
/* @param flag bit0= repair checksum
|
|
||||||
bit1= repair checksum if all pack CRCs are 0
|
|
||||||
@return 0= no mismatch , >0 number of unrepaired mismatches
|
|
||||||
<0 number of repaired mismatches
|
|
||||||
*/
|
|
||||||
int burn_cdtext_crc_mismatches(unsigned char *packs, int num_packs, int flag);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* mmc5r03c.pdf 6.3.3.3.3: DVD-R DL: Close Function 010b: Close Session
|
/* mmc5r03c.pdf 6.3.3.3.3: DVD-R DL: Close Function 010b: Close Session
|
||||||
|
|
|
@ -0,0 +1,41 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
cd ..
|
||||||
|
|
||||||
|
if [ ! -x configure ]; then
|
||||||
|
printf "\n*** please run ./bootstrap first.\n"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
build()
|
||||||
|
{
|
||||||
|
for F in ${1}
|
||||||
|
do
|
||||||
|
make clean
|
||||||
|
clear
|
||||||
|
printf "\n *** building with: %s\n" CPPFLAGS=-D${F}
|
||||||
|
sleep 1
|
||||||
|
# libcdio is not autodetected by default; should be available everywhere
|
||||||
|
CPPFLAGS=-D${F} ./configure --enable-libcdio; make 2> releng/libburn.${F}.log
|
||||||
|
make clean
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
OS=`uname -o`
|
||||||
|
|
||||||
|
case ${OS} in
|
||||||
|
GNU/Linux)
|
||||||
|
printf "OS: %s\n" ${OS}
|
||||||
|
sleep 1
|
||||||
|
build "__linux Libburn_use_sg_dummY Libburn_use_libcdiO"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
printf "Unknown OS: %s\n" ${OS}
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# just in case
|
||||||
|
unset CPPFLAGS
|
|
@ -3,8 +3,7 @@
|
||||||
Fakes a file in SUN .au format from a raw little-endian PCM audio file
|
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
|
(e.g. a file extracted from .wav by test/dewav). The input data are assumed
|
||||||
to be 16 bit, stereo, 44100 Hz.
|
to be 16 bit, stereo, 44100 Hz.
|
||||||
Copyright (C) 2006 - 2015 Thomas Schmitt <scdbackup@gmx.net>
|
Copyright (C) 2006 Thomas Schmitt <scdbackup@gmx.net>, provided under GPL
|
||||||
Provided under GPL version 2 or later.
|
|
||||||
|
|
||||||
Info used: http://www.opengroup.org/public/pubs/external/auformat.html
|
Info used: http://www.opengroup.org/public/pubs/external/auformat.html
|
||||||
*/
|
*/
|
||||||
|
@ -48,13 +47,6 @@ int main(int argc, char **argv)
|
||||||
exit_value= 1;
|
exit_value= 1;
|
||||||
goto help;
|
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++) {
|
for(i= 1; i<argc; i++) {
|
||||||
if(strcmp(argv[i],"-o")==0) {
|
if(strcmp(argv[i],"-o")==0) {
|
||||||
if(i>=argc-1) {
|
if(i>=argc-1) {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
|
|
||||||
/* test/libburner.c , API illustration of burning data or audio tracks to CD */
|
/* test/libburner.c , API illustration of burning data or audio tracks to CD */
|
||||||
/* Copyright (C) 2005 - 2016 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 */
|
/* Provided under GPL, see also "License and copyright aspects" at file end */
|
||||||
|
|
||||||
|
|
||||||
|
@ -16,25 +16,23 @@
|
||||||
to serve the libburnia team as reference application. libburner.c does indeed
|
to serve the libburnia team as reference application. libburner.c does indeed
|
||||||
define the standard way how above three gestures can be implemented and
|
define the standard way how above three gestures can be implemented and
|
||||||
stay upward compatible for a good while.
|
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
|
Before you can do anything, you have to initialize libburn by
|
||||||
burn_initialize()
|
burn_initialize()
|
||||||
and provide some signal and abort handling, e.g. by the builtin handler, by
|
and provide some signal and abort handling, e.g. by the builtin handler, by
|
||||||
burn_set_signal_handling("libburner : ", NULL, 0x0)
|
burn_set_signal_handling("libburner : ", NULL, 0x0)
|
||||||
as it is done in main() at the end of this file.
|
as it is done in main() at the end of this file.
|
||||||
Then you acquire a drive in an appropriate way conforming to the API. The two
|
Then you aquire a drive in an appropriate way conforming to the API. The twoi
|
||||||
main approaches are shown here in application functions:
|
main approaches are shown here in application functions:
|
||||||
libburner_aquire_by_adr() demonstrates usage as of cdrecord traditions
|
libburner_aquire_by_adr() demonstrates usage as of cdrecord traditions
|
||||||
libburner_aquire_by_driveno() demonstrates a scan-and-choose approach
|
libburner_aquire_by_driveno() demonstrates a scan-and-choose approach
|
||||||
|
|
||||||
With that acquired drive you can blank a CD-RW or DVD-RW as shown in
|
With that aquired drive you can blank a CD-RW or DVD-RW as shown in
|
||||||
libburner_blank_disc()
|
libburner_blank_disc()
|
||||||
or you can format a DVD-RW to profile "Restricted Overwrite" (needed once)
|
or you can format a DVD-RW to profile "Restricted Overwrite" (needed once)
|
||||||
or an unused BD to default size with spare blocks
|
or an unused BD to default size with spare blocks
|
||||||
libburner_format()
|
libburner_format()
|
||||||
With the acquired drive you can burn to CD, DVD, BD. See
|
With the aquired drive you can burn to CD, DVD, BD. See
|
||||||
libburner_payload()
|
libburner_payload()
|
||||||
|
|
||||||
These three functions switch temporarily to a non-fatal signal handler
|
These three functions switch temporarily to a non-fatal signal handler
|
||||||
|
@ -98,12 +96,12 @@ static unsigned int drive_count;
|
||||||
finally released */
|
finally released */
|
||||||
static int drive_is_grabbed = 0;
|
static int drive_is_grabbed = 0;
|
||||||
|
|
||||||
/** A number and a text describing the type of media in acquired drive */
|
/** A number and a text describing the type of media in aquired drive */
|
||||||
static int current_profile= -1;
|
static int current_profile= -1;
|
||||||
static char current_profile_name[80]= {""};
|
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 */
|
of the functions and their explanations in here */
|
||||||
int libburner_aquire_by_adr(char *drive_adr);
|
int libburner_aquire_by_adr(char *drive_adr);
|
||||||
int libburner_aquire_by_driveno(int *drive_no);
|
int libburner_aquire_by_driveno(int *drive_no);
|
||||||
|
@ -111,7 +109,7 @@ int libburner_aquire_by_driveno(int *drive_no);
|
||||||
|
|
||||||
/* ------------------------------- API gestures ---------------------------- */
|
/* ------------------------------- API gestures ---------------------------- */
|
||||||
|
|
||||||
/** You need to acquire a drive before burning. The API offers this as one
|
/** You need to aquire a drive before burning. The API offers this as one
|
||||||
compact call and alternatively as application controllable gestures of
|
compact call and alternatively as application controllable gestures of
|
||||||
whitelisting, scanning for drives and finally grabbing one of them.
|
whitelisting, scanning for drives and finally grabbing one of them.
|
||||||
|
|
||||||
|
@ -239,14 +237,14 @@ int libburner_aquire_by_driveno(int *driveno)
|
||||||
and to restart when the choice has been made. The list of selectable
|
and to restart when the choice has been made. The list of selectable
|
||||||
drives should also hold persistent drive addresses as obtained
|
drives should also hold persistent drive addresses as obtained
|
||||||
above by burn_drive_get_adr(). By such an address one may use
|
above by burn_drive_get_adr(). By such an address one may use
|
||||||
burn_drive_scan_and_grab() to finally acquire exactly one drive.
|
burn_drive_scan_and_grab() to finally aquire exactly one drive.
|
||||||
|
|
||||||
A not yet tested shortcut should be to call burn_drive_info_free()
|
A not yet tested shortcut should be to call burn_drive_info_free()
|
||||||
and to call either burn_drive_scan() or burn_drive_scan_and_grab()
|
and to call either burn_drive_scan() or burn_drive_scan_and_grab()
|
||||||
before accessing any drives again.
|
before accessing any drives again.
|
||||||
|
|
||||||
In both cases you have to be aware that the desired drive might get
|
In both cases you have to be aware that the desired drive might get
|
||||||
acquired 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)
|
/* 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
|
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.
|
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,
|
int libburner_payload(struct burn_drive *drive,
|
||||||
char source_adr[][4096], int source_adr_count,
|
char source_adr[][4096], int source_adr_count,
|
||||||
int multi, int simulate_burn, int all_tracks_type)
|
int multi, int simulate_burn, int all_tracks_type)
|
||||||
{
|
{
|
||||||
struct burn_source *data_src = NULL, *fifo_src[99];
|
struct burn_source *data_src, *fifo_src[99];
|
||||||
struct burn_disc *target_disc = NULL;
|
struct burn_disc *target_disc;
|
||||||
struct burn_session *session = NULL;
|
struct burn_session *session;
|
||||||
struct burn_write_opts *burn_options = NULL;
|
struct burn_write_opts *burn_options;
|
||||||
enum burn_disc_status disc_state;
|
enum burn_disc_status disc_state;
|
||||||
struct burn_track *track, *tracklist[99];
|
struct burn_track *track, *tracklist[99];
|
||||||
struct burn_progress progress;
|
struct burn_progress progress;
|
||||||
time_t start_time;
|
time_t start_time;
|
||||||
int last_sector = 0, padding = 0, trackno, unpredicted_size = 0, fd;
|
int last_sector = 0, padding = 0, trackno, unpredicted_size = 0, fd;
|
||||||
int fifo_chunksize = 2352, fifo_chunks = 1783; /* ~ 4 MB fifo */
|
int fifo_chunksize = 2352, fifo_chunks = 1783; /* ~ 4 MB fifo */
|
||||||
int ret;
|
|
||||||
off_t fixed_size;
|
off_t fixed_size;
|
||||||
char *adr, reasons[BURN_REASONS_LEN];
|
char *adr, reasons[BURN_REASONS_LEN];
|
||||||
struct stat stbuf;
|
struct stat stbuf;
|
||||||
|
|
||||||
for (trackno = 0 ; trackno < source_adr_count; trackno++) {
|
|
||||||
fifo_src[trackno] = NULL;
|
|
||||||
tracklist[trackno] = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (all_tracks_type != BURN_AUDIO) {
|
if (all_tracks_type != BURN_AUDIO) {
|
||||||
all_tracks_type = BURN_MODE1;
|
all_tracks_type = BURN_MODE1;
|
||||||
/* a padding of 300 kiB helps to avoid the read-ahead bug */
|
/* 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 */
|
/* Convert this filedescriptor into a burn_source object */
|
||||||
data_src = NULL;
|
data_src = NULL;
|
||||||
if (fd >= 0)
|
if (fd>=0)
|
||||||
data_src = burn_fd_source_new(fd, -1, fixed_size);
|
data_src = burn_fd_source_new(fd, -1, fixed_size);
|
||||||
if (data_src == NULL) {
|
if (data_src == NULL) {
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
|
@ -501,7 +496,7 @@ int libburner_payload(struct burn_drive *drive,
|
||||||
if(errno!=0)
|
if(errno!=0)
|
||||||
fprintf(stderr,"(Most recent system error: %s )\n",
|
fprintf(stderr,"(Most recent system error: %s )\n",
|
||||||
strerror(errno));
|
strerror(errno));
|
||||||
{ret = 0; goto ex;}
|
return 0;
|
||||||
}
|
}
|
||||||
/* Install a fifo object on top of that data source object */
|
/* Install a fifo object on top of that data source object */
|
||||||
fifo_src[trackno] = burn_fifo_source_new(data_src,
|
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) {
|
if (fifo_src[trackno] == NULL) {
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"FATAL: Could not create fifo object of 4 MB\n");
|
"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 */
|
/* Use the fifo object as data source for the track */
|
||||||
|
@ -517,7 +512,7 @@ int libburner_payload(struct burn_drive *drive,
|
||||||
!= BURN_SOURCE_OK) {
|
!= BURN_SOURCE_OK) {
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"FATAL: Cannot attach source object to track object\n");
|
"FATAL: Cannot attach source object to track object\n");
|
||||||
{ret = 0; goto ex;}
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
burn_session_add_track(session, track, BURN_POS_END);
|
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 */
|
/* Give up local reference to the data burn_source object */
|
||||||
burn_source_free(data_src);
|
burn_source_free(data_src);
|
||||||
data_src = NULL;
|
|
||||||
|
|
||||||
} /* trackno loop end */
|
} /* trackno loop end */
|
||||||
|
|
||||||
|
@ -542,7 +536,7 @@ int libburner_payload(struct burn_drive *drive,
|
||||||
else
|
else
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"FATAL: Cannot recognize state of drive and media\n");
|
"FATAL: Cannot recognize state of drive and media\n");
|
||||||
{ret = 0; goto ex;}
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
burn_options = burn_write_opts_new(drive);
|
burn_options = burn_write_opts_new(drive);
|
||||||
|
@ -557,7 +551,7 @@ int libburner_payload(struct burn_drive *drive,
|
||||||
reasons, 0) == BURN_WRITE_NONE) {
|
reasons, 0) == BURN_WRITE_NONE) {
|
||||||
fprintf(stderr, "FATAL: Failed to find a suitable write mode with this media.\n");
|
fprintf(stderr, "FATAL: Failed to find a suitable write mode with this media.\n");
|
||||||
fprintf(stderr, "Reasons given:\n%s\n", reasons);
|
fprintf(stderr, "Reasons given:\n%s\n", reasons);
|
||||||
{ret = 0; goto ex;}
|
return 0;
|
||||||
}
|
}
|
||||||
burn_set_signal_handling("libburner : ", NULL, 0x30);
|
burn_set_signal_handling("libburner : ", NULL, 0x30);
|
||||||
|
|
||||||
|
@ -565,6 +559,7 @@ int libburner_payload(struct burn_drive *drive,
|
||||||
start_time = time(0);
|
start_time = time(0);
|
||||||
burn_disc_write(burn_options, target_disc);
|
burn_disc_write(burn_options, target_disc);
|
||||||
|
|
||||||
|
burn_write_opts_free(burn_options);
|
||||||
while (burn_drive_get_status(drive, NULL) == BURN_DRIVE_SPAWNING)
|
while (burn_drive_get_status(drive, NULL) == BURN_DRIVE_SPAWNING)
|
||||||
usleep(100002);
|
usleep(100002);
|
||||||
while (burn_drive_get_status(drive, &progress) != BURN_DRIVE_IDLE) {
|
while (burn_drive_get_status(drive, &progress) != BURN_DRIVE_IDLE) {
|
||||||
|
@ -600,32 +595,21 @@ int libburner_payload(struct burn_drive *drive,
|
||||||
}
|
}
|
||||||
printf("\n");
|
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)
|
if (burn_is_aborting(0) > 0)
|
||||||
{ret = -1; goto ex;}
|
return -1;
|
||||||
if (multi && current_profile != 0x1a && current_profile != 0x13 &&
|
if (multi && current_profile != 0x1a && current_profile != 0x13 &&
|
||||||
current_profile != 0x12 && current_profile != 0x43)
|
current_profile != 0x12 && current_profile != 0x43)
|
||||||
/* not with DVD+RW, formatted DVD-RW, DVD-RAM, BD-RE */
|
/* not with DVD+RW, formatted DVD-RW, DVD-RAM, BD-RE */
|
||||||
printf("NOTE: Media left appendable.\n");
|
printf("NOTE: Media left appendable.\n");
|
||||||
if (simulate_burn)
|
if (simulate_burn)
|
||||||
printf("\n*** Did TRY to SIMULATE burning ***\n\n");
|
printf("\n*** Did TRY to SIMULATE burning ***\n\n");
|
||||||
ret = 1;
|
return 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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -784,7 +768,7 @@ int main(int argc, char **argv)
|
||||||
/** Note: driveno might change its value in this call */
|
/** Note: driveno might change its value in this call */
|
||||||
ret = libburner_aquire_drive(drive_adr, &driveno);
|
ret = libburner_aquire_drive(drive_adr, &driveno);
|
||||||
if (ret<=0) {
|
if (ret<=0) {
|
||||||
fprintf(stderr,"\nFATAL: Failed to acquire drive.\n");
|
fprintf(stderr,"\nFATAL: Failed to aquire drive.\n");
|
||||||
{ ret = 34; goto finish_libburn; }
|
{ ret = 34; goto finish_libburn; }
|
||||||
}
|
}
|
||||||
if (ret == 2)
|
if (ret == 2)
|
||||||
|
|
|
@ -7,7 +7,6 @@
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <string.h>
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
static struct burn_drive_info *drives;
|
static struct burn_drive_info *drives;
|
||||||
|
@ -63,7 +62,6 @@ int main()
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
memset(&newact, 0, sizeof(newact));
|
|
||||||
newact.sa_handler = catch_int;
|
newact.sa_handler = catch_int;
|
||||||
sigaction(SIGINT, &newact, &oldact);
|
sigaction(SIGINT, &newact, &oldact);
|
||||||
for (i = 0; i < (int) n_drives; i++) {
|
for (i = 0; i < (int) n_drives; i++) {
|
||||||
|
|
|
@ -0,0 +1,48 @@
|
||||||
|
#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;
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
232
test/telltoc.c
232
test/telltoc.c
|
@ -1,35 +1,32 @@
|
||||||
|
|
||||||
/* test/telltoc.c , API illustration of obtaining media status info */
|
/* test/telltoc.c , API illustration of obtaining media status info */
|
||||||
/* Copyright (C) 2006 - 2016 Thomas Schmitt <scdbackup@gmx.net>
|
/* Copyright (C) 2006 - 2011 Thomas Schmitt <scdbackup@gmx.net>
|
||||||
Provided under GPL */
|
Provided under GPL */
|
||||||
|
|
||||||
/** Overview
|
/** Overview
|
||||||
|
|
||||||
telltoc is a minimal demo application for the library libburn as provided
|
telltoc is a minimal demo application for the library libburn as provided
|
||||||
on http://libburnia-project.org . It can list the available devices, can
|
on http://libburnia-project.org . It can list the available devices, can
|
||||||
display some drive properties, the type of media, eventual table of content,
|
display some drive properties, the type of media, eventual table of content
|
||||||
multisession info for mkisofs option -C, and can read audio or data tracks.
|
and multisession info for mkisofs option -C .
|
||||||
|
|
||||||
It's main purpose, nevertheless, is to show you how to use libburn and also
|
It's main purpose, nevertheless, is to show you how to use libburn and also
|
||||||
to serve the libburn team as reference application. telltoc.c does indeed
|
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
|
define the standard way how above gestures can be implemented and stay upward
|
||||||
compatible for a good while.
|
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
|
Before you can do anything, you have to initialize libburn by
|
||||||
burn_initialize()
|
burn_initialize()
|
||||||
as it is done in main() at the end of this file. Then you acquire a
|
as it is done in main() at the end of this file. Then you aquire a
|
||||||
drive in an appropriate way conforming to the API. The two main
|
drive in an appropriate way conforming to the API. The two main
|
||||||
approaches are shown here in application functions:
|
approaches are shown here in application functions:
|
||||||
telltoc_aquire_by_adr() demonstrates usage as of cdrecord traditions
|
telltoc_aquire_by_adr() demonstrates usage as of cdrecord traditions
|
||||||
telltoc_aquire_by_driveno() demonstrates a scan-and-choose approach
|
telltoc_aquire_by_driveno() demonstrates a scan-and-choose approach
|
||||||
With that acquired drive you can call
|
With that aquired drive you can call
|
||||||
telltoc_media() prints some information about the media in a drive
|
telltoc_media() prints some information about the media in a drive
|
||||||
telltoc_toc() prints a table of content (if there is content)
|
telltoc_toc() prints a table of content (if there is content)
|
||||||
telltoc_msinfo() prints parameters for mkisofs option -C
|
telltoc_msinfo() prints parameters for mkisofs option -C
|
||||||
telltoc_read_and_print() reads from audio or data CD or from DVD or BD
|
telltoc_read_and_print() reads from data CD or from DVD and prints 7-bit
|
||||||
and prints 7-bit to stdout (encodings 0,2) or 8-bit to
|
to stdout (encodings 0,2) or 8-bit to file (encoding 1)
|
||||||
file (encoding 1)
|
|
||||||
When everything is done, main() releases the drive and shuts down libburn:
|
When everything is done, main() releases the drive and shuts down libburn:
|
||||||
burn_drive_release();
|
burn_drive_release();
|
||||||
burn_finish()
|
burn_finish()
|
||||||
|
@ -72,21 +69,20 @@ static unsigned int drive_count;
|
||||||
static int drive_is_grabbed = 0;
|
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 */
|
of the functions and their explanations in here */
|
||||||
int telltoc_aquire_by_adr(char *drive_adr);
|
int telltoc_aquire_by_adr(char *drive_adr);
|
||||||
int telltoc_aquire_by_driveno(int *drive_no, int silent);
|
int telltoc_aquire_by_driveno(int *drive_no, int silent);
|
||||||
|
|
||||||
|
|
||||||
/* Messages from --toc to --read_and_print (CD tracksize is a bit tricky) */
|
/* A message from --toc to --read_and_print (CD tracksize is a bit tricky) */
|
||||||
static int last_track_start = 0, last_track_size = -1;
|
static int last_track_start = 0, last_track_size = -1;
|
||||||
static int medium_is_cd_profile = 0; /* 0 = undecided , -1 = no , 1 = yes */
|
static int media_is_cd_profile = 0;
|
||||||
static int cd_is_audio = 0; /* 0 = undecided , -1 = no , 1 = yes */
|
|
||||||
|
|
||||||
|
|
||||||
/* ------------------------------- API gestures ---------------------------- */
|
/* ------------------------------- API gestures ---------------------------- */
|
||||||
|
|
||||||
/** You need to acquire a drive before burning. The API offers this as one
|
/** You need to aquire a drive before burning. The API offers this as one
|
||||||
compact call and alternatively as application controllable gestures of
|
compact call and alternatively as application controllable gestures of
|
||||||
whitelisting, scanning for drives and finally grabbing one of them.
|
whitelisting, scanning for drives and finally grabbing one of them.
|
||||||
|
|
||||||
|
@ -120,6 +116,10 @@ int telltoc_aquire_by_adr(char *drive_adr)
|
||||||
int ret;
|
int ret;
|
||||||
char libburn_drive_adr[BURN_DRIVE_ADR_LEN];
|
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 */
|
/* This tries to resolve links or alternative device files */
|
||||||
ret = burn_drive_convert_fs_adr(drive_adr, libburn_drive_adr);
|
ret = burn_drive_convert_fs_adr(drive_adr, libburn_drive_adr);
|
||||||
if (ret<=0) {
|
if (ret<=0) {
|
||||||
|
@ -128,7 +128,11 @@ int telltoc_aquire_by_adr(char *drive_adr)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
fprintf(stderr,"Acquiring drive '%s' ...\n", libburn_drive_adr);
|
/* <<< 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);
|
ret = burn_drive_scan_and_grab(&drive_list, libburn_drive_adr, 1);
|
||||||
|
|
||||||
if (ret <= 0) {
|
if (ret <= 0) {
|
||||||
|
@ -139,6 +143,10 @@ int telltoc_aquire_by_adr(char *drive_adr)
|
||||||
drive_is_grabbed = 1;
|
drive_is_grabbed = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* <<< ts A70907 FOR TESTING ONLY !
|
||||||
|
burn_drive_info_free(test_drive_list);
|
||||||
|
*/
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -240,14 +248,12 @@ int telltoc_regrab(struct burn_drive *drive) {
|
||||||
|
|
||||||
int telltoc_media(struct burn_drive *drive)
|
int telltoc_media(struct burn_drive *drive)
|
||||||
{
|
{
|
||||||
int ret, media_found = 0, profile_no = -1, num_profiles = 0, i;
|
int ret, media_found = 0, profile_no = -1;
|
||||||
int profiles[64];
|
|
||||||
char is_current_profile[64];
|
|
||||||
double max_speed = 0.0, min_speed = 0.0, speed_conv;
|
double max_speed = 0.0, min_speed = 0.0, speed_conv;
|
||||||
off_t available = 0;
|
off_t available = 0;
|
||||||
enum burn_disc_status s;
|
enum burn_disc_status s;
|
||||||
char profile_name[80], speed_unit[40];
|
char profile_name[80], speed_unit[40];
|
||||||
struct burn_multi_caps *caps = NULL;
|
struct burn_multi_caps *caps;
|
||||||
struct burn_write_opts *o = NULL;
|
struct burn_write_opts *o = NULL;
|
||||||
|
|
||||||
printf("Media current: ");
|
printf("Media current: ");
|
||||||
|
@ -260,32 +266,15 @@ int telltoc_media(struct burn_drive *drive)
|
||||||
} else
|
} else
|
||||||
printf("is not recognizable\n");
|
printf("is not recognizable\n");
|
||||||
|
|
||||||
/* Determine speed unit before profile_name gets reused */
|
|
||||||
speed_conv = 176.4;
|
speed_conv = 176.4;
|
||||||
strcpy(speed_unit,"176.4 kB/s (CD, data speed 150 KiB/s)");
|
strcpy(speed_unit,"176.4 kB/s (CD, data speed 150 KiB/s)");
|
||||||
if (strstr(profile_name, "DVD") == profile_name) {
|
if (strstr(profile_name, "DVD") == profile_name) {
|
||||||
speed_conv = 1385.0;
|
speed_conv = 1385.0;
|
||||||
strcpy(speed_unit,"1385.0 kB/s (DVD)");
|
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 : ");
|
printf("Media status : ");
|
||||||
s = burn_disc_get_status(drive);
|
s = burn_disc_get_status(drive);
|
||||||
if (s == BURN_DISC_FULL) {
|
if (s == BURN_DISC_FULL) {
|
||||||
|
@ -316,15 +305,15 @@ int telltoc_media(struct burn_drive *drive)
|
||||||
/* Media appears writeable */
|
/* Media appears writeable */
|
||||||
printf("Write multi : ");
|
printf("Write multi : ");
|
||||||
printf("%s multi-session , ",
|
printf("%s multi-session , ",
|
||||||
caps->multi_session == 1 ? "offers" : "cannot do");
|
caps->multi_session == 1 ? "allows" : "prohibits");
|
||||||
if (caps->multi_track)
|
if (caps->multi_track)
|
||||||
printf("offers multiple tracks\n");
|
printf("allows multiple tracks\n");
|
||||||
else
|
else
|
||||||
printf("offers only single track\n");
|
printf("enforces single track\n");
|
||||||
printf("Write start : ");
|
printf("Write start : ");
|
||||||
if (caps->start_adr == 1)
|
if (caps->start_adr == 1)
|
||||||
printf(
|
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_low / 2048 ,
|
||||||
(double) caps->start_range_high / 2048 ,
|
(double) caps->start_range_high / 2048 ,
|
||||||
(double) caps->start_alignment / 2048 );
|
(double) caps->start_alignment / 2048 );
|
||||||
|
@ -399,8 +388,6 @@ int telltoc_media(struct burn_drive *drive)
|
||||||
}
|
}
|
||||||
printf("Speed unit 1x: %s\n", speed_unit);
|
printf("Speed unit 1x: %s\n", speed_unit);
|
||||||
|
|
||||||
if (caps != NULL)
|
|
||||||
burn_disc_free_multi_caps(&caps);
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -477,25 +464,12 @@ int telltoc_formatlist(struct burn_drive *drive)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void telltoc_detect_cd(struct burn_drive *drive)
|
|
||||||
{
|
|
||||||
int pno;
|
|
||||||
char profile_name[80];
|
|
||||||
|
|
||||||
if (burn_disc_get_profile(drive, &pno, profile_name) > 0) {
|
|
||||||
if (pno >= 0x08 && pno <= 0x0a)
|
|
||||||
medium_is_cd_profile = 1;
|
|
||||||
else
|
|
||||||
medium_is_cd_profile = -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int telltoc_toc(struct burn_drive *drive)
|
int telltoc_toc(struct burn_drive *drive)
|
||||||
{
|
{
|
||||||
int num_sessions = 0 , num_tracks = 0 , lba = 0, pmin, psec, pframe;
|
int num_sessions = 0 , num_tracks = 0 , lba = 0, pmin, psec, pframe;
|
||||||
int track_count = 0, track_is_audio;
|
int track_count = 0, pno;
|
||||||
int session_no, track_no;
|
int session_no, track_no;
|
||||||
|
char profile_name[80];
|
||||||
struct burn_disc *disc= NULL;
|
struct burn_disc *disc= NULL;
|
||||||
struct burn_session **sessions;
|
struct burn_session **sessions;
|
||||||
struct burn_track **tracks;
|
struct burn_track **tracks;
|
||||||
|
@ -525,20 +499,10 @@ int telltoc_toc(struct burn_drive *drive)
|
||||||
pframe = toc_entry.pframe;
|
pframe = toc_entry.pframe;
|
||||||
lba= burn_msf_to_lba(pmin, psec, pframe);
|
lba= burn_msf_to_lba(pmin, psec, pframe);
|
||||||
}
|
}
|
||||||
|
printf("Media content: session %2d ", session_no+1);
|
||||||
if ((toc_entry.control & 7) < 4) {
|
printf("track %2d %s lba: %9d %4.2d:%2.2d:%2.2d\n",
|
||||||
if (cd_is_audio == 0)
|
|
||||||
cd_is_audio = 1;
|
|
||||||
track_is_audio = 1;
|
|
||||||
} else {
|
|
||||||
track_is_audio = 0;
|
|
||||||
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",
|
|
||||||
track_count,
|
track_count,
|
||||||
(track_is_audio ? "audio" : "data "),
|
((toc_entry.control&7)<4?"audio":"data "),
|
||||||
lba, pmin, psec, pframe);
|
lba, pmin, psec, pframe);
|
||||||
last_track_start = lba;
|
last_track_start = lba;
|
||||||
}
|
}
|
||||||
|
@ -553,11 +517,14 @@ int telltoc_toc(struct burn_drive *drive)
|
||||||
pframe = toc_entry.pframe;
|
pframe = toc_entry.pframe;
|
||||||
lba= burn_msf_to_lba(pmin, psec, pframe);
|
lba= burn_msf_to_lba(pmin, psec, pframe);
|
||||||
}
|
}
|
||||||
printf("Media content: session %3d ", session_no+1);
|
printf("Media content: session %2d ", session_no+1);
|
||||||
printf("leadout lba: %9d %4.2d:%2.2d:%2.2d\n",
|
printf("leadout lba: %9d %4.2d:%2.2d:%2.2d\n",
|
||||||
lba, pmin, psec, pframe);
|
lba, pmin, psec, pframe);
|
||||||
last_track_size = lba - last_track_start;
|
last_track_size = lba - last_track_start;
|
||||||
telltoc_detect_cd(drive);
|
if (burn_disc_get_profile(drive, &pno, profile_name) > 0)
|
||||||
|
if (pno == 0x09 || pno == 0x0a)
|
||||||
|
media_is_cd_profile = 1;
|
||||||
|
|
||||||
}
|
}
|
||||||
if (disc!=NULL)
|
if (disc!=NULL)
|
||||||
burn_disc_free(disc);
|
burn_disc_free(disc);
|
||||||
|
@ -630,26 +597,27 @@ int telltoc_read_and_print(struct burn_drive *drive,
|
||||||
int start_sector, int sector_count, char *raw_file, int encoding)
|
int start_sector, int sector_count, char *raw_file, int encoding)
|
||||||
{
|
{
|
||||||
int j, i, request = 16, done, lbas = 0, final_cd_try = -1, todo;
|
int j, i, request = 16, done, lbas = 0, final_cd_try = -1, todo;
|
||||||
int ret = 0, sector_size, chunk_size, read_audio = 0;
|
int ret = 0;
|
||||||
char buf[16 * 2048], line[81];
|
char buf[16 * 2048], line[81];
|
||||||
off_t data_count, total_count= 0, last_reported_count= 0;
|
off_t data_count, total_count= 0, last_reported_count= 0;
|
||||||
struct stat stbuf;
|
struct stat stbuf;
|
||||||
FILE *raw_fp = NULL;
|
FILE *raw_fp = NULL;
|
||||||
|
|
||||||
if (medium_is_cd_profile == 0)
|
|
||||||
telltoc_detect_cd(drive);
|
|
||||||
if (start_sector == -1)
|
if (start_sector == -1)
|
||||||
start_sector = last_track_start;
|
start_sector = last_track_start;
|
||||||
if (sector_count == -1) {
|
if (sector_count == -1) {
|
||||||
sector_count = last_track_start + last_track_size
|
sector_count = last_track_start + last_track_size
|
||||||
- start_sector;
|
- start_sector;
|
||||||
if (medium_is_cd_profile > 0) /* In case it is a TAO track */
|
if (media_is_cd_profile) /* In case it is a TAO track */
|
||||||
final_cd_try = 0; /* allow it (-1 is denial) */
|
final_cd_try = 0; /* allow it (-1 is denial) */
|
||||||
}
|
}
|
||||||
|
if (start_sector < 0)
|
||||||
|
start_sector = 0;
|
||||||
if (sector_count <= 0)
|
if (sector_count <= 0)
|
||||||
sector_count = 2147483632;
|
sector_count = 2147483632;
|
||||||
|
|
||||||
|
if (sector_count <= 0)
|
||||||
|
return -1;
|
||||||
if (encoding == 1) {
|
if (encoding == 1) {
|
||||||
if (stat(raw_file,&stbuf) != -1) {
|
if (stat(raw_file,&stbuf) != -1) {
|
||||||
if (!(S_ISCHR(stbuf.st_mode) || S_ISFIFO(stbuf.st_mode)
|
if (!(S_ISCHR(stbuf.st_mode) || S_ISFIFO(stbuf.st_mode)
|
||||||
|
@ -672,63 +640,26 @@ int telltoc_read_and_print(struct burn_drive *drive,
|
||||||
printf(
|
printf(
|
||||||
"Data : start=%ds , count=%ds , read=0 , encoding=%d\n",
|
"Data : start=%ds , count=%ds , read=0 , encoding=%d\n",
|
||||||
start_sector, sector_count, encoding);
|
start_sector, sector_count, encoding);
|
||||||
|
|
||||||
/* Whether to read audio or data */
|
|
||||||
if (cd_is_audio > 0) {
|
|
||||||
read_audio = 1;
|
|
||||||
} else if (medium_is_cd_profile > 0 && cd_is_audio == 0) {
|
|
||||||
/* Try whether the start sector is audio */
|
|
||||||
ret = burn_read_audio(drive, start_sector,
|
|
||||||
buf, (off_t) 2352, &data_count, 2 | 4);
|
|
||||||
if (ret > 0)
|
|
||||||
read_audio = 1;
|
|
||||||
}
|
|
||||||
if (read_audio) {
|
|
||||||
sector_size = 2352;
|
|
||||||
chunk_size = 12;
|
|
||||||
} else {
|
|
||||||
sector_size = 2048;
|
|
||||||
chunk_size = 16;
|
|
||||||
if (start_sector < 0)
|
|
||||||
start_sector = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
todo = sector_count - 2*(final_cd_try > -1);
|
todo = sector_count - 2*(final_cd_try > -1);
|
||||||
for (done = 0; done < todo && final_cd_try != 1; done += request) {
|
for (done = 0; done < todo && final_cd_try != 1; done += request) {
|
||||||
if (todo - done > chunk_size)
|
if (todo - done > 16)
|
||||||
request = chunk_size;
|
request = 16;
|
||||||
else
|
else
|
||||||
request = todo - done;
|
request = todo - done;
|
||||||
|
ret = burn_read_data(drive,
|
||||||
if (read_audio) {
|
((off_t) start_sector + done) * (off_t) 2048,
|
||||||
ret = burn_read_audio(drive, start_sector + done,
|
buf, (off_t) (request * 2048), &data_count, 1);
|
||||||
buf, (off_t) (request * sector_size),
|
|
||||||
&data_count, 0);
|
|
||||||
} else {
|
|
||||||
ret = burn_read_data(drive,
|
|
||||||
((off_t) start_sector + done) *
|
|
||||||
(off_t) sector_size,
|
|
||||||
buf, (off_t) (request * sector_size),
|
|
||||||
&data_count, 1);
|
|
||||||
}
|
|
||||||
print_result:;
|
print_result:;
|
||||||
total_count += data_count;
|
total_count += data_count;
|
||||||
if (encoding == 1) {
|
if (encoding == 1) {
|
||||||
if (data_count > 0) {
|
if (data_count > 0)
|
||||||
ret = fwrite(buf, data_count, 1, raw_fp);
|
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else for (i = 0; i < data_count; i += 16) {
|
} else for (i = 0; i < data_count; i += 16) {
|
||||||
if (encoding == 0) {
|
if (encoding == 0) {
|
||||||
sprintf(line, "%8ds + %4d : ",
|
sprintf(line, "%8ds + %4d : ",
|
||||||
start_sector + done + i / sector_size,
|
start_sector + done + i / 2048,
|
||||||
i % sector_size);
|
i % 2048);
|
||||||
lbas = strlen(line);
|
lbas = strlen(line);
|
||||||
}
|
}
|
||||||
for (j = 0; j < 16 && i + j < data_count; j++) {
|
for (j = 0; j < 16 && i + j < data_count; j++) {
|
||||||
|
@ -744,11 +675,11 @@ print_result:;
|
||||||
printf("%s\n",line);
|
printf("%s\n",line);
|
||||||
}
|
}
|
||||||
if (encoding == 1 &&
|
if (encoding == 1 &&
|
||||||
total_count - last_reported_count >= 1000 * sector_size) {
|
total_count - last_reported_count >= 1000 * 2048) {
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"\rReading data : start=%ds , count=%ds , read=%ds ",
|
"\rReading data : start=%ds , count=%ds , read=%ds ",
|
||||||
start_sector, sector_count,
|
start_sector, sector_count,
|
||||||
(int) (total_count / (off_t) sector_size));
|
(int) (total_count / (off_t) 2048));
|
||||||
last_reported_count = total_count;
|
last_reported_count = total_count;
|
||||||
}
|
}
|
||||||
if (ret <= 0) {
|
if (ret <= 0) {
|
||||||
|
@ -756,21 +687,13 @@ print_result:;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (ret > 0 && medium_is_cd_profile > 0 && final_cd_try == 0) {
|
if (ret > 0 && media_is_cd_profile && final_cd_try == 0) {
|
||||||
/* In a SAO track the last 2 frames should be data too */
|
/* In a SAO track the last 2 frames should be data too */
|
||||||
final_cd_try = 1;
|
final_cd_try = 1;
|
||||||
if (read_audio) {
|
burn_read_data(drive,
|
||||||
ret = burn_read_audio(drive, start_sector + todo,
|
((off_t) start_sector + todo) * (off_t) 2048,
|
||||||
buf, (off_t) (2 * sector_size),
|
buf, (off_t) (2 * 2048), &data_count, 2);
|
||||||
&data_count, 2);
|
if (data_count < 2 * 2048)
|
||||||
} else {
|
|
||||||
burn_read_data(drive,
|
|
||||||
((off_t) start_sector + todo) *
|
|
||||||
(off_t) sector_size,
|
|
||||||
buf, (off_t) (2 * sector_size),
|
|
||||||
&data_count, 2);
|
|
||||||
}
|
|
||||||
if (data_count < 2 * sector_size)
|
|
||||||
fprintf(stderr, "\rNOTE : Last two frames of CD track unreadable. This is normal if TAO track.\n");
|
fprintf(stderr, "\rNOTE : Last two frames of CD track unreadable. This is normal if TAO track.\n");
|
||||||
if (data_count > 0)
|
if (data_count > 0)
|
||||||
goto print_result;
|
goto print_result;
|
||||||
|
@ -779,11 +702,8 @@ print_result:;
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"\r \r");
|
"\r \r");
|
||||||
printf("End Of Data : start=%ds , count=%ds , read=%ds\n",
|
printf("End Of Data : start=%ds , count=%ds , read=%ds\n",
|
||||||
start_sector, sector_count,
|
start_sector, sector_count,(int) (total_count / (off_t) 2048));
|
||||||
(int) (total_count / (off_t) sector_size));
|
|
||||||
|
|
||||||
if (raw_fp != NULL)
|
|
||||||
fclose(raw_fp);
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -808,13 +728,6 @@ int telltoc_setup(int argc, char **argv)
|
||||||
{
|
{
|
||||||
int i;
|
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) {
|
for (i = 1; i < argc; ++i) {
|
||||||
if (!strcmp(argv[i], "--drive")) {
|
if (!strcmp(argv[i], "--drive")) {
|
||||||
++i;
|
++i;
|
||||||
|
@ -856,8 +769,7 @@ int telltoc_setup(int argc, char **argv)
|
||||||
sscanf(argv[i-2], "%d", &read_start);
|
sscanf(argv[i-2], "%d", &read_start);
|
||||||
sscanf(argv[i-1], "%d", &read_count);
|
sscanf(argv[i-1], "%d", &read_count);
|
||||||
print_encoding = 0;
|
print_encoding = 0;
|
||||||
if(strncmp(argv[i], "raw:", 4) == 0 ||
|
if(strncmp(argv[i], "raw:", 4) == 0 || strcmp(argv[i],"1:") == 0) {
|
||||||
strncmp(argv[i], "1:", 2) == 0) {
|
|
||||||
print_encoding = 1;
|
print_encoding = 1;
|
||||||
strcpy(print_raw_file, strchr(argv[i], ':') + 1);
|
strcpy(print_raw_file, strchr(argv[i], ':') + 1);
|
||||||
if (strcmp(print_raw_file, "-") == 0) {
|
if (strcmp(print_raw_file, "-") == 0) {
|
||||||
|
@ -896,10 +808,10 @@ int telltoc_setup(int argc, char **argv)
|
||||||
printf(" mkisofs ... -C \"$msinfo\" ...\n");
|
printf(" mkisofs ... -C \"$msinfo\" ...\n");
|
||||||
printf("Obtain what is available about drive 0 and its media\n");
|
printf("Obtain what is available about drive 0 and its media\n");
|
||||||
printf(" %s --drive 0\n",argv[0]);
|
printf(" %s --drive 0\n",argv[0]);
|
||||||
printf("View blocks 16 to 19 of audio or data CD or DVD or BD in human readable form\n");
|
printf("View blocks 16 to 19 of data CD or DVD in human readable form\n");
|
||||||
printf(" %s --drive /dev/sr1 --read_and_print 16 4 0 | less\n",
|
printf(" %s --drive /dev/sr1 --read_and_print 16 4 0 | less\n",
|
||||||
argv[0]);
|
argv[0]);
|
||||||
printf("Copy last track from CD to file /tmp/data\n");
|
printf("Copy last data track from CD to file /tmp/data\n");
|
||||||
printf(" %s --drive /dev/sr1 --toc --read_and_print -1 -1 raw:/tmp/data\n",
|
printf(" %s --drive /dev/sr1 --toc --read_and_print -1 -1 raw:/tmp/data\n",
|
||||||
argv[0]);
|
argv[0]);
|
||||||
}
|
}
|
||||||
|
@ -979,7 +891,7 @@ int main(int argc, char **argv)
|
||||||
if (ret<=0)
|
if (ret<=0)
|
||||||
{ret = 38; goto release_drive; }
|
{ret = 38; goto release_drive; }
|
||||||
}
|
}
|
||||||
if (read_start != -2 && (read_count > 0 || read_count == -1)) {
|
if (read_start >= -1 && (read_count > 0 || read_count == -1)) {
|
||||||
ret = telltoc_read_and_print(drive_list[driveno].drive,
|
ret = telltoc_read_and_print(drive_list[driveno].drive,
|
||||||
read_start, read_count, print_raw_file,
|
read_start, read_count, print_raw_file,
|
||||||
print_encoding);
|
print_encoding);
|
||||||
|
@ -1004,6 +916,6 @@ finish_libburn:;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* License and copyright aspects:
|
/* License and copyright aspects:
|
||||||
See test/libburner.c
|
See libburner.c
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue