Compare commits
55 Commits
release-1.
...
master
Author | SHA1 | Date |
---|---|---|
Thomas Schmitt | 6fb158b56d | |
Thomas Schmitt | 51f43127ac | |
Thomas Schmitt | f84d038121 | |
Thomas Schmitt | e5a8d91e4d | |
Thomas Schmitt | f0d9795cd1 | |
Thomas Schmitt | 29bfd7e5e7 | |
Thomas Schmitt | d48bbb4b66 | |
Thomas Schmitt | 17a020e9fc | |
Thomas Schmitt | 069b4edecd | |
Thomas Schmitt | 84e8efeb0a | |
Thomas Schmitt | ddebbf1b60 | |
Thomas Schmitt | ca29b77091 | |
Thomas Schmitt | 046f581baa | |
Thomas Schmitt | c8ceb73b5f | |
Thomas Schmitt | f4a09e9536 | |
Thomas Schmitt | 4628231cec | |
Thomas Schmitt | f795db5d61 | |
Thomas Schmitt | 9acb8ad6da | |
Thomas Schmitt | 1172ef74c6 | |
Thomas Schmitt | a904ae995a | |
Thomas Schmitt | 1954514210 | |
Thomas Schmitt | 629a4fa44d | |
Thomas Schmitt | 879cb991df | |
Thomas Schmitt | d4d63213ab | |
Thomas Schmitt | 7765fbd1ab | |
Thomas Schmitt | da44c706ea | |
Thomas Schmitt | 31591b8196 | |
Thomas Schmitt | 27e15689e5 | |
Thomas Schmitt | 0a1bbb1696 | |
Thomas Schmitt | c76145f5e1 | |
Thomas Schmitt | 8d270b1fda | |
Thomas Schmitt | 892df643c9 | |
Thomas Schmitt | 31e8f5cf0e | |
Thomas Schmitt | 2a977cfc4b | |
Thomas Schmitt | be039ff191 | |
Thomas Schmitt | f1d5c670c5 | |
Thomas Schmitt | d3bd97c05e | |
Thomas Schmitt | d146886763 | |
Thomas Schmitt | d95d5a2484 | |
Thomas Schmitt | 2a58d5ae5c | |
Thomas Schmitt | 3468a2ad38 | |
Thomas Schmitt | 6b2ae7d141 | |
Thomas Schmitt | ab6b1039a4 | |
Thomas Schmitt | 8b9a8cfb4b | |
Thomas Schmitt | 0e1f5dc3da | |
Thomas Schmitt | 8d934ee7b8 | |
Thomas Schmitt | e09acf3b8a | |
Thomas Schmitt | 799175019b | |
Thomas Schmitt | b57c05c874 | |
Thomas Schmitt | d4593f49ae | |
Thomas Schmitt | 91f7d4d34a | |
Thomas Schmitt | ba9b69b1df | |
Thomas Schmitt | 1c235e807e | |
Thomas Schmitt | 95ad059aba | |
Thomas Schmitt | 0a37e8cbe5 |
25
ChangeLog
25
ChangeLog
|
@ -1,3 +1,28 @@
|
|||
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
|
||||
|
|
|
@ -114,9 +114,9 @@ test_poll_CPPFLAGS = -Ilibburn
|
|||
test_poll_LDADD = $(libburn_libburn_la_OBJECTS) $(LIBBURN_EXTRALIBS)
|
||||
test_poll_SOURCES = test/poll.c
|
||||
|
||||
## cdrskin construction site - ts A60816 - B91026
|
||||
## cdrskin construction site - ts A60816 - C30607
|
||||
cdrskin_cdrskin_CPPFLAGS = -Ilibburn
|
||||
cdrskin_cdrskin_CFLAGS = -DCdrskin_libburn_1_5_2
|
||||
cdrskin_cdrskin_CFLAGS = -DCdrskin_libburn_1_5_7
|
||||
|
||||
# cdrskin_cdrskin_LDADD = $(libburn_libburn_la_OBJECTS) $(LIBBURN_EXTRALIBS)
|
||||
# ts A80123, change proposed by Simon Huggins to cause dynamic libburn linking
|
||||
|
@ -201,6 +201,7 @@ EXTRA_DIST = \
|
|||
doc/cookbook.txt \
|
||||
doc/mediainfo.txt \
|
||||
doc/cdtext.txt \
|
||||
doc/waveformat.txt \
|
||||
README \
|
||||
AUTHORS \
|
||||
CONTRIBUTORS \
|
||||
|
|
62
README
62
README
|
@ -6,12 +6,12 @@ This all is under GPL.
|
|||
------------------------------------------------------------------------------
|
||||
libburnia-project.org
|
||||
By Mario Danic <mario.danic@gmail.com> and Thomas Schmitt <scdbackup@gmx.net>
|
||||
Copyright (C) 2006-2019 Mario Danic, Thomas Schmitt
|
||||
Copyright (C) 2006-2023 Mario Danic, Thomas Schmitt
|
||||
Still containing parts of Libburn. By Derek Foreman <derek@signalmarketing.com>
|
||||
and Ben Jansens <xor@orodu.net>
|
||||
Copyright (C) 2002-2006 Derek Foreman and Ben Jansens
|
||||
|
||||
http://files.libburnia-project.org/releases/libburn-1.5.2.tar.gz
|
||||
http://files.libburnia-project.org/releases/libburn-1.5.6.tar.gz
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
|
@ -19,10 +19,10 @@ Copyright (C) 2002-2006 Derek Foreman and Ben Jansens
|
|||
|
||||
From tarball
|
||||
|
||||
Obtain libburn-1.5.2.tar.gz, take it to a directory of your choice and do:
|
||||
Obtain libburn-1.5.6.tar.gz, take it to a directory of your choice and do:
|
||||
|
||||
tar xzf libburn-1.5.2.tar.gz
|
||||
cd libburn-1.5.2
|
||||
tar xzf libburn-1.5.6.tar.gz
|
||||
cd libburn-1.5.6
|
||||
./configure --prefix=/usr
|
||||
make
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
||||
From SVN
|
||||
From git
|
||||
|
||||
Our build system is based on autotools. For preparing the build of a SVN
|
||||
Our build system is based on autotools. For preparing the build of a git
|
||||
snapshot you will need autotools of at least version 1.7.
|
||||
Do in a directory of your choice:
|
||||
|
||||
svn co http://svn.libburnia-project.org/libburn/trunk libburn-svn
|
||||
cd libburn-svn
|
||||
git clone https://dev.lovelyhq.com/libburnia/libburn.git libburn-git
|
||||
cd libburn-git
|
||||
./bootstrap
|
||||
./configure --prefix=/usr
|
||||
make
|
||||
make install
|
||||
|
||||
Warning: The trunk might contain experimental features which might not
|
||||
persist until next release.
|
||||
Warning: The master branch might contain experimental features which might
|
||||
not persist until next release.
|
||||
|
||||
|
||||
Special ./configure options
|
||||
|
@ -113,12 +113,11 @@ closing it immediately, waiting, and only then opening it for real:
|
|||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
An important part of the project, libisofs, is hosted in a bzr repository at
|
||||
launchpad.net :
|
||||
bzr branch lp:libisofs
|
||||
The other parts of the the libburnia project are hosted as neighbors of
|
||||
libburn:
|
||||
|
||||
Another part the project, libisoburn, is hosted in the libburnia SVN, too:
|
||||
svn co http://svn.libburnia-project.org/libisoburn/trunk libisoburn
|
||||
git clone https://dev.lovelyhq.com/libburnia/libisofs.git
|
||||
git clone https://dev.lovelyhq.com/libburnia/libisoburn.git
|
||||
|
||||
See README files there.
|
||||
|
||||
|
@ -791,6 +790,37 @@ Project history as far as known to me:
|
|||
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.
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
|
|
95
acinclude.m4
95
acinclude.m4
|
@ -16,6 +16,7 @@ AC_DEFUN([TARGET_SHIZZLE],
|
|||
|
||||
AC_MSG_CHECKING([target operating system])
|
||||
|
||||
libburn_check_libcam=
|
||||
LIBBURNIA_LDCONFIG_CMD="echo 'No ldconfig run performed. If needed, configure manually for:'"
|
||||
|
||||
case $target in
|
||||
|
@ -32,6 +33,7 @@ AC_DEFUN([TARGET_SHIZZLE],
|
|||
*-kfreebsd*-gnu*)
|
||||
ARCH=freebsd
|
||||
LIBBURN_ARCH_LIBS=-lcam
|
||||
libburn_check_libcam=yes
|
||||
;;
|
||||
*-solaris*)
|
||||
ARCH=solaris
|
||||
|
@ -43,8 +45,12 @@ AC_DEFUN([TARGET_SHIZZLE],
|
|||
# AC_ERROR([You are attempting to compile for an unsupported platform])
|
||||
;;
|
||||
esac
|
||||
|
||||
AC_MSG_RESULT([$ARCH])
|
||||
|
||||
if test x"$libburn_check_libcam" = xyes
|
||||
then
|
||||
LIBBURNIA_CHECK_LIBCAM
|
||||
fi
|
||||
])
|
||||
|
||||
|
||||
|
@ -120,6 +126,7 @@ 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"
|
||||
|
@ -140,11 +147,19 @@ AC_DEFUN([LIBBURNIA_CHECK_ARCH_LIBS],
|
|||
echo >&2
|
||||
(exit 1); exit 1;
|
||||
else
|
||||
echo "disabled linking with $LIBBURN_ARCH_LIBS (because not found)"
|
||||
if test x"$1" = xoptional
|
||||
then
|
||||
echo "disabled linking with $LIBBURN_ARCH_LIBS (because not found)"
|
||||
fi
|
||||
LIBBURN_ARCH_LIBS=""
|
||||
fi
|
||||
else
|
||||
echo "enabled linking with $LIBBURN_ARCH_LIBS"
|
||||
if test x"$1" = xsilent
|
||||
then
|
||||
dummy=dummy
|
||||
else
|
||||
echo "enabled linking with $LIBBURN_ARCH_LIBS"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
])
|
||||
|
@ -155,18 +170,72 @@ dnl
|
|||
AC_DEFUN([LIBBURNIA_CHECK_LINUX_SCSI],
|
||||
[
|
||||
dnl Check whether it is a Linux without scsi/scsi.h
|
||||
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([
|
||||
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])
|
||||
AC_MSG_RESULT([yes])]
|
||||
)
|
||||
],
|
||||
[;],
|
||||
[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,9 +4,9 @@
|
|||
cdrskin. By Thomas Schmitt <scdbackup@gmx.net>
|
||||
Integrated sub project of libburnia-project.org but also published via:
|
||||
http://scdbackup.sourceforge.net/cdrskin_eng.html
|
||||
http://scdbackup.sourceforge.net/cdrskin-1.5.2.tar.gz
|
||||
http://scdbackup.sourceforge.net/cdrskin-1.5.7.tar.gz
|
||||
|
||||
Copyright (C) 2006-2019 Thomas Schmitt, provided under GPL version 2 or later.
|
||||
Copyright (C) 2006-2023 Thomas Schmitt, provided under GPL version 2 or later.
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
@ -26,10 +26,10 @@ By using this software you agree to the disclaimer at the end of this text
|
|||
|
||||
Compilation, First Glimpse, Installation
|
||||
|
||||
Obtain cdrskin-1.5.2.tar.gz, take it to a directory of your choice and do:
|
||||
Obtain cdrskin-1.5.7.tar.gz, take it to a directory of your choice and do:
|
||||
|
||||
tar xzf cdrskin-1.5.2.tar.gz
|
||||
cd cdrskin-1.5.2
|
||||
tar xzf cdrskin-1.5.7.tar.gz
|
||||
cd cdrskin-1.5.7
|
||||
|
||||
Within that directory execute:
|
||||
|
||||
|
@ -563,7 +563,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.
|
||||
The worst mishaps which hit the author imposed the need to reboot the
|
||||
system because of drives gnawing endlessly on ill media. Permanent hardware
|
||||
damage did not occur in 3.5 years of development. But one never knows ...
|
||||
damage did not occur in 13 years of development. But one never knows ...
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
|
@ -591,7 +591,7 @@ contributions in a due way.
|
|||
Based on and sub project of:
|
||||
libburnia-project.org
|
||||
By Mario Danic <mario.danic@gmail.com> and Thomas Schmitt <scdbackup@gmx.net>
|
||||
Copyright (C) 2006-2019 Mario Danic, Thomas Schmitt
|
||||
Copyright (C) 2006-2023 Mario Danic, Thomas Schmitt
|
||||
|
||||
libburnia-project.org is inspired by and in other components still containing
|
||||
parts of
|
||||
|
|
|
@ -38,7 +38,7 @@ original="./libburn_svn_release.tgz"
|
|||
# My changes are in $changes , mainly in $changes/cdrskin
|
||||
changes="./libburn-release"
|
||||
|
||||
skin_release="1.5.2"
|
||||
skin_release="1.5.6"
|
||||
patch_level=""
|
||||
# patch_level=".pl00"
|
||||
skin_rev="$skin_release""$patch_level"
|
|
@ -38,7 +38,7 @@ original="./libburn_svn.tgz"
|
|||
# My changes are in $changes , mainly in $changes/cdrskin
|
||||
changes="./libburn-develop"
|
||||
|
||||
skin_release="1.5.3"
|
||||
skin_release="1.5.7"
|
||||
patch_level=""
|
||||
skin_rev="$skin_release""$patch_level"
|
||||
|
|
@ -28,7 +28,20 @@
|
|||
#ifndef Cdrfifo_standalonE
|
||||
/* for burn_os_alloc_buffer() */
|
||||
#include "../libburn/libburn.h"
|
||||
#define Libburn_has_open_trac_srC 1
|
||||
|
||||
/* 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
|
||||
|
||||
#include "cdrfifo.h"
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
.\" First parameter, NAME, should be all caps
|
||||
.\" Second parameter, SECTION, should be 1-8, maybe w/ subsection
|
||||
.\" other parameters are allowed: see man(7), man(1)
|
||||
.TH CDRSKIN 1 "Version 1.5.2, Oct 26, 2019"
|
||||
.TH CDRSKIN 1 "Version 1.5.7, Jun 07, 2023"
|
||||
.\" Please adjust this date whenever revising the manpage.
|
||||
.\"
|
||||
.\" Some roff macros, for reference:
|
||||
|
@ -573,9 +573,14 @@ Eject the disc after work is done.
|
|||
.TP
|
||||
.BI \-force
|
||||
Assume that the user knows better in situations when cdrskin or libburn are
|
||||
insecure about drive or media state. This includes the attempt to blank
|
||||
refusing because of concerns about drive or media state.
|
||||
.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
|
||||
write modes which libburn believes they are not supported by the drive.
|
||||
write modes of which libburn believes they are not supported by the drive.
|
||||
.br
|
||||
Another application is to enforce blanking or re-formatting of media
|
||||
which appear to be in the desired blank or format state already.
|
||||
|
@ -584,10 +589,22 @@ 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.
|
||||
.br
|
||||
It enables a burn run where cdrskin expects to exceed the available media
|
||||
capacity.
|
||||
capacity. This is known as "overburn" and might succeed on CD media with
|
||||
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
|
||||
.B Caution:
|
||||
Use this only when in urgent need.
|
||||
First consider to use a medium with more capacity rather than trying to
|
||||
overburn a CD.
|
||||
.TP
|
||||
.BI \-format
|
||||
Same as blank=format_overwrite_full -force but restricted to DVD+RW.
|
||||
|
@ -1087,11 +1104,11 @@ This directory has to already exist, but none of the track files may exist.
|
|||
This option will rather fail than overwrite an existing file.
|
||||
.br
|
||||
By default all tracks of the CD are extracted to files with names
|
||||
trackNN.wav, where NN is the track number from 01 to at most 99.
|
||||
NN.wav, where NN is the track number from 01 to at most 99.
|
||||
.TP
|
||||
.BI extract_basename= name
|
||||
Set a filename which shall be used by extract_audio_to= instead of the default
|
||||
name "track".
|
||||
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
|
||||
|
@ -1451,7 +1468,7 @@ full.
|
|||
.br
|
||||
If a write attempt is delayed, the program will wait for a number of
|
||||
microseconds which is given by parameter "min_usec" before inquiring the buffer
|
||||
again. iIf more retries occur, this waiting time between inquiries increases
|
||||
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
|
||||
|
@ -1471,46 +1488,6 @@ better buffer fills while still avoiding the problem:
|
|||
Alphabetical list of options which are only intended for very special
|
||||
situations and not for normal use:
|
||||
.TP
|
||||
.BI \--list_features
|
||||
List the SCSI/MMC features which were obtained from the drive when it was
|
||||
last acquired or re-assessed. Although this is better readable than the
|
||||
raw reply to SCSI command GET CONFIGURATION, the MMC specification text
|
||||
is still needed for interpreting it.
|
||||
.br
|
||||
The list consists of line groups of the form
|
||||
.br
|
||||
Code +/- : Name : Version,P/N
|
||||
.br
|
||||
Raw feature data bytes as hex numbers
|
||||
.br
|
||||
Parsed info as Name=Value pairs
|
||||
.br
|
||||
The headline is the only one which has no blank at its start.
|
||||
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
|
||||
.BI \--abort_handler
|
||||
Establish default signal handling not to leave a drive in busy state
|
||||
but rather to shut it down and to wait until it has ended the final operations.
|
||||
|
@ -1621,6 +1598,46 @@ Try to ignore any signals rather than to abort the program. This is not a
|
|||
very good idea. You might end up waiting a very long time for cdrskin
|
||||
to finish.
|
||||
.TP
|
||||
.BI \--list_features
|
||||
List the SCSI/MMC features which were obtained from the drive when it was
|
||||
last acquired or re-assessed. Although this is better readable than the
|
||||
raw reply to SCSI command GET CONFIGURATION, the MMC specification text
|
||||
is still needed for interpreting it.
|
||||
.br
|
||||
The list consists of line groups of the form
|
||||
.br
|
||||
Code +/- : Name : Version,P/N
|
||||
.br
|
||||
Raw feature data bytes as hex numbers
|
||||
.br
|
||||
Parsed info as Name=Value pairs
|
||||
.br
|
||||
The headline is the only one which has no blank at its start.
|
||||
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
|
||||
.BI \--no_abort_handler
|
||||
On signals exit even if the drive is in busy state. This is not a very good
|
||||
idea. You might end up with a stuck drive that refuses to hand out the media.
|
||||
|
@ -1640,16 +1657,27 @@ 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.)
|
||||
.TP
|
||||
.BI \--obs_pad
|
||||
Pad the data of last write operation of a DVD-R[W] DAO session or
|
||||
stdio: pseudo-drive up to the full size of an output chunk.
|
||||
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 DAO sessions abort with
|
||||
your kernel and/or DVD drive, if their size is not a multiple of 16 blocks.
|
||||
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
|
||||
Linux specific:
|
||||
Use and report literal Bus,Target,Lun addresses rather than real SCSI and
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
|
||||
/*
|
||||
cdrskin.c , Copyright 2006-2019 Thomas Schmitt <scdbackup@gmx.net>
|
||||
cdrskin.c , Copyright 2006-2023 Thomas Schmitt <scdbackup@gmx.net>
|
||||
Provided under GPL version 2 or later.
|
||||
|
||||
A cdrecord compatible command line interface for libburn.
|
||||
|
@ -87,7 +87,7 @@ or
|
|||
|
||||
/** The official program version */
|
||||
#ifndef Cdrskin_prog_versioN
|
||||
#define Cdrskin_prog_versioN "1.5.2"
|
||||
#define Cdrskin_prog_versioN "1.5.7"
|
||||
#endif
|
||||
|
||||
/** The official libburn interface revision to use.
|
||||
|
@ -100,7 +100,7 @@ or
|
|||
#define Cdrskin_libburn_minoR 5
|
||||
#endif
|
||||
#ifndef Cdrskin_libburn_micrO
|
||||
#define Cdrskin_libburn_micrO 2
|
||||
#define Cdrskin_libburn_micrO 6
|
||||
#endif
|
||||
|
||||
|
||||
|
@ -120,34 +120,34 @@ or
|
|||
#undef Cdrskin_libburn_versioN
|
||||
#endif
|
||||
|
||||
#ifdef Cdrskin_libburn_1_5_2
|
||||
#define Cdrskin_libburn_versioN "1.5.2"
|
||||
#ifdef Cdrskin_libburn_1_5_6
|
||||
#define Cdrskin_libburn_versioN "1.5.6"
|
||||
#endif
|
||||
|
||||
#ifdef Cdrskin_libburn_1_5_3
|
||||
#define Cdrskin_libburn_versioN "1.5.3"
|
||||
#ifdef Cdrskin_libburn_1_5_7
|
||||
#define Cdrskin_libburn_versioN "1.5.7"
|
||||
#endif
|
||||
|
||||
#ifndef Cdrskin_libburn_versioN
|
||||
#define Cdrskin_libburn_1_5_2
|
||||
#define Cdrskin_libburn_versioN "1.5.2"
|
||||
#define Cdrskin_libburn_1_5_6
|
||||
#define Cdrskin_libburn_versioN "1.5.6"
|
||||
#endif
|
||||
|
||||
#ifdef Cdrskin_libburn_1_5_2
|
||||
#ifdef Cdrskin_libburn_1_5_6
|
||||
#undef Cdrskin_libburn_majoR
|
||||
#undef Cdrskin_libburn_minoR
|
||||
#undef Cdrskin_libburn_micrO
|
||||
#define Cdrskin_libburn_majoR 1
|
||||
#define Cdrskin_libburn_minoR 5
|
||||
#define Cdrskin_libburn_micrO 2
|
||||
#define Cdrskin_libburn_micrO 6
|
||||
#endif
|
||||
#ifdef Cdrskin_libburn_1_5_3
|
||||
#ifdef Cdrskin_libburn_1_5_7
|
||||
#undef Cdrskin_libburn_majoR
|
||||
#undef Cdrskin_libburn_minoR
|
||||
#undef Cdrskin_libburn_micrO
|
||||
#define Cdrskin_libburn_majoR 1
|
||||
#define Cdrskin_libburn_minoR 5
|
||||
#define Cdrskin_libburn_micrO 3
|
||||
#define Cdrskin_libburn_micrO 7
|
||||
#endif
|
||||
|
||||
|
||||
|
@ -2914,6 +2914,8 @@ set_dev:;
|
|||
printf(
|
||||
" --no_rc as first argument: do not read startup files\n");
|
||||
printf(" --obs_pad pad DVD DAO to full 16 or 32 blocks\n");
|
||||
printf(
|
||||
" --bdr_obs_exempt possibly exempt BD-R from padding to full 64k\n");
|
||||
printf(" --old_pseudo_scsi_adr use and report literal Bus,Target,Lun\n");
|
||||
printf(" rather than real SCSI and pseudo ATA.\n");
|
||||
printf(
|
||||
|
@ -3152,7 +3154,8 @@ see_cdrskin_eng_html:;
|
|||
} else if(strncmp(argpt ,"textfile_to_v07t=", 17) == 0) {
|
||||
o->do_not_scan= 1;
|
||||
|
||||
} else if(strcmp(argv[i],"-V")==0 || strcmp(argpt, "-Verbose") == 0) {
|
||||
} else if(strcmp(argv[i],"-V")==0 || strcmp(argpt, "-Verbose") == 0 ||
|
||||
strcmp(argv[i],"-VV")==0 || strcmp(argpt, "-VVV") == 0) {
|
||||
burn_set_scsi_logging(2 | 4); /* log SCSI to stderr */
|
||||
|
||||
} else if(strcmp(argv[i],"-v")==0 || strcmp(argpt, "-verbose") == 0) {
|
||||
|
@ -3173,7 +3176,7 @@ set_severities:;
|
|||
int major, minor, micro;
|
||||
|
||||
printf(
|
||||
"Cdrecord 2.01a27 Emulation. Copyright (C) 2006-2018, see libburnia-project.org\n");
|
||||
"Cdrecord 2.01a27 Emulation. Copyright (C) 2006-2023, see libburnia-project.org\n");
|
||||
if(o->fallback_program[0]) {
|
||||
char *hargv[2];
|
||||
|
||||
|
@ -3340,7 +3343,8 @@ ex:;
|
|||
*/
|
||||
|
||||
|
||||
#define Cdrskin_tracksize_maX 1024.0*1024.0*1024.0*1024.0
|
||||
/* 4 TiB - 32 KiB : The libburn API works with int rather than uint32_t */
|
||||
#define Cdrskin_tracksize_maX 4398046478336.0
|
||||
|
||||
|
||||
/* Some constants obtained by hearsay and experiments */
|
||||
|
@ -3391,6 +3395,9 @@ struct CdrskiN {
|
|||
int stream_recording_is_set; /* see burn_write_opts_set_stream_recording() */
|
||||
int dvd_obs; /* DVD write chunk size: 0, 32k or 64k */
|
||||
int obs_pad; /* Whether to force obs end padding */
|
||||
int bdr_obs_exempt; /* Whether to possibly exempt BD-R from automatic
|
||||
obs_pad
|
||||
*/
|
||||
int stdio_sync; /* stdio fsync interval: -1, 0, >=32 */
|
||||
int single_track;
|
||||
int prodvd_cli_compatible;
|
||||
|
@ -3665,6 +3672,7 @@ int Cdrskin_new(struct CdrskiN **skin, struct CdrpreskiN *preskin, int flag)
|
|||
o->stream_recording_is_set= 0;
|
||||
o->dvd_obs= 0;
|
||||
o->obs_pad= 0;
|
||||
o->bdr_obs_exempt= 0;
|
||||
o->stdio_sync= 0;
|
||||
o->single_track= 0;
|
||||
o->prodvd_cli_compatible= 0;
|
||||
|
@ -4453,6 +4461,13 @@ int Cdrskin_driveno_to_btldev(struct CdrskiN *skin, int driveno,
|
|||
loc= adr;
|
||||
ret= burn_drive_get_drive_role(skin->drives[driveno].drive);
|
||||
if(ret!=1) {
|
||||
if(strlen(adr) > Cdrskin_adrleN - 7) {
|
||||
fprintf(stderr,
|
||||
"cdrskin : FAILURE : File path too long for \"stdio:\" prefix: %s\n",
|
||||
adr);
|
||||
sprintf(btldev, "stdio:"); /* Address of the null drive */
|
||||
return(-1);
|
||||
}
|
||||
sprintf(btldev,"stdio:%s",adr);
|
||||
{ret= 2; goto adr_translation;}
|
||||
}
|
||||
|
@ -7697,6 +7712,7 @@ burn_failed:;
|
|||
#endif
|
||||
burn_write_opts_set_dvd_obs(o, skin->dvd_obs);
|
||||
burn_write_opts_set_obs_pad(o, skin->obs_pad);
|
||||
burn_write_opts_set_bdr_obs_exempt(o, skin->bdr_obs_exempt);
|
||||
burn_write_opts_set_stdio_fsync(o, skin->stdio_sync);
|
||||
|
||||
if(skin->dummy_mode) {
|
||||
|
@ -9169,6 +9185,9 @@ msifile_equals:;
|
|||
} else if(strcmp(argv[i],"--obs_pad")==0) {
|
||||
skin->obs_pad= 1;
|
||||
|
||||
} else if(strcmp(argv[i],"--bdr_obs_exempt")==0) {
|
||||
skin->bdr_obs_exempt= 1;
|
||||
|
||||
} else if(strcmp(argv[i],"--old_pseudo_scsi_adr")==0) {
|
||||
/* is handled in Cdrpreskin_setup() */;
|
||||
|
||||
|
@ -9396,7 +9415,8 @@ track_too_large:;
|
|||
return(0);
|
||||
}
|
||||
|
||||
} else if(strcmp(argv[i],"-V")==0 || strcmp(argpt, "-Verbose")==0) {
|
||||
} else if(strcmp(argv[i],"-V") == 0 || strcmp(argpt, "-Verbose") == 0 ||
|
||||
strcmp(argv[i],"-VV") == 0 || strcmp(argpt, "-VVV") == 0) {
|
||||
/* is handled in Cdrpreskin_setup() */;
|
||||
} else if(strcmp(argv[i],"-v")==0 || strcmp(argpt,"-verbose")==0) {
|
||||
/* is handled in Cdrpreskin_setup() */;
|
||||
|
|
|
@ -67,7 +67,7 @@ with drives connected via SCSI, PATA (aka IDE, ATA), USB, or SATA.
|
|||
GPL software included:<BR>
|
||||
</H2>
|
||||
<DL>
|
||||
<DT>libburn-1.5.2</DT>
|
||||
<DT>libburn-1.5.6</DT>
|
||||
<DD>(founded by Derek Foreman and Ben Jansens,
|
||||
developed and maintained since August 2006 by
|
||||
Thomas Schmitt from team of libburnia-project.org)
|
||||
|
@ -202,15 +202,15 @@ Standalone ISO 9660 multi-session CD/DVD/BD tool
|
|||
<P>
|
||||
<DL>
|
||||
<DT>Download as source code (see README):</DT>
|
||||
<DD><A HREF="cdrskin-1.5.2.tar.gz">cdrskin-1.5.2.tar.gz</A>
|
||||
(1060 KB).
|
||||
<DD><A HREF="cdrskin-1.5.6.tar.gz">cdrskin-1.5.6.tar.gz</A>
|
||||
(1075 KB).
|
||||
</DD>
|
||||
<DD><A HREF="cdrskin-1.5.2.tar.gz.sig">cdrskin-1.5.2.tar.gz.sig</A></DD>
|
||||
<DD><A HREF="cdrskin-1.5.6.tar.gz.sig">cdrskin-1.5.6.tar.gz.sig</A></DD>
|
||||
<DD>
|
||||
(detached GPG signature for verification by
|
||||
<KBD>gpg --verify cdrskin-1.5.2.tar.gz.sig cdrskin-1.5.2.tar.gz</KBD>
|
||||
<KBD>gpg --verify cdrskin-1.5.6.tar.gz.sig cdrskin-1.5.6.tar.gz</KBD>
|
||||
<BR>
|
||||
after <KBD>gpg --keyserver keys.gnupg.net --recv-keys ABC0A854</KBD>).
|
||||
after <KBD>gpg --keyserver keyserver.ubuntu.com --recv-keys ABC0A854</KBD>).
|
||||
</DD>
|
||||
<DD>
|
||||
The cdrskin tarballs are source code identical with libburn releases
|
||||
|
@ -259,48 +259,35 @@ cdrskin_0.4.2.pl00-x86-suse9_0-static.tar.gz</A>, (310 KB), -static compiled,
|
|||
<HR>
|
||||
|
||||
<P>
|
||||
Enhancements towards previous stable version cdrskin-1.5.0:
|
||||
Enhancements towards previous stable version cdrskin-1.5.4:
|
||||
<UL>
|
||||
<LI>New cdrskin option --list_features</LI>
|
||||
<LI>New cdrskin option --bdr_obs_exempt</LI>
|
||||
<LI>Officially enabled overburning on CD media</LI>
|
||||
<!--
|
||||
<LI>none</LI>
|
||||
-->
|
||||
</UL>
|
||||
|
||||
Bug fixes towards cdrskin-1.5.0:
|
||||
Bug fixes towards cdrskin-1.5.4:
|
||||
<UL>
|
||||
<LI>
|
||||
No lock was obtained for setting up a fifo object
|
||||
</LI>
|
||||
<LI>
|
||||
TDK Corporation was not recognized as manufacturer of DVD-R "TTH02"
|
||||
</LI>
|
||||
<LI>
|
||||
Stream recording was applied regardless whether the drive offers it.
|
||||
This caused Xfburn failures with some MATSHITA laptop drives.
|
||||
</LI>
|
||||
<LI>Overburning with cdrskin option -force ended by a libburn error</LI>
|
||||
</UL>
|
||||
<!--
|
||||
<LI>none</LI>
|
||||
Bug fixes towards cdrskin-1.4.2 (without .pl01):
|
||||
<UL>
|
||||
</UL>
|
||||
-->
|
||||
|
||||
<HR>
|
||||
|
||||
<P>
|
||||
<DL>
|
||||
<DT><H3>Development snapshot, version 1.5.3 :</H3></DT>
|
||||
<DD>Enhancements towards current stable version 1.5.2:
|
||||
<DT><H3>Development snapshot, version 1.5.7 :</H3></DT>
|
||||
<DD>Enhancements towards current stable version 1.5.6:
|
||||
<UL>
|
||||
<LI>none yet</LI>
|
||||
<!--
|
||||
<LI>none yet</LI>
|
||||
-->
|
||||
</UL>
|
||||
</DD>
|
||||
|
||||
<DD>Bug fixes towards cdrskin-1.5.2:
|
||||
Bug fixes towards cdrskin-1.5.6:
|
||||
<UL>
|
||||
<LI>none yet</LI>
|
||||
<!--
|
||||
|
@ -310,14 +297,15 @@ Bug fixes towards cdrskin-1.4.2 (without .pl01):
|
|||
</DD>
|
||||
|
||||
<DD> </DD>
|
||||
<DD><A HREF="README_cdrskin_devel">README 1.5.3</A>
|
||||
<DD><A HREF="cdrskin__help_devel">cdrskin-1.5.3 --help</A></DD>
|
||||
<DD><A HREF="cdrskin_help_devel">cdrskin-1.5.3 -help</A></DD>
|
||||
<DD><A HREF="man_1_cdrskin_devel.html">man cdrskin (as of 1.5.3)</A></DD>
|
||||
<DD><A HREF="README_cdrskin_devel">README 1.5.7</A>
|
||||
<DD><A HREF="cdrskin__help_devel">cdrskin-1.5.7 --help</A></DD>
|
||||
<DD><A HREF="cdrskin_help_devel">cdrskin-1.5.7 -help</A></DD>
|
||||
<DD><A HREF="man_1_cdrskin_devel.html">man cdrskin (as of 1.5.7)</A></DD>
|
||||
<DD> </DD>
|
||||
<DT>Maintainers of cdrskin unstable packages please use SVN of
|
||||
<DT>Maintainers of cdrskin unstable packages please use git of
|
||||
<A HREF="http://libburnia-project.org"> libburnia-project.org</A></DT>
|
||||
<DD>Download: <KBD><B>svn co http://svn.libburnia-project.org/libburn/trunk libburn</B>
|
||||
<DD>Download: <KBD>
|
||||
<B>git clone https://dev.lovelyhq.com/libburnia/libburn.git</B>
|
||||
</KBD></DD>
|
||||
<DD>Build: <KBD><B>cd libburn ; ./bootstrap ; ./configure --prefix /usr ; make ; cdrskin/compile_cdrskin.sh</B>
|
||||
</KBD></DD>
|
||||
|
@ -333,8 +321,8 @@ admins with full system sovereignty.</DT>
|
|||
<A HREF="README_cdrskin_devel">upcoming README</A> ):
|
||||
</DD>
|
||||
<DD>
|
||||
<A HREF="cdrskin-1.5.3.tar.gz">cdrskin-1.5.3.tar.gz</A>
|
||||
(1060 KB).
|
||||
<A HREF="cdrskin-1.5.7.tar.gz">cdrskin-1.5.7.tar.gz</A>
|
||||
(1075 KB).
|
||||
</DD>
|
||||
|
||||
<!-- This is not offered any more since spring 2008
|
||||
|
@ -509,7 +497,7 @@ opportunity is the goal of a cdrecord compatibility wrapper.
|
|||
<BR>
|
||||
<BR>
|
||||
It is very important to me that this project is not perceived as hostile
|
||||
towards Joerg Schilling and his ongoing work.
|
||||
towards Joerg Schilling and his work.
|
||||
I owe him much. For cdrecord, for mkisofs, for star. Chapeau.
|
||||
<BR>
|
||||
</P>
|
||||
|
|
|
@ -1 +1 @@
|
|||
#define Cdrskin_timestamP "2019.10.26.143001"
|
||||
#define Cdrskin_timestamP "2024.04.27.162735"
|
||||
|
|
|
@ -13931,7 +13931,7 @@ ChangeLog
|
|||
cdrskin/changelog.txt
|
||||
Updated change log
|
||||
|
||||
26 Oct 2019 []
|
||||
26 Oct 2019 [3a94030]
|
||||
libburn/mmc.h
|
||||
cdrskin/changelog.txt
|
||||
Committed forgotten header file
|
||||
|
@ -13945,13 +13945,329 @@ Committed forgotten header file
|
|||
* New cdrskin option --list_features
|
||||
|
||||
|
||||
2019.10.27.142135 [0a37e8c]
|
||||
Makefile.am
|
||||
configure.ac
|
||||
libburn/libburn.h
|
||||
cdrskin/cdrskin.c
|
||||
cdrskin/cdrskin.1
|
||||
cdrskin/README
|
||||
cdrskin/cdrskin_timestamp.h
|
||||
Made number transition to 1.5.3
|
||||
|
||||
27 Oct 2019 [95ad059]
|
||||
ChangeLog
|
||||
cdrskin/changelog.txt
|
||||
Updated change log
|
||||
|
||||
------------------------------------ cycle - cdrskin-1.5.3 - 2019.10.27.142135
|
||||
|
||||
|
||||
27 Oct 2019 [1c235e8]
|
||||
cdrskin/cdrskin.1
|
||||
Corrected alphabetical sort rank of --list_features in man cdrskin
|
||||
|
||||
2019.10.28.155736 [ba9b69b]
|
||||
libburn/libdax_audioxtr.c
|
||||
libburn/async.c
|
||||
libburn/libdax_msgs.h
|
||||
libburn/file.c
|
||||
libburn/options.c
|
||||
libburn/spc.c
|
||||
libburn/structure.h
|
||||
libburn/sector.c
|
||||
libburn/libdax_audioxtr.h
|
||||
libburn/transport.h
|
||||
libburn/sg-dummy.c
|
||||
libburn/sg-linux.c
|
||||
libburn/sg-netbsd.c
|
||||
libburn/cdtext.c
|
||||
libburn/drive.c
|
||||
libburn/init.c
|
||||
libburn/write.c
|
||||
libburn/read.c
|
||||
libburn/libburn.h
|
||||
libburn/options.h
|
||||
libburn/mmc.c
|
||||
libburn/ddlpa.c
|
||||
libburn/sg-solaris.c
|
||||
libburn/ecma130ab.c
|
||||
libburn/sg-libcdio.c
|
||||
libburn/sg-freebsd-port.c
|
||||
libburn/init.h
|
||||
Fixed spelling errors found by fossies.org with codespell
|
||||
|
||||
2019.11.25.091234 [91f7d4d] [release-1.5.2.pl01 30c9f6d]
|
||||
configure.ac
|
||||
libburn/sg-linux.c
|
||||
cdrskin/cdrfifo.c
|
||||
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
|
||||
|
||||
[]
|
||||
ChangeLog
|
||||
cdrskin/cdrskin_eng.html
|
||||
cdrskin/changelog.txt
|
||||
Updated change log
|
||||
|
||||
------------------------------------ cycle - cdrskin-1.5.1 -
|
||||
25 Nov 2019 [branch-1.5.2.pl01 4c0ebf1]
|
||||
README
|
||||
cdrskin/README
|
||||
ChangeLog
|
||||
cdrskin/changelog.txt
|
||||
cdrskin/cdrskin_eng.html
|
||||
Mentioned bug fix and pl01
|
||||
|
||||
25 Nov 2019 [d4593f4]
|
||||
README
|
||||
Updated README about 1.5.2.pl01
|
||||
|
||||
---------------------- bug fix release - cdrskin-1.5.2.pl01 - 2019.11.25.094931
|
||||
------------------------------------ cycle - cdrskin-1.5.3 - 2019.11.25.194241
|
||||
* 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.
|
||||
|
||||
|
||||
26 Nov 2019 [b57c05c]
|
||||
configure.ac
|
||||
Incremented .so numbering to libburn.so.4.106.0
|
||||
|
||||
2020.04.15.185125 [7991750]
|
||||
libburn/sg-linux.c
|
||||
Bug fix: Early SCSI commands from sg-linux.c were not logged
|
||||
|
||||
11 Jul 2020 [e09acf3]
|
||||
cdrskin/cdrskin.1
|
||||
Corrected a typo in man cdrskin found by lintian
|
||||
|
||||
2020.08.22.132046 [8d934ee]
|
||||
libburn/transport.h
|
||||
libburn/drive.c
|
||||
libburn/write.c
|
||||
libburn/sg-linux.c
|
||||
Testing use of experimental ioctl CDROM_REVALIDATE after media state changes
|
||||
|
||||
2020.08.22.132046 [8d934ee]
|
||||
libburn/transport.h
|
||||
libburn/drive.c
|
||||
libburn/write.c
|
||||
libburn/sg-linux.c
|
||||
Testing use of experimental ioctl CDROM_REVALIDATE after media state changes
|
||||
|
||||
2020.08.24.132739 [0e1f5dc]
|
||||
libburn/libburn.h
|
||||
libburn/libburn.ver
|
||||
libburn/transport.h
|
||||
libburn/drive.c
|
||||
libburn/mmc.c
|
||||
New API call burn_drive_set_speed_exact()
|
||||
|
||||
2020.08.26.140343 [8b9a8cf]
|
||||
libburn/libburn.h
|
||||
libburn/libburn.ver
|
||||
libburn/write.c
|
||||
New API call burn_nominal_slowdown()
|
||||
|
||||
2020.09.20.084444 [ab6b103]
|
||||
libburn/sg-linux.c
|
||||
Changed experimental ioctl from CDROM_REVALIDATE to CDROM_SIMUL_CHANGE
|
||||
|
||||
2020.09.20.204320 [9bc9900]
|
||||
libburn/sg-linux.c
|
||||
For now using CDROM_SIMUL_CHANGE only if -DLibburn_use_linux_ioctl_simul_changE
|
||||
|
||||
2020.09.30.185335 [3468a2a]
|
||||
libburn/spc.c
|
||||
Tolerating all sense replies of form 6,28,*
|
||||
|
||||
2021.01.30.103001 [2a58d5a]
|
||||
Makefile.am
|
||||
configure.ac
|
||||
README
|
||||
libburn/libburn.h
|
||||
cdrskin/cdrskin.c
|
||||
cdrskin/cdrskin.1
|
||||
cdrskin/README
|
||||
cdrskin/compile_cdrskin.sh
|
||||
cdrskin/cdrskin_timestamp.h
|
||||
cdrskin/cdrskin_eng.html
|
||||
Made number transition to 1.5.4
|
||||
|
||||
30 Jan 2021 [d95d5a2]
|
||||
- cdrskin/add_ts_changes_to_libburn_1_5_2
|
||||
- cdrskin/add_ts_changes_to_libburn_1_5_3
|
||||
+ cdrskin/add_ts_changes_to_libburn_1_5_4
|
||||
+ cdrskin/add_ts_changes_to_libburn_1_5_5
|
||||
Updated cdrskin tarball generator
|
||||
|
||||
30 Jan 2021 [d146886]
|
||||
configure.ac
|
||||
Corrected SONAME parameters to produce libburn.so.4.107.0
|
||||
|
||||
30 Jan 2021 [d3bd97c]
|
||||
ChangeLog
|
||||
cdrskin/cdrskin_eng.html
|
||||
cdrskin/changelog.txt
|
||||
Updated change log
|
||||
|
||||
----------------------------------- release - cdrskin-1.5.4 - 2021.01.30.103001
|
||||
* 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()
|
||||
|
||||
2021.01.30.153517 [f1d5c67]
|
||||
Makefile.am
|
||||
configure.ac
|
||||
libburn/libburn.h
|
||||
cdrskin/cdrskin.c
|
||||
cdrskin/cdrskin.1
|
||||
cdrskin/README
|
||||
cdrskin/cdrskin_timestamp.h
|
||||
Made number transition to 1.5.5
|
||||
|
||||
2021.02.28.121708 [2a977cf]
|
||||
libburn/libdax_msgs.h
|
||||
libburn/structure.c
|
||||
libburn/write.c
|
||||
libburn/sector.c
|
||||
Improved error message if a track is larger than 4 TiB - 32 KiB
|
||||
|
||||
2021.02.28.121943 [31e8f5c]
|
||||
libburn/transport.h
|
||||
libburn/drive.h
|
||||
libburn/drive.c
|
||||
Unified size of large or unlimited pseudo drives to 4 TiB - 32 KiB
|
||||
|
||||
2021.03.12.082731 [892df64]
|
||||
acinclude.m4
|
||||
Made optional the use of libcam and thus SCSI passthrough on GNU/FreeBSD systems
|
||||
|
||||
02 Sep 2021 [8d270b1]
|
||||
configure.ac
|
||||
Removed unneeded configure.ac macro AC_C_BIGENDIAN
|
||||
|
||||
02 Sep 2021 [c76145f]
|
||||
cdrskin/cdrskin.1
|
||||
Corrected man page about the default of extract_basename=
|
||||
|
||||
02 Sep 2021 [0a1bbb1]
|
||||
Makefile.am
|
||||
Added doc/waveformat.txt to libburn tarball
|
||||
|
||||
2021.09.02.181259 [27e1568]
|
||||
libburn/mmc.c
|
||||
Let mmc_read_cd() for CD-DA set command.dxfer_len
|
||||
|
||||
2021.09.12.084139 [31591b8]
|
||||
libburn/libburn.h
|
||||
libburn/options.h
|
||||
libburn/options.c
|
||||
libburn/write.c
|
||||
libburn/libburn.ver
|
||||
New API call burn_write_opts_set_bdr_obs_exempt()
|
||||
|
||||
2021.09.12.084556 [da44c70]
|
||||
cdrskin/cdrskin.c
|
||||
cdrskin/cdrskin.1
|
||||
New cdrskin option --bdr_obs_exempt
|
||||
|
||||
2021.11.24.114417 [7765fbd]
|
||||
libburn/libburn.h
|
||||
libburn/mmc.c
|
||||
Enabled overburning with burn_write_opts_set_force(,1)
|
||||
|
||||
24 Nov 2021 [d4d6321]
|
||||
cdrskin/cdrskin.1
|
||||
Improved man page of cdrskin about -force after enabling overburning in libburn
|
||||
|
||||
25 Nov 2021 [879cb99]
|
||||
ChangeLog
|
||||
cdrskin/cdrskin_eng.html
|
||||
cdrskin/changelog.txt
|
||||
Updated change log
|
||||
|
||||
------------------------------------ cycle - cdrskin-1.5.5 - 2021.11.25.094022
|
||||
* New API call burn_write_opts_set_bdr_obs_exempt()
|
||||
* New cdrskin option --bdr_obs_exempt
|
||||
* Enabled overburning with burn_write_opts_set_force(,1)
|
||||
* Bug fix: Overburning with cdrskin option -force ended by a libburn error
|
||||
|
||||
|
||||
2022.04.05.135930 [629a4fa]
|
||||
cdrskin/cdrskin.c
|
||||
Let cdrskin take options -VV and -VVV as -V
|
||||
|
||||
2022.04.05.140409 [1954514]
|
||||
cdrskin/cdrskin.c
|
||||
Updated copyright dates of cdrskin
|
||||
|
||||
2022.12.10.093508 [a904ae9]
|
||||
cdrskin/cdrskin.c
|
||||
Enlarged maximum allowed tsize= value to 4 TiB - 2 KiB (just in case)
|
||||
|
||||
2023.06.07.143001 [1172ef7]
|
||||
Makefile.am
|
||||
configure.ac
|
||||
README
|
||||
libburn/libburn.h
|
||||
cdrskin/cdrskin.c
|
||||
cdrskin/cdrskin.1
|
||||
cdrskin/README
|
||||
cdrskin/compile_cdrskin.sh
|
||||
cdrskin/cdrskin_timestamp.h
|
||||
cdrskin/cdrskin_eng.html
|
||||
Made number transition to 1.5.6
|
||||
|
||||
07 Jun 2023 [9acb8ad]
|
||||
- cdrskin/add_ts_changes_to_libburn_1_5_4
|
||||
- cdrskin/add_ts_changes_to_libburn_1_5_5
|
||||
+ cdrskin/add_ts_changes_to_libburn_1_5_6
|
||||
+ cdrskin/add_ts_changes_to_libburn_1_5_7
|
||||
Updated cdrskin tarball generator
|
||||
|
||||
07 Jun 2023 [f795db5]
|
||||
cdrskin/cdrskin_eng.html
|
||||
Last minute correction in cdrskin web page
|
||||
|
||||
07 Jun 2023 [4628231]
|
||||
ChangeLog
|
||||
cdrskin/changelog.txt
|
||||
Updated change log
|
||||
|
||||
----------------------------------- release - cdrskin-1.5.6 - 2023.06.07.143001
|
||||
* New API call burn_write_opts_set_bdr_obs_exempt()
|
||||
* New cdrskin option --bdr_obs_exempt
|
||||
* Enabled overburning with burn_write_opts_set_force(,1)
|
||||
* Bug fix: Overburning with cdrskin option -force ended by a libburn error
|
||||
|
||||
|
||||
2023.06.07.183206 []
|
||||
Makefile.am
|
||||
configure.ac
|
||||
libburn/libburn.h
|
||||
cdrskin/cdrskin.c
|
||||
cdrskin/cdrskin.1
|
||||
cdrskin/README
|
||||
cdrskin/cdrskin_timestamp.h
|
||||
Made number transition to 1.5.7
|
||||
|
||||
07 Jun 2023 []
|
||||
ChangeLog
|
||||
cdrskin/changelog.txt
|
||||
Updated change log
|
||||
|
||||
|
||||
[]
|
||||
libburn/cleanup.c
|
||||
>>> SIGCONT in non_signal_list : local but not in git
|
||||
|
||||
|
||||
|
||||
------------------------------------ cycle - cdrskin-1.5.7 -
|
||||
|
||||
|
||||
------------------------------------ cycle - cdrskin-1.5.7 -
|
||||
|
||||
(((
|
||||
[]
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
#!/bin/sh
|
||||
|
||||
# compile_cdrskin.sh
|
||||
# Copyright 2005 - 2019 Thomas Schmitt, scdbackup@gmx.net, GPL v2 or later
|
||||
# Copyright 2005 - 2023 Thomas Schmitt, scdbackup@gmx.net, GPL v2 or later
|
||||
# to be executed within ./libburn-* or./cdrskin-*
|
||||
|
||||
debug_opts="-O2"
|
||||
def_opts=
|
||||
largefile_opts="-D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE=1"
|
||||
fifo_opts=""
|
||||
libvers="-DCdrskin_libburn_1_5_2"
|
||||
libvers="-DCdrskin_libburn_1_5_6"
|
||||
|
||||
# To be used if Makefile.am uses libburn_libburn_la_CFLAGS
|
||||
# burn="libburn/libburn_libburn_la-"
|
||||
|
@ -41,15 +41,15 @@ do
|
|||
elif test "$i" = "-compile_dewav"
|
||||
then
|
||||
compile_dewav=1
|
||||
elif test "$i" = "-libburn_1_5_2"
|
||||
elif test "$i" = "-libburn_1_5_6"
|
||||
then
|
||||
libvers="-DCdrskin_libburn_1_5_2"
|
||||
libvers="-DCdrskin_libburn_1_5_6"
|
||||
libdax_audioxtr_o="$burn"libdax_audioxtr.o
|
||||
libdax_msgs_o="$burn"libdax_msgs.o
|
||||
cleanup_src_or_obj="$burn"cleanup.o
|
||||
elif test "$i" = "-libburn_svn"
|
||||
then
|
||||
libvers="-DCdrskin_libburn_1_5_3"
|
||||
libvers="-DCdrskin_libburn_1_5_7"
|
||||
libdax_audioxtr_o="$burn"libdax_audioxtr.o
|
||||
libdax_msgs_o="$burn"libdax_msgs.o
|
||||
cleanup_src_or_obj="$burn"cleanup.o
|
||||
|
@ -99,8 +99,8 @@ do
|
|||
echo "Options:"
|
||||
echo " -compile_cdrfifo compile program cdrskin/cdrfifo."
|
||||
echo " -compile_dewav compile program test/dewav without libburn."
|
||||
echo " -libburn_1_5_2 set macro to match libburn-1.5.2"
|
||||
echo " -libburn_svn set macro to match current libburn-SVN."
|
||||
echo " -libburn_1_5_6 set macro to match libburn-1.5.6"
|
||||
echo " -libburn_svn set macro to match current libburn git."
|
||||
echo " -dvd_obs_64k 64 KB default size for DVD/BD writing."
|
||||
echo " -use_libcdio link with -lcdio because libburn uses it."
|
||||
echo " -do_not_compile_cdrskin omit compilation of cdrskin/cdrskin."
|
||||
|
|
28
configure.ac
28
configure.ac
|
@ -1,4 +1,4 @@
|
|||
AC_INIT([libburn], [1.5.2], [http://libburnia-project.org])
|
||||
AC_INIT([libburn], [1.5.7], [http://libburnia-project.org])
|
||||
AC_PREREQ([2.50])
|
||||
dnl AC_CONFIG_HEADER([config.h])
|
||||
|
||||
|
@ -112,6 +112,8 @@ 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 So LT_CURRENT, LT_REVISION and LT_AGE get set directly here.
|
||||
dnl SONAME of the emerging library is LT_CURRENT - LT_AGE.
|
||||
|
@ -137,7 +139,7 @@ dnl
|
|||
dnl As said: Only copies. Original in libburn/libburn.h : burn_header_version_*
|
||||
BURN_MAJOR_VERSION=1
|
||||
BURN_MINOR_VERSION=5
|
||||
BURN_MICRO_VERSION=2
|
||||
BURN_MICRO_VERSION=7
|
||||
BURN_VERSION=$BURN_MAJOR_VERSION.$BURN_MINOR_VERSION.$BURN_MICRO_VERSION
|
||||
|
||||
AC_SUBST(BURN_MAJOR_VERSION)
|
||||
|
@ -148,14 +150,14 @@ AC_SUBST(BURN_VERSION)
|
|||
dnl Libtool versioning
|
||||
LT_RELEASE=$BURN_MAJOR_VERSION.$BURN_MINOR_VERSION.$BURN_MICRO_VERSION
|
||||
dnl
|
||||
dnl This is the release version libburn-1.5.2
|
||||
dnl ### This is the development version after above release version
|
||||
dnl LT_CURRENT++, LT_AGE++ has not yet happened.
|
||||
dnl ### LT_CURRENT++, LT_AGE++ has happened meanwhile.
|
||||
dnl ### This is the release version libburn-1.5.6
|
||||
dnl This is the development version after above release version
|
||||
dnl ### LT_CURRENT++, LT_AGE++ has not yet happened.
|
||||
dnl LT_CURRENT++, LT_AGE++ has happened meanwhile.
|
||||
dnl
|
||||
dnl SONAME = 109 - 105 = 4 . Linux library name = libburn.so.4.105.0
|
||||
LT_CURRENT=109
|
||||
LT_AGE=105
|
||||
dnl SONAME = 114 - 110 = 4 . Linux library name = libburn.so.4.110.0
|
||||
LT_CURRENT=114
|
||||
LT_AGE=110
|
||||
LT_REVISION=0
|
||||
LT_CURRENT_MINUS_AGE=`expr $LT_CURRENT - $LT_AGE`
|
||||
|
||||
|
@ -180,7 +182,6 @@ dnl AM_MAINTAINER_MODE
|
|||
AM_PROG_CC_C_O
|
||||
AC_C_CONST
|
||||
AC_C_INLINE
|
||||
AC_C_BIGENDIAN
|
||||
|
||||
dnl Large file support
|
||||
AC_SYS_LARGEFILE
|
||||
|
@ -218,11 +219,12 @@ CFLAGS="$STATVFS_DEF $CFLAGS"
|
|||
|
||||
dnl ts A91122
|
||||
AC_ARG_ENABLE(track-src-odirect,
|
||||
[ --enable-track-src-odirect Enable use of O_DIRECT with track input, default=no],
|
||||
[ --enable-track-src-odirect Banned for now: (Enable use of O_DIRECT with track input, default=no)],
|
||||
, enable_track_src_odirect=no)
|
||||
if test x$enable_track_src_odirect = xyes; then
|
||||
LIBBURN_O_DIRECT_DEF="-DLibburn_read_o_direcT"
|
||||
echo "enabled use of O_DIRECT with track input"
|
||||
# LIBBURN_O_DIRECT_DEF="-DLibburn_read_o_direcT"
|
||||
# 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
|
||||
LIBBURN_O_DIRECT_DEF=
|
||||
echo "disabled use of O_DIRECT with track input"
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||
|
||||
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
|
||||
Copyright (c) 2006 - 2017 Thomas Schmitt <scdbackup@gmx.net>
|
||||
Copyright (c) 2006 - 2024 Thomas Schmitt <scdbackup@gmx.net>
|
||||
Provided under GPL version 2 or later.
|
||||
*/
|
||||
|
||||
|
@ -279,7 +279,7 @@ static void *scan_worker_func(struct w_list *w)
|
|||
}
|
||||
|
||||
static void reset_progress(struct burn_drive *d, int sessions, int tracks,
|
||||
int indices, int sectors, int flag)
|
||||
int indices, off_t sectors, int flag)
|
||||
{
|
||||
/* reset the progress indicator */
|
||||
d->progress.session = 0;
|
||||
|
@ -412,14 +412,14 @@ void burn_disc_erase(struct burn_drive *drive, int fast)
|
|||
return;
|
||||
}
|
||||
|
||||
reset_progress(drive, 1, 1, 1, 0x10000, 0);
|
||||
reset_progress(drive, 1, 1, 1, (off_t) 0x10000, 0);
|
||||
|
||||
/* A70103 : will be set to 0 by burn_disc_erase_sync() */
|
||||
drive->cancel = 1;
|
||||
|
||||
/* ts A70103 moved up from burn_disc_erase_sync() */
|
||||
/* ts A60825 : allow on parole to blank appendable CDs */
|
||||
/* ts A70131 : allow blanking of overwriteable DVD-RW (profile 0x13) */
|
||||
/* ts A70131 : allow blanking of overwritable DVD-RW (profile 0x13) */
|
||||
/* ts A70216 : allow blanking of CD-RW or DVD-RW in any regular state
|
||||
and of any kind of full media */
|
||||
/* ts A70909 : the willingness to burn any BURN_DISC_FULL media is
|
||||
|
@ -494,7 +494,7 @@ void burn_disc_format(struct burn_drive *drive, off_t size, int flag)
|
|||
int ok = 0, ret;
|
||||
char msg[40];
|
||||
|
||||
reset_progress(drive, 1, 1, 1, 0x10000, 0);
|
||||
reset_progress(drive, 1, 1, 1, (off_t) 0x10000, 0);
|
||||
|
||||
if ((SCAN_GOING()) || find_worker(drive) != NULL) {
|
||||
libdax_msgs_submit(libdax_messenger, drive->global_index,
|
||||
|
@ -652,7 +652,7 @@ void burn_disc_write(struct burn_write_opts *opts, struct burn_disc *disc)
|
|||
}
|
||||
|
||||
reset_progress(d, disc->sessions, disc->session[0]->tracks,
|
||||
disc->session[0]->track[0]->indices, 0, 0);
|
||||
disc->session[0]->track[0]->indices, (off_t) 0, 0);
|
||||
|
||||
/* For the next lines any return indicates failure */
|
||||
d->cancel = 1;
|
||||
|
|
|
@ -77,7 +77,7 @@ int burn_create_new_pack(int pack_type, int track_no, int double_byte,
|
|||
|
||||
|
||||
/* Plain implementation of polynomial division on a Galois field, where
|
||||
addition and subtraction both are binary exor. Euclidian algorithm.
|
||||
addition and subtraction both are binary exor. Euclidean algorithm.
|
||||
Divisor is x^16 + x^12 + x^5 + 1 = 0x11021.
|
||||
*/
|
||||
static int crc_11021(unsigned char *data, int count, int flag)
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
-DDDLPA_C_STANDALONE -o ddlpa ddlpa.c
|
||||
|
||||
The system macros enable 64-bit off_t and open(2) flag O_LARGEFILE, which
|
||||
are not absolutely necessary but explicitely take into respect that
|
||||
are not absolutely necessary but explicitly take into respect that
|
||||
our devices can offer more than 2 GB of addressable data.
|
||||
|
||||
Run test program:
|
||||
|
|
196
libburn/drive.c
196
libburn/drive.c
|
@ -1,7 +1,7 @@
|
|||
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||
|
||||
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
|
||||
Copyright (c) 2006 - 2017 Thomas Schmitt <scdbackup@gmx.net>
|
||||
Copyright (c) 2006 - 2024 Thomas Schmitt <scdbackup@gmx.net>
|
||||
Provided under GPL version 2 or later.
|
||||
*/
|
||||
|
||||
|
@ -191,7 +191,7 @@ int burn_drive_is_released(struct burn_drive *d)
|
|||
/* ts A60906 */
|
||||
/** Inquires drive status in respect to degree of app usage.
|
||||
@param return -2 = drive is forgotten
|
||||
-1 = drive is closed (i.e. released explicitely)
|
||||
-1 = drive is closed (i.e. released explicitly)
|
||||
0 = drive is open, not grabbed (after scan, before 1st grab)
|
||||
1 = drive is grabbed but BURN_DRIVE_IDLE
|
||||
2 = drive is grabbed, synchronous read/write interrupted
|
||||
|
@ -287,7 +287,7 @@ int burn_drive_inquire_media(struct burn_drive *d)
|
|||
|
||||
/* ts A61020 : d->status was set to BURN_DISC_BLANK as pure guess */
|
||||
|
||||
/* ts A71128 : run read_disc_info() for any recognizeable profile */
|
||||
/* ts A71128 : run read_disc_info() for any recognizable profile */
|
||||
if (d->current_profile > 0 || d->current_is_guessed_profile ||
|
||||
(d->mdata->p2a_valid > 0 &&
|
||||
(d->mdata->cdr_write || d->mdata->cdrw_write ||
|
||||
|
@ -375,8 +375,8 @@ static int burn_drive__is_rdwr(char *fname, int *stat_ret,
|
|||
else if (is_rdwr)
|
||||
ret = burn_os_stdio_capacity(fname, 0, &read_size);
|
||||
if (ret <= 0 ||
|
||||
read_size / (off_t) 2048 >= (off_t) 0x7ffffff0)
|
||||
read_size = (off_t) 0x7ffffff0 * (off_t) 2048;
|
||||
read_size >= BURN_DRIVE_MAX_BYTES)
|
||||
read_size = BURN_DRIVE_MAX_BYTES;
|
||||
}
|
||||
|
||||
if (is_rdwr && fd >= 0) {
|
||||
|
@ -451,10 +451,10 @@ int burn_drive_grab_stdio(struct burn_drive *d, int flag)
|
|||
if (stat_ret != -1 && S_ISREG(stbuf.st_mode) &&
|
||||
stbuf.st_size > 0) {
|
||||
d->status = BURN_DISC_APPENDABLE;
|
||||
if (stbuf.st_size / (off_t) 2048
|
||||
>= 0x7ffffff0) {
|
||||
if (stbuf.st_size >= BURN_DRIVE_MAX_BYTES) {
|
||||
d->status = BURN_DISC_FULL;
|
||||
d->role_5_nwa = 0x7ffffff0;
|
||||
d->role_5_nwa = (off_t) BURN_DRIVE_MAX_BYTES /
|
||||
(off_t) 2048;
|
||||
} else
|
||||
d->role_5_nwa = stbuf.st_size / 2048 +
|
||||
!!(stbuf.st_size % 2048);
|
||||
|
@ -556,6 +556,9 @@ struct burn_drive *burn_drive_register(struct burn_drive *d)
|
|||
d->thread_pid = 0;
|
||||
d->thread_pid_valid = 0;
|
||||
memset(&(d->thread_tid), 0, sizeof(d->thread_tid));
|
||||
d->medium_state_changed = 0;
|
||||
d->set_streaming_exact_bit = 0;
|
||||
d->set_streaming_err = 0;
|
||||
d->toc_entries = 0;
|
||||
d->toc_entry = NULL;
|
||||
d->disc = NULL;
|
||||
|
@ -883,6 +886,7 @@ void burn_disc_erase_sync(struct burn_drive *d, int fast)
|
|||
d->progress.sector = 0;
|
||||
#endif /* Libburn_reset_progress_asynC */
|
||||
|
||||
d->medium_state_changed = 1;
|
||||
d->erase(d, fast);
|
||||
d->busy = BURN_DRIVE_ERASING;
|
||||
|
||||
|
@ -972,6 +976,7 @@ void burn_disc_format_sync(struct burn_drive *d, off_t size, int flag)
|
|||
stages = 1 + ((flag & 1) && size > 1024 * 1024);
|
||||
d->cancel = 0;
|
||||
d->busy = BURN_DRIVE_FORMATTING;
|
||||
d->medium_state_changed = 1;
|
||||
|
||||
ret = d->format_unit(d, size, flag & 0xfff6); /* forward bits */
|
||||
if (ret <= 0)
|
||||
|
@ -1131,12 +1136,13 @@ int burn_disc_erasable(struct burn_drive *d)
|
|||
{
|
||||
return d->erasable;
|
||||
}
|
||||
enum burn_drive_status burn_drive_get_status(struct burn_drive *d,
|
||||
struct burn_progress *p)
|
||||
|
||||
|
||||
void burn_drive_get_status_sig_handling(void)
|
||||
{
|
||||
/* --- Part of asynchronous signal handling --- */
|
||||
/* This frequently used call may be used to react on messages from
|
||||
the libburn built-in signal handler.
|
||||
/* The frequently used call burn_drive_get_status*() may be used
|
||||
to react on messages from the libburn built-in signal handler.
|
||||
*/
|
||||
|
||||
/* ts B00225 :
|
||||
|
@ -1160,11 +1166,61 @@ enum burn_drive_status burn_drive_get_status(struct burn_drive *d,
|
|||
}
|
||||
|
||||
/* --- End of asynchronous signal handling --- */
|
||||
}
|
||||
|
||||
|
||||
enum burn_drive_status burn_drive_get_status(struct burn_drive *d,
|
||||
struct burn_progress *p)
|
||||
{
|
||||
burn_drive_get_status_sig_handling();
|
||||
|
||||
if (p != NULL) {
|
||||
memcpy(p, &(d->progress), sizeof(struct burn_progress));
|
||||
/* TODO: add mutex */
|
||||
|
||||
p->sessions = d->progress.sessions;
|
||||
p->session = d->progress.session;
|
||||
p->tracks = d->progress.tracks;
|
||||
p->track = d->progress.track;
|
||||
p->indices = d->progress.indices;
|
||||
p->index = d->progress.index;
|
||||
if(d->progress.start_sector < 0x80000000)
|
||||
p->start_sector = d->progress.start_sector;
|
||||
else
|
||||
p->start_sector = 0x7fffffff;
|
||||
if(d->progress.sectors < 0x80000000)
|
||||
p->sectors = d->progress.sectors;
|
||||
else
|
||||
p->sectors = 0x7fffffff;
|
||||
if(d->progress.sector < 0x80000000)
|
||||
p->sector = d->progress.sector;
|
||||
else
|
||||
p->sector = 0x7fffffff;
|
||||
if(d->progress.buffer_capacity < 0x100000000)
|
||||
p->buffer_capacity = d->progress.buffer_capacity;
|
||||
else
|
||||
p->buffer_capacity = 0xffffffff;
|
||||
if(d->progress.buffer_available < 0x100000000)
|
||||
p->buffer_available = d->progress.buffer_available;
|
||||
else
|
||||
p->buffer_available = 0xffffffff;
|
||||
p->buffered_bytes = d->progress.buffered_bytes;
|
||||
if(d->progress.buffer_min_fill < 0x100000000)
|
||||
p->buffer_min_fill = d->progress.buffer_min_fill;
|
||||
else
|
||||
p->buffer_min_fill = 0xffffffff;
|
||||
}
|
||||
return d->busy;
|
||||
}
|
||||
|
||||
|
||||
enum burn_drive_status burn_drive_get_status_v2(struct burn_drive *d,
|
||||
struct burn_progress_v2 *p)
|
||||
{
|
||||
burn_drive_get_status_sig_handling();
|
||||
if (p != NULL) {
|
||||
/* TODO: add mutex */
|
||||
|
||||
memcpy(p, &(d->progress), sizeof(struct burn_progress_v2));
|
||||
}
|
||||
return d->busy;
|
||||
}
|
||||
|
@ -1327,7 +1383,7 @@ static int drive_getcaps(struct burn_drive *d, struct burn_drive_info *out)
|
|||
|
||||
/* ts A91112 */
|
||||
/* Set default block types. The call d->probe_write_modes() is quite
|
||||
obtrusive. It may be performed explicitely by new API call
|
||||
obtrusive. It may be performed explicitly by new API call
|
||||
burn_drive_probe_cd_write_modes().
|
||||
*/
|
||||
if (out->write_dvdram || out->write_dvdr ||
|
||||
|
@ -1426,7 +1482,7 @@ int burn_drive_scan_sync(struct burn_drive_info *drives[],
|
|||
|
||||
*n_drives = 0;
|
||||
|
||||
/* ts A70907 : wether to scan from scratch or to extend */
|
||||
/* ts A70907 : whether to scan from scratch or to extend */
|
||||
for (i = 0; i < (int) sizeof(scanned); i++)
|
||||
scanned[i] = 0;
|
||||
if (flag & 1) {
|
||||
|
@ -1567,7 +1623,7 @@ void burn_drive_info_free(struct burn_drive_info drive_infos[])
|
|||
/* ts A70903 : THIS IS WRONG ! (disabled now)
|
||||
It endangers multi drive usage.
|
||||
This call is not entitled to delete all drives, only the
|
||||
ones of the array which it receives a parmeter.
|
||||
ones of the array which it receives a parameter.
|
||||
|
||||
Problem: It was unclear how many items are listed in drive_infos
|
||||
Solution: Added a end marker element to any burn_drive_info array
|
||||
|
@ -1596,6 +1652,22 @@ void burn_drive_set_speed(struct burn_drive *d, int r, int w)
|
|||
d->set_speed(d, r, w);
|
||||
}
|
||||
|
||||
int burn_drive_set_speed_exact(struct burn_drive *d, int r, int w)
|
||||
{
|
||||
int sose;
|
||||
|
||||
d->nominal_write_speed = w;
|
||||
if(d->drive_role != 1)
|
||||
return 0;
|
||||
sose = d->silent_on_scsi_error;
|
||||
d->silent_on_scsi_error = 3;
|
||||
d->set_streaming_err = 0;
|
||||
d->set_streaming_exact_bit = 1;
|
||||
d->set_speed(d, r, w);
|
||||
d->silent_on_scsi_error = sose;
|
||||
d->set_streaming_exact_bit = 0;
|
||||
return !d->set_streaming_err;
|
||||
}
|
||||
|
||||
/* ts A70711 API function */
|
||||
int burn_drive_set_buffer_waiting(struct burn_drive *d, int enable,
|
||||
|
@ -1761,8 +1833,7 @@ int burn_drive_grab_dummy(struct burn_drive_info *drive_infos[], char *fname)
|
|||
{
|
||||
int ret = -1, role = 0, fd;
|
||||
int is_rdwr = 0, stat_ret = -1;
|
||||
/* divided by 512 it needs to fit into a signed long integer */
|
||||
off_t size = ((off_t) (512 * 1024 * 1024 - 1) * (off_t) 2048);
|
||||
off_t size = BURN_DRIVE_MAX_BYTES;
|
||||
off_t read_size = -1;
|
||||
struct burn_drive *d= NULL, *regd_d;
|
||||
struct stat stbuf;
|
||||
|
@ -1838,10 +1909,11 @@ int burn_drive_grab_dummy(struct burn_drive_info *drive_infos[], char *fname)
|
|||
(burn_drive_role_4_allowed & 8)) {
|
||||
d->status = BURN_DISC_APPENDABLE;
|
||||
d->block_types[BURN_WRITE_SAO] = 0;
|
||||
if (stbuf.st_size / (off_t) 2048
|
||||
>= 0x7ffffff0) {
|
||||
if (stbuf.st_size > BURN_DRIVE_MAX_BYTES) {
|
||||
d->status = BURN_DISC_FULL;
|
||||
d->role_5_nwa = 0x7ffffff0;
|
||||
d->role_5_nwa =
|
||||
(off_t) BURN_DRIVE_MAX_BYTES /
|
||||
(off_t) 2048; ;
|
||||
} else
|
||||
d->role_5_nwa = stbuf.st_size / 2048 +
|
||||
!!(stbuf.st_size % 2048);
|
||||
|
@ -1915,7 +1987,7 @@ int burn_drive_scan_and_grab(struct burn_drive_info *drive_infos[], char* adr,
|
|||
unsigned int n_drives;
|
||||
int ret, i;
|
||||
|
||||
/* check wether drive address is already registered */
|
||||
/* check whether drive address is already registered */
|
||||
for (i = 0; i <= drivetop; i++)
|
||||
if (drive_array[i].global_index >= 0)
|
||||
if (strcmp(drive_array[i].devname, adr) == 0)
|
||||
|
@ -2020,7 +2092,7 @@ int burn_drive_get_adr(struct burn_drive_info *drive_info, char adr[])
|
|||
|
||||
|
||||
/* ts A60922 ticket 33 */
|
||||
/** Evaluate wether the given address would be enumerated by libburn */
|
||||
/** Evaluate whether the given address would be enumerated by libburn */
|
||||
int burn_drive_is_enumerable_adr(char *adr)
|
||||
{
|
||||
return sg_is_enumerable_adr(adr);
|
||||
|
@ -2254,12 +2326,12 @@ int burn_drive_find_scsi_equiv(char *path, char adr[])
|
|||
burn_drive_adr_debug_msg(msg, NULL);
|
||||
return 0;
|
||||
}
|
||||
sprintf(msg, "burn_drive_find_scsi_equiv( %s ) : (%d),%d,%d,%d,%d",
|
||||
sprintf(msg, "burn_drive_find_scsi_equiv( %s ) : %d,%d,%d,%d,%d",
|
||||
path, bus_no, host_no, channel_no, target_no, lun_no);
|
||||
burn_drive_adr_debug_msg(msg, NULL);
|
||||
|
||||
ret= burn_drive_convert_scsi_adr(-1, host_no, channel_no, target_no,
|
||||
lun_no, adr);
|
||||
ret= burn_drive_convert_scsi_adr(bus_no, host_no, channel_no,
|
||||
target_no, lun_no, adr);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -2621,10 +2693,10 @@ int burn_disc_read_atip(struct burn_drive *d)
|
|||
}
|
||||
|
||||
/* ts A61110 : new API function */
|
||||
int burn_disc_track_lba_nwa(struct burn_drive *d, struct burn_write_opts *o,
|
||||
int trackno, int *lba, int *nwa)
|
||||
int burn_disc_track_lba_nwa_v2(struct burn_drive *d, struct burn_write_opts *o,
|
||||
int trackno, off_t *lba, off_t *nwa)
|
||||
{
|
||||
int ret;
|
||||
int ret, int_lba, int_nwa;
|
||||
|
||||
if (burn_drive_is_released(d)) {
|
||||
libdax_msgs_submit(libdax_messenger,
|
||||
|
@ -2652,11 +2724,38 @@ int burn_disc_track_lba_nwa(struct burn_drive *d, struct burn_write_opts *o,
|
|||
return 0;
|
||||
if (o != NULL)
|
||||
d->send_write_parameters(d, NULL, -1, o);
|
||||
ret = d->get_nwa(d, trackno, lba, nwa);
|
||||
ret = d->get_nwa(d, trackno, &int_lba, &int_nwa);
|
||||
if (ret <= 0)
|
||||
return ret;
|
||||
*lba = int_lba;
|
||||
*nwa = int_nwa;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/* ts A61110 / C40302 : API */
|
||||
int burn_disc_track_lba_nwa(struct burn_drive *d, struct burn_write_opts *o,
|
||||
int trackno, int *lba, int *nwa)
|
||||
{
|
||||
int ret;
|
||||
off_t off_lba, off_nwa;
|
||||
|
||||
ret = burn_disc_track_lba_nwa_v2(d, o, trackno, &off_lba, &off_nwa);
|
||||
if (ret <= 0)
|
||||
return ret;
|
||||
if (off_lba > 0x7fffffff)
|
||||
*lba = 0x7fffffff;
|
||||
else
|
||||
*lba = off_lba;
|
||||
if (off_nwa > 0x7fffffff) {
|
||||
*nwa = 0x7fffffff;
|
||||
return 0;
|
||||
} else {
|
||||
*nwa = off_nwa;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* ts A70131 : new API function */
|
||||
int burn_disc_get_msc1(struct burn_drive *d, int *start)
|
||||
{
|
||||
|
@ -2706,7 +2805,7 @@ off_t burn_disc_available_space(struct burn_drive *d,
|
|||
if (ret != 1)
|
||||
bytes = d->media_capacity_remaining;
|
||||
if (bytes <= 0)
|
||||
bytes = (off_t) (512 * 1024 * 1024 - 1) * (off_t) 2048;
|
||||
bytes = BURN_DRIVE_MAX_BYTES;
|
||||
if (bytes != d->media_capacity_remaining)
|
||||
burn_drive_set_media_capacity_remaining(d, bytes);
|
||||
} else {
|
||||
|
@ -3049,7 +3148,7 @@ int burn_disc_get_multi_caps(struct burn_drive *d, enum burn_write_types wt,
|
|||
d->current_profile == 0x1a ||
|
||||
d->current_profile == 0x43
|
||||
) {
|
||||
/* DVD-RAM, overwriteable DVD-RW, DVD+RW, BD-RE */
|
||||
/* DVD-RAM, overwritable DVD-RW, DVD+RW, BD-RE */
|
||||
o->start_adr = 1;
|
||||
ret = burn_disc_get_formats(d, &status, &size, &dummy,
|
||||
&num_formats);
|
||||
|
@ -3308,7 +3407,7 @@ int burn_drive_equals_adr(struct burn_drive *d1, char *adr2_in, int role2)
|
|||
/* one dir existing, one not */
|
||||
|
||||
/* Both directories exist. The basenames are equal.
|
||||
So the adresses are equal if the directories are
|
||||
So the addresses are equal if the directories are
|
||||
equal.*/
|
||||
}
|
||||
if (stbuf1.st_ino == stbuf2.st_ino &&
|
||||
|
@ -3389,21 +3488,38 @@ int burn_drive_find_by_thread_pid(struct burn_drive **d, pid_t pid,
|
|||
*/
|
||||
int burn_drive_set_media_capacity_remaining(struct burn_drive *d, off_t value)
|
||||
{
|
||||
if (value / (off_t) 2048 > (off_t) 0x7ffffff0)
|
||||
value = ((off_t) 0x7ffffff0) * (off_t) 2048;
|
||||
if (value > BURN_DRIVE_MAX_BYTES)
|
||||
value = BURN_DRIVE_MAX_BYTES;
|
||||
d->media_capacity_remaining = value;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* ts C40303 : API */
|
||||
int burn_get_read_capacity_v2(struct burn_drive *d, off_t *capacity, int flag)
|
||||
{
|
||||
*capacity = d->media_read_capacity +
|
||||
(d->media_read_capacity != 0x7fffffffffffffff);
|
||||
return (d->media_read_capacity != 0x7fffffffffffffff);
|
||||
}
|
||||
|
||||
/* ts A81215 : API */
|
||||
int burn_get_read_capacity(struct burn_drive *d, int *capacity, int flag)
|
||||
{
|
||||
*capacity = d->media_read_capacity +
|
||||
(d->media_read_capacity != 0x7fffffff);
|
||||
return (d->media_read_capacity != 0x7fffffff);
|
||||
}
|
||||
int ret;
|
||||
off_t cap;
|
||||
|
||||
ret= burn_get_read_capacity_v2(d, &cap, flag);
|
||||
if (cap < -0x7fffffff) {
|
||||
*capacity = -0x7fffffff;
|
||||
ret = 0;
|
||||
} else if (cap > 0x7fffffff) {
|
||||
*capacity = 0x7fffffff;
|
||||
ret = 0;
|
||||
} else {
|
||||
*capacity = cap;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* ts A90903 : API */
|
||||
int burn_disc_get_media_id(struct burn_drive *d,
|
||||
|
@ -3432,7 +3548,7 @@ int burn_disc_get_media_id(struct burn_drive *d,
|
|||
bit3= disc_app_code valid
|
||||
bit4= Disc is unrestricted (URU bit)
|
||||
bit5= Disc is nominally erasable (Erasable bit)
|
||||
This will be set with overwriteable media which
|
||||
This will be set with overwritable media which
|
||||
libburn normally considers to be unerasable blank.
|
||||
*/
|
||||
int burn_disc_get_cd_info(struct burn_drive *d, char disc_type[80],
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||
|
||||
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
|
||||
Copyright (c) 2006 - 2014 Thomas Schmitt <scdbackup@gmx.net>
|
||||
Copyright (c) 2006 - 2024 Thomas Schmitt <scdbackup@gmx.net>
|
||||
Provided under GPL version 2 or later.
|
||||
*/
|
||||
|
||||
|
@ -170,4 +170,12 @@ int burn_drive_has_feature(struct burn_drive *d, int feature_code,
|
|||
|
||||
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 */
|
||||
|
|
|
@ -75,11 +75,11 @@
|
|||
>>> See correctness reservation below.
|
||||
|
||||
Algebra on Galois fields is the same as on Rational Numbers.
|
||||
But arithmetics is defined by operations on polynomials rather than the
|
||||
usual integer arithmetics on binary numbers.
|
||||
But arithmetics on its polynomials differ from usual integer arithmetics
|
||||
on binary numbers.
|
||||
Addition and subtraction are identical with the binary exor operator.
|
||||
Multiplication and division would demand polynomial division, e.g. by the
|
||||
euclidian algorithm. The computing path over logarithms and powers follows
|
||||
euclidean algorithm. The computing path over logarithms and powers follows
|
||||
algebra and reduces the arithmetic task to table lookups, additions
|
||||
modulo 255, and exor operations. Note that the logarithms are natural
|
||||
numbers, not polynomials. They get added or subtracted by the usual addition
|
||||
|
|
|
@ -43,7 +43,7 @@ an unreadable disc */
|
|||
|
||||
|
||||
/* This is a generic OS oriented function wrapper which compensates
|
||||
shortcommings of read() in respect to a guaranteed amount of return data.
|
||||
shortcomings of read() in respect to a guaranteed amount of return data.
|
||||
See man 2 read , paragraph "RETURN VALUE".
|
||||
*/
|
||||
static int read_full_buffer(int fd, unsigned char *buffer, int size)
|
||||
|
|
|
@ -88,7 +88,7 @@ struct burn_source_offst {
|
|||
int size_adjustable;
|
||||
|
||||
/* for set_size/get_size */
|
||||
int nominal_size;
|
||||
off_t nominal_size;
|
||||
|
||||
/* To help offst_free() */
|
||||
struct burn_source *next;
|
||||
|
|
|
@ -52,7 +52,7 @@ double lib_start_time;
|
|||
*/
|
||||
int burn_sg_open_o_excl = 1;
|
||||
|
||||
/* ts A70403 : GNU/Linux: wether to use fcntl(,F_SETLK,)
|
||||
/* ts A70403 : GNU/Linux: whether to use fcntl(,F_SETLK,)
|
||||
after open() of device files */
|
||||
int burn_sg_fcntl_f_setlk = 1;
|
||||
|
||||
|
@ -71,7 +71,7 @@ int burn_sg_use_family = 0;
|
|||
has been thoroughly tested. */
|
||||
int burn_sg_open_o_nonblock = 1;
|
||||
|
||||
/* wether to take a busy drive as an error */
|
||||
/* whether to take a busy drive as an error */
|
||||
/* Caution: this is implemented by a rough hack and eventually leads
|
||||
to unconditional abort of the process */
|
||||
int burn_sg_open_abort_busy = 0;
|
||||
|
@ -98,7 +98,7 @@ int burn_builtin_signal_action = 0; /* burn_set_signal_handling() */
|
|||
volatile int burn_builtin_triggered_action = 0; /* burn_is_aborting() */
|
||||
|
||||
|
||||
/* ts A70223 : wether implemented untested profiles are supported */
|
||||
/* ts A70223 : whether implemented untested profiles are supported */
|
||||
int burn_support_untested_profiles = 0;
|
||||
|
||||
/* ts A91111 :
|
||||
|
@ -112,7 +112,7 @@ int burn_sg_log_scsi = 0;
|
|||
|
||||
/* ts B10312 :
|
||||
Whether to map random-access readonly files to drive role 4.
|
||||
Else it is role 2 overwriteable drive
|
||||
Else it is role 2 overwritable drive
|
||||
*/
|
||||
int burn_drive_role_4_allowed = 0;
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@ 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.
|
||||
0= all works well ,
|
||||
1 to 5 = waiting for eventual signal on control thread
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||
|
||||
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
|
||||
Copyright (c) 2006 - 2019 Thomas Schmitt <scdbackup@gmx.net>
|
||||
Copyright (c) 2006 - 2024 Thomas Schmitt <scdbackup@gmx.net>
|
||||
Provided under GPL version 2 or later.
|
||||
|
||||
This is the official API definition of libburn.
|
||||
|
@ -9,6 +9,8 @@
|
|||
*/
|
||||
/* Important: If you add a public API function then add its name to file
|
||||
libburn/libburn.ver
|
||||
in the node LIBBURN4_Major.Minor.Micro with the numbers of
|
||||
the next release version, citing the previous node.
|
||||
*/
|
||||
|
||||
|
||||
|
@ -29,6 +31,9 @@ processing tracks of more than 2 GB size.
|
|||
*/
|
||||
#include <sys/types.h>
|
||||
|
||||
/* For struct timeval */
|
||||
#include <sys/time.h>
|
||||
|
||||
#ifndef DOXYGEN
|
||||
|
||||
#if defined(__cplusplus)
|
||||
|
@ -144,7 +149,7 @@ enum burn_write_types
|
|||
With sequential DVD-R[W]: Incremental Streaming
|
||||
With DVD+R and BD-R: Track of open size
|
||||
With DVD-RAM, DVD+RW, BD-RE: Random Writeable (used sequentially)
|
||||
With overwriteable DVD-RW: Rigid Restricted Overwrite
|
||||
With overwritable DVD-RW: Rigid Restricted Overwrite
|
||||
*/
|
||||
BURN_WRITE_TAO,
|
||||
|
||||
|
@ -235,7 +240,7 @@ enum burn_disc_status
|
|||
CD-R, CD-RW, DVD-R, DVD-RW, DVD+R, BD-R
|
||||
Blanked multi-session media (i.e. treated by burn_disc_erase())
|
||||
CD-RW, DVD-RW
|
||||
Overwriteable media with or without valid data
|
||||
Overwritable media with or without valid data
|
||||
DVD-RAM, DVD+RW, formatted DVD-RW, BD-RE
|
||||
*/
|
||||
BURN_DISC_BLANK,
|
||||
|
@ -373,6 +378,9 @@ struct burn_toc_entry
|
|||
@since 0.5.2 : DVD extensions are made valid for CD too
|
||||
bit1= LRA extension is valid @since 0.7.2
|
||||
bit2= Track status bits extension is valid @since 1.2.8
|
||||
bit3= Long block address is valid:
|
||||
long_start_lba, long_track_blocks, long_last_rec_adr
|
||||
@since 1.5.8
|
||||
*/
|
||||
unsigned char extensions_valid;
|
||||
|
||||
|
@ -383,8 +391,10 @@ struct burn_toc_entry
|
|||
unsigned char session_msb;
|
||||
unsigned char point_msb;
|
||||
/* pmin, psec, and pframe may be too small if DVD extension is valid */
|
||||
/* -1 means that only long_start_lba is valid */
|
||||
int start_lba;
|
||||
/* min, sec, and frame may be too small if DVD extension is valid */
|
||||
/* -1 means that only long_track_blocks is valid */
|
||||
int track_blocks;
|
||||
|
||||
/* ts A90909 : LRA extension. extensions_valid:bit1 */
|
||||
|
@ -393,6 +403,7 @@ struct burn_toc_entry
|
|||
DVD-R DL when LJRS = 00b, DVD-RW, HD DVD-R, and BD-R.
|
||||
This would mean profiles: 0x11, 0x15, 0x13, 0x14, 0x51, 0x41, 0x42
|
||||
*/
|
||||
/* -1 means that only long_last_rec_adr is valid */
|
||||
int last_recorded_address;
|
||||
|
||||
/* ts B30112 : Track status bits extension. extensions_valid:bit2 */
|
||||
|
@ -412,6 +423,12 @@ struct burn_toc_entry
|
|||
*/
|
||||
int track_status_bits;
|
||||
|
||||
/* ts C40221 : Long block address extension. extensions_valid:bit3 */
|
||||
/* @since 1.5.8 */
|
||||
off_t long_start_lba;
|
||||
off_t long_track_blocks;
|
||||
off_t long_last_rec_adr;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
@ -663,7 +680,8 @@ struct burn_drive_info
|
|||
|
||||
|
||||
/** Operation progress report. All values are 0 based indices.
|
||||
* */
|
||||
Handed out by burn_drive_get_status().
|
||||
**/
|
||||
struct burn_progress {
|
||||
/** The total number of sessions */
|
||||
int sessions;
|
||||
|
@ -675,7 +693,7 @@ struct burn_progress {
|
|||
int track;
|
||||
/** The total number of indices */
|
||||
int indices;
|
||||
/** Curent index. */
|
||||
/** Current index. */
|
||||
int index;
|
||||
/** The starting logical block address */
|
||||
int start_sector;
|
||||
|
@ -705,6 +723,52 @@ struct burn_progress {
|
|||
};
|
||||
|
||||
|
||||
/** Operation progress report with long block numbers.
|
||||
All values are 0 based indices.
|
||||
Handed out by burn_drive_get_status_v2().
|
||||
@since 1.5.8
|
||||
**/
|
||||
struct burn_progress_v2 {
|
||||
/** Revision of the struct format.
|
||||
0= Elements up to .buffer_min_fill */
|
||||
int revision;
|
||||
|
||||
/** The total number of sessions */
|
||||
int sessions;
|
||||
/** Current session.*/
|
||||
int session;
|
||||
/** The total number of tracks */
|
||||
int tracks;
|
||||
/** Current track. */
|
||||
int track;
|
||||
/** The total number of indices */
|
||||
int indices;
|
||||
/** Current index. */
|
||||
int index;
|
||||
/** The starting logical block address */
|
||||
off_t start_sector;
|
||||
/** On write: The number of sectors.
|
||||
On blank: 0x10000 as upper limit for relative progress steps */
|
||||
off_t sectors;
|
||||
/** On write: The current sector being processed.
|
||||
On blank: Relative progress steps 0 to 0x10000 */
|
||||
off_t sector;
|
||||
|
||||
/** The capacity of the drive buffer */
|
||||
off_t buffer_capacity;
|
||||
/** The free space in the drive buffer (might be slightly outdated) */
|
||||
off_t buffer_available;
|
||||
|
||||
/** The number of bytes sent to the drive buffer */
|
||||
off_t buffered_bytes;
|
||||
/** The minimum number of bytes stored in buffer during write.
|
||||
(Caution: Before surely one buffer size of bytes was processed,
|
||||
this value is 0x7fffffffffffffff.)
|
||||
*/
|
||||
off_t buffer_min_fill;
|
||||
};
|
||||
|
||||
|
||||
/* ts A61226 */
|
||||
/* @since 0.3.0 */
|
||||
/** Description of a speed capability as reported by the drive in conjunction
|
||||
|
@ -1328,7 +1392,7 @@ int burn_drive_get_bd_r_pow(struct burn_drive *drive);
|
|||
/* ts A61020 */
|
||||
/** Returns start and end lba of the media which is currently inserted
|
||||
in the given drive. The drive has to be grabbed to have hope for reply.
|
||||
Shortcomming (not a feature): unless burn_disc_read_atip() was called
|
||||
Shortcoming (not a feature): unless burn_disc_read_atip() was called
|
||||
only blank media will return valid info.
|
||||
@param drive The drive to query.
|
||||
@param start_lba Returns the start lba value
|
||||
|
@ -1386,7 +1450,7 @@ char *burn_guess_cd_manufacturer(int m_li, int s_li, int f_li,
|
|||
This seems to be broken with my drives. The bit is
|
||||
0 and the validity bit for disc_app_code is 0 too.
|
||||
bit5= Disc is nominally erasable (Erasable bit)
|
||||
This will be set with overwriteable media which
|
||||
This will be set with overwritable media which
|
||||
libburn normally considers to be unerasable blank.
|
||||
@return 1 success, <= 0 an error occurred
|
||||
@since 0.7.2
|
||||
|
@ -1478,6 +1542,13 @@ int burn_disc_get_phys_format_info(struct burn_drive *d, int *disk_category,
|
|||
int burn_disc_track_lba_nwa(struct burn_drive *d, struct burn_write_opts *o,
|
||||
int trackno, int *lba, int *nwa);
|
||||
|
||||
/* ts C40302 */
|
||||
/** Like burn_disc_track_lba_nwa(), but with off_t results.
|
||||
@since 1.5.8
|
||||
*/
|
||||
int burn_disc_track_lba_nwa_v2(struct burn_drive *d, struct burn_write_opts *o,
|
||||
int trackno, off_t *lba, off_t *nwa);
|
||||
|
||||
/* ts B10525 */
|
||||
/** Tells whether a previous attempt to determine the Next Writeable Address
|
||||
of the upcoming track reveiled that the READ TRACK INFORMATION Damage Bit
|
||||
|
@ -1650,6 +1721,15 @@ int burn_disc_erasable(struct burn_drive *d);
|
|||
enum burn_drive_status burn_drive_get_status(struct burn_drive *drive,
|
||||
struct burn_progress *p);
|
||||
|
||||
/** Returns the progress with long block numbers and the status of the drive.
|
||||
@param drive The drive to query busy state for.
|
||||
@param p Returns the progress of the operation, NULL if you don't care
|
||||
@return the current status of the drive. See also burn_drive_status.
|
||||
@since 1.5.8
|
||||
*/
|
||||
enum burn_drive_status burn_drive_get_status_v2(struct burn_drive *drive,
|
||||
struct burn_progress_v2 *p);
|
||||
|
||||
/** Creates a write_opts struct for burning to the specified drive.
|
||||
The returned object must later be freed with burn_write_opts_free().
|
||||
@param drive The drive to write with
|
||||
|
@ -1819,7 +1899,7 @@ void burn_disc_read(struct burn_drive *drive, const struct burn_read_opts *o);
|
|||
with drive and media. This function is called by burn_disc_write() but
|
||||
an application might be interested in this check in advance.
|
||||
@param o The options for the writing operation.
|
||||
@param disc The descrition of the disc to be created
|
||||
@param disc The description of the disc to be created
|
||||
@param reasons Eventually returns a list of rejection reason statements
|
||||
@param silent 1= do not issue error messages , 0= report problems
|
||||
@return 1 ok, -1= no recordable media detected, 0= other failure
|
||||
|
@ -2983,6 +3063,11 @@ int burn_track_set_size(struct burn_track *t, off_t size);
|
|||
*/
|
||||
int burn_track_get_sectors(struct burn_track *);
|
||||
|
||||
/* ts C40302 */
|
||||
/** Like burn_track_get_sectors(), but with return type off_t.
|
||||
@since 1.5.8
|
||||
*/
|
||||
off_t burn_track_get_sectors_v2(struct burn_track *);
|
||||
|
||||
/* ts A61101 */
|
||||
/** Tells how many source bytes have been read and how many data bytes have
|
||||
|
@ -2996,7 +3081,7 @@ int burn_track_get_counters(struct burn_track *t,
|
|||
off_t *read_bytes, off_t *written_bytes);
|
||||
|
||||
|
||||
/** Sets drive read and write speed
|
||||
/** Sets drive read and write speed.
|
||||
Note: "k" is 1000, not 1024.
|
||||
1xCD = 176.4 k/s, 1xDVD = 1385 k/s, 1xBD = 4496 k/s.
|
||||
Fractional speeds should be rounded up. Like 4xCD = 706.
|
||||
|
@ -3007,6 +3092,63 @@ int burn_track_get_counters(struct burn_track *t,
|
|||
void burn_drive_set_speed(struct burn_drive *d, int read, int write);
|
||||
|
||||
|
||||
/* ts C00822 */
|
||||
/** Sets drive read and write speed using the "Exact" bit of SCSI command
|
||||
SET STREAMING. This command will be used even if a CD medium is present.
|
||||
MMC specifies that with the Exact bit the desired speed settings shall
|
||||
either be obeyed by the drive exactly, or that the drive shall indicate
|
||||
failure and not accept the settings.
|
||||
But many drives reply no error and nevertheless adjust their read speed
|
||||
only coarsly or ignore the setting after a few MB of fast read attempts.
|
||||
|
||||
The call parameters have the same meaning as with burn_drive_set_speed().
|
||||
@param d The drive to set speed for. It must be a role 1 drive.
|
||||
@param read Read speed in k/s (0 is max, -1 is min).
|
||||
@param write Write speed in k/s (0 is max, -1 is min).
|
||||
@return 1=success , 0=failure
|
||||
@since 1.5.4
|
||||
*/
|
||||
int burn_drive_set_speed_exact(struct burn_drive *d, int read, int write);
|
||||
|
||||
|
||||
/* ts C00822 */
|
||||
/** Waits until the time has elapsed since the given previous time to transmit
|
||||
the given byte count with the given speed in KB/second (KB = 1000 bytes).
|
||||
This call may be used between random access read operations like
|
||||
burn_read_data() in order to force a slower speed than the drive is
|
||||
willing to use if it gets read requests as fast as it delivers data.
|
||||
|
||||
The parameter us_corr carries microseconds of time deviations from one
|
||||
call to the next one. Such deviations may happen because of small
|
||||
inexactnesses of the sleeper function and because of temporary delays
|
||||
in the data supply so that sleeping for a negative time span would have
|
||||
been necessary. The next call will reduce or enlarge its own sleeping
|
||||
period by this value.
|
||||
|
||||
@param kb_per_second the desired speed in 1000 bytes per second.
|
||||
Supplied by the caller.
|
||||
@max_corr the maximum backlog in microseconds which shall
|
||||
be compensated by the next call. Supplied by the
|
||||
caller. Not more than 1 billion = 1000 seconds.
|
||||
@param prev_time time keeper updated by burn_nominal_slowdown().
|
||||
The caller provides the memory and elsewise should
|
||||
carry it unchanged from call to call.
|
||||
@param us_corr updated by burn_nominal_slowdown(). See above.
|
||||
The caller provides the memory and elsewise should
|
||||
carry it unchanged from call to call.
|
||||
@param b_since_prev byte count since the previous call. This number
|
||||
has to be counted and supplied by the caller.
|
||||
@param flag Bitfield for control purposes:
|
||||
bit0= initialize *prev_time and *us_corr,
|
||||
ignore other parameters, do not wait
|
||||
@return 2=no wait because no usable kb_per_second , 1=success , 0=failure
|
||||
@since 1.5.4
|
||||
*/
|
||||
int burn_nominal_slowdown(int kb_per_second, int max_corr,
|
||||
struct timeval *prev_time,
|
||||
int *us_corr, off_t b_since_prev, int flag);
|
||||
|
||||
|
||||
/* ts A70711 */
|
||||
/** Controls the behavior with writing when the drive buffer is suspected to
|
||||
be full. To check and wait for enough free buffer space before writing
|
||||
|
@ -3277,9 +3419,13 @@ void burn_write_opts_set_fillup(struct burn_write_opts *opts,
|
|||
|
||||
|
||||
/* ts A70303 */
|
||||
/** Eventually makes libburn ignore the failure of some conformance checks:
|
||||
/** Lets libburn ignore the failure of some conformance checks:
|
||||
- the check whether CD write+block type is supported by the drive
|
||||
- the check whether the media profile supports simulated burning
|
||||
- @since 1.5.6
|
||||
The check whether a write operation exceeds the size of the medium
|
||||
as announced by the drive. This is known as "overburn" and may work
|
||||
for a few thousand additional blocks on CD media with write type SAO.
|
||||
@param opts The write opts to change
|
||||
@param use_force 1=ignore above checks, 0=refuse work on failed check
|
||||
@since 0.3.4
|
||||
|
@ -3329,12 +3475,27 @@ void burn_write_opts_set_dvd_obs(struct burn_write_opts *opts, int obs);
|
|||
void burn_write_opts_set_obs_pad(struct burn_write_opts *opts, int pad);
|
||||
|
||||
|
||||
/* ts C10909 */
|
||||
/** Exempts BD-R media from the elsewise unavoidable automatic padding of the
|
||||
last write chunk to its full size.
|
||||
Even if this exempt is granted it gets into effect only if stream recording
|
||||
is disabled and burn_write_opts_set_obs_pad() is set to 0.
|
||||
@param opts The write opts to change
|
||||
@param value 1= possibly exempt BD-R from end chunk padding.
|
||||
0= always act on BD-R as if
|
||||
burn_write_opts_set_obs_pad(opts, 1) is in effect.
|
||||
@since 1.5.6
|
||||
*/
|
||||
void burn_write_opts_set_bdr_obs_exempt(struct burn_write_opts *opts,
|
||||
int value);
|
||||
|
||||
|
||||
/* ts A91115 */
|
||||
/** Sets the rhythm by which stdio pseudo drives force their output data to
|
||||
be consumed by the receiving storage device. This forcing keeps the memory
|
||||
from being clogged with lots of pending data for slow devices.
|
||||
@param opts The write opts to change
|
||||
@param rythm Number of 2KB output blocks after which fsync(2) is
|
||||
@param rhythm Number of 2KB output blocks after which fsync(2) is
|
||||
performed.
|
||||
-1 means no fsync()
|
||||
0 means default
|
||||
|
@ -3343,7 +3504,7 @@ void burn_write_opts_set_obs_pad(struct burn_write_opts *opts, int pad);
|
|||
Default is currently 8192 = 16 MB.
|
||||
@since 0.7.4
|
||||
*/
|
||||
void burn_write_opts_set_stdio_fsync(struct burn_write_opts *opts, int rythm);
|
||||
void burn_write_opts_set_stdio_fsync(struct burn_write_opts *opts, int rhythm);
|
||||
|
||||
|
||||
/** Sets whether to read in raw mode or not
|
||||
|
@ -3628,12 +3789,12 @@ struct burn_multi_caps {
|
|||
/** Profile number which was current when the reply was generated */
|
||||
int current_profile;
|
||||
|
||||
/** Wether the current profile indicates CD media. 1=yes, 0=no */
|
||||
/** Whether the current profile indicates CD media. 1=yes, 0=no */
|
||||
int current_is_cd_profile;
|
||||
|
||||
/* ts A70528 */
|
||||
/* @since 0.3.8 */
|
||||
/** Wether the current profile is able to perform simulated write */
|
||||
/** Whether the current profile is able to perform simulated write */
|
||||
int might_simulate;
|
||||
};
|
||||
|
||||
|
@ -3700,8 +3861,19 @@ struct burn_session **burn_disc_get_sessions(struct burn_disc *d,
|
|||
int burn_disc_get_incomplete_sessions(struct burn_disc *d);
|
||||
|
||||
|
||||
/** Tells how many sectors a disc will have, or already has.
|
||||
This is the sum of all burn_session_get_sectors() results of the disc.
|
||||
The result is NOT RELIABLE with tracks of undefined length
|
||||
*/
|
||||
int burn_disc_get_sectors(struct burn_disc *d);
|
||||
|
||||
/* ts C40302 */
|
||||
/** Like burn_disc_get_sectors(), but with return type off_t.
|
||||
@since 1.5.8
|
||||
*/
|
||||
off_t burn_disc_get_sectors_v2(struct burn_disc *d);
|
||||
|
||||
|
||||
/** Gets an array of all the tracks for a session
|
||||
THIS IS NO LONGER VALID AFTER YOU ADD OR REMOVE A TRACK
|
||||
@param s session to get track array for
|
||||
|
@ -3711,8 +3883,19 @@ int burn_disc_get_sectors(struct burn_disc *d);
|
|||
struct burn_track **burn_session_get_tracks(struct burn_session *s,
|
||||
int *num);
|
||||
|
||||
/** Tells how many sectors a session will have, or already has on disc.
|
||||
This is the sum of all burn_track_get_sectors() results of the session.
|
||||
The result is NOT RELIABLE with tracks of undefined length
|
||||
*/
|
||||
int burn_session_get_sectors(struct burn_session *s);
|
||||
|
||||
/* ts C40302 */
|
||||
/** Like burn_session_get_sectors(), but with return type off_t.
|
||||
@since 1.5.8
|
||||
*/
|
||||
off_t burn_session_get_sectors_v2(struct burn_session *s);
|
||||
|
||||
|
||||
/** Gets the mode of a track
|
||||
@param track the track to query
|
||||
@return the track's mode
|
||||
|
@ -3755,7 +3938,7 @@ void burn_version(int *major, int *minor, int *micro);
|
|||
*/
|
||||
#define burn_header_version_major 1
|
||||
#define burn_header_version_minor 5
|
||||
#define burn_header_version_micro 2
|
||||
#define burn_header_version_micro 7
|
||||
/** Note:
|
||||
Above version numbers are also recorded in configure.ac because libtool
|
||||
wants them as parameters at build time.
|
||||
|
@ -3765,7 +3948,7 @@ void burn_version(int *major, int *minor, int *micro);
|
|||
/** Usage discussion:
|
||||
|
||||
Some developers of the libburnia project have differing
|
||||
opinions how to ensure the compatibility of libaries
|
||||
opinions how to ensure the compatibility of libraries
|
||||
and applications.
|
||||
|
||||
It is about whether to use at compile time and at runtime
|
||||
|
@ -4015,7 +4198,7 @@ int burn_is_aborting(int flag);
|
|||
/** Write data in random access mode.
|
||||
The drive must be grabbed successfully before calling this function which
|
||||
circumvents usual libburn session processing and rather writes data without
|
||||
preparations or finalizing. This will work only with overwriteable media
|
||||
preparations or finalizing. This will work only with overwritable media
|
||||
which are also suitable for burn_write_opts_set_start_byte(). The same
|
||||
address alignment restrictions as with this function apply. I.e. for DVD
|
||||
it is best to align to 32 KiB blocks (= 16 LBA units). The amount of data
|
||||
|
@ -4051,10 +4234,13 @@ int burn_random_access_write(struct burn_drive *d, off_t byte_address,
|
|||
|
||||
/* ts A81215 */
|
||||
/** Inquire the maximum amount of readable data.
|
||||
It is supposed that all LBAs in the range from 0 to capacity - 1
|
||||
can be read via burn_read_data() although some of them may never have been
|
||||
recorded. If tracks are recognizable then it is better to only read
|
||||
LBAs which are part of some track.
|
||||
On DVD and BD it is supposed that all LBAs in the range from 0 to
|
||||
capacity - 1 can be read via burn_read_data() although some of them may
|
||||
never have been recorded. With multi-session CD there have to be
|
||||
expected unreadable TAO Run-out blocks.
|
||||
If tracks are recognizable then it is better to only read LBAs which
|
||||
are part of some track and on CD to be cautious about the last two blocks
|
||||
of each track which might be TAO Run-out blocks.
|
||||
If the drive is actually a large file or block device, then the capacity
|
||||
is curbed to a maximum of 0x7ffffff0 blocks = 4 TB - 32 KB.
|
||||
@param d The drive from which to read
|
||||
|
@ -4065,6 +4251,12 @@ int burn_random_access_write(struct burn_drive *d, off_t byte_address,
|
|||
*/
|
||||
int burn_get_read_capacity(struct burn_drive *d, int *capacity, int flag);
|
||||
|
||||
/* ts C40303 */
|
||||
/** Like burn_get_read_capacity(), but with off_t result.
|
||||
@since 1.5.8
|
||||
*/
|
||||
int burn_get_read_capacity_v2(struct burn_drive *d, off_t *capacity, int flag);
|
||||
|
||||
|
||||
/* ts A70812 */
|
||||
/** Read data in random access mode.
|
||||
|
@ -4295,7 +4487,7 @@ int burn_drive_equals_adr(struct burn_drive *d1, char *adr2, int drive_role2);
|
|||
struct libdax_audioxtr;
|
||||
|
||||
|
||||
/** Open an audio file, check wether suitable, create extractor object.
|
||||
/** Open an audio file, check whether suitable, create extractor object.
|
||||
@param xtr Opaque handle to extractor. Gets attached extractor object.
|
||||
@param path Address of the audio file to extract. "-" is stdin (but might
|
||||
be not suitable for all futurely supported formats).
|
||||
|
@ -4393,7 +4585,7 @@ BURN_END_DECLS
|
|||
/* The following experiments may be interesting in future:
|
||||
*/
|
||||
|
||||
/* Perform OPC explicitely.
|
||||
/* Perform OPC explicitly.
|
||||
# define Libburn_pioneer_dvr_216d_with_opC 1
|
||||
*/
|
||||
|
||||
|
|
|
@ -80,6 +80,7 @@ burn_drive_scan_and_grab;
|
|||
burn_drive_set_buffer_waiting;
|
||||
burn_drive_set_immed;
|
||||
burn_drive_set_speed;
|
||||
burn_drive_set_speed_exact;
|
||||
burn_drive_set_stream_recording;
|
||||
burn_drive_snooze;
|
||||
burn_drive_was_feat21_failure;
|
||||
|
@ -107,6 +108,7 @@ burn_msf_to_sectors;
|
|||
burn_msgs_obtain;
|
||||
burn_msgs_set_severities;
|
||||
burn_msgs_submit;
|
||||
burn_nominal_slowdown;
|
||||
burn_obtain_profile_name;
|
||||
burn_offst_source_new;
|
||||
burn_os_alloc_buffer;
|
||||
|
@ -184,6 +186,7 @@ burn_write_opts_auto_write_type;
|
|||
burn_write_opts_free;
|
||||
burn_write_opts_get_drive;
|
||||
burn_write_opts_new;
|
||||
burn_write_opts_set_bdr_obs_exempt;
|
||||
burn_write_opts_set_dvd_obs;
|
||||
burn_write_opts_set_fail21h_sev;
|
||||
burn_write_opts_set_fillup;
|
||||
|
@ -210,3 +213,13 @@ libdax_audioxtr_new;
|
|||
libdax_audioxtr_read;
|
||||
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;
|
||||
|
||||
|
|
|
@ -158,7 +158,7 @@ static int libdax_audioxtr_identify_wav(struct libdax_audioxtr *o, int flag)
|
|||
char buf[16];
|
||||
unsigned char *ubuf;
|
||||
|
||||
/* check wether this is a MS WAVE file .wav */
|
||||
/* check whether this is a MS WAVE file .wav */
|
||||
/* info used: http://ccrma.stanford.edu/courses/422/projects/WaveFormat/
|
||||
https://en.wikipedia.org/wiki/WAV
|
||||
see summary in: doc/waveformat.txt
|
||||
|
@ -247,7 +247,7 @@ static int libdax_audioxtr_identify_au(struct libdax_audioxtr *o, int flag)
|
|||
int ret,encoding;
|
||||
char buf[24];
|
||||
|
||||
/* Check wether this is a Sun Audio, .au file */
|
||||
/* Check whether this is a Sun Audio, .au file */
|
||||
/* info used: http://ccrma.stanford.edu/courses/422/projects/WaveFormat/ */
|
||||
|
||||
if(o->fd!=0) {
|
||||
|
|
|
@ -38,7 +38,7 @@ struct libdax_audioxtr;
|
|||
/* Calls from applications (to be forwarded by libdax/libburn) */
|
||||
|
||||
|
||||
/** Open an audio file, check wether suitable, create extractor object.
|
||||
/** Open an audio file, check whether suitable, create extractor object.
|
||||
@param xtr Opaque handle to extractor. Gets attached extractor object.
|
||||
@param path Address of the audio file to extract. "-" is stdin (but might
|
||||
be not suitable for all futurely supported formats).
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
|
||||
/* libdax_msgs
|
||||
Message handling facility of libburn and libisofs.
|
||||
Copyright (C) 2006-2016 Thomas Schmitt <scdbackup@gmx.net>,
|
||||
Copyright (C) 2006-2021 Thomas Schmitt <scdbackup@gmx.net>,
|
||||
provided under GPL version 2 or later.
|
||||
*/
|
||||
|
||||
|
@ -425,7 +425,7 @@ Range "elmom" : 0x00010000 to 0x0001ffff
|
|||
------------------------------------------------------------------------------
|
||||
Range "scdbackup" : 0x00020000 to 0x0002ffff
|
||||
|
||||
Acessing and defending drives:
|
||||
Accessing and defending drives:
|
||||
|
||||
0x00020001 (SORRY,LOW) = Cannot open busy device
|
||||
0x00020002 (SORRY,HIGH) = Encountered error when closing drive
|
||||
|
@ -555,7 +555,7 @@ Range "scdbackup" : 0x00020000 to 0x0002ffff
|
|||
0x0002016e (DEBUG,HIGH) = MODE SENSE page 2A too short
|
||||
0x0002016f (DEBUG,HIGH) = Unable to grab scanned drive
|
||||
0x00020170 (NOTE,HIGH) = Closing open session before writing new one
|
||||
0x00020171 (NOTE,HIGH) = Closing BD-R with accidentaly open session
|
||||
0x00020171 (NOTE,HIGH) = Closing BD-R with accidentally open session
|
||||
0x00020172 (SORRY,HIGH) = Read start address larger than number of readable blocks
|
||||
0x00020173 (FAILURE,HIGH) = Drive tells NWA smaller than last written address
|
||||
0x00020174 (SORRY,HIGH) = Fifo alignment does not allow desired read size
|
||||
|
@ -580,7 +580,7 @@ Range "scdbackup" : 0x00020000 to 0x0002ffff
|
|||
0x00020187 (NOTE,HIGH) = Track not marked as damaged. No action taken.
|
||||
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 cancled.
|
||||
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
|
||||
|
@ -616,6 +616,7 @@ Range "scdbackup" : 0x00020000 to 0x0002ffff
|
|||
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:
|
||||
|
@ -646,11 +647,11 @@ Range "vreixo" : 0x00030000 to 0x0003ffff
|
|||
0x0003ffbc (FAILURE,HIGH) = Image already bootable
|
||||
0x0003ffbb (FAILURE,HIGH) = Trying to use an invalid file as boot image
|
||||
0x0003ff80 (FAILURE,HIGH) = Error on file operation
|
||||
0x0003ff7f (FAILURE,HIGH) = Trying to open an already openned file
|
||||
0x0003ff7f (FAILURE,HIGH) = Trying to open an already opened file
|
||||
0x0003ff7e (FAILURE,HIGH) = Access to file is not allowed
|
||||
0x0003ff7d (FAILURE,HIGH) = Incorrect path to file
|
||||
0x0003ff7c (FAILURE,HIGH) = The file does not exist in the filesystem
|
||||
0x0003ff7b (FAILURE,HIGH) = Trying to read or close a file not openned
|
||||
0x0003ff7b (FAILURE,HIGH) = Trying to read or close a file not opened
|
||||
0x0003ff7a (FAILURE,HIGH) = Directory used where no dir is expected
|
||||
0x0003ff79 (FAILURE,HIGH) = File read error
|
||||
0x0003ff78 (FAILURE,HIGH) = Not dir used where a dir is expected
|
||||
|
@ -701,7 +702,7 @@ X 0x00030203 (HINT,MEDIUM) = Unsupported El-Torito feature
|
|||
X 0x00030204 (SORRY,HIGH) = Invalid file to be an El-Torito image
|
||||
X 0x00030205 (WARNING,MEDIUM)= Cannot properly patch isolinux image
|
||||
X 0x00030206 (WARNING,MEDIUM)= Copying El-Torito from a previous image without
|
||||
X enought info about it
|
||||
X enough info about it
|
||||
X 0x00030301 (NOTE,MEDIUM) = Unsupported file type for Joliet tree
|
||||
|
||||
|
||||
|
|
235
libburn/mmc.c
235
libburn/mmc.c
|
@ -1,7 +1,7 @@
|
|||
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||
|
||||
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
|
||||
Copyright (c) 2006 - 2016 Thomas Schmitt <scdbackup@gmx.net>
|
||||
Copyright (c) 2006 - 2024 Thomas Schmitt <scdbackup@gmx.net>
|
||||
Provided under GPL version 2 or later.
|
||||
*/
|
||||
|
||||
|
@ -109,7 +109,7 @@ extern struct libdax_msgs *libdax_messenger;
|
|||
Error messages of class DEBUG appear because of inability to
|
||||
read TOC or track info. Nevertheless, the written images verify.
|
||||
ts A61220 : Burned to a virgin DVD+RW by help of new mmc_format_unit()
|
||||
(did not test wether it would work without). Burned to a
|
||||
(did not test whether it would work without). Burned to a
|
||||
not completely formatted DVD+RW. (Had worked before without
|
||||
mmc_format_unit() but i did not exceed the formatted range
|
||||
as reported by dvd+rw-mediainfo.)
|
||||
|
@ -300,6 +300,14 @@ int mmc_four_char_to_int(unsigned char *data)
|
|||
}
|
||||
|
||||
|
||||
/* ts C40226 */
|
||||
unsigned int mmc_four_char_to_uint(unsigned char *data)
|
||||
{
|
||||
return (((unsigned int) data[0]) << 24) | (data[1] << 16) |
|
||||
(data[2] << 8) | data[3];
|
||||
}
|
||||
|
||||
|
||||
/* ts A70201 */
|
||||
int mmc_int_to_four_char(unsigned char *data, int num)
|
||||
{
|
||||
|
@ -311,6 +319,17 @@ int mmc_int_to_four_char(unsigned char *data, int num)
|
|||
}
|
||||
|
||||
|
||||
/* ts C40226 */
|
||||
int mmc_uint_to_four_char(unsigned char *data, unsigned int num)
|
||||
{
|
||||
data[0] = (num >> 24) & 0xff;
|
||||
data[1] = (num >> 16) & 0xff;
|
||||
data[2] = (num >> 8) & 0xff;
|
||||
data[3] = num & 0xff;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static int mmc_start_for_bit0 = 0;
|
||||
|
||||
/* @param flag bit0= the calling function should need no START UNIT.
|
||||
|
@ -502,7 +521,7 @@ int mmc_get_nwa(struct burn_drive *d, int trackno, int *lba, int *nwa)
|
|||
sprintf(msg, "Upcoming track: ");
|
||||
if (d->current_profile == 0x1a || d->current_profile == 0x13 ||
|
||||
d->current_profile == 0x12 || d->current_profile == 0x43) {
|
||||
/* overwriteable */
|
||||
/* overwritable */
|
||||
*lba = *nwa = num = 0;
|
||||
|
||||
} else if (data[5] & 32) { /* ts B10534 : MMC-5 6.27.3.7 Damage Bit */
|
||||
|
@ -747,7 +766,8 @@ ex:;
|
|||
*/
|
||||
static int mmc_wait_for_buffer_free(struct burn_drive *d, struct buffer *buf)
|
||||
{
|
||||
int usec= 0, need, reported_3s = 0, first_wait = 1;
|
||||
int usec= 0, reported_3s = 0, first_wait = 1;
|
||||
off_t need;
|
||||
struct timeval t0,tnow;
|
||||
double max_fac, min_fac, waiting;
|
||||
|
||||
|
@ -926,11 +946,11 @@ static int print_time(int flag)
|
|||
#endif /* Libburn_write_time_debuG */
|
||||
|
||||
|
||||
int mmc_write(struct burn_drive *d, int start, struct buffer *buf)
|
||||
int mmc_write(struct burn_drive *d, off_t start_long, struct buffer *buf)
|
||||
{
|
||||
int cancelled;
|
||||
struct command *c;
|
||||
int len, key, asc, ascq;
|
||||
int len, key, asc, ascq, start;
|
||||
char *msg = NULL;
|
||||
|
||||
#ifdef Libburn_write_time_debuG
|
||||
|
@ -942,6 +962,16 @@ fprintf(stderr, "libburn_DEBUG: buffer sectors= %d bytes= %d\n",
|
|||
buf->sectors, buf->bytes);
|
||||
*/
|
||||
|
||||
if (start_long > (off_t) 0x7fffffff) {
|
||||
libdax_msgs_submit(libdax_messenger, d->global_index,
|
||||
0x0002012d,
|
||||
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
|
||||
"Exceeding range of signed integer block addresses",
|
||||
0, 0);
|
||||
d->cancel = 1;
|
||||
return BE_CANCELLED;
|
||||
}
|
||||
start = start_long;
|
||||
|
||||
c = &(d->casual_command);
|
||||
|
||||
|
@ -963,26 +993,18 @@ fprintf(stderr, "libburn_DEBUG: buffer sectors= %d bytes= %d\n",
|
|||
return BE_CANCELLED;
|
||||
|
||||
/* ts A70215 */
|
||||
if (d->media_lba_limit > 0 && start >= d->media_lba_limit) {
|
||||
if (d->media_lba_limit > 0 && start >= d->media_lba_limit &&
|
||||
!d->write_opts->force_is_set) {
|
||||
|
||||
msg = calloc(1, 320);
|
||||
if (msg != NULL) {
|
||||
sprintf(msg,
|
||||
"Exceeding range of permissible write addresses (%d >= %d)",
|
||||
start, d->media_lba_limit);
|
||||
libdax_msgs_submit(libdax_messenger, d->global_index,
|
||||
libdax_msgs_submit(libdax_messenger, d->global_index,
|
||||
0x0002012d,
|
||||
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
|
||||
msg, 0, 0);
|
||||
strcpy(msg, "CDB= ");
|
||||
if (spc_human_readable_cmd(c, msg + strlen(msg),
|
||||
320 - strlen(msg), 1) > 0) {
|
||||
libdax_msgs_submit(libdax_messenger,
|
||||
d->global_index, 0x0002012d,
|
||||
LIBDAX_MSGS_SEV_FATAL,
|
||||
LIBDAX_MSGS_PRIO_HIGH,
|
||||
msg, 0, 0);
|
||||
}
|
||||
free(msg);
|
||||
}
|
||||
d->cancel = 1; /* No need for mutexing because atomic */
|
||||
|
@ -1054,7 +1076,7 @@ fprintf(stderr, "libburn_DEBUG: buffer sectors= %d bytes= %d\n",
|
|||
*/
|
||||
if (d->current_profile == 0x14 && d->write_opts != NULL &&
|
||||
(d->progress.buffer_capacity == 0 ||
|
||||
start < (int) d->progress.buffer_capacity / 2048) &&
|
||||
start < (off_t) d->progress.buffer_capacity / 2048) &&
|
||||
key == 5 && asc == 0x64 && ascq == 0) {
|
||||
if (d->write_opts->write_type == BURN_WRITE_TAO) {
|
||||
d->was_feat21h_failure = 1 + (start == 0);
|
||||
|
@ -1095,10 +1117,11 @@ int mmc_fake_toc_entry(struct burn_toc_entry *entry, int session_number,
|
|||
unsigned char *size_data, unsigned char *start_data,
|
||||
unsigned char *last_adr_data)
|
||||
{
|
||||
int min, sec, frames, num;
|
||||
int min, sec, frames;
|
||||
unsigned int num;
|
||||
|
||||
/* mark DVD extensions and Track Info extension as valid */
|
||||
entry->extensions_valid |= (1 | 2);
|
||||
/* mark extensions as valid: DVD, Track Info, Long block address */
|
||||
entry->extensions_valid |= (1 | 2 | 8);
|
||||
|
||||
/* defaults are as of mmc5r03.pdf 6.26.3.2.4 Fabricated TOC */
|
||||
entry->session = session_number & 0xff;
|
||||
|
@ -1108,9 +1131,16 @@ int mmc_fake_toc_entry(struct burn_toc_entry *entry, int session_number,
|
|||
entry->tno = 0;
|
||||
entry->point = track_number & 0xff;
|
||||
entry->point_msb = (track_number >> 8) & 0xff;
|
||||
num = mmc_four_char_to_int(size_data);
|
||||
entry->track_blocks = num;
|
||||
burn_lba_to_msf(num, &min, &sec, &frames);
|
||||
num = mmc_four_char_to_uint(size_data);
|
||||
if (num < 0x80000000) {
|
||||
entry->track_blocks = num;
|
||||
burn_lba_to_msf(num, &min, &sec, &frames);
|
||||
} else {
|
||||
entry->track_blocks = -1;
|
||||
min = 477218; /* ~=LBA 0x7fffffff */
|
||||
sec = frames = 0;
|
||||
}
|
||||
entry->long_track_blocks = num;
|
||||
if (min > 255) {
|
||||
min = 255;
|
||||
sec = 255;
|
||||
|
@ -1120,9 +1150,16 @@ int mmc_fake_toc_entry(struct burn_toc_entry *entry, int session_number,
|
|||
entry->sec = sec;
|
||||
entry->frame = frames;
|
||||
entry->zero = 0;
|
||||
num = mmc_four_char_to_int(start_data);
|
||||
entry->start_lba = num;
|
||||
burn_lba_to_msf(num, &min, &sec, &frames);
|
||||
num = mmc_four_char_to_uint(start_data);
|
||||
if (num < 0x80000000) {
|
||||
entry->start_lba = num;
|
||||
burn_lba_to_msf(num, &min, &sec, &frames);
|
||||
} else {
|
||||
entry->start_lba = -1;
|
||||
min = 477218;
|
||||
sec = frames = 0;
|
||||
}
|
||||
entry->long_start_lba = num;
|
||||
if (min > 255) {
|
||||
min = 255;
|
||||
sec = 255;
|
||||
|
@ -1131,7 +1168,13 @@ int mmc_fake_toc_entry(struct burn_toc_entry *entry, int session_number,
|
|||
entry->pmin = min;
|
||||
entry->psec = sec;
|
||||
entry->pframe = frames;
|
||||
entry->last_recorded_address = mmc_four_char_to_int(last_adr_data);
|
||||
num = mmc_four_char_to_uint(last_adr_data);
|
||||
if (num < 0x80000000) {
|
||||
entry->last_recorded_address = num;
|
||||
} else {
|
||||
entry->last_recorded_address = -1;
|
||||
}
|
||||
entry->long_last_rec_adr = num;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -1145,7 +1188,7 @@ static int mmc_read_toc_fmt0_al(struct burn_drive *d, int *alloc_len)
|
|||
struct buffer *buf = NULL;
|
||||
struct command *c = NULL;
|
||||
int dlen, i, old_alloc_len, session_number, prev_session = -1, ret;
|
||||
int lba, size;
|
||||
unsigned int lba, size;
|
||||
unsigned char *tdata, size_data[4], start_data[4], end_data[4];
|
||||
|
||||
if (*alloc_len < 4)
|
||||
|
@ -1224,11 +1267,11 @@ err_ex:;
|
|||
if (session_number != prev_session && prev_session > 0) {
|
||||
/* leadout entry previous session */
|
||||
entry = &(d->toc_entry[(i - 1) + prev_session]);
|
||||
lba = mmc_four_char_to_int(start_data) +
|
||||
mmc_four_char_to_int(size_data);
|
||||
mmc_int_to_four_char(start_data, lba);
|
||||
mmc_int_to_four_char(size_data, 0);
|
||||
mmc_int_to_four_char(end_data, lba - 1);
|
||||
lba = mmc_four_char_to_uint(start_data) +
|
||||
mmc_four_char_to_uint(size_data);
|
||||
mmc_uint_to_four_char(start_data, lba);
|
||||
mmc_uint_to_four_char(size_data, 0);
|
||||
mmc_uint_to_four_char(end_data, lba - 1);
|
||||
mmc_fake_toc_entry(entry, prev_session, 0xA2,
|
||||
size_data, start_data, end_data);
|
||||
entry->min= entry->sec= entry->frame= 0;
|
||||
|
@ -1253,11 +1296,11 @@ err_ex:;
|
|||
memcpy(start_data, tdata + 4, 4);
|
||||
/* size_data are estimated from next track start */
|
||||
memcpy(size_data, tdata + 8 + 4, 4);
|
||||
mmc_int_to_four_char(end_data,
|
||||
mmc_four_char_to_int(size_data) - 1);
|
||||
size = mmc_four_char_to_int(size_data) -
|
||||
mmc_four_char_to_int(start_data);
|
||||
mmc_int_to_four_char(size_data, size);
|
||||
mmc_uint_to_four_char(end_data,
|
||||
mmc_four_char_to_uint(size_data) - 1);
|
||||
size = mmc_four_char_to_uint(size_data) -
|
||||
mmc_four_char_to_uint(start_data);
|
||||
mmc_uint_to_four_char(size_data, size);
|
||||
mmc_fake_toc_entry(entry, session_number, i + 1,
|
||||
size_data, start_data, end_data);
|
||||
if (prev_session != session_number)
|
||||
|
@ -1270,9 +1313,9 @@ err_ex:;
|
|||
tdata = c->page->data + 4 + d->last_track_no * 8;
|
||||
entry = &(d->toc_entry[(d->last_track_no - 1) + prev_session]);
|
||||
memcpy(start_data, tdata + 4, 4);
|
||||
mmc_int_to_four_char(size_data, 0);
|
||||
mmc_int_to_four_char(end_data,
|
||||
mmc_four_char_to_int(start_data) - 1);
|
||||
mmc_uint_to_four_char(size_data, 0);
|
||||
mmc_uint_to_four_char(end_data,
|
||||
mmc_four_char_to_uint(start_data) - 1);
|
||||
mmc_fake_toc_entry(entry, prev_session, 0xA2,
|
||||
size_data, start_data, end_data);
|
||||
entry->min= entry->sec= entry->frame= 0;
|
||||
|
@ -1309,7 +1352,8 @@ int mmc_fake_toc(struct burn_drive *d)
|
|||
struct burn_session *session;
|
||||
struct burn_toc_entry *entry;
|
||||
struct buffer *buf = NULL;
|
||||
int i, session_number, prev_session = -1, ret, lba, alloc_len = 34;
|
||||
int i, session_number, prev_session = -1, ret, alloc_len = 34;
|
||||
unsigned int lba;
|
||||
unsigned char *tdata, size_data[4], start_data[4], end_data[4];
|
||||
char *msg = NULL;
|
||||
|
||||
|
@ -1414,11 +1458,11 @@ int mmc_fake_toc(struct burn_drive *d)
|
|||
if (session_number != prev_session && prev_session > 0) {
|
||||
/* leadout entry previous session */
|
||||
entry = &(d->toc_entry[(i - 1) + prev_session]);
|
||||
lba = mmc_four_char_to_int(start_data) +
|
||||
mmc_four_char_to_int(size_data);
|
||||
mmc_int_to_four_char(start_data, lba);
|
||||
mmc_int_to_four_char(size_data, 0);
|
||||
mmc_int_to_four_char(end_data, lba - 1);
|
||||
lba = mmc_four_char_to_uint(start_data) +
|
||||
mmc_four_char_to_uint(size_data);
|
||||
mmc_uint_to_four_char(start_data, lba);
|
||||
mmc_uint_to_four_char(size_data, 0);
|
||||
mmc_uint_to_four_char(end_data, lba - 1);
|
||||
mmc_fake_toc_entry(entry, prev_session, 0xA2,
|
||||
size_data, start_data, end_data);
|
||||
entry->min= entry->sec= entry->frame= 0;
|
||||
|
@ -1439,7 +1483,7 @@ int mmc_fake_toc(struct burn_drive *d)
|
|||
if (i == d->last_track_no - 1) {
|
||||
/* ts A70212 : Last track field Free Blocks */
|
||||
burn_drive_set_media_capacity_remaining(d,
|
||||
((off_t) mmc_four_char_to_int(tdata + 16)) *
|
||||
((off_t) mmc_four_char_to_uint(tdata + 16)) *
|
||||
((off_t) 2048));
|
||||
d->media_lba_limit = 0;
|
||||
}
|
||||
|
@ -1485,11 +1529,11 @@ int mmc_fake_toc(struct burn_drive *d)
|
|||
if (prev_session > 0 && prev_session <= d->disc->sessions) {
|
||||
/* leadout entry of last session of closed disc */
|
||||
entry = &(d->toc_entry[(d->last_track_no - 1) + prev_session]);
|
||||
lba = mmc_four_char_to_int(start_data) +
|
||||
mmc_four_char_to_int(size_data);
|
||||
mmc_int_to_four_char(start_data, lba);
|
||||
mmc_int_to_four_char(size_data, 0);
|
||||
mmc_int_to_four_char(end_data, lba - 1);
|
||||
lba = mmc_four_char_to_uint(start_data) +
|
||||
mmc_four_char_to_uint(size_data);
|
||||
mmc_uint_to_four_char(start_data, lba);
|
||||
mmc_uint_to_four_char(size_data, 0);
|
||||
mmc_uint_to_four_char(end_data, lba - 1);
|
||||
mmc_fake_toc_entry(entry, prev_session, 0xA2,
|
||||
size_data, start_data, end_data);
|
||||
entry->min= entry->sec= entry->frame= 0;
|
||||
|
@ -1581,7 +1625,7 @@ static int mmc_read_toc_al(struct burn_drive *d, int *alloc_len)
|
|||
|
||||
/* ts A61020 : this snaps on non-blank DVD media */
|
||||
/* ts A61106 : also snaps on CD with unclosed track/session */
|
||||
/* Very unsure wether this old measure is ok.
|
||||
/* Very unsure whether this old measure is ok.
|
||||
Obviously higher levels do not care about this.
|
||||
outdated info: DVD+RW burns go on after passing through here.
|
||||
|
||||
|
@ -1740,8 +1784,8 @@ static int mmc_read_toc_al(struct burn_drive *d, int *alloc_len)
|
|||
TOC format 2 always reports 2 blocks more than are readable.
|
||||
So here it is possible to check and mark as trusted.
|
||||
*/
|
||||
if (highest_leadout > 0 && d->media_read_capacity != 0x7fffffff &&
|
||||
!d->mr_capacity_trusted) {
|
||||
if (highest_leadout > 0 && d->media_read_capacity != 0x7fffffffffffffff
|
||||
&& !d->mr_capacity_trusted) {
|
||||
if (highest_leadout - 3 == d->media_read_capacity) {
|
||||
d->mr_capacity_trusted = 1;
|
||||
libdax_msgs_submit(libdax_messenger, d->global_index,
|
||||
|
@ -1782,12 +1826,12 @@ void mmc_read_toc(struct burn_drive *d)
|
|||
}
|
||||
|
||||
|
||||
/* ts A70131 : This tries to get the start of the last complete session */
|
||||
/* ts C40226 : long address reply version of mmc_read_multi_session_c1 */
|
||||
/* man mkisofs , option -C :
|
||||
The first number is the sector number of the first sector in
|
||||
the last session of the disk that should be appended to.
|
||||
*/
|
||||
int mmc_read_multi_session_c1(struct burn_drive *d, int *trackno, int *start)
|
||||
int mmc_read_msc1_long(struct burn_drive *d, int *trackno, off_t *start)
|
||||
{
|
||||
struct buffer *buf = NULL;
|
||||
struct command *c = NULL;
|
||||
|
@ -1820,7 +1864,11 @@ int mmc_read_multi_session_c1(struct burn_drive *d, int *trackno, int *start)
|
|||
continue;
|
||||
burn_track_get_entry(tracks[0], &toc_entry);
|
||||
if (toc_entry.extensions_valid & 1) { /* DVD extension valid */
|
||||
*start = toc_entry.start_lba;
|
||||
if (toc_entry.extensions_valid & 8) { /* Long adr */
|
||||
*start = toc_entry.long_start_lba;
|
||||
} else {
|
||||
*start = toc_entry.start_lba;
|
||||
}
|
||||
*trackno = (toc_entry.point_msb << 8)| toc_entry.point;
|
||||
} else {
|
||||
*start = burn_msf_to_lba(toc_entry.pmin,
|
||||
|
@ -1855,7 +1903,7 @@ inquire_drive:;
|
|||
|
||||
tdata = c->page->data + 4;
|
||||
*trackno = tdata[2];
|
||||
*start = mmc_four_char_to_int(tdata + 4);
|
||||
*start = mmc_four_char_to_uint(tdata + 4);
|
||||
ret = 1;
|
||||
ex:;
|
||||
BURN_FREE_MEM(buf);
|
||||
|
@ -1864,6 +1912,24 @@ ex:;
|
|||
}
|
||||
|
||||
|
||||
/* ts A70131 : This tries to get the start of the last complete session */
|
||||
int mmc_read_multi_session_c1(struct burn_drive *d, int *trackno, int *start)
|
||||
{
|
||||
int ret;
|
||||
off_t num;
|
||||
|
||||
ret = mmc_read_msc1_long(d, trackno, &num);
|
||||
if (ret <= 0)
|
||||
return ret;
|
||||
if(num >= 0x80000000) {
|
||||
*start = 0x7fffffff;
|
||||
return 0;
|
||||
}
|
||||
*start = num;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* ts A61201 */
|
||||
char *mmc_obtain_profile_name(int profile_number)
|
||||
{
|
||||
|
@ -1959,7 +2025,7 @@ static int mmc_read_disc_info_al(struct burn_drive *d, int *alloc_len)
|
|||
d->media_lba_limit = 0;
|
||||
|
||||
/* ts A81210 */
|
||||
d->media_read_capacity = 0x7fffffff;
|
||||
d->media_read_capacity = 0x7fffffffffffffff;
|
||||
d->mr_capacity_trusted = -1;
|
||||
|
||||
/* ts A61202 */
|
||||
|
@ -2635,7 +2701,7 @@ int mmc_read_cd(struct burn_drive *d, int start, int len,
|
|||
int sec_type, int main_ch,
|
||||
const struct burn_read_opts *o, struct buffer *buf, int flag)
|
||||
{
|
||||
int temp, req, ret, dap_bit;
|
||||
int temp, req, ret, dap_bit, len_shift;
|
||||
int subcodes_audio = 0, subcodes_data = 0;
|
||||
struct command *c;
|
||||
|
||||
|
@ -2674,6 +2740,9 @@ int mmc_read_cd(struct burn_drive *d, int start, int len,
|
|||
}
|
||||
|
||||
scsi_init_command(c, MMC_READ_CD, sizeof(MMC_READ_CD));
|
||||
/* (this was never tested with anything but sec_type = 1 = CD-DA) */
|
||||
if(sec_type == 1 && main_ch == 0x10)
|
||||
c->dxfer_len = len * 2352;
|
||||
c->retry = 1;
|
||||
c->opcode[1] = ((sec_type & 7) << 2) | ((!!dap_bit) << 1);
|
||||
temp = start;
|
||||
|
@ -2684,11 +2753,12 @@ int mmc_read_cd(struct burn_drive *d, int start, int len,
|
|||
c->opcode[3] = temp & 0xFF;
|
||||
temp >>= 8;
|
||||
c->opcode[2] = temp & 0xFF;
|
||||
c->opcode[8] = len & 0xFF;
|
||||
len >>= 8;
|
||||
c->opcode[7] = len & 0xFF;
|
||||
len >>= 8;
|
||||
c->opcode[6] = len & 0xFF;
|
||||
len_shift = len;
|
||||
c->opcode[8] = len_shift & 0xFF;
|
||||
len_shift >>= 8;
|
||||
c->opcode[7] = len_shift & 0xFF;
|
||||
len_shift >>= 8;
|
||||
c->opcode[6] = len_shift & 0xFF;
|
||||
req = main_ch & 0xf8;
|
||||
|
||||
#ifdef Libburn_mmc_report_recovereD
|
||||
|
@ -2832,6 +2902,8 @@ int mmc_set_streaming(struct burn_drive *d,
|
|||
pd = c->page->data;
|
||||
|
||||
pd[0] = 0; /* WRC=0 (Default Rotation Control), RDD=Exact=RA=0 */
|
||||
if (d->set_streaming_exact_bit)
|
||||
pd[0] |= 2; /* Exact= 1 */
|
||||
|
||||
if (w_speed == 0)
|
||||
w_speed = 0x10000000; /* ~ 2 TB/s */
|
||||
|
@ -2849,8 +2921,9 @@ int mmc_set_streaming(struct burn_drive *d,
|
|||
} else
|
||||
eff_end_lba = end_lba;
|
||||
|
||||
sprintf(msg, "mmc_set_streaming: end_lba=%d , r=%d , w=%d",
|
||||
eff_end_lba, r_speed, w_speed);
|
||||
sprintf(msg,
|
||||
"mmc_set_streaming: end_lba=%d , r=%d , w=%d , exact=%d",
|
||||
eff_end_lba, r_speed, w_speed, !!(pd[0] & 2));
|
||||
libdax_msgs_submit(libdax_messenger, d->global_index, 0x00000002,
|
||||
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_ZERO,
|
||||
msg, 0, 0);
|
||||
|
@ -2886,6 +2959,8 @@ int mmc_set_streaming(struct burn_drive *d,
|
|||
LIBDAX_MSGS_SEV_DEBUG : LIBDAX_MSGS_SEV_SORRY,
|
||||
LIBDAX_MSGS_PRIO_HIGH, msg, 0, 0);
|
||||
}
|
||||
if (key != 0)
|
||||
d->set_streaming_err = 1;
|
||||
{ret = 0; goto ex;}
|
||||
}
|
||||
ret = 1;
|
||||
|
@ -2963,8 +3038,8 @@ void mmc_set_speed(struct burn_drive *d, int r, int w)
|
|||
|
||||
/* ts A61221 : try to set DVD speed via command B6h */
|
||||
if (strstr(d->current_profile_text, "DVD") == d->current_profile_text
|
||||
||
|
||||
strstr(d->current_profile_text, "BD") == d->current_profile_text) {
|
||||
|| strstr(d->current_profile_text, "BD") == d->current_profile_text
|
||||
|| d->set_streaming_exact_bit) {
|
||||
ret = mmc_set_streaming(d, r, w, end_lba);
|
||||
if (ret != 0)
|
||||
return; /* success or really fatal failure */
|
||||
|
@ -3642,7 +3717,7 @@ int mmc_read_buffer_capacity(struct burn_drive *d)
|
|||
d->pessimistic_buffer_free = d->progress.buffer_available;
|
||||
d->pbf_altered = 0;
|
||||
if (d->progress.buffered_bytes >= d->progress.buffer_capacity){
|
||||
double fill;
|
||||
off_t fill;
|
||||
|
||||
fill = d->progress.buffer_capacity
|
||||
- d->progress.buffer_available;
|
||||
|
@ -3660,7 +3735,7 @@ ex:;
|
|||
/* ts A61219 : learned much from dvd+rw-tools-7.0: plus_rw_format()
|
||||
and mmc5r03c.pdf, 6.5 FORMAT UNIT */
|
||||
/*
|
||||
@param size The size (in bytes) to be sent with the FORMAT comand
|
||||
@param size The size (in bytes) to be sent with the FORMAT command
|
||||
@param flag bit1+2: size mode
|
||||
0 = use parameter size as far as it makes sense
|
||||
1 = insist in size 0 even if there is a better default known
|
||||
|
@ -3715,7 +3790,7 @@ int mmc_format_unit(struct burn_drive *d, off_t size, int flag)
|
|||
num_of_blocks = size / 2048;
|
||||
mmc_int_to_four_char(c->page->data + 4, num_of_blocks);
|
||||
|
||||
if (flag & 128) { /* explicitely chosen format descriptor */
|
||||
if (flag & 128) { /* explicitly chosen format descriptor */
|
||||
/* use case: the app knows what to do */
|
||||
|
||||
ret = mmc_read_format_capacities(d, -1);
|
||||
|
@ -4902,7 +4977,7 @@ int mmc_read_capacity(struct burn_drive *d)
|
|||
|
||||
BURN_ALLOC_MEM(buf, struct buffer, 1);
|
||||
BURN_ALLOC_MEM(c, struct command, 1);
|
||||
d->media_read_capacity = 0x7fffffff;
|
||||
d->media_read_capacity = 0x7fffffffffffffff;
|
||||
d->mr_capacity_trusted = -1;
|
||||
mmc_start_if_needed(d, 1);
|
||||
if (mmc_function_spy(d, "mmc_read_capacity") <= 0)
|
||||
|
@ -4916,11 +4991,7 @@ int mmc_read_capacity(struct burn_drive *d)
|
|||
c->page->sectors = 0;
|
||||
c->dir = FROM_DRIVE;
|
||||
d->issue_command(d, c);
|
||||
d->media_read_capacity = mmc_four_char_to_int(c->page->data);
|
||||
if (d->media_read_capacity < 0) {
|
||||
d->media_read_capacity = 0x7fffffff;
|
||||
{ret = 0; goto ex;}
|
||||
}
|
||||
d->media_read_capacity = mmc_four_char_to_uint(c->page->data);
|
||||
if (d->current_profile >= 0x08 && d->current_profile <= 0x0A)
|
||||
d->mr_capacity_trusted = 0;
|
||||
else
|
||||
|
@ -5440,7 +5511,7 @@ int mmc_setup_drive(struct burn_drive *d)
|
|||
d->last_track_no = 1;
|
||||
d->media_capacity_remaining = 0;
|
||||
d->media_lba_limit = 0;
|
||||
d->media_read_capacity = 0x7fffffff;
|
||||
d->media_read_capacity = 0x7fffffffffffffff;
|
||||
d->mr_capacity_trusted = 0;
|
||||
d->pessimistic_buffer_free = 0;
|
||||
d->pbf_altered = 0;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||
|
||||
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
|
||||
Copyright (c) 2006 - 2014 Thomas Schmitt <scdbackup@gmx.net>
|
||||
Copyright (c) 2006 - 2024 Thomas Schmitt <scdbackup@gmx.net>
|
||||
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_get_event(struct burn_drive *);
|
||||
int mmc_write(struct burn_drive *, int start, struct buffer *buf);
|
||||
int mmc_write(struct burn_drive *, off_t 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_load(struct burn_drive *);
|
||||
|
@ -78,6 +78,8 @@ int mmc_compose_mode_page_5(struct burn_drive *d,
|
|||
|
||||
/* ts A70201 */
|
||||
int mmc_four_char_to_int(unsigned char *data);
|
||||
/* ts C40226 */
|
||||
unsigned int mmc_four_char_to_uint(unsigned char *data);
|
||||
|
||||
/* ts A70201 :
|
||||
Common track info fetcher for mmc_get_nwa() and mmc_fake_toc()
|
||||
|
|
|
@ -55,6 +55,7 @@ struct burn_write_opts *burn_write_opts_new(struct burn_drive *drive)
|
|||
opts->obs_pad = 0;
|
||||
#endif
|
||||
|
||||
opts->bdr_obs_exempt = 0;
|
||||
opts->start_byte = -1;
|
||||
opts->fill_up_media = 0;
|
||||
opts->force_is_set = 0;
|
||||
|
@ -535,17 +536,25 @@ void burn_write_opts_set_obs_pad(struct burn_write_opts *opts, int pad)
|
|||
}
|
||||
|
||||
|
||||
/* ts A91115: API */
|
||||
void burn_write_opts_set_stdio_fsync(struct burn_write_opts *opts, int rythm)
|
||||
/* ts C10909: API */
|
||||
void burn_write_opts_set_bdr_obs_exempt(struct burn_write_opts *opts,
|
||||
int value)
|
||||
{
|
||||
if (rythm == -1)
|
||||
opts->bdr_obs_exempt = !!value;
|
||||
}
|
||||
|
||||
|
||||
/* ts A91115: API */
|
||||
void burn_write_opts_set_stdio_fsync(struct burn_write_opts *opts, int rhythm)
|
||||
{
|
||||
if (rhythm == -1)
|
||||
opts->stdio_fsync_size = -1; /* never */
|
||||
else if (rythm == 0)
|
||||
else if (rhythm == 0)
|
||||
opts->stdio_fsync_size = Libburn_stdio_fsync_limiT;
|
||||
else if (rythm == 1)
|
||||
else if (rhythm == 1)
|
||||
opts->stdio_fsync_size = 0; /* only at end of writing */
|
||||
else if (rythm >= 32)
|
||||
opts->stdio_fsync_size = rythm;
|
||||
else if (rhythm >= 32)
|
||||
opts->stdio_fsync_size = rhythm;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -46,14 +46,17 @@ struct burn_write_opts
|
|||
2 indicates burn_write_opts_set_obs_pad(,1)
|
||||
*/
|
||||
|
||||
/* 1= do not apply obs_pad=1 to BD-R if not stream recording. */
|
||||
int bdr_obs_exempt;
|
||||
|
||||
/* ts A61222 : Start address for media which offer a choice */
|
||||
off_t start_byte;
|
||||
|
||||
/* ts A70213 : Wether to fill up the available space on media */
|
||||
/* ts A70213 : Whether to fill up the available space on media */
|
||||
int fill_up_media;
|
||||
|
||||
/* ts A70303 : Wether to override conformance checks:
|
||||
- the check wether CD write+block type is supported by the drive
|
||||
/* ts A70303 : Whether to override conformance checks:
|
||||
- the check whether CD write+block type is supported by the drive
|
||||
*/
|
||||
int force_is_set;
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||
|
||||
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
|
||||
Copyright (c) 2006 - 2014 Thomas Schmitt <scdbackup@gmx.net>
|
||||
Copyright (c) 2006 - 2024 Thomas Schmitt <scdbackup@gmx.net>
|
||||
Provided under GPL version 2 or later.
|
||||
*/
|
||||
|
||||
|
@ -286,7 +286,7 @@ void burn_packet_process(struct burn_drive *d, unsigned char *data,
|
|||
*//* write(o->datafd, data, 2352); */
|
||||
}
|
||||
|
||||
/* so yeah, when you uncomment these, make them write zeros insted of crap
|
||||
/* so yeah, when you uncomment these, make them write zeros instead of crap
|
||||
static void write_empty_sector(int fd)
|
||||
{
|
||||
static char sec[2352], initialized = 0;
|
||||
|
@ -492,13 +492,13 @@ int burn_read_data(struct burn_drive *d, off_t byte_address,
|
|||
msg, 0, 0);
|
||||
{ret = 0; goto ex;}
|
||||
}
|
||||
if (d->media_read_capacity != 0x7fffffff && byte_address >=
|
||||
((off_t) d->media_read_capacity + (off_t) 1) * (off_t) 2048) {
|
||||
if (d->media_read_capacity != 0x7fffffffffffffff &&
|
||||
byte_address >= (d->media_read_capacity + 1) * (off_t) 2048) {
|
||||
if (!(flag & 2)) {
|
||||
sprintf(msg,
|
||||
"Read start address %ds larger than number of readable blocks %d",
|
||||
(int) (byte_address / 2048 + !!(byte_address % 2048)),
|
||||
d->media_read_capacity + 1);
|
||||
"Read start address %.fs larger than number of readable blocks %.f",
|
||||
(double) (byte_address / 2048 + !!(byte_address % 2048)),
|
||||
(double) (d->media_read_capacity + 1));
|
||||
libdax_msgs_submit(libdax_messenger, d->global_index,
|
||||
0x00020172, (flag & 32) ?
|
||||
LIBDAX_MSGS_SEV_DEBUG : LIBDAX_MSGS_SEV_SORRY,
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||
|
||||
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
|
||||
Copyright (c) 2006 - 2016 Thomas Schmitt <scdbackup@gmx.net>
|
||||
Copyright (c) 2006 - 2021 Thomas Schmitt <scdbackup@gmx.net>
|
||||
Provided under GPL version 2 or later.
|
||||
*/
|
||||
|
||||
|
@ -193,7 +193,9 @@ static void get_bytes(struct burn_track *track, int count, unsigned char *data)
|
|||
off_t missing, inp_block_size, track_blocks;
|
||||
|
||||
inp_block_size = burn_sector_length(track->mode);
|
||||
track_blocks = burn_track_get_sectors_2(track, 1);
|
||||
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,
|
||||
"Premature end of input encountered. Missing: %.f bytes",
|
||||
|
@ -923,7 +925,7 @@ void process_q(struct burn_drive *d, unsigned char *q)
|
|||
break;
|
||||
default:
|
||||
|
||||
/* ts A61009 : if reactivated then witout Assert */
|
||||
/* ts A61009 : if reactivated then without Assert */
|
||||
a ssert(0);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -144,7 +144,7 @@ int scsi_enumerate_drives(void)
|
|||
}
|
||||
|
||||
|
||||
/** Tells wether 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
|
||||
it is time to give up usage and reservation.
|
||||
*/
|
||||
|
@ -180,7 +180,7 @@ int sg_release(struct burn_drive *d)
|
|||
}
|
||||
|
||||
|
||||
/** Sends a SCSI command to the drive, receives reply and evaluates wether
|
||||
/** 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
|
||||
|
@ -213,7 +213,7 @@ int sg_obtain_scsi_adr(char *path, int *bus_no, int *host_no, int *channel_no,
|
|||
}
|
||||
|
||||
|
||||
/** Tells wether a text is a persistent address as listed by the enumeration
|
||||
/** Tells whether a text is a persistent address as listed by the enumeration
|
||||
functions.
|
||||
*/
|
||||
int sg_is_enumerable_adr(char *adr)
|
||||
|
|
|
@ -47,8 +47,8 @@ sg_initialize() performs global initialization of the SCSI transport
|
|||
facilities. Checks for compatibility of supporting
|
||||
software components.
|
||||
|
||||
sg_shutdown() performs global finalizations and releases golbally
|
||||
aquired resources.
|
||||
sg_shutdown() performs global finalizations and releases globally
|
||||
acquired resources.
|
||||
|
||||
sg_give_next_adr() iterates over the set of potentially useful drive
|
||||
address strings.
|
||||
|
@ -57,10 +57,10 @@ scsi_enumerate_drives() brings all available, not-whitelist-banned, and
|
|||
accessible drives into libburn's list of drives.
|
||||
|
||||
sg_dispose_drive() finalizes adapter specifics of struct burn_drive
|
||||
on destruction. Releases resources which were aquired
|
||||
on destruction. Releases resources which were acquired
|
||||
underneath scsi_enumerate_drives().
|
||||
|
||||
sg_drive_is_open() tells wether libburn has the given drive in use.
|
||||
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.
|
||||
|
@ -68,7 +68,7 @@ sg_grab() opens the drive for SCSI commands and ensures
|
|||
sg_release() closes a drive opened by sg_grab()
|
||||
|
||||
sg_issue_command() sends a SCSI command to the drive, receives reply,
|
||||
and evaluates wether the command succeeded or shall
|
||||
and evaluates whether the command succeeded or shall
|
||||
be retried or finally failed.
|
||||
|
||||
sg_obtain_scsi_adr() tries to obtain SCSI address parameters.
|
||||
|
@ -307,7 +307,7 @@ int sg_initialize(char msg[1024], int flag)
|
|||
|
||||
|
||||
/** Performs global finalization of the SCSI transport adapter and eventually
|
||||
needed operating system facilities. Releases globally aquired resources.
|
||||
needed operating system facilities. Releases globally acquired resources.
|
||||
@param flag unused yet, submit 0
|
||||
@return 1 = success, <=0 = failure
|
||||
*/
|
||||
|
@ -444,7 +444,7 @@ int scsi_enumerate_drives(void)
|
|||
}
|
||||
|
||||
|
||||
/** Tells wether 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
|
||||
it is time to give up usage and reservation.
|
||||
*/
|
||||
|
@ -485,7 +485,7 @@ int sg_grab(struct burn_drive *d)
|
|||
}
|
||||
|
||||
|
||||
/** PORTING: Is mainly about the call to sg_close_drive() and wether it
|
||||
/** 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.
|
||||
|
@ -500,7 +500,7 @@ int sg_release(struct burn_drive *d)
|
|||
}
|
||||
|
||||
|
||||
/** Sends a SCSI command to the drive, receives reply and evaluates wether
|
||||
/** 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
|
||||
|
@ -647,7 +647,7 @@ int sg_obtain_scsi_adr(char *path, int *bus_no, int *host_no, int *channel_no,
|
|||
}
|
||||
|
||||
|
||||
/** Tells wether a text is a persistent address as listed by the enumeration
|
||||
/** Tells whether a text is a persistent address as listed by the enumeration
|
||||
functions.
|
||||
*/
|
||||
int sg_is_enumerable_adr(char* adr)
|
||||
|
|
|
@ -44,7 +44,7 @@ sg_initialize() performs global initialization of the SCSI transport
|
|||
facilities. Checks for compatibility of supporting
|
||||
software components.
|
||||
|
||||
sg_shutdown() performs global finalizations and releases golbally
|
||||
sg_shutdown() performs global finalizations and releases globally
|
||||
acquired resources.
|
||||
|
||||
sg_give_next_adr() iterates over the set of potentially useful drive
|
||||
|
@ -57,7 +57,7 @@ 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 wether libburn has the given drive in use.
|
||||
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.
|
||||
|
@ -65,7 +65,7 @@ sg_grab() opens the drive for SCSI commands and ensures
|
|||
sg_release() closes a drive opened by sg_grab()
|
||||
|
||||
sg_issue_command() sends a SCSI command to the drive, receives reply,
|
||||
and evaluates wether the command succeeded or shall
|
||||
and evaluates whether the command succeeded or shall
|
||||
be retried or finally failed.
|
||||
|
||||
sg_obtain_scsi_adr() tries to obtain SCSI address parameters.
|
||||
|
@ -609,7 +609,7 @@ int sg_release(struct burn_drive *d)
|
|||
}
|
||||
|
||||
|
||||
/** Sends a SCSI command to the drive, receives reply and evaluates wether
|
||||
/** 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
|
||||
|
@ -768,7 +768,7 @@ int sg_obtain_scsi_adr(char *path, int *bus_no, int *host_no, int *channel_no,
|
|||
}
|
||||
|
||||
|
||||
/** Tells wether a text is a persistent address as listed by the enumeration
|
||||
/** Tells whether a text is a persistent address as listed by the enumeration
|
||||
functions.
|
||||
*/
|
||||
int sg_is_enumerable_adr(char* adr)
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||
|
||||
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
|
||||
Copyright (c) 2006 - 2019 Thomas Schmitt <scdbackup@gmx.net>
|
||||
Copyright (c) 2006 - 2020 Thomas Schmitt <scdbackup@gmx.net>
|
||||
Provided under GPL version 2 or later.
|
||||
*/
|
||||
|
||||
|
@ -50,7 +50,7 @@ sg_initialize() performs global initialization of the SCSI transport
|
|||
facilities. Checks for compatibility of supporting
|
||||
software components.
|
||||
|
||||
sg_shutdown() performs global finalizations and releases golbally
|
||||
sg_shutdown() performs global finalizations and releases globally
|
||||
acquired resources.
|
||||
|
||||
sg_give_next_adr() iterates over the set of potentially useful drive
|
||||
|
@ -63,7 +63,7 @@ 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 wether libburn has the given drive in use.
|
||||
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.
|
||||
|
@ -71,7 +71,7 @@ sg_grab() opens the drive for SCSI commands and ensures
|
|||
sg_release() closes a drive opened by sg_grab()
|
||||
|
||||
sg_issue_command() sends a SCSI command to the drive, receives reply,
|
||||
and evaluates wether the command succeeded or shall
|
||||
and evaluates whether the command succeeded or shall
|
||||
be retried or finally failed.
|
||||
|
||||
sg_obtain_scsi_adr() tries to obtain SCSI address parameters.
|
||||
|
@ -111,6 +111,15 @@ Hint: You should also look into sg-freebsd-port.c, which is a younger and
|
|||
|
||||
/** PORTING : ------- OS dependent headers and definitions ------ */
|
||||
|
||||
#ifdef Libburn_read_o_direcT
|
||||
/* ts B91124:
|
||||
DISABLED, because this spoils multi-track burning of cdrskin by a hard to
|
||||
fix bug in cdrskin/cdrfifo.c
|
||||
DO NOT ENABLE before the wait code in that source file is fixed.
|
||||
*/
|
||||
#undef Libburn_read_o_direcT
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef Libburn_read_o_direcT
|
||||
# ifndef _GNU_SOURCE
|
||||
|
@ -216,7 +225,7 @@ static char linux_ata_device_family[80] = {"/dev/hd%c"};
|
|||
|
||||
/* Set this to 1 in order to get on stderr messages from ata_enumerate()
|
||||
*/
|
||||
static int linux_ata_enumerate_verbous = 0;
|
||||
static int linux_ata_enumerate_verbose = 0;
|
||||
|
||||
|
||||
/** PORTING : ------ libburn portable headers and definitions ----- */
|
||||
|
@ -287,7 +296,7 @@ int mmc_function_spy(struct burn_drive *d, char * text);
|
|||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
/* ts A70413 */
|
||||
/* This finds out wether the software is running on kernel >= 2.6
|
||||
/* This finds out whether the software is running on kernel >= 2.6
|
||||
*/
|
||||
static void sg_evaluate_kernel(void)
|
||||
{
|
||||
|
@ -305,7 +314,7 @@ static void sg_evaluate_kernel(void)
|
|||
|
||||
|
||||
/* ts A70314 */
|
||||
/* This installs the device file family if one was chosen explicitely
|
||||
/* This installs the device file family if one was chosen explicitly
|
||||
by burn_preset_device_open()
|
||||
*/
|
||||
static void sg_select_device_family(void)
|
||||
|
@ -374,11 +383,16 @@ static int sg_exchange_scd_for_sr(char *fname, int flag)
|
|||
/* This is an early stage version of scsi_log_cmd.
|
||||
>>> It will become obsolete when the /tmp file handler is moved into
|
||||
>>> scsi_log_command().
|
||||
@param flag bit0= data direction is FROM_DRIVE
|
||||
*/
|
||||
static int sgio_log_cmd(unsigned char *cmd, int cmd_len, FILE *fp_in, int flag)
|
||||
{
|
||||
FILE *fp = fp_in;
|
||||
int ret = 0;
|
||||
int data_dir = NO_TRANSFER;
|
||||
|
||||
if (flag & 1)
|
||||
data_dir = FROM_DRIVE;
|
||||
|
||||
/* >>> ts B11110 : move this into scsi_log_command() */
|
||||
if (fp == NULL && (burn_sg_log_scsi & 1)) {
|
||||
|
@ -389,10 +403,13 @@ static int sgio_log_cmd(unsigned char *cmd, int cmd_len, FILE *fp_in, int flag)
|
|||
}
|
||||
|
||||
if (fp != NULL)
|
||||
ret = scsi_log_command(cmd, cmd_len, NO_TRANSFER, NULL, 0,
|
||||
ret = scsi_log_command(cmd, cmd_len, data_dir, NULL, 0,
|
||||
fp, flag);
|
||||
if (fp_in == NULL && fp != NULL)
|
||||
fclose(fp);
|
||||
if (fp == stderr || !(burn_sg_log_scsi & 2))
|
||||
return ret;
|
||||
ret = scsi_log_command(cmd, cmd_len, data_dir, NULL, 0, stderr, 0);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -464,7 +481,7 @@ static int sgio_inquiry_cd_drive(int fd, char *fname)
|
|||
s.dxfer_len = 36;
|
||||
s.usr_ptr = NULL;
|
||||
|
||||
sgio_log_cmd(s.cmdp, s.cmd_len, NULL, 0);
|
||||
sgio_log_cmd(s.cmdp, s.cmd_len, NULL, 1);
|
||||
|
||||
c_start_time = burn_get_time(0);
|
||||
ret = ioctl(fd, SG_IO, &s);
|
||||
|
@ -650,7 +667,7 @@ ex:;
|
|||
So libburn will by default use open(O_EXCL) first and afterwards
|
||||
as second assertion will use fcntl(F_SETLK). One lock more should not harm.
|
||||
*/
|
||||
static int sg_fcntl_lock(int *fd, char *fd_name, int l_type, int verbous)
|
||||
static int sg_fcntl_lock(int *fd, char *fd_name, int l_type, int verbose)
|
||||
{
|
||||
struct flock lockthing;
|
||||
char msg[81];
|
||||
|
@ -671,7 +688,7 @@ static int sg_fcntl_lock(int *fd, char *fd_name, int l_type, int verbous)
|
|||
|
||||
ret = fcntl(*fd, F_SETLK, &lockthing);
|
||||
if (ret == -1) {
|
||||
if (verbous) {
|
||||
if (verbose) {
|
||||
sprintf(msg, "Device busy. Failed to fcntl-lock '%s'",
|
||||
fd_name);
|
||||
libdax_msgs_submit(libdax_messenger, -1, 0x00020008,
|
||||
|
@ -803,6 +820,88 @@ static int sg_release_siblings(int sibling_fds[],
|
|||
}
|
||||
|
||||
|
||||
/* ts C00806 */
|
||||
/** Urges the operating system to re-assess drive and medium state
|
||||
*/
|
||||
static int sg_os_revalidate_disc(struct burn_drive *d)
|
||||
{
|
||||
|
||||
#ifdef Libburn_use_linux_ioctl_simul_changE
|
||||
|
||||
/* <<< only for compiler tests */
|
||||
#ifndef CDROM_SIMUL_CHANGE
|
||||
/* # def ine CDROM_SIMUL_CHANGE 0x5332 */
|
||||
#endif
|
||||
|
||||
#ifdef CDROM_SIMUL_CHANGE
|
||||
|
||||
int fd, ret;
|
||||
long old_blocks, new_blocks;
|
||||
char *msg = NULL;
|
||||
|
||||
BURN_ALLOC_MEM(msg, char, 161);
|
||||
|
||||
ret = ioctl(d->fd, BLKGETSIZE, &old_blocks);
|
||||
if (ret == -1)
|
||||
old_blocks = -1;
|
||||
|
||||
/* Schedule a simulated medium change event.
|
||||
Although the implemented ioctl cannot fail, the kernel might be too
|
||||
old to know it and then throw errors like ENOTTY.
|
||||
*/
|
||||
ret = ioctl(d->fd, CDROM_SIMUL_CHANGE, 0);
|
||||
if (ret == -1) {
|
||||
libdax_msgs_submit(libdax_messenger, d->global_index,
|
||||
0x02, LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH,
|
||||
"ioctl(CDROM_SIMUL_CHANGE) failed", errno, 0);
|
||||
ret = 0; goto ex;
|
||||
}
|
||||
libdax_msgs_submit(libdax_messenger, d->global_index,
|
||||
0x02, LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH,
|
||||
"ioctl(CDROM_SIMUL_CHANGE) was performed", 0, 0);
|
||||
/* Try to trigger actual device assessment by a open(2) call */
|
||||
fd = open(d->devname, O_RDONLY | O_NDELAY);
|
||||
if (fd == -1) {
|
||||
libdax_msgs_submit(libdax_messenger, d->global_index,
|
||||
0x02, LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH,
|
||||
"Failed to open device file after ioctl(CDROM_SIMUL_CHANGE)",
|
||||
errno, 0);
|
||||
ret = 0; goto ex;
|
||||
}
|
||||
close(fd);
|
||||
ret = ioctl(d->fd, BLKGETSIZE, &new_blocks);
|
||||
if (ret == -1) {
|
||||
libdax_msgs_submit(libdax_messenger, d->global_index,
|
||||
0x02, LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH,
|
||||
"BLKGETSIZE failed after ioctl(CDROM_SIMUL_CHANGE)",
|
||||
errno, 0);
|
||||
} else if (old_blocks != new_blocks) {
|
||||
sprintf(msg,
|
||||
"BLKGETSIZE indicates size change from %ld to %ld blocks",
|
||||
old_blocks , new_blocks);
|
||||
libdax_msgs_submit(libdax_messenger, d->global_index,
|
||||
0x02, LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH,
|
||||
msg, 0, 0);
|
||||
}
|
||||
ex:
|
||||
BURN_FREE_MEM(msg);
|
||||
return ret;
|
||||
|
||||
#else /* CDROM_SIMUL_CHANGE */
|
||||
|
||||
return 0;
|
||||
|
||||
#endif /* ! CDROM_SIMUL_CHANGE */
|
||||
|
||||
#else /* Libburn_use_linux_ioctl_simul_changE */
|
||||
|
||||
return 0;
|
||||
|
||||
#endif /* ! Libburn_use_linux_ioctl_simul_changE */
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* ts A60926 */
|
||||
static int sg_close_drive(struct burn_drive *d)
|
||||
{
|
||||
|
@ -812,6 +911,9 @@ static int sg_close_drive(struct burn_drive *d)
|
|||
return 0;
|
||||
sg_release_siblings(d->sibling_fds, d->sibling_fnames,
|
||||
&(d->sibling_count));
|
||||
if(d->medium_state_changed > 0)
|
||||
sg_os_revalidate_disc(d);
|
||||
d->medium_state_changed = -1;
|
||||
ret = sg_close_drive_fd(d->devname, d->global_index, &(d->fd), 0);
|
||||
return ret;
|
||||
}
|
||||
|
@ -919,7 +1021,7 @@ static int is_ata_drive(char *fname, int fd_in)
|
|||
else
|
||||
fd = sg_open_drive_fd(fname, 1);
|
||||
if (fd == -1) {
|
||||
if (linux_ata_enumerate_verbous)
|
||||
if (linux_ata_enumerate_verbose)
|
||||
fprintf(stderr,"open failed, errno=%d '%s'\n",
|
||||
errno, strerror(errno));
|
||||
return 0;
|
||||
|
@ -930,7 +1032,7 @@ static int is_ata_drive(char *fname, int fd_in)
|
|||
|
||||
/* not atapi */
|
||||
if (!(tm.config & 0x8000) || (tm.config & 0x4000)) {
|
||||
if (linux_ata_enumerate_verbous)
|
||||
if (linux_ata_enumerate_verbose)
|
||||
fprintf(stderr, "not marked as ATAPI\n");
|
||||
if (fd_in < 0)
|
||||
sg_close_drive_fd(fname, -1, &fd, 0);
|
||||
|
@ -940,7 +1042,7 @@ static int is_ata_drive(char *fname, int fd_in)
|
|||
/* if SG_IO fails on an atapi device, we should stop trying to
|
||||
use hd* devices */
|
||||
if (sgio_test(fd) == -1) {
|
||||
if (linux_ata_enumerate_verbous)
|
||||
if (linux_ata_enumerate_verbose)
|
||||
fprintf(stderr,
|
||||
"FATAL: sgio_test() failed: errno=%d '%s'\n",
|
||||
errno, strerror(errno));
|
||||
|
@ -951,7 +1053,7 @@ static int is_ata_drive(char *fname, int fd_in)
|
|||
if (fd_in >= 0)
|
||||
return 1;
|
||||
if (sg_close_drive_fd(fname, -1, &fd, 1) <= 0) {
|
||||
if (linux_ata_enumerate_verbous)
|
||||
if (linux_ata_enumerate_verbose)
|
||||
fprintf(stderr,
|
||||
"cannot close properly, errno=%d '%s'\n",
|
||||
errno, strerror(errno));
|
||||
|
@ -1097,7 +1199,7 @@ static int sg_open_for_enumeration(char *fname, int flag)
|
|||
|
||||
fd = sg_open_drive_fd(fname, 1 + (flag & 1));
|
||||
if (fd < 0) {
|
||||
if (linux_sg_enumerate_debug || linux_ata_enumerate_verbous)
|
||||
if (linux_sg_enumerate_debug || linux_ata_enumerate_verbose)
|
||||
fprintf(stderr, "open failed, errno=%d '%s'\n",
|
||||
errno, strerror(errno));
|
||||
return -1;
|
||||
|
@ -1113,7 +1215,7 @@ static void ata_enumerate(void)
|
|||
int ret, i, fd = -1;
|
||||
char fname[10];
|
||||
|
||||
if (linux_ata_enumerate_verbous)
|
||||
if (linux_ata_enumerate_verbose)
|
||||
fprintf(stderr, "libburn_debug: linux_ata_device_family = %s\n",
|
||||
linux_ata_device_family);
|
||||
|
||||
|
@ -1122,12 +1224,12 @@ static void ata_enumerate(void)
|
|||
|
||||
for (i = 0; i < 26; i++) {
|
||||
sprintf(fname, linux_ata_device_family, 'a' + i);
|
||||
if (linux_ata_enumerate_verbous)
|
||||
if (linux_ata_enumerate_verbose)
|
||||
fprintf(stderr, "libburn_debug: %s : ", fname);
|
||||
|
||||
/* ts A51221 */
|
||||
if (burn_drive_is_banned(fname)) {
|
||||
if (linux_ata_enumerate_verbous)
|
||||
if (linux_ata_enumerate_verbose)
|
||||
fprintf(stderr, "not in whitelist\n");
|
||||
continue;
|
||||
}
|
||||
|
@ -1139,7 +1241,7 @@ static void ata_enumerate(void)
|
|||
break;
|
||||
if (ret == 0)
|
||||
continue;
|
||||
if (linux_ata_enumerate_verbous)
|
||||
if (linux_ata_enumerate_verbose)
|
||||
fprintf(stderr, "accepting as drive without SCSI address\n");
|
||||
enumerate_common(fname, fd, -1, -1, -1, -1, -1);
|
||||
}
|
||||
|
@ -1667,7 +1769,7 @@ int scsi_enumerate_drives(void)
|
|||
}
|
||||
|
||||
|
||||
/** Tells wether 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
|
||||
it is time to give up usage and reservation.
|
||||
*/
|
||||
|
@ -1722,7 +1824,7 @@ int sg_grab(struct burn_drive *d)
|
|||
/* ts A60813 - A60822
|
||||
After enumeration the drive fd is probably still open.
|
||||
-1337 is the initial value of burn_drive.fd and the value after
|
||||
relase of drive. Unclear why not the official error return
|
||||
release of drive. Unclear why not the official error return
|
||||
value -1 of open(2) war used. */
|
||||
if(! burn_drive_is_open(d)) {
|
||||
char msg[120];
|
||||
|
@ -1847,7 +1949,7 @@ drive_is_in_use:;
|
|||
}
|
||||
|
||||
|
||||
/** PORTING: Is mainly about the call to sg_close_drive() and wether it
|
||||
/** 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.
|
||||
|
@ -2045,7 +2147,7 @@ static void react_on_drive_loss(struct burn_drive *d, struct command *c,
|
|||
scsi_log_message(d, fp, "--- SG_IO: Gave up connection to drive", 0);
|
||||
}
|
||||
|
||||
/** Sends a SCSI command to the drive, receives reply and evaluates wether
|
||||
/** 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
|
||||
|
@ -2276,7 +2378,7 @@ static int sg_obtain_scsi_adr_fd(char *path, int fd_in,
|
|||
};
|
||||
struct my_scsi_idlun idlun;
|
||||
|
||||
/* valgrind called idlun unitialized because it is blind for ioctl */
|
||||
/* valgrind called idlun uninitialized because it is blind for ioctl */
|
||||
idlun.x = 0;
|
||||
idlun.host_unique_id = 0;
|
||||
|
||||
|
@ -2345,7 +2447,7 @@ int sg_obtain_scsi_adr(char *path, int *bus_no, int *host_no, int *channel_no,
|
|||
|
||||
|
||||
/* ts A60922 ticket 33 : called from drive.c */
|
||||
/** Tells wether a text is a persistent address as listed by the enumeration
|
||||
/** Tells whether a text is a persistent address as listed by the enumeration
|
||||
functions.
|
||||
*/
|
||||
int sg_is_enumerable_adr(char *adr)
|
||||
|
|
|
@ -51,7 +51,7 @@ sg_initialize() performs global initialization of the SCSI transport
|
|||
facilities. Checks for compatibility of supporting
|
||||
software components.
|
||||
|
||||
sg_shutdown() performs global finalizations and releases golbally
|
||||
sg_shutdown() performs global finalizations and releases globally
|
||||
acquired resources.
|
||||
|
||||
sg_give_next_adr() iterates over the set of potentially useful drive
|
||||
|
@ -64,7 +64,7 @@ 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 wether libburn has the given drive in use.
|
||||
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.
|
||||
|
@ -72,7 +72,7 @@ sg_grab() opens the drive for SCSI commands and ensures
|
|||
sg_release() closes a drive opened by sg_grab()
|
||||
|
||||
sg_issue_command() sends a SCSI command to the drive, receives reply,
|
||||
and evaluates wether the command succeeded or shall
|
||||
and evaluates whether the command succeeded or shall
|
||||
be retried or finally failed.
|
||||
|
||||
sg_obtain_scsi_adr() tries to obtain SCSI address parameters.
|
||||
|
@ -525,7 +525,7 @@ int sg_release(struct burn_drive *d)
|
|||
}
|
||||
|
||||
|
||||
/** Sends a SCSI command to the drive, receives reply and evaluates wether
|
||||
/** 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
|
||||
|
@ -721,7 +721,7 @@ ex:;
|
|||
}
|
||||
|
||||
|
||||
/** Tells wether a text is a persistent address as listed by the enumeration
|
||||
/** Tells whether a text is a persistent address as listed by the enumeration
|
||||
functions.
|
||||
*/
|
||||
int sg_is_enumerable_adr(char* adr)
|
||||
|
|
|
@ -44,7 +44,7 @@ sg_initialize() performs global initialization of the SCSI transport
|
|||
facilities. Checks for compatibility of supporting
|
||||
software components.
|
||||
|
||||
sg_shutdown() performs global finalizations and releases golbally
|
||||
sg_shutdown() performs global finalizations and releases globally
|
||||
acquired resources.
|
||||
|
||||
sg_give_next_adr() iterates over the set of potentially useful drive
|
||||
|
@ -57,7 +57,7 @@ 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 wether libburn has the given drive in use.
|
||||
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.
|
||||
|
@ -65,7 +65,7 @@ sg_grab() opens the drive for SCSI commands and ensures
|
|||
sg_release() closes a drive opened by sg_grab()
|
||||
|
||||
sg_issue_command() sends a SCSI command to the drive, receives reply,
|
||||
and evaluates wether the command succeeded or shall
|
||||
and evaluates whether the command succeeded or shall
|
||||
be retried or finally failed.
|
||||
|
||||
sg_obtain_scsi_adr() tries to obtain SCSI address parameters.
|
||||
|
@ -690,7 +690,7 @@ int sg_release(struct burn_drive *d)
|
|||
}
|
||||
|
||||
|
||||
/** Sends a SCSI command to the drive, receives reply and evaluates wether
|
||||
/** 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
|
||||
|
@ -837,7 +837,7 @@ int sg_obtain_scsi_adr(char *path, int *bus_no, int *host_no, int *channel_no,
|
|||
}
|
||||
|
||||
|
||||
/** Tells wether a text is a persistent address as listed by the enumeration
|
||||
/** Tells whether a text is a persistent address as listed by the enumeration
|
||||
functions.
|
||||
*/
|
||||
|
||||
|
|
|
@ -195,8 +195,8 @@ int spc_wait_unit_attention(struct burn_drive *d, int max_sec, char *cmd_text,
|
|||
*/
|
||||
break;
|
||||
}
|
||||
if (key == 0x6 && asc == 0x28 && ascq == 0x00)
|
||||
/* media change notice = try again */
|
||||
if (key == 0x6 && asc == 0x28)
|
||||
/* medium change notice or alike = try again */
|
||||
goto slumber;
|
||||
|
||||
handle_error:;
|
||||
|
@ -1056,7 +1056,7 @@ void spc_probe_write_modes(struct burn_drive *d)
|
|||
struct buffer *buf = NULL;
|
||||
int try_write_type = 1;
|
||||
int try_block_type = 0;
|
||||
int key, asc, ascq, useable_write_type = -1, useable_block_type = -1;
|
||||
int key, asc, ascq, usable_write_type = -1, usable_block_type = -1;
|
||||
int last_try = 0;
|
||||
struct command *c = NULL;
|
||||
|
||||
|
@ -1071,11 +1071,11 @@ void spc_probe_write_modes(struct burn_drive *d)
|
|||
while (try_write_type != 5) {
|
||||
/* ts A70213 */
|
||||
if (try_write_type == 4) {
|
||||
/* Pseudo write type NONE . Set a useable write mode */
|
||||
if (useable_write_type == -1)
|
||||
/* Pseudo write type NONE . Set a usable write mode */
|
||||
if (usable_write_type == -1)
|
||||
break;
|
||||
try_write_type = useable_write_type;
|
||||
try_block_type = useable_block_type;
|
||||
try_write_type = usable_write_type;
|
||||
try_block_type = usable_block_type;
|
||||
last_try= 1;
|
||||
}
|
||||
|
||||
|
@ -1118,12 +1118,12 @@ void spc_probe_write_modes(struct burn_drive *d)
|
|||
1 << try_block_type;
|
||||
|
||||
/* ts A70213 */
|
||||
if ((useable_write_type < 0 && try_write_type > 0) ||
|
||||
if ((usable_write_type < 0 && try_write_type > 0) ||
|
||||
(try_write_type == 1 && try_block_type == 8)) {
|
||||
/* Packet is not supported yet.
|
||||
Prefer TAO MODE_1. */
|
||||
useable_write_type = try_write_type;
|
||||
useable_block_type = try_block_type;
|
||||
usable_write_type = try_write_type;
|
||||
usable_block_type = try_block_type;
|
||||
}
|
||||
}
|
||||
switch (try_block_type) {
|
||||
|
@ -1446,8 +1446,15 @@ enum response scsi_error_msg(struct burn_drive *d, unsigned char *sense,
|
|||
case 0x28:
|
||||
if (*ascq == 0)
|
||||
sprintf(msg, "Medium may have changed");
|
||||
else if (*ascq == 1)
|
||||
sprintf(msg, "Import or export element accessed");
|
||||
else if (*ascq == 2)
|
||||
sprintf(msg, "Format layer may have changed");
|
||||
else if (*ascq == 3)
|
||||
sprintf(msg,
|
||||
"Import/export element accessed, medium changed");
|
||||
else if (*key == 6)
|
||||
sprintf(msg, "Unknown ASCQ with drive event ASC 28");
|
||||
else
|
||||
break;
|
||||
goto return_retry;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
|
||||
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
|
||||
Copyright (c) 2006 - 2014 Thomas Schmitt <scdbackup@gmx.net>
|
||||
Copyright (c) 2006 - 2021 Thomas Schmitt <scdbackup@gmx.net>
|
||||
Provided under GPL version 2 or later.
|
||||
*/
|
||||
|
||||
|
@ -34,6 +34,7 @@
|
|||
#include "util.h"
|
||||
#include "transport.h"
|
||||
#include "mmc.h"
|
||||
#include "drive.h"
|
||||
|
||||
#include "libdax_msgs.h"
|
||||
extern struct libdax_msgs *libdax_messenger;
|
||||
|
@ -319,8 +320,8 @@ void burn_structure_print_track(struct burn_track *t)
|
|||
{
|
||||
char msg[80];
|
||||
|
||||
sprintf(msg, " track size %d sectors",
|
||||
burn_track_get_sectors(t));
|
||||
sprintf(msg, " track size %.f sectors",
|
||||
(double) burn_track_get_sectors_v2(t));
|
||||
libdax_msgs_submit(libdax_messenger, -1, 0x00000002,
|
||||
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH,
|
||||
msg, 0, 0);
|
||||
|
@ -506,14 +507,14 @@ int burn_track_set_postgap_size(struct burn_track *t, int size, int flag)
|
|||
return 1;
|
||||
}
|
||||
|
||||
/* ts B20119: outsourced from burn_track_get_sectors()
|
||||
/* ts B20119 / C40302: outsourced from burn_track_get_sectors()
|
||||
@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)
|
||||
{
|
||||
/* ts A70125 : was int */
|
||||
off_t size = 0;
|
||||
int sectors, seclen;
|
||||
off_t size = 0, sectors;
|
||||
int seclen;
|
||||
|
||||
seclen = burn_sector_length(t->mode);
|
||||
|
||||
|
@ -529,9 +530,23 @@ int burn_track_get_sectors_2(struct burn_track *t, int flag)
|
|||
} else if(t->entry != NULL) {
|
||||
/* ts A80808 : all burn_toc_entry of track starts should now
|
||||
have (extensions_valid & 1), even those from CD.
|
||||
ts C40302 : Now there should be long_track_blocks.
|
||||
*/
|
||||
if (t->entry->extensions_valid & 1)
|
||||
if (t->entry->extensions_valid & 8) {
|
||||
size = t->entry->long_track_blocks * (off_t) 2048;
|
||||
} else if (t->entry->extensions_valid & 1) {
|
||||
size = ((off_t) t->entry->track_blocks) * (off_t) 2048;
|
||||
}
|
||||
}
|
||||
if (size > BURN_DRIVE_MAX_BYTES) {
|
||||
char msg[80];
|
||||
|
||||
sprintf(msg, "Track size exceeds limit of %.f bytes",
|
||||
(double) (BURN_DRIVE_MAX_BYTES));
|
||||
libdax_msgs_submit(libdax_messenger, -1, 0x000201ae,
|
||||
LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH,
|
||||
msg, 0, 0);
|
||||
return -1;
|
||||
}
|
||||
sectors = size / seclen;
|
||||
if (size % seclen)
|
||||
|
@ -539,14 +554,34 @@ int burn_track_get_sectors_2(struct burn_track *t, int flag)
|
|||
return sectors;
|
||||
}
|
||||
|
||||
int burn_track_get_sectors_2(struct burn_track *t, int flag)
|
||||
{
|
||||
/* ts A70125 : was int */
|
||||
off_t sectors = 0;
|
||||
|
||||
sectors = burn_track_get_sectors_2_v2(t, flag);
|
||||
if (sectors > (off_t) 0x7ffffff0) {
|
||||
libdax_msgs_submit(libdax_messenger, -1, 0x000201ae,
|
||||
LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH,
|
||||
"Track size exceeds 4 TiB - 32 KiB", 0, 0);
|
||||
return -1;
|
||||
}
|
||||
return (int) sectors;
|
||||
}
|
||||
|
||||
int burn_track_get_sectors(struct burn_track *t)
|
||||
{
|
||||
return burn_track_get_sectors_2(t, 0);
|
||||
}
|
||||
|
||||
/* ts C40302 : API */
|
||||
off_t burn_track_get_sectors_v2(struct burn_track *t)
|
||||
{
|
||||
return burn_track_get_sectors_2_v2(t, 0);
|
||||
}
|
||||
|
||||
/* ts A70125 */
|
||||
int burn_track_set_sectors(struct burn_track *t, int sectors)
|
||||
int burn_track_set_sectors(struct burn_track *t, off_t sectors)
|
||||
{
|
||||
off_t size, seclen;
|
||||
int ret;
|
||||
|
@ -589,17 +624,29 @@ int burn_track_set_fillup(struct burn_track *t, int fill_up_media)
|
|||
*/
|
||||
int burn_track_apply_fillup(struct burn_track *t, off_t max_size, int flag)
|
||||
{
|
||||
int max_sectors, ret = 2;
|
||||
int ret = 2;
|
||||
off_t max_sectors, track_sectors;
|
||||
char msg[80];
|
||||
|
||||
if (t->fill_up_media <= 0)
|
||||
return 2;
|
||||
if (max_size > BURN_DRIVE_MAX_BYTES) {
|
||||
sprintf(msg, "Track size exceeds limit of %.f bytes",
|
||||
(double) (BURN_DRIVE_MAX_BYTES));
|
||||
libdax_msgs_submit(libdax_messenger, -1, 0x000201ae,
|
||||
LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH,
|
||||
msg, 0, 0);
|
||||
return 0;
|
||||
}
|
||||
max_sectors = max_size / 2048;
|
||||
if (burn_track_get_sectors(t) < max_sectors || (flag & 1)) {
|
||||
sprintf(msg, "Setting total track size to %ds (payload %ds)\n",
|
||||
max_sectors & 0x7fffffff,
|
||||
(int) ((t->source->get_size(t->source) / 2048)
|
||||
& 0x7fffffff));
|
||||
track_sectors = burn_track_get_sectors_v2(t);
|
||||
if (track_sectors < 0)
|
||||
return 0;
|
||||
if (track_sectors < max_sectors || (flag & 1)) {
|
||||
sprintf(msg,
|
||||
"Setting total track size to %.fs (payload %.fs)\n",
|
||||
(double) max_sectors,
|
||||
(double) (t->source->get_size(t->source) / 2048));
|
||||
libdax_msgs_submit(libdax_messenger, -1, 0x00000002,
|
||||
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_ZERO,
|
||||
msg, 0, 0);
|
||||
|
@ -653,7 +700,7 @@ int burn_track_is_data_done(struct burn_track *t)
|
|||
|
||||
int burn_track_get_shortage(struct burn_track *t)
|
||||
{
|
||||
int size;
|
||||
off_t size;
|
||||
int seclen;
|
||||
|
||||
seclen = burn_sector_length(t->mode);
|
||||
|
@ -665,13 +712,31 @@ int burn_track_get_shortage(struct burn_track *t)
|
|||
|
||||
int burn_session_get_sectors(struct burn_session *s)
|
||||
{
|
||||
int sectors = 0, i;
|
||||
int sectors = 0, i, track_sectors;
|
||||
|
||||
for (i = 0; i < s->tracks; i++)
|
||||
sectors += burn_track_get_sectors(s->track[i]);
|
||||
for (i = 0; i < s->tracks; i++) {
|
||||
track_sectors = burn_track_get_sectors(s->track[i]);
|
||||
if (track_sectors < 0)
|
||||
track_sectors = 0;
|
||||
sectors += track_sectors;
|
||||
}
|
||||
return sectors;
|
||||
}
|
||||
|
||||
/* ts C40302: API */
|
||||
off_t burn_session_get_sectors_v2(struct burn_session *s)
|
||||
{
|
||||
int i;
|
||||
off_t sectors = 0, track_sectors;
|
||||
|
||||
for (i = 0; i < s->tracks; i++) {
|
||||
track_sectors = burn_track_get_sectors_v2(s->track[i]);
|
||||
if (track_sectors < 0)
|
||||
track_sectors = 0;
|
||||
sectors += track_sectors;
|
||||
}
|
||||
return sectors;
|
||||
}
|
||||
|
||||
int burn_disc_get_sectors(struct burn_disc *d)
|
||||
{
|
||||
|
@ -682,6 +747,17 @@ int burn_disc_get_sectors(struct burn_disc *d)
|
|||
return sectors;
|
||||
}
|
||||
|
||||
/* ts C40302: API */
|
||||
off_t burn_disc_get_sectors_v2(struct burn_disc *d)
|
||||
{
|
||||
int i;
|
||||
off_t sectors = 0;
|
||||
|
||||
for (i = 0; i < d->sessions; i++)
|
||||
sectors += burn_session_get_sectors_v2(d->session[i]);
|
||||
return sectors;
|
||||
}
|
||||
|
||||
void burn_track_get_entry(struct burn_track *t, struct burn_toc_entry *entry)
|
||||
{
|
||||
if (t->entry == NULL)
|
||||
|
@ -749,7 +825,7 @@ int burn_session_get_hidefirst(struct burn_session *session)
|
|||
}
|
||||
|
||||
|
||||
/* ts A80808 : Enhance CD toc to DVD toc */
|
||||
/* ts A80808,C40226 : Enhance CD toc to DVD toc with Long block addresses */
|
||||
int burn_disc_cd_toc_extensions(struct burn_drive *drive, int flag)
|
||||
{
|
||||
int sidx= 0, tidx= 0, ret, track_offset, alloc_len = 34;
|
||||
|
@ -817,6 +893,7 @@ int burn_disc_cd_toc_extensions(struct burn_drive *drive, int flag)
|
|||
entry->point_msb = 0;
|
||||
entry->start_lba = burn_msf_to_lba(entry->pmin,
|
||||
entry->psec, entry->pframe);
|
||||
entry->long_start_lba = entry->start_lba;
|
||||
if (tidx > 0) {
|
||||
prev_entry->track_blocks =
|
||||
entry->start_lba
|
||||
|
@ -836,13 +913,16 @@ int burn_disc_cd_toc_extensions(struct burn_drive *drive, int flag)
|
|||
ret < prev_entry->track_blocks - 2))
|
||||
prev_entry->track_blocks = ret;
|
||||
}
|
||||
prev_entry->extensions_valid |= 1;
|
||||
prev_entry->long_track_blocks =
|
||||
prev_entry->track_blocks;
|
||||
prev_entry->extensions_valid |= 1 | 8;
|
||||
}
|
||||
if (tidx == d->session[sidx]->tracks) {
|
||||
entry->session_msb = 0;
|
||||
entry->point_msb = 0;
|
||||
entry->track_blocks = 0;
|
||||
entry->extensions_valid |= 1;
|
||||
entry->long_track_blocks = entry->track_blocks;
|
||||
entry->extensions_valid |= 1 | 8;
|
||||
}
|
||||
prev_entry = entry;
|
||||
}
|
||||
|
|
|
@ -53,7 +53,7 @@ struct burn_track
|
|||
/** 1 means Pad with zeros, 0 means start reading the next track */
|
||||
int pad;
|
||||
|
||||
/* ts A70213 : wether to expand this track to full available media */
|
||||
/* ts A70213 : whether to expand this track to full available media */
|
||||
int fill_up_media;
|
||||
|
||||
/* ts A70218 : a track size to use if it is mandarory to have some */
|
||||
|
@ -137,7 +137,7 @@ struct burn_session
|
|||
unsigned char cdtext_language[8];
|
||||
|
||||
/* ts B11226 */
|
||||
unsigned char mediacatalog[14]; /* overrideable by burn_write_opts */
|
||||
unsigned char mediacatalog[14]; /* overridable by burn_write_opts */
|
||||
};
|
||||
|
||||
struct burn_disc
|
||||
|
@ -160,7 +160,7 @@ int burn_track_is_open_ended(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 */
|
||||
int burn_track_set_sectors(struct burn_track *t, int sectors);
|
||||
int burn_track_set_sectors(struct burn_track *t, off_t sectors);
|
||||
|
||||
/* ts A70218 : sets the payload size alone */
|
||||
int burn_track_set_size(struct burn_track *t, off_t size);
|
||||
|
@ -185,6 +185,7 @@ void burn_cdtext_free(struct burn_cdtext **cdtext);
|
|||
/* @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 */
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||
|
||||
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
|
||||
Copyright (c) 2006 - 2016 Thomas Schmitt <scdbackup@gmx.net>
|
||||
Copyright (c) 2006 - 2024 Thomas Schmitt <scdbackup@gmx.net>
|
||||
Provided under GPL version 2 or later.
|
||||
*/
|
||||
|
||||
|
@ -277,7 +277,7 @@ struct burn_drive
|
|||
(which could need closing after write) */
|
||||
int needs_close_session;
|
||||
/* ts A71003 : whether a random write operation was done and no
|
||||
synchronize chache has happened yet */
|
||||
synchronize cache has happened yet */
|
||||
int needs_sync_cache;
|
||||
|
||||
/* ts A80412 : whether to use WRITE12 with Streaming bit set
|
||||
|
@ -335,7 +335,7 @@ struct burn_drive
|
|||
|
||||
int stdio_fd;
|
||||
|
||||
int nwa; /* next writeable address */
|
||||
off_t nwa; /* next writeable address */
|
||||
int alba; /* absolute lba */
|
||||
int rlba; /* relative lba in section */
|
||||
int start_lba;
|
||||
|
@ -371,19 +371,21 @@ struct burn_drive
|
|||
/* ts A70215 : if > 0 : first lba on media that is too high for write*/
|
||||
int media_lba_limit;
|
||||
|
||||
/* ts A81210 : Upper limit of readable data size,
|
||||
0x7fffffff = unknown
|
||||
0x7ffffff0 = 32 bit overflow, or unknown stdio size
|
||||
/* ts A81210 / C40303 : Upper limit of readable data size,
|
||||
0x7fffffffffffffff = unknown
|
||||
BURN_DRIVE_MAX_BYTES / 2048 = possibly truncated
|
||||
or unknown stdio size
|
||||
*/
|
||||
int media_read_capacity;
|
||||
off_t media_read_capacity;
|
||||
|
||||
/* ts B60305 : Whether READ CAPACITY of CD is credible:
|
||||
-1= no READ CAPACITY yet , 0= untrusted READ CAPACITY
|
||||
1= READ CAPACITY confirmed or corrected by other commands
|
||||
*/
|
||||
int mr_capacity_trusted;
|
||||
|
||||
/* ts B10314 : Next Writeable Address for drive_role == 5 */
|
||||
int role_5_nwa;
|
||||
/* ts B10314 / C40302 : Next Writeable Address for drive_role == 5 */
|
||||
off_t role_5_nwa;
|
||||
|
||||
/* ts B60730 */
|
||||
int do_no_immed;
|
||||
|
@ -392,7 +394,7 @@ struct burn_drive
|
|||
struct burn_disc *disc; /* disc structure */
|
||||
int block_types[4];
|
||||
struct buffer *buffer;
|
||||
struct burn_progress progress;
|
||||
struct burn_progress_v2 progress;
|
||||
|
||||
/* 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
|
||||
|
@ -438,6 +440,17 @@ struct burn_drive
|
|||
/* 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 */
|
||||
int (*grab) (struct burn_drive *);
|
||||
int (*release) (struct burn_drive *);
|
||||
|
@ -454,7 +467,7 @@ struct burn_drive
|
|||
/* ts A61021 */
|
||||
void (*read_atip) (struct burn_drive *);
|
||||
|
||||
int (*write) (struct burn_drive *, int, struct buffer *);
|
||||
int (*write) (struct burn_drive *, off_t, struct buffer *);
|
||||
void (*read_toc) (struct burn_drive *);
|
||||
void (*lock) (struct burn_drive *);
|
||||
void (*unlock) (struct burn_drive *);
|
||||
|
|
173
libburn/write.c
173
libburn/write.c
|
@ -1,7 +1,7 @@
|
|||
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
||||
|
||||
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
|
||||
Copyright (c) 2006 - 2017 Thomas Schmitt <scdbackup@gmx.net>
|
||||
Copyright (c) 2006 - 2024 Thomas Schmitt <scdbackup@gmx.net>
|
||||
Provided under GPL version 2 or later.
|
||||
*/
|
||||
|
||||
|
@ -630,11 +630,13 @@ struct cue_sheet *burn_create_toc_entries(struct burn_write_opts *o,
|
|||
track length.
|
||||
*/
|
||||
track_length = burn_track_get_sectors_2(tar[i], 1);
|
||||
if (track_length < 0)
|
||||
goto failed;
|
||||
if (track_length < 300 && !burn_track_is_open_ended(tar[i])) {
|
||||
track_length = 300;
|
||||
if (!tar[i]->pad)
|
||||
tar[i]->pad = 1;
|
||||
burn_track_set_sectors(tar[i], track_length);
|
||||
burn_track_set_sectors(tar[i], (off_t) track_length);
|
||||
}
|
||||
|
||||
type_to_form(tar[i]->mode, &ctladr, &form);
|
||||
|
@ -723,7 +725,7 @@ struct cue_sheet *burn_create_toc_entries(struct burn_write_opts *o,
|
|||
runtime += 150;
|
||||
} else if (pform != form) {
|
||||
|
||||
/* ts A70121 : This seems to be thw wrong test. Correct would
|
||||
/* ts A70121 : This seems to be the wrong test. Correct would
|
||||
be to compare tar[]->mode or bit2 of ctladr.
|
||||
*/
|
||||
|
||||
|
@ -1025,7 +1027,7 @@ static int burn_write_leadin_cdtext(struct burn_write_opts *o,
|
|||
}
|
||||
#endif /* Libburn_debug_cd_texT */
|
||||
|
||||
err = d->write(d, write_lba, buf);
|
||||
err = d->write(d, (off_t) write_lba, buf);
|
||||
if (err == BE_CANCELLED)
|
||||
{ ret = 0; goto ex; }
|
||||
write_lba += sectors;
|
||||
|
@ -1072,10 +1074,10 @@ ex:;
|
|||
}
|
||||
|
||||
|
||||
/* ts A61218 : outsourced from burn_write_track() */
|
||||
/* ts A61218 / C40303 : outsourced from burn_write_track() */
|
||||
int burn_disc_init_track_status(struct burn_write_opts *o,
|
||||
struct burn_session *s, struct burn_track *t,
|
||||
int tnum, int sectors)
|
||||
int tnum, off_t sectors)
|
||||
{
|
||||
struct burn_drive *d = o->drive;
|
||||
|
||||
|
@ -1177,8 +1179,8 @@ int burn_write_track(struct burn_write_opts *o, struct burn_session *s,
|
|||
|
||||
/* <<< */
|
||||
sprintf(msg,
|
||||
"TAO pre-track %2.2d : get_nwa(%d)=%d, d=%d , demand=%.f , cap=%.f\n",
|
||||
tnum+1, nwa, ret, d->nwa,
|
||||
"TAO pre-track %2.2d : get_nwa(%d)=%d, d=%.f , demand=%.f , cap=%.f\n",
|
||||
tnum+1, nwa, ret, (double) d->nwa,
|
||||
(double) burn_track_get_sectors_2(t, 1) * 2048.0,
|
||||
(double) d->media_capacity_remaining);
|
||||
libdax_msgs_submit(libdax_messenger, d->global_index,
|
||||
|
@ -1203,9 +1205,11 @@ int burn_write_track(struct burn_write_opts *o, struct burn_session *s,
|
|||
/* user data */
|
||||
|
||||
sectors = burn_track_get_sectors_2(t, 1);
|
||||
if (sectors < 0)
|
||||
{ ret = 0; goto ex; }
|
||||
open_ended = burn_track_is_open_ended(t);
|
||||
|
||||
burn_disc_init_track_status(o, s, t, tnum, sectors);
|
||||
burn_disc_init_track_status(o, s, t, tnum, (off_t) sectors);
|
||||
|
||||
/* ts A61030 : this cannot happen. tnum is always < s->tracks */
|
||||
if (tnum == s->tracks)
|
||||
|
@ -1354,7 +1358,7 @@ int burn_disc_init_write_status(struct burn_write_opts *o,
|
|||
d->progress.buffer_capacity = 0;
|
||||
d->progress.buffer_available = 0;
|
||||
d->progress.buffered_bytes = 0;
|
||||
d->progress.buffer_min_fill = 0xffffffff;
|
||||
d->progress.buffer_min_fill = 0x7fffffffffffffff;
|
||||
|
||||
/* ts A70711 */
|
||||
d->pessimistic_buffer_free = 0;
|
||||
|
@ -1566,8 +1570,8 @@ int burn_disc_open_track_dvd_minus_r(struct burn_write_opts *o,
|
|||
d->send_write_parameters(d, NULL, -1, o);
|
||||
ret = d->get_nwa(d, -1, &lba, &nwa);
|
||||
sprintf(msg,
|
||||
"DVD pre-track %2.2d : get_nwa(%d), ret= %d , d->nwa= %d",
|
||||
tnum+1, nwa, ret, d->nwa);
|
||||
"DVD pre-track %2.2d : get_nwa(%d), ret= %d , d->nwa= %.f",
|
||||
tnum+1, nwa, ret, (double) d->nwa);
|
||||
libdax_msgs_submit(libdax_messenger, d->global_index, 0x00000002,
|
||||
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_ZERO, msg,0,0);
|
||||
if (nwa > d->nwa)
|
||||
|
@ -1591,6 +1595,8 @@ int burn_disc_open_track_dvd_minus_r(struct burn_write_opts *o,
|
|||
if (o->write_type == BURN_WRITE_SAO) { /* DAO */
|
||||
size = ((off_t) burn_track_get_sectors_2(s->track[tnum], 1))
|
||||
* (off_t) 2048;
|
||||
if (size < 0)
|
||||
{ret = 0; goto ex;}
|
||||
|
||||
/* Eventually round track size up to write chunk */
|
||||
if (o->obs_pad && (size % o->obs))
|
||||
|
@ -1626,8 +1632,8 @@ int burn_disc_open_track_dvd_plus_r(struct burn_write_opts *o,
|
|||
BURN_ALLOC_MEM(msg, char, 160);
|
||||
ret = d->get_nwa(d, -1, &lba, &nwa);
|
||||
sprintf(msg,
|
||||
"DVD+R pre-track %2.2d : get_nwa(%d), ret= %d , d->nwa= %d",
|
||||
tnum+1, nwa, ret, d->nwa);
|
||||
"DVD+R pre-track %2.2d : get_nwa(%d), ret= %d , d->nwa= %.f",
|
||||
tnum+1, nwa, ret, (double) d->nwa);
|
||||
libdax_msgs_submit(libdax_messenger, d->global_index, 0x00000002,
|
||||
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_ZERO, msg,0,0);
|
||||
if (nwa > d->nwa)
|
||||
|
@ -1640,6 +1646,8 @@ int burn_disc_open_track_dvd_plus_r(struct burn_write_opts *o,
|
|||
/* Reserve track */
|
||||
size = ((off_t) burn_track_get_sectors_2(s->track[tnum], 1))
|
||||
* (off_t) 2048;
|
||||
if (size < 0)
|
||||
{ret = 0; goto ex;}
|
||||
if (o->obs_pad) {
|
||||
/* Round track size up to write chunk size */
|
||||
/* o->obs should be 32k or 64k already. But 32k
|
||||
|
@ -1650,16 +1658,6 @@ int burn_disc_open_track_dvd_plus_r(struct burn_write_opts *o,
|
|||
size += (off_t) (o->obs - (size % o->obs));
|
||||
}
|
||||
|
||||
/* <<< Only for now until the first DVD+R succeeded */
|
||||
if (!o->obs_pad) {
|
||||
sprintf(msg, "Program error: encountered DVD+R without chunk padding");
|
||||
libdax_msgs_submit(libdax_messenger, d->global_index,
|
||||
0x00000004,
|
||||
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
|
||||
msg, 0, 0);
|
||||
{ret = 0; goto ex;}
|
||||
}
|
||||
|
||||
ret = d->reserve_track(d, size);
|
||||
if (ret <= 0) {
|
||||
sprintf(msg, "Cannot reserve track of %.f bytes",
|
||||
|
@ -1899,11 +1897,14 @@ int burn_dvd_write_track(struct burn_write_opts *o,
|
|||
struct buffer *out = d->buffer;
|
||||
int sectors;
|
||||
int i, open_ended = 0, ret= 0, is_flushed = 0, track_open = 0;
|
||||
int first_buf_cap = 0, further_cap = 0, buf_cap_step = 1024;
|
||||
off_t first_buf_cap = 0, further_cap = 0, buf_cap_step = 1024;
|
||||
|
||||
/* ts A70213 : eventually expand size of track to max */
|
||||
burn_track_apply_fillup(t, d->media_capacity_remaining, 0);
|
||||
|
||||
/* ts C00806 : Consider the track state changed by try to open */
|
||||
d->medium_state_changed = 1;
|
||||
|
||||
if (d->current_profile == 0x11 || d->current_profile == 0x14 ||
|
||||
d->current_profile == 0x15) {
|
||||
/* DVD-R, DVD-RW Sequential, DVD-R/DL Sequential */
|
||||
|
@ -1929,11 +1930,13 @@ int burn_dvd_write_track(struct burn_write_opts *o,
|
|||
track_open = 1;
|
||||
|
||||
sectors = burn_track_get_sectors_2(t, 1);
|
||||
if (sectors < 0)
|
||||
{ret = 0; goto ex;}
|
||||
open_ended = burn_track_is_open_ended(t);
|
||||
|
||||
/* (offset padding is done within sector_data()) */
|
||||
|
||||
burn_disc_init_track_status(o, s, t, tnum, sectors);
|
||||
burn_disc_init_track_status(o, s, t, tnum, (off_t) sectors);
|
||||
for (i = 0; open_ended || i < sectors; i++) {
|
||||
|
||||
/* From time to time inquire drive buffer */
|
||||
|
@ -2097,7 +2100,7 @@ int burn_dvd_write_session(struct burn_write_opts *o,
|
|||
is not readable.
|
||||
|
||||
By default the open session gets closed here before the new
|
||||
session is written. E.g. after writing a small dummy seesion
|
||||
session is written. E.g. after writing a small dummy session
|
||||
number 2 one can read session 1 and write session 3 which
|
||||
points to data of session 1.
|
||||
|
||||
|
@ -2230,7 +2233,8 @@ int burn_disc_setup_dvd_minus_rw(struct burn_write_opts *o,
|
|||
if (o->start_byte >= 0) {
|
||||
d->nwa = o->start_byte / 32768; /* align to 32 kB */
|
||||
|
||||
sprintf(msg, "Write start address is %d * 32768", d->nwa);
|
||||
sprintf(msg, "Write start address is %.f * 32768",
|
||||
(double) d->nwa);
|
||||
libdax_msgs_submit(libdax_messenger, d->global_index,
|
||||
0x00020127,
|
||||
LIBDAX_MSGS_SEV_NOTE, LIBDAX_MSGS_PRIO_HIGH,
|
||||
|
@ -2332,8 +2336,8 @@ int burn_dvd_write_sync(struct burn_write_opts *o,
|
|||
d->nwa = 0;
|
||||
if (o->start_byte >= 0) {
|
||||
d->nwa = o->start_byte / 2048;
|
||||
sprintf(msg, "Write start address is %d * 2048",
|
||||
d->nwa);
|
||||
sprintf(msg, "Write start address is %.f * 2048",
|
||||
(double) d->nwa);
|
||||
libdax_msgs_submit(libdax_messenger, d->global_index,
|
||||
0x00020127,
|
||||
LIBDAX_MSGS_SEV_NOTE, LIBDAX_MSGS_PRIO_HIGH,
|
||||
|
@ -2423,9 +2427,17 @@ int burn_dvd_write_sync(struct burn_write_opts *o,
|
|||
msg, 0, 0);
|
||||
goto early_failure;
|
||||
}
|
||||
/* ??? padding needed ??? cowardly doing it for now */
|
||||
if (o->obs_pad < 2)
|
||||
/* Unaligned BD-R track end works with various drives and
|
||||
produces exact READ CAPACITY results.
|
||||
Nevertheless stream recording hates unaligned WRITE.
|
||||
With DVD+R it seems that obs_pad is silently applied by the
|
||||
drive if a non-aligned final WRITE is received.
|
||||
*/
|
||||
if (o->obs_pad < 2 &&
|
||||
!(d->current_profile == 0x41 && !d->do_stream_recording &&
|
||||
o->bdr_obs_exempt))
|
||||
o->obs_pad = 1; /* fill-up track's last obs buffer */
|
||||
|
||||
if (d->current_profile == 0x41) /* BD-R */
|
||||
o->obs = Libburn_bd_r_obS;
|
||||
if (d->do_stream_recording) {
|
||||
|
@ -2647,7 +2659,7 @@ ex:;
|
|||
|
||||
|
||||
/* ts A70910 : to be used as burn_drive.write(), emulating mmc_write() */
|
||||
int burn_stdio_mmc_write(struct burn_drive *d, int start, struct buffer *buf)
|
||||
int burn_stdio_mmc_write(struct burn_drive *d, off_t start, struct buffer *buf)
|
||||
{
|
||||
int ret;
|
||||
off_t start_byte;
|
||||
|
@ -2690,7 +2702,7 @@ int burn_stdio_mmc_write(struct burn_drive *d, int start, struct buffer *buf)
|
|||
|
||||
/* ts A70910 : to be used as burn_drive.write(),
|
||||
emulating mmc_write() with simulated writing. */
|
||||
int burn_stdio_mmc_dummy_write(struct burn_drive *d, int start,
|
||||
int burn_stdio_mmc_dummy_write(struct burn_drive *d, off_t start,
|
||||
struct buffer *buf)
|
||||
{
|
||||
if (d->cancel)
|
||||
|
@ -2762,30 +2774,57 @@ void burn_stdio_mmc_sync_cache(struct burn_drive *d)
|
|||
}
|
||||
|
||||
|
||||
/* ts A70912 */
|
||||
/* Enforces eventual nominal write speed.
|
||||
@param flag bit0= initialize *prev_time */
|
||||
int burn_stdio_slowdown(struct burn_drive *d, struct timeval *prev_time,
|
||||
int amount, int flag)
|
||||
/* ts C00824 : API */
|
||||
/* Enforces nominal write speed */
|
||||
int burn_nominal_slowdown(int kb_per_second, int max_corr,
|
||||
struct timeval *prev_time,
|
||||
int *us_corr, off_t b_since_prev, int flag)
|
||||
{
|
||||
struct timeval tnow;
|
||||
double to_wait;
|
||||
double to_wait, goal, corr;
|
||||
int abs_max_corr;
|
||||
|
||||
if (flag & 1) {
|
||||
gettimeofday(prev_time, NULL);
|
||||
*us_corr = 0;
|
||||
return 1;
|
||||
}
|
||||
if(d->nominal_write_speed <= 0)
|
||||
if (kb_per_second <= 0)
|
||||
return 2;
|
||||
|
||||
if (max_corr < -1.0e9 || max_corr > 1.0e9)
|
||||
abs_max_corr = 1000000000;
|
||||
else
|
||||
abs_max_corr = abs(max_corr);
|
||||
gettimeofday(&tnow, NULL);
|
||||
to_wait = ( ((double) amount) / (double) d->nominal_write_speed ) -
|
||||
(double) ( tnow.tv_sec - prev_time->tv_sec ) -
|
||||
(double) ( tnow.tv_usec - prev_time->tv_usec ) / 1.0e6
|
||||
- 0.001; /* best would be 1 / kernel granularity HZ */
|
||||
if (to_wait >= 0.0001) {
|
||||
usleep((int) (to_wait * 1000000.0));
|
||||
goal = ((double) b_since_prev) / 1000.0 / ((double) kb_per_second) +
|
||||
((double) prev_time->tv_sec) +
|
||||
((double) prev_time->tv_usec) / 1.0e6 +
|
||||
((double) *us_corr) / 1.0e6 ;
|
||||
to_wait = goal - ((double) tnow.tv_sec) -
|
||||
((double) tnow.tv_usec) / 1.0e6;
|
||||
|
||||
/* usleep might be restricted to 999999 microseconds */
|
||||
while (to_wait > 0.0) {
|
||||
if (to_wait >= 0.5) {
|
||||
usleep(500000);
|
||||
to_wait -= 0.5;
|
||||
} else if (to_wait >= 0.00001) {
|
||||
usleep((int) (to_wait * 1000000.0));
|
||||
to_wait = 0.0;
|
||||
} else {
|
||||
to_wait = 0.0;
|
||||
}
|
||||
}
|
||||
gettimeofday(prev_time, NULL);
|
||||
corr = (goal - ((double) prev_time->tv_sec) -
|
||||
((double) prev_time->tv_usec) / 1.0e6) * 1.0e6;
|
||||
if (corr > abs_max_corr)
|
||||
*us_corr = abs_max_corr;
|
||||
else if (corr < -abs_max_corr)
|
||||
*us_corr = -abs_max_corr;
|
||||
else
|
||||
*us_corr = corr;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -2794,17 +2833,20 @@ int burn_stdio_slowdown(struct burn_drive *d, struct timeval *prev_time,
|
|||
int burn_stdio_write_track(struct burn_write_opts *o, struct burn_session *s,
|
||||
int tnum, int flag)
|
||||
{
|
||||
int open_ended, bufsize = 16 * 2048, ret, sectors;
|
||||
int open_ended, bufsize = 16 * 2048, ret;
|
||||
struct burn_track *t = s->track[tnum];
|
||||
struct burn_drive *d = o->drive;
|
||||
char *buf = NULL;
|
||||
int i, prev_sync_sector = 0;
|
||||
int us_corr = 0, max_corr = 250000;
|
||||
off_t prev_sync_sector = 0, sectors, i;
|
||||
struct buffer *out = d->buffer;
|
||||
struct timeval prev_time;
|
||||
|
||||
BURN_ALLOC_MEM(buf, char, bufsize);
|
||||
|
||||
sectors = burn_track_get_sectors_2(t, 1);
|
||||
sectors = burn_track_get_sectors_2_v2(t, 1);
|
||||
if (sectors < 0)
|
||||
{ret = 0; goto ex;}
|
||||
burn_disc_init_track_status(o, s, t, tnum, sectors);
|
||||
open_ended = burn_track_is_open_ended(t);
|
||||
|
||||
|
@ -2818,7 +2860,10 @@ int burn_stdio_write_track(struct burn_write_opts *o, struct burn_session *s,
|
|||
d->do_simulate = o->simulate;
|
||||
d->sync_cache = burn_stdio_mmc_sync_cache;
|
||||
|
||||
burn_stdio_slowdown(d, &prev_time, 0, 1); /* initialize */
|
||||
/* initialize */
|
||||
burn_nominal_slowdown(d->nominal_write_speed, max_corr,
|
||||
&prev_time, &us_corr, (off_t) 0, 1);
|
||||
|
||||
for (i = 0; open_ended || i < sectors; i++) {
|
||||
/* transact a (CD sized) sector */
|
||||
if (!sector_data(o, t, 0))
|
||||
|
@ -2831,14 +2876,25 @@ int burn_stdio_write_track(struct burn_write_opts *o, struct burn_session *s,
|
|||
}
|
||||
d->progress.sector++;
|
||||
/* Flush to disk from time to time */
|
||||
if (d->progress.sector - prev_sync_sector >=
|
||||
o->stdio_fsync_size && o->stdio_fsync_size > 0) {
|
||||
prev_sync_sector = d->progress.sector;
|
||||
if (!o->simulate)
|
||||
burn_stdio_sync_cache(d->stdio_fd, d, 1);
|
||||
if (o->stdio_fsync_size > 0) {
|
||||
if (d->progress.sector - prev_sync_sector >=
|
||||
o->stdio_fsync_size) {
|
||||
if (!o->simulate)
|
||||
burn_stdio_sync_cache(d->stdio_fd, d,
|
||||
1);
|
||||
burn_nominal_slowdown(
|
||||
d->nominal_write_speed, max_corr,
|
||||
&prev_time, &us_corr,
|
||||
(off_t) (d->progress.sector -
|
||||
prev_sync_sector) *
|
||||
(off_t) 2048,
|
||||
0);
|
||||
prev_sync_sector = d->progress.sector;
|
||||
}
|
||||
} else if ((d->progress.sector % 512) == 0) {
|
||||
burn_nominal_slowdown(d->nominal_write_speed, max_corr,
|
||||
&prev_time, &us_corr, (off_t) (512 * 2048), 0);
|
||||
}
|
||||
if ((d->progress.sector % 512) == 0)
|
||||
burn_stdio_slowdown(d, &prev_time, 512 * 2, 0);
|
||||
}
|
||||
|
||||
/* Pad up buffer to next full o->obs (usually 32 kB) */
|
||||
|
@ -3074,6 +3130,7 @@ return crap. so we send the command, then ignore the result.
|
|||
/* goto fail_wo_sync; */
|
||||
#endif /* Libburn_write_with_function_print_cuE */
|
||||
|
||||
d->medium_state_changed = 1;
|
||||
ret = 1;
|
||||
if (o->write_type == BURN_WRITE_SAO)
|
||||
ret = d->send_cue_sheet(d, sheet);
|
||||
|
|
Loading…
Reference in New Issue