Compare commits

...

147 Commits

Author SHA1 Message Date
Thomas Schmitt 51f43127ac Comitted file which was forgotten with commit f0d9795 2024-03-09 18:59:18 +01:00
Thomas Schmitt f84d038121 Removed remaining 31/32-bit bottlenecks from stdio writing 2024-03-03 21:14:17 +01:00
Thomas Schmitt e5a8d91e4d New API call burn_get_read_capacity_v2() 2024-03-03 16:24:13 +01:00
Thomas Schmitt f0d9795cd1 New API calls burn_disc_get_sectors_v2(), burn_session_get_sectors_v2(), burn_track_get_sectors_v2() 2024-03-03 11:52:15 +01:00
Thomas Schmitt 29bfd7e5e7 New API call burn_disc_track_lba_nwa_v2() 2024-03-02 14:12:22 +01:00
Thomas Schmitt d48bbb4b66 New struct burn_progress_v2 and API call burn_drive_get_status_v2() 2024-03-01 19:51:34 +01:00
Thomas Schmitt 17a020e9fc Augmented struct burn_toc_entry by new off_t block addresses and counters 2024-02-27 20:48:11 +01:00
Thomas Schmitt 069b4edecd Removed use of undefined data by a rarely occuring error message 2024-02-26 16:06:56 +01:00
Thomas Schmitt 84e8efeb0a Changed a byte size variable from int to off_t. Currently only used with CD DAO and thus not really necessary. 2024-02-26 15:58:36 +01:00
Thomas Schmitt ddebbf1b60 Bug fix: burn_offst_source_new() parameter "size" rolled over at 2 exp 31 2024-02-26 15:57:18 +01:00
Thomas Schmitt ca29b77091 Checking length of pseudo-drive address to prevent possible overflow 2023-09-12 15:21:17 +02:00
Thomas Schmitt 046f581baa Changed gpg key server recommendation to keyserver.ubuntu.com. Corrected repo instructions from SVN to git. 2023-06-20 19:56:33 +02:00
Thomas Schmitt c8ceb73b5f Updated change log 2023-06-07 20:40:00 +02:00
Thomas Schmitt f4a09e9536 Made number transition to 1.5.7 2023-06-07 20:36:56 +02:00
Thomas Schmitt 4628231cec Updated change log 2023-06-07 15:54:15 +02:00
Thomas Schmitt f795db5d61 Last minute correction in cdrskin web page 2023-06-07 15:51:14 +02:00
Thomas Schmitt 9acb8ad6da Updated cdrskin tarball generator 2023-06-07 15:33:00 +02:00
Thomas Schmitt 1172ef74c6 Made number transition to 1.5.6 2023-06-07 15:23:54 +02:00
Thomas Schmitt a904ae995a Enlarged maximum allowed tsize= value to 4 TiB - 2 KiB (just in case) 2022-12-10 11:18:05 +01:00
Thomas Schmitt 1954514210 Updated copyright dates of cdrskin 2022-04-05 16:04:43 +02:00
Thomas Schmitt 629a4fa44d Let cdrskin take options -VV and -VVV as -V 2022-04-05 15:59:50 +02:00
Thomas Schmitt 879cb991df Updated change log 2021-11-25 19:11:37 +01:00
Thomas Schmitt d4d63213ab Improved man page of cdrskin about -force after enabling overburning in libburn 2021-11-24 12:47:16 +01:00
Thomas Schmitt 7765fbd1ab Enabled overburning with burn_write_opts_set_force(,1) 2021-11-24 12:45:07 +01:00
Thomas Schmitt da44c706ea New cdrskin option --bdr_obs_exempt 2021-09-12 10:46:28 +02:00
Thomas Schmitt 31591b8196 New API call burn_write_opts_set_bdr_obs_exempt() 2021-09-12 10:41:59 +02:00
Thomas Schmitt 27e15689e5 Let mmc_read_cd() for CD-DA set command.dxfer_len 2021-09-02 20:13:23 +02:00
Thomas Schmitt 0a1bbb1696 Added doc/waveformat.txt to libburn tarball 2021-09-02 20:11:02 +02:00
Thomas Schmitt c76145f5e1 Corrected man page about the default of extract_basename= 2021-09-02 20:09:42 +02:00
Thomas Schmitt 8d270b1fda Removed unneeded configure.ac macro AC_C_BIGENDIAN 2021-09-02 20:07:44 +02:00
Thomas Schmitt 892df643c9 Made optional the use of libcam and thus SCSI passthrough on GNU/FreeBSD systems 2021-03-12 09:28:36 +01:00
Thomas Schmitt 31e8f5cf0e Unified size of large or unlimited pseudo drives to 4 TiB - 32 KiB 2021-02-28 13:20:09 +01:00
Thomas Schmitt 2a977cfc4b Improved error message if a track is larger than 4 TiB - 32 KiB 2021-02-28 13:17:27 +01:00
Thomas Schmitt be039ff191 Updated change log 2021-01-30 16:48:07 +01:00
Thomas Schmitt f1d5c670c5 Made number transition to 1.5.5 2021-01-30 16:46:15 +01:00
Thomas Schmitt d3bd97c05e Updated change log 2021-01-30 16:41:02 +01:00
Thomas Schmitt d146886763 Corrected SONAME parameters to produce libburn.so.4.107.0 2021-01-30 12:51:39 +01:00
Thomas Schmitt d95d5a2484 Updated cdrskin tarball generator 2021-01-30 10:55:10 +01:00
Thomas Schmitt 2a58d5ae5c Made number transition to 1.5.4 2021-01-30 10:52:56 +01:00
Thomas Schmitt 3468a2ad38 Tolerating all sense replies of form 6,28,* 2020-09-30 20:53:53 +02:00
Thomas Schmitt 6b2ae7d141 For now using CDROM_SIMUL_CHANGE only if -DLibburn_use_linux_ioctl_simul_changE 2020-09-20 22:46:55 +02:00
Thomas Schmitt ab6b1039a4 Changed experimental ioctl from CDROM_REVALIDATE to CDROM_SIMUL_CHANGE 2020-09-20 10:45:15 +02:00
Thomas Schmitt 8b9a8cfb4b New API call burn_nominal_slowdown() 2020-08-26 16:04:06 +02:00
Thomas Schmitt 0e1f5dc3da New API call burn_drive_set_speed_exact() 2020-08-24 15:28:15 +02:00
Thomas Schmitt 8d934ee7b8 Testing use of experimental ioctl CDROM_REVALIDATE after media state changes 2020-08-22 15:22:11 +02:00
Thomas Schmitt e09acf3b8a Corrected a typo in man cdrskin found by lintian 2020-07-11 11:47:46 +02:00
Thomas Schmitt 799175019b Bug fix: Early SCSI commands from sg-linux.c were not logged 2020-04-15 20:52:05 +02:00
Thomas Schmitt b57c05c874 Incremented .so numbering to libburn.so.4.106.0 2019-11-26 18:07:40 +01:00
Thomas Schmitt d4593f49ae Updated README about 1.5.2.pl01 2019-11-25 20:36:31 +01:00
Thomas Schmitt 91f7d4d34a 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 2019-11-25 10:13:29 +01:00
Thomas Schmitt ba9b69b1df Fixed spelling errors found by fossies.org with codespell 2019-10-28 16:58:20 +01:00
Thomas Schmitt 1c235e807e Corrected alphabetical sort rank of --list_features in man cdrskin 2019-10-27 19:37:24 +01:00
Thomas Schmitt 95ad059aba Updated change log 2019-10-27 15:27:45 +01:00
Thomas Schmitt 0a37e8cbe5 Made number transition to 1.5.3 2019-10-27 15:26:21 +01:00
Thomas Schmitt 3a940300e2 Committed forgotten header file 2019-10-26 17:10:03 +02:00
Thomas Schmitt a6fdbc7a25 Updated change log 2019-10-26 17:04:11 +02:00
Thomas Schmitt ce2ddab081 Updated cdrskin tarball generator 2019-10-26 17:01:24 +02:00
Thomas Schmitt 2298dfd08a Made number transition to 1.5.2 2019-10-26 16:59:53 +02:00
Thomas Schmitt 354d45e640 Bug fix: TDK Corporation was not recognized as manufacturer of DVD-R "TTH02". Thanks Steve. 2019-09-20 12:37:59 +02:00
Thomas Schmitt 6905bb447a Showing more info in case of drive errors and transport problems 2019-07-05 15:36:42 +02:00
Thomas Schmitt 0e73afd17c New cdrskin option --list_features 2019-04-17 11:58:32 +02:00
Thomas Schmitt c5bc9f6de7 New API calls burn_drive_get_feature_codes(), burn_drive_get_feature() 2019-04-17 11:23:59 +02:00
Thomas Schmitt 610e213f70 Putting out more info in case of failed Linux SG_IO ioctl 2019-04-17 11:00:03 +02:00
Thomas Schmitt 4d5486acf5 Applying stream recording only to DVD-RAM, BD-R, BD-RE media 2019-04-13 19:36:31 +02:00
Thomas Schmitt 39f2712bb7 Bug fix: Stream recording was applied regardless whether the drive offers it 2019-04-13 19:34:31 +02:00
Thomas Schmitt 9ac8efa61e Disabled autotools macro AM_MAINTAINER_MODE on advise of Ross Burton 2019-04-07 10:45:44 +02:00
Thomas Schmitt 1c06669465 Made libburn ready for building out-of-source. Thanks Ross Burton. 2019-04-05 17:49:17 +02:00
Thomas Schmitt d72fb13225 Emitting cleartext for errors with ASC 6F (CSS problems) 2018-12-12 13:55:54 +01:00
Thomas Schmitt 7282eaab2c Silenced gcc warnings about printf target buffer 2018-10-11 09:41:04 +02:00
Thomas Schmitt 042fe178bf Bug fix: No lock was obtained for setting up a fifo object 2018-10-10 18:03:24 +02:00
Thomas Schmitt af65852dc8 Silenced gcc warnings about switch-cases and printf target buffers 2018-10-10 18:01:00 +02:00
Thomas Schmitt f52507116b Updated change log 2018-09-16 15:55:23 +02:00
Thomas Schmitt 04f9a30787 Made number transition to 1.5.1 2018-09-16 15:53:33 +02:00
Thomas Schmitt c2bcf78c81 Added to cdrskin standalone scripts a compile run for unite_html_b_line.c 2018-09-15 13:48:46 +02:00
Thomas Schmitt ef3609e021 Fixed a typo that was made during version leap 2018-09-15 13:29:42 +02:00
Thomas Schmitt 9ee80eec9a Updated change log 2018-09-15 12:01:06 +02:00
Thomas Schmitt 255afdde45 Updated cdrskin tarball generator 2018-09-15 11:56:34 +02:00
Thomas Schmitt c75ad3162c Made number transition to 1.5.0 2018-09-15 11:52:05 +02:00
Thomas Schmitt d32bb30e79 With --enable-track-src-odirect, do not report error 22 due to unaligned EOF 2018-09-06 12:08:04 +02:00
Thomas Schmitt 3fdf11817d Bug fix: Device file comparison parameters were recorded wrong with Linux sg 2018-09-02 22:02:02 +02:00
Thomas Schmitt 2fe4b3ca2a Restricted enforcement of minimum track size to CD media profiles 2018-08-26 16:16:53 +02:00
Thomas Schmitt ff039e8096 Bug fix: SIGSEGV could happen if a track ended by reaching its fixed size while the track source still was willing to deliver bytes 2018-08-08 17:27:09 +02:00
Thomas Schmitt e35995b85e Updated change log 2018-02-05 13:39:03 +01:00
Thomas Schmitt c84889bb81 Reporting in SCSI log when commands get repeated 2018-02-05 11:37:20 +01:00
Thomas Schmitt 84fad99eba Bug fix: cdrskin threw errno 22 on data file input if libburn is configured --enable-track-src-odirect 2018-02-05 11:33:51 +01:00
Thomas Schmitt 95f5b1ce2b Added missing header file for previous commit 2017-12-31 12:48:16 +01:00
Thomas Schmitt ef2fa1d99d Adapting to surplus chunks and subchunks in .wav files 2017-12-31 12:15:36 +01:00
Thomas Schmitt b5b5cc1fb2 Reacted on compiler warning about theoretical overflow of an sprintf 2017-09-16 12:57:29 +02:00
Thomas Schmitt 99e828c72f Reacted on compiler warning about theoretical overflow of an sprintf 2017-09-16 12:51:59 +02:00
Thomas Schmitt 2886b82bf0 Reacted on compiler warning about theoretical overflow of an sprintf 2017-09-16 11:50:35 +02:00
Thomas Schmitt ef0d713b25 Updated change log 2017-09-13 10:19:38 +02:00
Thomas Schmitt f1fc16bb8a Made number transition to 1.4.9 2017-09-13 10:10:11 +02:00
Thomas Schmitt 260fc2983d Updated change log 2017-09-12 13:39:54 +02:00
Thomas Schmitt ea486a109f Updated cdrskin tarball generator 2017-09-12 13:37:57 +02:00
Thomas Schmitt 516dc2ca76 Made number transition to 1.4.8 2017-09-12 13:36:08 +02:00
Thomas Schmitt 113f5873cb Fixed the block count in error message about read attempt after medium end 2017-07-15 21:42:27 +02:00
Thomas Schmitt 2bb8bf470d Reporting POW formatted BD-R as unusable 2017-02-06 17:15:03 +01:00
Thomas Schmitt a4b688ab52 Refusing to write to BD-R if formatted to Pseudo Overwrite 2017-02-06 15:12:41 +01:00
Thomas Schmitt d71d80d1a1 New API call burn_drive_get_bd_r_pow() 2017-02-06 14:58:39 +01:00
Thomas Schmitt 858e42d696 Corrected harmless typos found by lintian 2017-01-28 21:08:32 +01:00
Thomas Schmitt 724d518dbc Giving up use of function pthread_cancel() 2017-01-28 21:02:17 +01:00
Thomas Schmitt 6f6bf688d9 Small adjustement for previous commit 2017-01-27 16:05:37 +01:00
Thomas Schmitt 6b020a3ab7 Detecting Linux systems without generic SCSI support by scsi/scsi.h 2017-01-27 12:05:35 +01:00
Thomas Schmitt 074f88fe98 Corrected documentation of bytes/second value of 1x CD speed 2017-01-11 12:28:19 +01:00
Thomas Schmitt 19a1b8e768 Bug fix: Option -dummy did not affect writing by direct_write_amount= 2016-11-18 14:24:13 +01:00
Thomas Schmitt 80175e0054 Let random access writing obey simulation mode of previous sequential run. New API call burn_drive_reset_simulate(). 2016-11-18 14:21:33 +01:00
Thomas Schmitt d7b5090ff9 Let random access writing obey simulation mode of previous sequential run. New API call burn_drive_reset_simulate(). 2016-11-18 14:19:37 +01:00
Thomas Schmitt 2a2d60d95d Updated change log 2016-09-16 19:13:05 +00:00
Thomas Schmitt b5a84e7f01 Updated cdrskin tarball generator 2016-09-16 19:10:44 +00:00
Thomas Schmitt 261538cea7 Made number transition to 1.4.7 2016-09-16 19:09:18 +00:00
Thomas Schmitt 607f339501 Added a few ASCQ texts to error code 5,30,X 2016-09-10 08:30:36 +00:00
Thomas Schmitt b9f67a86a1 Removed @abs_top_builddir@ from doxygen.conf.in where it hampered reproducibe build 2016-08-28 14:51:37 +00:00
Thomas Schmitt e1d8d11c5f Eased re-enabling of libtool --silent at bootstrap time 2016-08-23 19:39:00 +00:00
Thomas Schmitt cd6b19a065 Bug fix: SAO CD could be perceived 2 blocks too short. Regression in 1.4.4 by rev 5672. 2016-07-31 19:04:51 +00:00
Thomas Schmitt 7cc62d99e9 Enabled overriding of OpenBSD default for Immed usage 2016-07-30 20:05:39 +00:00
Thomas Schmitt ed6bf59026 Forgot to commit the libburn.ver file with the new API symbols 2016-07-30 16:35:19 +00:00
Thomas Schmitt 0731eaa3e0 New cdrskin option use_immed_bit= 2016-07-30 14:08:29 +00:00
Thomas Schmitt 740e726ffe New API call burn_drive_set_immed() 2016-07-30 14:03:10 +00:00
Thomas Schmitt 2e8dec42e5 Reacted on some of the complaints of codespell 2016-07-23 10:40:43 +00:00
Thomas Schmitt ba7422b2b6 Mentioned OpenBSD in adapter files 2016-07-21 17:50:48 +00:00
Thomas Schmitt 2e76a4dfdf Fixed a macro typo in rev 5720. Thanks again to SASANO Takayoshi. 2016-07-21 14:12:02 +00:00
Thomas Schmitt 078f75c2a7 Enabled SCSI command execution on OpenBSD. Thanks to SASANO Takayoshi. 2016-07-21 10:29:15 +00:00
Thomas Schmitt 6f072d870d Fixed three spelling errors found by lintian 2016-07-03 19:16:08 +00:00
Thomas Schmitt f312d00a73 Updated change log 2016-07-01 19:23:35 +00:00
Thomas Schmitt d5d802a226 Updated cdrskin tarball generator 2016-07-01 19:17:23 +00:00
Thomas Schmitt daa9160df7 Made number transition to 1.4.5 2016-07-01 19:15:33 +00:00
Thomas Schmitt 4189a000fe Removed option --silent from libtool runs 2016-04-27 14:51:56 +00:00
Thomas Schmitt e631f2d977 Prevented option --version-script with linker runs of binaries. By Matthias Klose. 2016-04-19 07:05:36 +00:00
Thomas Schmitt 6e5d3dc2d1 Bug fix: burn_make_input_sheet_v07t() used character code of block 0 for all blocks 2016-03-31 12:45:40 +00:00
Thomas Schmitt bdbcde351f Bug fix: DVD book type of DVD+RW DL and DVD+R DL was reported wrong. Thanks to Etienne Bergeron. 2016-03-30 20:06:38 +00:00
Thomas Schmitt 37c53a22c8 Updated change log 2016-03-30 19:25:18 +00:00
Thomas Schmitt 34866215f7 Bug fix: Double free at end of run if burn_write_opts_set_leadin_text() is used 2016-03-30 19:00:28 +00:00
Thomas Schmitt f4ce749188 Bug fix: burn_make_input_sheet_v07t() falsly recognized double byte encoding 2016-03-30 11:33:20 +00:00
Thomas Schmitt 9e852c2b7c Updated change log 2016-03-18 14:38:32 +00:00
Thomas Schmitt f61caa7feb Bug fix: Linux /proc/sys/dev/cdrom/info overrode SCSI dev family conversion 2016-03-17 20:33:15 +00:00
Thomas Schmitt 94f02caddb Replaced unused timezone parameter of gettimeofday() by NULL 2016-03-10 19:56:14 +00:00
Thomas Schmitt 69d12929e3 Trying to find out whether READ CAPACITY on CD media includes 2 TAO end blocks 2016-03-08 07:33:45 +00:00
Thomas Schmitt df1483c78d Changed type of length counters of serial numbers from char to int. Warning of gcc on Ubuntu powerpc. 2016-02-18 11:48:17 +00:00
Thomas Schmitt 92e29de695 Fixed a typo found by lintian 2016-02-05 13:03:40 +00:00
Thomas Schmitt 02d06cffbc Fixed a typo found by lintian 2016-02-05 13:00:41 +00:00
Thomas Schmitt 2f4613fd26 Updated README and change log 2016-01-29 12:37:17 +00:00
Thomas Schmitt 541ea7aa09 Updated change log 2016-01-28 10:05:36 +00:00
Thomas Schmitt 224fe43539 Bug fix: "failed to attach fifo" when burning from stdin. Regression of 1.4.2, r 2016-01-27 17:45:03 +00:00
Thomas Schmitt 80225c93a9 Checking for availability of LIBBURN_ARCH_LIBS 2015-12-10 19:24:06 +00:00
Thomas Schmitt 7f35793928 Updated change log 2015-11-28 21:10:01 +00:00
Thomas Schmitt 91c4ba0179 Updated cdrskin tarball generator 2015-11-28 21:05:25 +00:00
Thomas Schmitt 80ebe2923a Made number transition to 1.4.3 2015-11-28 21:04:27 +00:00
67 changed files with 4977 additions and 841 deletions

View File

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

View File

@ -1,8 +1,87 @@
SVN trunk (to become libburn-1.4.2 or higher)
git clone git@dev.lovelyhq.com:libburnia/libburn.git
(to become libburn-1.5.8 or higher)
===============================================================================
- no novelties yet -
libburn-1.5.6.tar.gz Wed Jun 07 2023
===============================================================================
* Bug fix: Overburning with cdrskin option -force ended by a libburn error
* New API call burn_write_opts_set_bdr_obs_exempt()
* New cdrskin option --bdr_obs_exempt
* Officially enabled overburning with burn_write_opts_set_force(,1)
libburn-1.5.4.tar.gz Sat Jan 30 2021
===============================================================================
* Bug fix: Early SCSI commands from sg-linux.c were not logged
* New API call burn_drive_set_speed_exact()
* New API call burn_nominal_slowdown()
libburn-1.5.2.pl01.tar.gz Mon Nov 25 2019
===============================================================================
* Bug fix: cdrskin multi-track burning was slow and stalled after track 1.
Regression introduced in version 1.5.0 by commit 84fad99, 2018.02.05
O_DIRECT is now disabled for track sources.
libburn-1.5.2.tar.gz Sat Oct 26 2019
===============================================================================
* Bug fix: No lock was obtained for setting up a fifo object
* Bug fix: Stream recording was applied regardless whether the drive offers it.
This caused Xfburn failures with some MATSHITA laptop drives.
* Bug fix: TDK Corporation was not recognized as manufacturer of DVD-R "TTH02"
* Made libburn ready for building out-of-source. Thanks Ross Burton.
* New API calls burn_drive_get_feature_codes(), burn_drive_get_feature()
* New cdrskin option --list_features
libburn-1.5.0.tar.gz Sat Sep 15 2018
===============================================================================
* Bug fix: cdrskin threw errno 22 on data file input if libburn is
configured with --enable-track-src-odirect
* Bug fix: SIGSEGV could happen if a track ended by reaching its fixed size
while the track source still was willing to deliver bytes.
Thanks to user swordragon.
* Bug fix: Device file comparison parameters were recorded wrong with Linux sg
libburn-1.4.8.tar.gz Tue Sep 12 2017
===============================================================================
* Bug fix: Option -dummy did not affect writing by direct_write_amount=
* New API call burn_drive_reset_simulate()
* New API call burn_drive_get_bd_r_pow()
* Refusing to write to BD-R if formatted to Pseudo Overwrite
libburn-1.4.6.tar.gz Fri Sep 16 2016
===============================================================================
* Bug fix: SAO CD could be perceived 2 blocks to short.
Regression in 1.4.4 by rev 5672.
* Now operating optical drives on OpenBSD. Thanks to SASANO Takayoshi.
* New API call burn_drive_set_immed()
* New cdrskin option use_immed_bit=
libburn-1.4.4.tar.gz Fri Jul 01 2016
===============================================================================
* Bug fix: Option drive_scsi_dev_family=sg did not convert /dev/sr* to /dev/sg*
* Bug fix: burn_make_input_sheet_v07t() falsly recognized double byte encoding.
Affected cdrskin option: cdtext_to_v07t=
* Bug fix: Double free at end of run if burn_write_opts_set_leadin_text() is
used. Affected cdrskin option: textfile=
* Bug fix: DVD book type of DVD+RW DL and DVD+R DL was reported wrong.
Thanks to Etienne Bergeron.
libburn-1.4.2.pl01.tar.gz Fri Jan 29 2016
===============================================================================
* Bug fix: cdrskin "failed to attach fifo" when burning from stdin.
Regression of 1.4.2, rev 5522.
libburn-1.4.2.tar.gz Sat Nov 28 2015
===============================================================================
* Bug fix: burn_disc_get_media_id() returned BD identifiers 2 chars too long
* Bug fix: burn_disc_get_multi_caps() returned 2048 bytes too many in
caps.start_range_high
* Bug fix: Media summary session count of blank and closed media was short by 1
* Bug fix: Endless loop if transport error occurs while waiting for drive ready
* New API calls burn_drive_get_serial_no() and burn_drive_get_media_sno()
* Result of a Coverity audit: 40+ code changes, but no easy-to-trigger bugs
libburn-1.4.0.tar.gz Sun May 17 2015
===============================================================================
* Bug fix: Double free with cdrskin -vvv.

View File

@ -12,7 +12,7 @@ ACLOCAL_AMFLAGS = -I ./
# Build libraries
libburn_libburn_la_LDFLAGS = \
-version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE)
-version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE) $(LIBLDFLAGS)
# This causes undesired .o names
# configure.ac appends -D options to variable CFLAG
### libburn_libburn_la_CFLAGS = $(LIBBURN_DVD_OBS_64K)
@ -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 - B50517
## cdrskin construction site - ts A60816 - C30607
cdrskin_cdrskin_CPPFLAGS = -Ilibburn
cdrskin_cdrskin_CFLAGS = -DCdrskin_libburn_1_4_1
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 \

139
README
View File

@ -6,12 +6,12 @@ This all is under GPL.
------------------------------------------------------------------------------
libburnia-project.org
By Mario Danic <mario.danic@gmail.com> and Thomas Schmitt <scdbackup@gmx.net>
Copyright (C) 2006-2015 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.4.0.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.4.0.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.4.0.tar.gz
cd libburn-1.4.0
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.
@ -255,7 +254,7 @@ Project history as far as known to me:
which by about nearly everybody else was perceived as unfriendly fork.
Derek Foreman four days later posted a message which expressed his
discontent.
The situation first caused me to publically regret it and then - after i
The situation first caused me to publicly regret it and then - after i
got the opportunity to move in with cdrskin - gave me true reason to
personally apologize to Derek Foreman, Ben Jansens and the contributors at
icculus.org/burn. Posted to both projects:
@ -329,7 +328,7 @@ Project history as far as known to me:
and write modes, and better protection against typical user mishaps.
- 24th October 2007 version 0.4.0 is the foundation of new library libisoburn
and an upcomming integrated application for manipulating and writing
and an upcoming integrated application for manipulating and writing
ISO 9660 + Rock Ridge images. cdrskin-0.4.0 got capabilities like growisofs
by these enhancements: growing of overwriteable media and disk files.
Taking again a bow towards Andy Polyakov.
@ -389,7 +388,7 @@ Project history as far as known to me:
and cdrecord style. xorriso now can serve underneath growisofs.
- 20th Aug 2008 libburn-0.5.2 revokes the necessity that a drive must be
enumerable in order to be adressable. Enumeration is enhanced by examining
enumerable in order to be addressable. Enumeration is enhanced by examining
/proc/sys/dev/cdrom/info.
- 24th Aug 2008 libisoburn/xorriso-0.2.4 introduces a media readability check
@ -421,7 +420,7 @@ Project history as far as known to me:
signature, and for producing ISO images with MBR which boot from hard disk
or USB stick. Three minor bugs were fixed.
- 7th Dec 2008 libburn-0.5.8 prevents a SIGSEGV with wierd CD table-of-content
- 7th Dec 2008 libburn-0.5.8 prevents a SIGSEGV with weird CD table-of-content
and improves BD-RE formatting.
- 9th Dec 2008 Our project received a donation from Thomas Weber.
@ -646,7 +645,7 @@ Project history as far as known to me:
- Sat Jun 18 2011 release 1.1.0:
The consumption of stack memory was reduced. Statical program analysis found
some rarely occuring memory leaks. Several small bugs were fixed.
some rarely occurring memory leaks. Several small bugs were fixed.
The suffix .plXY was dropped from tarball names of libburn and libisoburn.
- Mon Jun 20 2011 patch release libburn-1.1.0.pl01:
@ -683,10 +682,10 @@ Project history as far as known to me:
- Mon Apr 02 2012 release 1.2.2:
The handling of intentional deviations from ECMA-119 specifications has
been improved in libisofs. libisoburn and xorriso now make use of these
improvements. Some rarely occuring bugs have been fixed.
improvements. Some rarely occurring bugs have been fixed.
- Fri Jul 20 2012 release 1.2.4:
libburn and libisofs got some rarely occuring bugs fixed. libisofs learned
libburn and libisofs got some rarely occurring bugs fixed. libisofs learned
to produce HFS+ metadata and Apple Partition Map. The capabilities of
isohybrid options --efi and --mac have been implemented (GPT and APM).
@ -697,7 +696,7 @@ Project history as far as known to me:
xorriso-tcltk
- Mon Mar 18 2013 release 1.2.8:
Some rarely occuring bugs were fixed in libisofs and libburn. libburn's
Some rarely occurring bugs were fixed in libisofs and libburn. libburn's
handling of incomplete sessions has been improved. xorriso's mkisofs
emulation learned to set El Torito section id strings.
@ -712,7 +711,7 @@ Project history as far as known to me:
Regression introduced by version 1.2.8.
- Fri Aug 07 2013 release 1.3.2:
cdrskin has aquired the capability to copy audio tracks to .wav files.
cdrskin has acquired the capability to copy audio tracks to .wav files.
It can extract CD-TEXT in a form that is readable for humans and for
cdrskin itself. Several small bugs were fixed in xorriso. Its capabilities
to serve frontend programs in dialog mode have been improved.
@ -721,25 +720,107 @@ Project history as far as known to me:
A long standing hidden bug was fixed, which affected inspection of
unformatted DVD+RW.
xorriso now by default puts EL Torito boot images to low block addresses.
It can report and set read speeds. Several rarely occuring bugs were fixed.
It can report and set read speeds. Several rarely occurring bugs were fixed.
- Tue Mar 04 2014 release 1.3.6
- Tue Mar 04 2014 release 1.3.6:
libburn learned to operate optical drives and media on NetBSD. libisofs got
a bug fix about HFS+ and enhancements about character set conversion.
Minor bugs were fixed in libisoburn. xorriso can now find files with names
which cannot be represented unchanged in ECMA-119, Joliet, or HFS+.
- Sat Jun 28 2014 release 1.3.8
- Sat Jun 28 2014 release 1.3.8:
libburn got several bugs fixed. libisofs offers new API calls for inspection
of boot sectors in ISO 9660 filesystems. xorriso improved its support for
NetBSD, offers new features with command -find, and a command to extract
ISO 9660 file content onto standard output or into filter processes.
- Sun May 17 2015 release 1.4.0
- Sun May 17 2015 release 1.4.0:
This release is mainly about bug fixes and a new feature of xorriso to
propose commands or as_mkisofs options which can reproduce the boot
equipment of the loaded ISO filesystem.
- Sat Nov 28 2015 release 1.4.2:
libburn got some bugs fixed and learned to inquire the drive serial number.
libisofs now sorts data file content by ECMA-119 file names for better
reproducability of ISO content. Rock Ridge filenames may be restricted to
lengths between 64 and 255 bytes. If needed, a qualified truncation happens.
xorriso now can replay boot settings when modifying ISO filesystems.
In order to avoid clogging of concurrent Linux SG_IO, xorriso got command
-modesty_on_drive to enable an old workaround from IDE master/slave days.
The source code underwent a scan by Coverity. About 150 code changes
resulted, but no easy-to-trigger bugs were found.
- Fri Jan 29 2016 patch release libburn-1.4.2.pl01:
cdrskin did not work with "-" (stdin) as input.
Regression introduced by version 1.4.2.
- Fri Jul 01 2016 release 1.4.4:
The capability to use Linux /dev/sg was revived in order to circumvent the
sr_mutex lock which hampers concurrent use of optical drives via SG_IO.
libisofs now can use appended partitions by El Torito, avoiding the need
for duplicate EFI System Partition images.
Several bugs have been fixed.
- Fri Sep 16 2016 release 1.4.6:
libburn now operates optical drives on OpenBSD. libisofs makes pseudo-random
id generation reproducible by relating it to the volume date.
xorriso interprets environment variable SOURCE_DATE_EPOCH of
reproducible-builds.org to prepare a default setting which leads to identical
ISO images on identical input and identical constant options.
Several moderately embarrassing bugs have been fixed.
- Tue Sep 12 2017 release 1.4.8:
libburn now refuses to write to SRM+POW formatted BD-R, because it would
spoil them. libisofs got several bugs fixed and offers new API calls to
support new xorriso features. libisoburn and xorriso offer more detail
control with particular boot sector types. New bugs and a regression from
version 1.4.4 were fixed.
- Sat Sep 15 2018 release 1.5.0
libisofs now can record all xattr namespaces, user defined padding was moved
after appended partitions. libisoburn and xorriso make use of the new xattr
capability of libisofs.
All three libraries got some rarely triggered bugs fixed.
- Sat Oct 26 2019 release 1.5.2
The libraries are now ready for building out-of-source. libisofs got minor
API extensions. libburn got a bug fixed which spoiled burn runs on
some MATSHITA laptop drives. It is now able to list all features which
the drive announces. xorriso can now set GPT type GUIDs with appended
partitions and the ISO partition.
All three libraries got some rarely triggered bugs fixed.
- Mon Nov 25 2019 patch release 1.5.2.pl01
cdrskin did not properly burn multiple tracks. Track 1 was slow and burning
stalled before track 2. Regression introduced by 1.5.0.
- Sat Jan 30 2021 , 07 Feb 2021 release 1.5.4
libburn offers new opportunities to influence drive speed.
libisofs got a bug fixed which under medium rare circumstances spoiled
zisofs production. libisofs switched to usage of libjte-2.0.0. Further it
can now write and read zisofs2 format, which enables compression of files
>= 4 GiB. When reading Joliet file trees, the names get stripped of their
version numbers by default. After loading metadata, libisofs can now tell
which directory tree was loaded and whether Rock Ridge is used.
libisoburn and xorriso make use of these new features.
xorriso can put out the data stream of -check_media to standard output. It
can restore files with many zero bytes as sparse files and it is able to
extract recognized boot images into data files on hard disk.
A new script xorriso-dd-target helps to put an ISO image onto an USB stick
without endangering valuable hard disk content.
Several rarely triggered bugs were fixed.
- Wed Jun 07 2023 release 1.5.6
libburn can overburn CD media, i.e. write more data than the drive announced
as medium capacity.
libisofs can assess many of the features which were in effect when a
given ISO 9660 filesystem was created. A safety limit was introduced not
to exceed the limit of Linux which is imposed on the number of SUSP CE
entries which is good for about 60 KiB of AAIP data. Some rarely occuring
bugs were fixed in libisofs.
libisoburn and xorriso expose the new library features to the user and
got some minor improvements. Many minor bugs were fixed.
------------------------------------------------------------------------------
This program is free software; you can redistribute it and/or modify

View File

@ -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
])
@ -53,15 +59,17 @@ dnl It tests whether -Wl,--version-script=... works with the compiler
AC_DEFUN([LIBBURN_ASSERT_VERS_LIBS],
[
libburnia_save_LDFLAGS="$LDFLAGS"
LDFLAGS="$LDFLAGS -Wl,--version-script=libburn/libburn.ver"
LDFLAGS="$LDFLAGS -Wl,--version-script=$srcdir/libburn/libburn.ver"
AC_TRY_LINK([#include <stdio.h>], [printf("Hello\n");],
[vers_libs_test="yes"], [vers_libs_test="no"])
if test x$vers_libs_test = xno
if test x$vers_libs_test = xyes
then
LDFLAGS="$libburnia_save_LDFLAGS"
LIBLDFLAGS="-Wl,--version-script=$srcdir/libburn/libburn.ver"
fi
LDFLAGS="$libburnia_save_LDFLAGS"
AC_SUBST(LIBLDFLAGS)
])
dnl LIBBURNIA_SET_PKGCONFIG determines the install directory for the *.pc file.
dnl Important: Must be performed _after_ TARGET_SHIZZLE
@ -113,3 +121,121 @@ dnl For debugging only
])
dnl LIBBURNIA_CHECK_ARCH_LIBS is by Thomas Schmitt, libburnia project
dnl It tests whether the OS dependent libraries are available.
dnl With libisoburn they are needed only for the case that indirect linking
dnl does not work. So it is worth a try to omit them.
dnl $1 = "mandatory" or "optional" define the action if test linking fails.
dnl "silent" is like "optional" but without message.
AC_DEFUN([LIBBURNIA_CHECK_ARCH_LIBS],
[
libburnia_save_LIBS="$LIBS"
if test "x$LIBBURN_ARCH_LIBS" = x
then
dummy=dummy
else
LIBS="$LIBS $LIBBURN_ARCH_LIBS"
AC_TRY_LINK([#include <stdio.h>], [printf("Hello\n");],
[archlibs_test="yes"], [archlibs_test="no"])
LIBS="$libburnia_save_LIBS"
if test x$archlibs_test = xno
then
if test x"$1" = xmandatory
then
echo >&2
echo "FATAL: Test linking with mandatory library options failed: $LIBBURN_ARCH_LIBS" >&2
echo >&2
(exit 1); exit 1;
else
if test x"$1" = xoptional
then
echo "disabled linking with $LIBBURN_ARCH_LIBS (because not found)"
fi
LIBBURN_ARCH_LIBS=""
fi
else
if test x"$1" = xsilent
then
dummy=dummy
else
echo "enabled linking with $LIBBURN_ARCH_LIBS"
fi
fi
fi
])
dnl LIBBURNIA_CHECK_LINUX_SCSI is by Thomas Schmitt, libburnia project
dnl
AC_DEFUN([LIBBURNIA_CHECK_LINUX_SCSI],
[
dnl Check whether it is a Linux without scsi/scsi.h
libburn_scsi_disabled=
if test x"$ARCH" = xlinux
then
AH_TEMPLATE([Libburn_use_sg_dummY],
[Define to compile without OS specific SCSI features])
AC_MSG_CHECKING([for missing scsi/scsi.h on Linux])
AC_TRY_COMPILE([
#ifdef __linux
#include <scsi/scsi.h>
#endif
],
[;],
[AC_MSG_RESULT([no])],
[AC_DEFINE([Libburn_use_sg_dummY], [yes])
libburn_scsi_disabled=yes
AC_MSG_RESULT([yes])]
)
fi
if test x"$libburn_scsi_disabled" = xyes
then
echo "disabled operation of optical drives via SCSI"
fi
])
dnl LIBBURNIA_CHECK_LIBCAM is by Thomas Schmitt, libburnia project
dnl
AC_DEFUN([LIBBURNIA_CHECK_LIBCAM],
[
dnl Check whether libcam is requested for FreeBSD kernel but missing
libburn_scsi_disabled=
if test x"$LIBBURN_ARCH_LIBS" = x"-lcam"
then
AH_TEMPLATE([Libburn_use_sg_dummY],
[Define to compile without OS specific SCSI features])
AC_MSG_CHECKING([for missing libcam for SCSI on FreeBSD kernel])
dnl If libcam is not available, LIBBURN_ARCH_LIBS will be made empty
LIBBURNIA_CHECK_ARCH_LIBS(silent)
if test x"$LIBBURN_ARCH_LIBS" = x
then
AC_DEFINE([Libburn_use_sg_dummY], [yes])
libburn_scsi_disabled=yes
AC_MSG_RESULT([yes])
else
AC_MSG_RESULT([no])
fi
fi
if test x"$LIBBURN_ARCH_LIBS" = x"-lcam"
then
AC_MSG_CHECKING([for missing libcam headers])
AC_TRY_COMPILE([
#include <stdio.h>
#include <camlib.h>
#include <cam/scsi/scsi_message.h>
#include <cam/scsi/scsi_pass.h>
],
[;],
[AC_MSG_RESULT([no])],
[AC_DEFINE([Libburn_use_sg_dummY], [yes])
libburn_scsi_disabled=yes
AC_MSG_RESULT([yes])]
)
fi
if test x"$libburn_scsi_disabled" = xyes
then
echo "disabled operation of optical drives via SCSI"
fi
])

View File

@ -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.4.1.tar.gz
http://scdbackup.sourceforge.net/cdrskin-1.5.7.tar.gz
Copyright (C) 2006-2015 Thomas Schmitt, provided under GPL version 2 or later.
Copyright (C) 2006-2023 Thomas Schmitt, provided under GPL version 2 or later.
------------------------------------------------------------------------------
@ -15,7 +15,7 @@ most of the libburn features from the command line.
Currently it is fully supported on GNU/Linux with kernels >= 2.4, on FreeBSD,
on OpenSolaris, and on NetBSD.
IDE drives under Linux 2.4. need kernel module ide-scsi.
IDE drives under Linux 2.4 need kernel module ide-scsi.
ATA and SATA drives under FreeBSD need kernel module atapicam.
On other X/Open compliant systems there will only be emulated drives, but no
direct MMC operation on real CD/DVD/BD drives.
@ -26,10 +26,10 @@ By using this software you agree to the disclaimer at the end of this text
Compilation, First Glimpse, Installation
Obtain cdrskin-1.4.1.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.4.1.tar.gz
cd cdrskin-1.4.1
tar xzf cdrskin-1.5.7.tar.gz
cd cdrskin-1.5.7
Within that directory execute:
@ -206,7 +206,7 @@ See output of command
If you have use cases for them, please report your wishes and expectations.
On the other hand, the capability of multi-session and of writing streams
of unpredicted lenght surpass the current DVD capabilities of cdrecord.
of unpredicted length surpass the current DVD capabilities of cdrecord.
Inspiration and Standard
@ -357,7 +357,7 @@ but leaves the media in "intermediate" state. In the first session of writing
one may only write sequentially to such a DVD. After that, it gets random
addressable by cdrskin. DVD-ROM drives might show ill behavior with them.
blank=format_overwrite_full uses preferrably "Full Format" (type 00h).
blank=format_overwrite_full uses preferably "Full Format" (type 00h).
This formatting lasts as long as writing a full DVD. It includes writing of
lead-out which is said to be good for DVD ROM compatibility.
@ -526,7 +526,7 @@ Run cdrskin by
The following settings will make pfexec keep original UID and EUID and prevent
most superuser powers. Be aware that you still can manipulate all device files
if you have the file permissions for that.
Full root privileges for cdrskin can then be aquired only by command su.
Full root privileges for cdrskin can then be acquired only by command su.
Edit /etc/security/exec_attr and add this line to the other "Media Backup"
lines:
@ -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-2014 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

View File

@ -38,7 +38,7 @@ original="./libburn_svn_release.tgz"
# My changes are in $changes , mainly in $changes/cdrskin
changes="./libburn-release"
skin_release="1.4.0"
skin_release="1.5.6"
patch_level=""
# patch_level=".pl00"
skin_rev="$skin_release""$patch_level"
@ -60,7 +60,8 @@ man_to_html_cmd="./cdrskin/convert_man_to_html.sh"
man_page_html="cdrskin/man_1_cdrskin.html"
# bintarget_dynamic="cdrskin_${skin_rev}-x86-suse9_0"
bintarget_dynamic="cdrskin_${skin_rev}-amd64-suse10_2"
# bintarget_dynamic="cdrskin_${skin_rev}-amd64-suse10_2"
bintarget_dynamic="cdrskin_${skin_rev}-amd64-debian8_0"
bintarget_static="$bintarget_dynamic"-static
if test -d "$changes"
@ -228,6 +229,7 @@ tar czf "$cdrskin_tarball" "$target"
"$compile_cmd" $compile_static_opts -O2 -do_strip
cp "$compile_result" "../$bintarget_static"
fi
( cd cdrskin ; cc -g -Wall -o unite_html_b_line unite_html_b_line.c )
"$man_to_html_cmd"
mv "$man_page_html" ..
)

View File

@ -38,7 +38,7 @@ original="./libburn_svn.tgz"
# My changes are in $changes , mainly in $changes/cdrskin
changes="./libburn-develop"
skin_release="1.4.1"
skin_release="1.5.7"
patch_level=""
skin_rev="$skin_release""$patch_level"
@ -58,7 +58,8 @@ compile_result="cdrskin/cdrskin"
man_to_html_cmd="./cdrskin/convert_man_to_html.sh"
man_page_html="cdrskin/man_1_cdrskin.html"
bintarget_dynamic="cdrskin_${skin_rev}-amd64-suse10_2"
# bintarget_dynamic="cdrskin_${skin_rev}-amd64-suse10_2"
bintarget_dynamic="cdrskin_${skin_rev}-amd64-debian8_0"
bintarget_static="$bintarget_dynamic"-static
if test -d "$changes"
@ -228,6 +229,8 @@ tar czf "$cdrskin_tarball" "$target"
fi
# "$compile_cmd" -libburn_svn -O2 -do_diet -do_strip
# cp "$compile_result" "../$bintarget_dynamic"_diet
( cd cdrskin ; cc -g -Wall -o unite_html_b_line unite_html_b_line.c )
"$man_to_html_cmd"
mv "$man_page_html" ..
)

View File

@ -1,5 +1,5 @@
/*
cdrfifo.c , Copyright 2006 Thomas Schmitt <scdbackup@gmx.net>
cdrfifo.c , Copyright 2006 - 2016 Thomas Schmitt <scdbackup@gmx.net>
A fd-to-fd or fd-to-memory fifo to be used within cdrskin or independently.
By chaining of fifo objects, several fifos can be run simultaneously
@ -26,8 +26,22 @@
#include <sys/select.h>
#ifndef Cdrfifo_standalonE
/* <<< until release of 0.7.4 : for Libburn_has_open_trac_srC */
/* for burn_os_alloc_buffer() */
#include "../libburn/libburn.h"
/* ts B91124:
DISABLED, because this spoils multi-track burning by slowing down first
track and stalling before the second track begins. Obviously a problem
with chained input and waiting for full O_DRIECT suitable read chunks.
DO NOT ENABLE before the wait code in this source file is fixed.
That long, ./configure option --enable-track-src-odirect must not
get into effect in libburn. NO -DLibburn_read_o_direcT either.
For extra safety, O_DIRECT has been banned in libburn/sg-linux.c too.
# def ine Libburn_has_open_trac_srC 1
*/
#endif
#include "cdrfifo.h"
@ -107,6 +121,9 @@ struct CdrfifO {
/* index of currently active (i.e. reading) follow-up */
int follow_up_fd_idx;
/* short read encountered, take subsequent errno 22 with O_DIRECT as EOF */
int o_direct_was_short;
/* (simultaneous) peer chaining */
struct CdrfifO *next;
@ -177,6 +194,7 @@ int Cdrfifo_new(struct CdrfifO **ff, int source_fd, int dest_fd,
}
o->follow_up_fd_counter= 0;
o->follow_up_fd_idx= -1;
o->o_direct_was_short= 0;
o->next= o->prev= NULL;
o->chain_idx= 0;
@ -696,8 +714,17 @@ after_write:;
else if(can_read < Cdrfifo_o_direct_chunK)
can_read= -1;
ret= 0;
if(can_read>0)
if(can_read>0) {
ret= read(o->source_fd,o->buffer+o->write_idx,can_read);
if(ret > 0) {
if(ret < can_read) {
/* Probably EOF. Prepare for errno = 22 in the next read. */
o->o_direct_was_short= 1;
} else {
o->o_direct_was_short= 0;
}
}
}
if(can_read < 0) {
/* waiting for a full Cdrfifo_o_direct_chunK to fit */
if(can_write <= 0 && o->dest_fd >= 0) {
@ -731,6 +758,8 @@ after_write:;
#endif /* ! Libburn_has_open_trac_srC */
if(ret==-1) {
if(o->o_direct_was_short && errno == 22)
goto have_eof;
/* >>> handle input error */;
fprintf(stderr,"\ncdrfifo %d: on read: errno=%d , \"%s\"\n",
@ -739,6 +768,7 @@ after_write:;
o->source_fd= -1;
} else if(ret==0) { /* eof */
have_eof:;
/* activate eventual follow-up source fd */
if(Cdrfifo_debuG || (flag&1))
fprintf(stderr,"\ncdrfifo %d: on read(%d,buffer,%d): eof\n",
@ -799,7 +829,7 @@ ex:;
/** Check for pending data at the fifo's source file descriptor and wether the
fifo is ready to take them. Simultaneously check the buffer for existing
data and the destination fd for readiness to accept some. If so, a small
chunk of data is transfered to and/or from the fifo.
chunk of data is transferred to and/or from the fifo.
This is done for the given fifo object and all members of its next-chain.
The check and transactions are repeated until a given timespan has elapsed.
libburn applications call this function in the burn loop instead of sleep().

View File

@ -1,6 +1,6 @@
/*
cdrfifo.c , Copyright 2006 Thomas Schmitt <scdbackup@gmx.net>
cdrfifo.c , Copyright 2006 - 2016 Thomas Schmitt <scdbackup@gmx.net>
A fd-to-fd or fd-to-memory fifo to be used within cdrskin or independently.
By chaining of fifo objects, several fifos can be run simultaneously
@ -136,7 +136,7 @@ int Cdrfifo_adopt_iso_fs_descr(struct CdrfifO *o, char **pt, int flag);
/** Check for pending data at the fifo's source file descriptor and wether the
fifo is ready to take them. Simultaneously check the buffer for existing
data and the destination fd for readiness to accept some. If so, a small
chunk of data is transfered to and/or from the fifo.
chunk of data is transferred to and/or from the fifo.
This is done for the given fifo object and all members of its next-chain.
The check and transactions are repeated until a given timespan has elapsed.
libburn applications call this function in the burn loop instead of sleep().

View File

@ -2,7 +2,7 @@
.\" First parameter, NAME, should be all caps
.\" Second parameter, SECTION, should be 1-8, maybe w/ subsection
.\" other parameters are allowed: see man(7), man(1)
.TH CDRSKIN 1 "Version 1.4.1, Aug 30, 2015"
.TH CDRSKIN 1 "Version 1.5.7, Jun 07, 2023"
.\" Please adjust this date whenever revising the manpage.
.\"
.\" Some roff macros, for reference:
@ -111,7 +111,7 @@ header part which identifies it as MS-WAVE or SUN Audio with suitable
parameters. Such files are burned as audio tracks by default.
.PP
While audio tracks just contain a given time span of acoustic vibrations,
data tracks may have an arbitray meaning. Nevertheless, ISO-9660 filesystems
data tracks may have an arbitrary meaning. Nevertheless, ISO-9660 filesystems
are established as a format which can represent a tree of directories and
files on all major operating systems. Such filesystem images can be
produced by programs mkisofs or genisoimage or xorriso.
@ -532,6 +532,7 @@ to mark the end of the range of an eventual option -audio or -xa1.
.br
Options -mode2, -xa, and -xa2 get mapped to -data, not using the desired CD
sector formats and thus not taking advantage of eventual higher payload.
.TP
.BI \-xa1
Subsequent tracks are data tracks with input suitable for CD-ROM XA mode 2
form 1. This differs from -data input by 8 additional header bytes per block.
@ -572,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.
@ -583,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.
@ -618,7 +636,8 @@ modesty_on_drive=1:min_percent=75:max_percent=95
The name of this cdrecord option stems from the "Immed" bit which can make some
long running drive commands asynchronous and thus eases the load on some
wiring hardware types. Regardless of option -immed, cdrskin uses asynchronous
commands where possible and appropriate.
commands where possible and appropriate. To really disable asynchronous command
execution, use option use_immed_bit=off .
.TP
.BI index= list
Set a comma separated list of index start address numbers for the next track.
@ -809,7 +828,7 @@ means -nocopy surely without -scms.
.TP
.BI speed= number
Set speed of drive. With data CD, 1x speed corresponds to a throughput of
150,000 bytes/second. With DVD, 1x = 1,385,000 bytes/second.
153,600 bytes/second. With DVD, 1x = 1,385,000 bytes/second.
With BD 1x = 4,495,625 bytes/second.
It is not an error to set a speed higher than is suitable for drive
and media. One should stay within a realistic speed range, though.
@ -1067,7 +1086,7 @@ padded up to the necessary size by zeros. Size -1 revokes direct writing
and switches back to normal session oriented writing.
.br
Both, write_start_address and direct_write_amount size must be aligned to a
media dependend transaction size. With DVD-RAM, BD-RE, DVD+RW this is 2k, with
media dependent transaction size. With DVD-RAM, BD-RE, DVD+RW this is 2k, with
overwriteable DVD-RW it is 32k.
.TP
.BI dvd_obs= default|32k|64k
@ -1085,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
@ -1140,7 +1159,7 @@ of bytes is read. This option may be helpful to bring the average throughput
near to the maximum throughput of a drive. A large fs= and a small
fifo_start_at= combine a quick burn start and a large savings buffer to
compensate for temporary lack of source data. At the beginning of burning,
the software protection against buffer underun is as weak as the size of
the software protection against buffer underrun is as weak as the size of
fifo_start_at= . So it is best if the drive offers hardware protection which
is enabled automatically if not driveropts=noburnfree is given.
.TP
@ -1449,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
@ -1579,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.
@ -1598,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
@ -1632,9 +1702,19 @@ This setting affects only CD SAO write runs.
.br
The first track automatically gets a pre-gap of at least 150 sectors. Its
size can only be enlarged by this call.
.TP
.BI use_immed_bit= on|off|default
Control whether several long lasting SCSI commands shall be executed with the
Immed bit, which makes the commands end early while the drive operation is
still going on. cdrskin then inquires progress indication until the drive
reports to be ready again. If this feature is turned off, then blanking and
formatting will show no progress indication.
.br
It may depend on the operating system whether use_immed_bit= is set to "off"
by default.
.TP
.BI --xa1-ignore
Silently interpret option -xa1 as -data. This may be necessary if a frontent
Silently interpret option -xa1 as -data. This may be necessary if a frontend
does not prepare -xa1 block headers but insists in using option -xa1.
.SH EXAMPLES
.SS

View File

@ -1,6 +1,6 @@
/*
cdrskin.c , Copyright 2006-2015 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.4.1"
#define Cdrskin_prog_versioN "1.5.7"
#endif
/** The official libburn interface revision to use.
@ -97,10 +97,10 @@ or
#define Cdrskin_libburn_majoR 1
#endif
#ifndef Cdrskin_libburn_minoR
#define Cdrskin_libburn_minoR 4
#define Cdrskin_libburn_minoR 5
#endif
#ifndef Cdrskin_libburn_micrO
#define Cdrskin_libburn_micrO 1
#define Cdrskin_libburn_micrO 6
#endif
@ -120,34 +120,34 @@ or
#undef Cdrskin_libburn_versioN
#endif
#ifdef Cdrskin_libburn_1_4_0
#define Cdrskin_libburn_versioN "1.4.0"
#ifdef Cdrskin_libburn_1_5_6
#define Cdrskin_libburn_versioN "1.5.6"
#endif
#ifdef Cdrskin_libburn_1_4_1
#define Cdrskin_libburn_versioN "1.4.1"
#ifdef Cdrskin_libburn_1_5_7
#define Cdrskin_libburn_versioN "1.5.7"
#endif
#ifndef Cdrskin_libburn_versioN
#define Cdrskin_libburn_1_4_0
#define Cdrskin_libburn_versioN "1.4.0"
#define Cdrskin_libburn_1_5_6
#define Cdrskin_libburn_versioN "1.5.6"
#endif
#ifdef Cdrskin_libburn_1_4_0
#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 4
#define Cdrskin_libburn_micrO 0
#define Cdrskin_libburn_minoR 5
#define Cdrskin_libburn_micrO 6
#endif
#ifdef Cdrskin_libburn_1_4_1
#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 4
#define Cdrskin_libburn_micrO 1
#define Cdrskin_libburn_minoR 5
#define Cdrskin_libburn_micrO 7
#endif
@ -1318,6 +1318,7 @@ int Cdrtrack_seek_isosize(struct CdrtracK *track, int fd, int flag)
bit1=open as source for direct write:
no audio extract, no minimum track size
bit2=permission to use burn_os_open_track_src() (evtl O_DIRECT)
bit3=This is a CD. Enforce minimum track size if not bit1.
@return <=0 error, 1 success
*/
int Cdrtrack_open_source_path(struct CdrtracK *track, int *fd, int flag)
@ -1430,7 +1431,7 @@ int Cdrtrack_open_source_path(struct CdrtracK *track, int *fd, int flag)
track->source_fd= *fd;
if(track->fixed_size < Cdrtrack_minimum_sizE * track->sector_size
&& (track->fixed_size>0 || size_from_file) && !(flag&2)) {
&& (track->fixed_size>0 || size_from_file) && (flag & 8) && !(flag&2)) {
if(track->track_type == BURN_AUDIO) {
/* >>> cdrecord: We differ in automatic padding with audio:
Audio tracks must be at least 705600 bytes and a multiple of 2352.
@ -1446,7 +1447,7 @@ int Cdrtrack_open_source_path(struct CdrtracK *track, int *fd, int flag)
track->fixed_size= Cdrtrack_minimum_sizE*track->sector_size;
}
}
return((*fd >= 0) * (2 * self_opened));
return((*fd >= 0) * (1 + self_opened));
}
@ -1461,6 +1462,8 @@ int Cdrtrack_open_source_path(struct CdrtracK *track, int *fd, int flag)
bit1= Do not create and attach a new fifo
but attach new follow-up fd pair to previous_fifo
bit2= Do not enforce fixed_size if not container extraction
bit3= This is a CD. Enforce minimum track size.
(Forward to Cdrtrack_open_source_path)
@return <=0 error, 1 success
*/
int Cdrtrack_attach_fifo(struct CdrtracK *track, int *outlet_fd,
@ -1473,7 +1476,7 @@ int Cdrtrack_attach_fifo(struct CdrtracK *track, int *outlet_fd,
if(track->fifo_size<=0)
return(2);
ret= Cdrtrack_open_source_path(track,&source_fd,
(flag&1) | (4 * (track->fifo_size >= 256 * 1024)));
(flag & (1 | 8)) | (4 * (track->fifo_size >= 256 * 1024)));
if(ret<=0)
return(ret);
if(pipe(pipe_fds)==-1)
@ -1701,6 +1704,7 @@ int Cdrtrack_add_to_session(struct CdrtracK *track, int trackno,
bit0= debugging verbosity
bit1= apply padding hack (<<< should be unused for now)
bit2= permission to use O_DIRECT (if enabled at compile time)
bit3= This is a CD. (Forward to Cdrtrack_open_source_path)
*/
{
struct burn_track *tr;
@ -1723,7 +1727,7 @@ int Cdrtrack_add_to_session(struct CdrtracK *track, int trackno,
/* Note: track->track_type may get set in here */
if(track->source_fd==-1) {
ret= Cdrtrack_open_source_path(track, &source_fd, flag & (4 | 1));
ret= Cdrtrack_open_source_path(track, &source_fd, flag & (8 | 4 | 1));
if(ret<=0)
goto ex;
}
@ -1906,7 +1910,7 @@ static char Cdrpreskin_sys_rc_nameS[Cdrpreskin_rc_nuM][80]= {
*/
struct CdrpreskiN {
/* to be transfered into skin */
/* to be transferred into skin */
int verbosity;
char queue_severity[81];
char print_severity[81];
@ -2855,7 +2859,7 @@ set_dev:;
printf(" --drive_not_exclusive combined not_o_excl and not_f_setlk.\n");
printf(" --drive_not_f_setlk do not obtain exclusive lock via fcntl.\n");
printf(" --drive_not_o_excl do not ask kernel to prevent opening\n");
printf(" busy drives. Effect is kernel dependend.\n");
printf(" busy drives. Effect is kernel dependent.\n");
printf(
" drive_scsi_dev_family=<sr|scd|sg|default> select Linux device\n");
printf(" file family to be used for (pseudo-)SCSI.\n");
@ -2900,6 +2904,7 @@ set_dev:;
printf(" --list_formats list format descriptors for loaded media.\n");
printf(" --list_ignored_options list all ignored cdrecord options.\n");
printf(" --list_speeds list speed descriptors for loaded media.\n");
printf(" --list_features list SCSI features reported by the drive\n");
printf(" --long_toc print overview of media content\n");
printf(" modesty_on_drive=<options> no writing into full drive buffer\n");
printf(" --no_abort_handler exit even if the drive is in busy state\n");
@ -2909,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(
@ -2949,6 +2956,8 @@ set_dev:;
printf(
" print CD-TEXT file in Sony format and exit.\n");
printf(" --two_channel indicate that audio tracks have 2 channels\n");
printf(
" use_immed_bit=on|off|default real control over SCSI Immed bit\n");
printf(
" write_start_address=<num> write to given byte address (DVD+RW)\n");
printf(
@ -3145,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) {
@ -3166,7 +3176,7 @@ set_severities:;
int major, minor, micro;
printf(
"Cdrecord 2.01a27 Emulation. Copyright (C) 2006-2014, 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];
@ -3329,11 +3339,12 @@ ex:;
/** List of furter wishes towards libburn:
- a possibilty to implement cdrskin -reset
- a possibility to implement cdrskin -reset
*/
#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 */
@ -3358,7 +3369,7 @@ static double Cdrskin_libburn_bd_speed_factoR= 4495.625;
/* The effective speed conversion factor for burn_drive_set_speed() */
static double Cdrskin_libburn_speed_factoR= 176.4;
/** Add-on for burn_drive_set_speed() to accomodate to the slightley oversized
/** Add-on for burn_drive_set_speed() to accommodate to the slightly oversized
speed ideas of my LG DVDRAM GSA-4082B. LITE-ON LTR-48125S tolerates it.
*/
static double Cdrskin_libburn_cd_speed_addoN= 40.0;
@ -3384,9 +3395,13 @@ 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;
int use_immed; /* 1= yes, 0= libburn default, -1= no */
int do_devices; /* 1= --devices , 2= --device_links */
@ -3402,6 +3417,7 @@ struct CdrskiN {
int do_atip;
int do_list_speeds;
int do_list_formats;
int do_list_features;
int do_cdtext_to_textfile;
char cdtext_to_textfile_path[Cdrskin_strleN];
int do_cdtext_to_vt07;
@ -3476,7 +3492,7 @@ struct CdrskiN {
int tell_media_space; /* actually do not burn but tell the available space */
int burnfree;
/** The write mode (like SAO or TAO). See libburn.
Controled by preskin->write_mode_name */
Controlled by preskin->write_mode_name */
enum burn_write_types write_type;
int block_type;
int multi;
@ -3656,9 +3672,11 @@ 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;
o->use_immed= 0;
o->do_devices= 0;
o->do_scanbus= 0;
o->do_load= 0;
@ -3668,6 +3686,7 @@ int Cdrskin_new(struct CdrskiN **skin, struct CdrpreskiN *preskin, int flag)
o->do_atip= 0;
o->do_list_speeds= 0;
o->do_list_formats= 0;
o->do_list_features= 0;
o->do_cdtext_to_textfile= 0;
o->cdtext_to_textfile_path[0]= 0;
o->do_cdtext_to_vt07= 0;
@ -3902,9 +3921,6 @@ int Cdrskin_attach_fifo(struct CdrskiN *skin, int flag)
{
struct CdrfifO *ff= NULL;
int ret,i,hflag;
#ifdef Cdrskin_use_libburn_fifO
int profile_number;
char profile_name[80];
@ -3912,9 +3928,12 @@ int Cdrskin_attach_fifo(struct CdrskiN *skin, int flag)
if(ret <= 0)
return(ret);
/* Refuse here and thus use libburn fifo only with single track, non-CD */
ret= burn_disc_get_profile(skin->drives[skin->driveno].drive,
&profile_number, profile_name);
#ifdef Cdrskin_use_libburn_fifO
/* Refuse here and thus use libburn fifo only with single track, non-CD */
if(profile_number != 0x09 && profile_number != 0x0a &&
skin->track_counter == 1)
return(1);
@ -3923,7 +3942,8 @@ int Cdrskin_attach_fifo(struct CdrskiN *skin, int flag)
skin->fifo= NULL;
for(i=0;i<skin->track_counter;i++) {
hflag= (skin->verbosity>=Cdrskin_verbose_debuG);
hflag= (skin->verbosity>=Cdrskin_verbose_debuG) |
((profile_number == 0x09 || profile_number == 0x0a) << 3);
if(i==skin->track_counter-1)
hflag|= 4;
if(skin->verbosity>=Cdrskin_verbose_cmD) {
@ -4169,6 +4189,8 @@ aborted:;
goto ex;
}
}
if(skin->use_immed != 0)
burn_drive_set_immed(drive, skin->use_immed > 0);
skin->drive_is_grabbed= 1;
s= burn_disc_get_status(drive);
@ -4439,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;}
}
@ -5096,7 +5125,7 @@ int Cdrskin_cdtext_to_file(struct CdrskiN *skin, char *path, int flag)
printf("CD-Text len: %d\n", num_packs * 18 + 4);
} else {
fprintf(stderr, "cdrskin: FATAL : Program error : Unknow format %d with Cdrskin_cdtext_to_file.\n", fmt);
fprintf(stderr, "cdrskin: FATAL : Program error : Unknown format %d with Cdrskin_cdtext_to_file.\n", fmt);
{ret= -1; goto ex;}
}
ret= 1;
@ -5128,7 +5157,7 @@ int Cdrskin_toc(struct CdrskiN *skin, int flag)
struct burn_toc_entry toc_entry;
enum burn_disc_status s;
char profile_name[80];
int profile_number;
int profile_number, is_bdr_pow= 0;
drive= skin->drives[skin->driveno].drive;
@ -5249,8 +5278,10 @@ summary:
if(open_sessions > 0 && !have_real_open_session)
open_sessions--;
is_bdr_pow= burn_drive_get_bd_r_pow(drive);
printf("Media summary: %d sessions, %d tracks, %s %s\n",
num_sessions + open_sessions, track_count,
is_bdr_pow ? "unusable (POW)" :
s==BURN_DISC_BLANK ? "blank" :
s==BURN_DISC_APPENDABLE ? "appendable" :
s==BURN_DISC_FULL ? "closed" :
@ -5288,7 +5319,7 @@ int Cdrskin_minfo(struct CdrskiN *skin, int flag)
struct burn_toc_entry toc_entry;
enum burn_disc_status s, show_status;
char profile_name[80];
int pno;
int pno, is_bdr_pow= 0;
char media_class[80];
int nominal_sessions= 1, ftils= 1, ltils= 1, first_track= 1, read_capacity= 0;
int app_code, cd_info_valid, lra, alloc_blocks, free_blocks;
@ -5317,10 +5348,12 @@ int Cdrskin_minfo(struct CdrskiN *skin, int flag)
strcpy(media_class, "BD");
else
sprintf(media_class, "Unknown class (profile 0x%4.4X)", pno);
is_bdr_pow= burn_drive_get_bd_r_pow(drive);
printf("\n");
printf("Mounted media class: %s\n", media_class);
printf("Mounted media type: %s\n", profile_name);
printf("Mounted media type: %s%s\n", profile_name,
is_bdr_pow ? ", Pseudo Overwrite formatted" : "");
ret= burn_disc_erasable(drive);
printf("Disk Is %serasable\n",
(ret || skin->media_is_overwriteable) ? "" : "not ");
@ -5333,6 +5366,7 @@ int Cdrskin_minfo(struct CdrskiN *skin, int flag)
if(ovwrt_full)
show_status= BURN_DISC_FULL;
printf("disk status: %s\n",
is_bdr_pow ? "unusable (POW)" :
show_status == BURN_DISC_BLANK ? "empty" :
show_status == BURN_DISC_APPENDABLE ? "incomplete/appendable" :
show_status == BURN_DISC_FULL ? "complete" :
@ -5570,7 +5604,7 @@ int Cdrskin_atip(struct CdrskiN *skin, int flag)
char profile_name[80], *manuf= NULL, *media_code1= NULL, *media_code2= NULL;
char *book_type= NULL, *product_id= NULL;
char *sno= NULL;
int sno_len = 0, i;
int sno_len = 0, i, is_bdr_pow= 0;
ClN(printf("cdrskin: pseudo-atip on drive %d\n",skin->driveno));
ret= Cdrskin_grab_drive(skin,0);
@ -5645,7 +5679,9 @@ int Cdrskin_atip(struct CdrskiN *skin, int flag)
if(profile_number==0x13) /* DVD-RW */
printf("cdrskin: message for sdvdbackup: \"(growisofs mode Restricted Overwrite)\"\n");
} else if(strstr(profile_name,"BD")==profile_name) {
printf("Mounted Media: %2.2Xh, %s\n", profile_number, profile_name);
is_bdr_pow= burn_drive_get_bd_r_pow(drive);
printf("Mounted Media: %2.2Xh, %s%s\n", profile_number, profile_name,
is_bdr_pow ? ", Pseudo Overwrite formatted" : "");
} else {
printf("ATIP info from disk:\n");
if(burn_disc_erasable(drive)) {
@ -5760,6 +5796,7 @@ int Cdrskin_list_formats(struct CdrskiN *skin, int flag)
{
struct burn_drive *drive;
int ret, i, status, num_formats, profile_no, type, alloc_blocks, free_blocks;
int is_bdr_pow= 0;
off_t size;
unsigned dummy;
char status_text[80], profile_name[90];
@ -5776,10 +5813,12 @@ int Cdrskin_list_formats(struct CdrskiN *skin, int flag)
ret= 0; goto ex;
}
ret= burn_disc_get_profile(drive, &profile_no, profile_name);
is_bdr_pow= burn_drive_get_bd_r_pow(drive);
printf("Media current: ");
if(profile_no > 0 && ret > 0) {
if(profile_name[0])
printf("%s\n", profile_name);
printf("%s%s\n", profile_name,
is_bdr_pow ? ", Pseudo Overwrite formatted" : "");
else
printf("%4.4Xh\n", profile_no);
} else
@ -5829,7 +5868,7 @@ ex:;
int Cdrskin_list_speeds(struct CdrskiN *skin, int flag)
{
struct burn_drive *drive;
int ret, i, profile_no, high= -1, low= 0x7fffffff, is_cd= 0;
int ret, i, profile_no, high= -1, low= 0x7fffffff, is_cd= 0, is_bdr_pow= 0;
char profile_name[90], *speed_unit= "D";
double speed_factor= 1385000.0, cd_factor= 75.0 * 2352;
struct burn_speed_descriptor *speed_list= NULL, *item, *other;
@ -5844,10 +5883,12 @@ int Cdrskin_list_speeds(struct CdrskiN *skin, int flag)
ret= 0; goto ex;
}
ret= burn_disc_get_profile(drive, &profile_no, profile_name);
is_bdr_pow= burn_drive_get_bd_r_pow(drive);
printf("Media current: ");
if(profile_no > 0 && ret > 0) {
if(profile_name[0])
printf("%s\n", profile_name);
printf("%s%s\n", profile_name,
is_bdr_pow ? ", Pseudo Overwrite formatted" : "");
else
printf("%4.4Xh\n", profile_no);
} else
@ -5933,6 +5974,128 @@ ex:;
}
/* @param flag: bit0= do not print prefix on first line
bit1= plan for multiples of 4 hex words
*/
static int Feature_printf(char *prefix, char *text, int flag)
{
char *tpt, *npt;
int lp, lp0, line_size;
lp0= !(flag & 1);
tpt= text;
lp= strlen(prefix);
/* Plan 2 char shorter for possible comma inclusion */
line_size= 77;
if(flag & 2) {
line_size= (80 - lp) / 3;
line_size-= line_size % 4;
line_size= line_size * 3 - 1 + lp;
}
while(lp * lp0 + strlen(tpt) >= 80) {
/* Line size for 20 */
for(npt= tpt + line_size - lp * lp0; npt > tpt; npt--)
if(*npt == ' ')
break;
if(npt <= tpt) {
printf("%s%s\n", lp0 ? prefix : "", tpt);
return(2);
}
/* Keep comma in printed line */
if(*(npt + 1) == ',' && *(npt + 1) == ' ')
npt+= 2;
/* Print and advance */
*npt= 0;
printf("%s%s\n", lp0 ? prefix : "", tpt);
tpt= npt + 1;
lp0= 1;
}
printf("%s%s\n", lp0 ? prefix : "", tpt);
return(1);
}
/** Perform --list_features
@param flag Bitfield for control purposes:
@return <=0 error, 1 success
*/
int Cdrskin_list_features(struct CdrskiN *skin, int flag)
{
struct burn_drive *d;
int ret, count, i, j;
unsigned int *feature_codes= NULL;
unsigned char flags, additional_length, *feature_data = NULL;
char *feature_text = NULL, *cpt, *dpt;
ret= Cdrskin_grab_drive(skin,0);
if(ret <= 0)
return(ret);
d= skin->drives[skin->driveno].drive;
fprintf(stderr, "SCSI Features reported by the drive:\n");
fprintf(stderr,
" + = Current, - = Not Current, P = Persistent, N = Not Persistent\n");
fprintf(stderr, "Code C : Name : Version,Persistent\n");
fprintf(stderr, " Additional data if present (hex bytes)\n");
fprintf(stderr, " Parsed info if available (fieldname=content)\n");
fprintf(stderr, "\n");
burn_drive_get_feature_codes(d, &count, &feature_codes);
if(count <= 0) {
fprintf(stderr, "cdrskin: NOTE: The drive feature list is empty\n");
ret= 1; goto ex;
}
for(i= 0; i < count; i++) {
ret= burn_drive_get_feature(d, feature_codes[i], &flags, &additional_length,
&feature_data, &feature_text);
if(ret <= 0) {
fprintf(stderr, "cdrskin: SORRY: Cannot obtain data of feature %4.4x\n",
feature_codes[i]);
continue;
}
cpt= feature_text;
for(j= 0; j < 3 && cpt != NULL; j++)
cpt= strchr(cpt + 1, ':');
if(cpt != NULL) {
*cpt= 0;
cpt++;
}
Feature_printf(" ", feature_text, 1);
if(cpt != NULL) {
dpt= cpt;
if(*dpt == ' ')
dpt++;
for(j= 0; j < 1 && cpt != NULL; j++)
cpt= strchr(cpt + 1, ':');
if(cpt != NULL) {
*cpt= 0;
cpt++;
}
Feature_printf(" ", dpt, 2);
}
if(cpt != NULL) {
if(*cpt == ' ')
cpt++;
Feature_printf(" ", cpt, 0);
} else {
printf("\n");
}
if(feature_data != NULL)
free(feature_data);
feature_data= NULL;
if(feature_text != NULL)
free(feature_text);
feature_text= NULL;
}
ret= 1;
ex:;
if(feature_codes != NULL)
free(feature_codes);
return(ret);
}
int Cdrskin_read_textfile(struct CdrskiN *skin, char *path, int flag)
{
int ret, num_packs = 0;
@ -6163,12 +6326,12 @@ int Cdrskin_blank(struct CdrskiN *skin, int flag)
struct burn_progress p;
struct burn_drive *drive;
int ret,loop_counter= 0,hint_force= 0,do_format= 0, profile_number= -1;
int wrote_well= 1, format_flag= 0, status, num_formats;
int wrote_well= 1, format_flag= 0, status, num_formats, using_immed= 1;
off_t size;
unsigned dummy;
double start_time;
char *verb= "blank", *presperf="blanking", *fmt_text= "...";
char profile_name[80];
char profile_name[80], progress_text[40];
static char fmtp[][40]= {
"...", "format_overwrite", "deformat_sequential",
"(-format)", "format_defectmgt", "format_by_index",
@ -6379,6 +6542,7 @@ unsupported_format_type:;
if(Cdrskin__is_aborting(0))
{ret= 0; goto ex;}
using_immed= burn_drive_get_immed(drive);
skin->drive_is_busy= 1;
if(do_format==0 || do_format==2) {
burn_disc_erase(drive,skin->blank_fast);
@ -6401,6 +6565,8 @@ unsupported_format_type:;
loop_counter= 0;
start_time= Sfile_microtime(0);
if(!using_immed)
sprintf(progress_text, "synchronous");
while(burn_drive_get_status(drive, &p) != BURN_DRIVE_IDLE) {
if(loop_counter>0)
if(skin->verbosity>=Cdrskin_verbose_progresS) {
@ -6408,10 +6574,14 @@ unsupported_format_type:;
if(p.sectors>0) /* i want a display of 1 to 99 percent */
percent= 1.0+((double) p.sector+1.0)/((double) p.sectors)*98.0;
if(using_immed)
sprintf(progress_text, "done %.1f%%", percent);
fprintf(stderr,
"%scdrskin: %s ( done %.1f%% , %lu seconds elapsed ) %s",
"%scdrskin: %s ( %s , %lu seconds elapsed ) %s",
skin->pacifier_with_newline ? "" : "\r",
presperf,percent,(unsigned long) (Sfile_microtime(0)-start_time),
presperf,
progress_text,
(unsigned long) (Sfile_microtime(0)-start_time),
skin->pacifier_with_newline ? "\n" : "");
}
sleep(1);
@ -6976,6 +7146,7 @@ int Cdrskin_direct_write(struct CdrskiN *skin, int flag)
int ret, max_chunksize= 64*1024, source_fd= -1, is_from_stdin, eof_sensed= 0;
int self_opened= 0;
char *buf= NULL, *source_path, amount_text[81];
char *dummy_text= "";
struct burn_multi_caps *caps= NULL;
ret= Cdrskin_grab_drive(skin,0);
@ -7029,8 +7200,11 @@ int Cdrskin_direct_write(struct CdrskiN *skin, int flag)
sprintf(amount_text,"%.fk",(double) (data_count/1024));
else
strcpy(amount_text,"0=open_ended");
fprintf(stderr,"Beginning direct write (start=%.fk,amount=%s) ...\n",
(double) (byte_address/1024),amount_text);
burn_drive_reset_simulate(skin->grabbed_drive, !!skin->dummy_mode);
if(skin->dummy_mode)
dummy_text= " simulation of";
fprintf(stderr,"Beginning%s direct write (start=%.fk,amount=%s) ...\n",
dummy_text, (double) (byte_address / 1024), amount_text);
for(i= 0; i<data_count || data_count==0; i+= chunksize) {
if(data_count==0)
chunksize= (alignment > 0 ? alignment : 2048);
@ -7295,14 +7469,14 @@ int Cdrskin_burn(struct CdrskiN *skin, int flag)
int source_fd, is_from_stdin;
int text_flag= 4; /* Check CRCs and silently repair CRCs if all are 0 */
unsigned char *text_packs= NULL;
int num_packs= 0, start_block, block_no;
int num_packs= 0, start_block, block_no, profile_number;
#ifndef Cdrskin_no_cdrfifO
double put_counter, get_counter, empty_counter, full_counter;
int total_min_fill, fifo_percent;
#endif
off_t free_space;
char msg[80];
char msg[80], profile_name[80];
if(skin->tell_media_space)
doing= "estimating";
@ -7322,6 +7496,7 @@ int Cdrskin_burn(struct CdrskiN *skin, int flag)
s= burn_disc_get_status(drive);
if(skin->verbosity>=Cdrskin_verbose_progresS)
Cdrskin_report_disc_status(skin,s,1);
burn_disc_get_profile(drive, &profile_number, profile_name);
disc= burn_disc_create();
session= burn_session_create();
@ -7377,7 +7552,9 @@ burn_failed:;
/* if(skin->fifo_size >= 256 * 1024) */
hflag|= 4;
hflag|= 4;
if(profile_number == 0x09 || profile_number == 0x0a)
hflag|= 8;
ret= Cdrtrack_add_to_session(skin->tracklist[i],i,session,hflag);
if(ret<=0) {
@ -7535,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) {
@ -7924,7 +8102,7 @@ int Cdrskin_qcheck(struct CdrskiN *skin, int flag)
int Cdrskin_msinfo(struct CdrskiN *skin, int flag)
{
int num_sessions, session_no, ret, num_tracks, open_sessions= 0;
int nwa= -123456789, lba= -123456789, aux_lba;
int nwa= -123456789, lba= -123456789, aux_lba, is_bdr_pow= 0;
char msg[80];
enum burn_disc_status s;
struct burn_drive *drive;
@ -7953,6 +8131,12 @@ int Cdrskin_msinfo(struct CdrskiN *skin, int flag)
fprintf(stderr,"cdrskin: or on overwriteables with existing ISO-9660 file system.\n");
{ret= 0; goto ex;}
}
is_bdr_pow= burn_drive_get_bd_r_pow(drive);
if(is_bdr_pow) {
fprintf(stderr,
"cdrskin: FATAL : -msinfo cannot operate on POW formatted BD-R discs\n");
{ret= 0; goto ex;}
}
disc= burn_drive_get_disc(drive);
if(disc==NULL) {
/* No TOC available. Try to inquire directly. */
@ -8800,6 +8984,10 @@ set_isrc:;
skin->do_list_speeds= 1;
skin->preskin->demands_cdrskin_caps= 1;
} else if(strcmp(argv[i],"--list_features")==0) {
skin->do_list_features= 1;
skin->preskin->demands_cdrskin_caps= 1;
} else if(strncmp(argv[i],"fallback_program=",17)==0) {
/* is handled in Cdrpreskin_setup() */;
@ -8997,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() */;
@ -9212,7 +9403,20 @@ track_too_large:;
} else if(strcmp(argv[i],"--two_channel")==0) {
skin->track_modemods&= ~BURN_4CH;
} else if(strcmp(argv[i],"-V")==0 || strcmp(argpt, "-Verbose")==0) {
} else if(strncmp(argv[i], "use_immed_bit=", 14) == 0) {
if(strcmp(argv[i] + 14, "on") == 0) {
skin->use_immed= 1;
} else if(strcmp(argv[i] + 14, "off") == 0) {
skin->use_immed= -1;
} else if(strcmp(argv[i] + 14, "default") == 0) {
skin->use_immed= 0;
} else {
fprintf(stderr, "cdrskin: FATAL : use_immed_bits= must be \"on\", \"off\", or \"default\"\n");
return(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() */;
@ -9656,6 +9860,15 @@ int Cdrskin_run(struct CdrskiN *skin, int *exit_value, int flag)
if(ret<=0)
{*exit_value= 16; goto ex;}
}
if(skin->do_list_features) {
if(skin->n_drives<=0)
{*exit_value= 20; goto no_drive;}
if(Cdrskin__is_aborting(0))
goto ex;
ret= Cdrskin_list_features(skin, 0);
if(ret<=0)
{*exit_value= 20; goto ex;}
}
if(skin->do_blank) {
if(skin->n_drives<=0)
{*exit_value= 8; goto no_drive;}

View File

@ -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.4.0</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.4.0.tar.gz">cdrskin-1.4.0.tar.gz</A>
(975 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.4.0.tar.gz.sig">cdrskin-1.4.0.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.4.0.tar.gz.sig cdrskin-1.4.0.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
@ -247,8 +247,8 @@ cdrskin_0.4.2.pl00-x86-suse9_0-static.tar.gz</A>, (310 KB), -static compiled,
</DL>
<DL><DT>Contact:</DT>
<DD>Thomas Schmitt, <A HREF="mailto:scdbackup@gmx.net">scdbackup@gmx.net</A></DD>
<DD>libburn development mailing list,
<A HREF="mailto:libburn-hackers@pykix.org">libburn-hackers@pykix.org</A></DD>
<DD>GNU xorriso mailing list, where cdrskin and libburn are on topic, too:
<A HREF="mailto:bug-xorriso@gnu.org">bug-xorriso@gnu.org</A></DD>
</DL>
<DL><DT>License:</DT>
<DD><A HREF="COPYING_cdrskin">GPL</A>, an <A HREF="http://www.opensource.org/">Open Source</A> approved license</DD>
@ -259,38 +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.3.8:
Enhancements towards previous stable version cdrskin-1.5.4:
<UL>
<LI>none</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.3.8:
Bug fixes towards cdrskin-1.5.4:
<UL>
<LI>Double free with cdrskin -vvv. Introduced with rev 5065, version 1.3.1</LI>
<LI>Wrong read access to memory. Reported by valgrind of lian jianfei.</LI>
<!--
<LI>none</LI>
-->
<LI>Overburning with cdrskin option -force ended by a libburn error</LI>
</UL>
<!--
-->
<HR>
<P>
<DL>
<DT><H3>Development snapshot, version 1.4.1 :</H3></DT>
<DD>Enhancements towards current stable version 1.4.0:
<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.4.0:
Bug fixes towards cdrskin-1.5.6:
<UL>
<LI>none yet</LI>
<!--
@ -300,14 +297,15 @@ Bug fixes towards cdrskin-1.3.8:
</DD>
<DD>&nbsp;</DD>
<DD><A HREF="README_cdrskin_devel">README 1.4.1</A>
<DD><A HREF="cdrskin__help_devel">cdrskin-1.4.1 --help</A></DD>
<DD><A HREF="cdrskin_help_devel">cdrskin-1.4.1 -help</A></DD>
<DD><A HREF="man_1_cdrskin_devel.html">man cdrskin (as of 1.4.1)</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>&nbsp;</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>
@ -323,8 +321,8 @@ admins with full system sovereignty.</DT>
<A HREF="README_cdrskin_devel">upcoming README</A> ):
</DD>
<DD>
<A HREF="cdrskin-1.4.1.tar.gz">cdrskin-1.4.1.tar.gz</A>
(975 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
@ -499,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>

View File

@ -1 +1 @@
#define Cdrskin_timestamP "2015.11.25.093414"
#define Cdrskin_timestamP "2024.03.09.175618"

File diff suppressed because it is too large Load Diff

View File

@ -1,14 +1,14 @@
#!/bin/sh
# compile_cdrskin.sh
# Copyright 2005 - 2015 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_4_1"
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_4_0"
elif test "$i" = "-libburn_1_5_6"
then
libvers="-DCdrskin_libburn_1_4_0"
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_4_1"
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_4_0 set macro to match libburn-1.4.0"
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."

View File

@ -85,7 +85,7 @@ Option blank= offers several specialized blanking and formatting types,
which one may use for particular purposes on DVD-RW, DVD-RAM and BD-RE.
(See also below: blank=format_overwrite)
The drive offers a list of possible formats by cdrskin option --list_formats.
One should aquire MMC background information before making use of them.
One should acquire MMC background information before making use of them.
--------------------------------------------------------------------------
@ -263,7 +263,7 @@ would be the appropriate translation:
{{{
dev_translation=+0,0,0+/dev/hdc
}}}
The "+" character is a separator to be choosen by you.
The "+" character is a separator to be chosen by you.
Currently i am not aware of the need to choose any other than "+"
unless you get playful with custom translations like
{{{

View File

@ -1,4 +1,4 @@
AC_INIT([libburn], [1.4.1], [http://libburnia-project.org])
AC_INIT([libburn], [1.5.7], [http://libburnia-project.org])
AC_PREREQ([2.50])
dnl AC_CONFIG_HEADER([config.h])
@ -106,6 +106,14 @@ dnl 1.3.4 = libburn.so.4.87.0
dnl 1.3.6 = libburn.so.4.89.0
dnl 1.3.8 = libburn.so.4.91.0
dnl 1.4.0 = libburn.so.4.93.0
dnl 1.4.2 = libburn.so.4.95.0
dnl 1.4.4 = libburn.so.4.97.0
dnl 1.4.6 = libburn.so.4.99.0
dnl 1.4.8 = libburn.so.4.101.0
dnl 1.5.0 = libburn.so.4.103.0
dnl 1.5.2 = libburn.so.4.105.0
dnl 1.5.4 = libburn.so.4.107.0
dnl 1.5.6 = libburn.so.4.109.0
dnl
dnl So LT_CURRENT, LT_REVISION and LT_AGE get set directly here.
dnl SONAME of the emerging library is LT_CURRENT - LT_AGE.
@ -130,8 +138,8 @@ dnl If BURN_*_VERSION changes, be sure to change AC_INIT above to match.
dnl
dnl As said: Only copies. Original in libburn/libburn.h : burn_header_version_*
BURN_MAJOR_VERSION=1
BURN_MINOR_VERSION=4
BURN_MICRO_VERSION=1
BURN_MINOR_VERSION=5
BURN_MICRO_VERSION=7
BURN_VERSION=$BURN_MAJOR_VERSION.$BURN_MINOR_VERSION.$BURN_MICRO_VERSION
AC_SUBST(BURN_MAJOR_VERSION)
@ -142,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.4.0
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 ### LT_CURRENT++, LT_AGE++ has not yet happened.
dnl LT_CURRENT++, LT_AGE++ has happened meanwhile.
dnl
dnl SONAME = 97 - 93 = 4 . Linux library name = libburn.so.4.93.0
LT_CURRENT=97
LT_AGE=93
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`
@ -168,12 +176,12 @@ AC_SUBST(BURN_BINARY_AGE)
AC_PREFIX_DEFAULT([/usr/local])
test "$prefix" = "NONE" && prefix=$ac_default_prefix
AM_MAINTAINER_MODE
dnl ts B90405 : Disabled on advise of Ross Burton
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
@ -185,7 +193,7 @@ fi
AC_PROG_LIBTOOL
AC_SUBST(LIBTOOL_DEPS)
LIBTOOL="$LIBTOOL --silent"
# LIBTOOL="$LIBTOOL --silent"
AC_PROG_INSTALL
@ -211,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"
@ -295,6 +304,10 @@ else
fi
fi
dnl ts B70127
# There are Linuxes with no public generic SCSI interface
LIBBURNIA_CHECK_LINUX_SCSI
dnl ts B00704
# Library versioning normally serves a complex purpose.
# Since libburn obeys strict ABI backward compatibility, it needs only the
@ -316,6 +329,9 @@ else
echo "disabled strict symbol encapsulation"
fi
# Check for system dependent mandatory libraries (LIBBURN_ARCH_LIBS)
LIBBURNIA_CHECK_ARCH_LIBS(mandatory)
AC_ARG_ENABLE(ldconfig-at-install,
[ --enable-ldconfig-at-install On GNU/Linux run ldconfig, default=yes],
, ldconfig_at_install=yes)

View File

@ -803,7 +803,7 @@ Two format types are relevant for DVD-RAM : 00h and 01h.
00h offers the default size format and usually a maximum payload size format.
Even with that maximum size payload there is hardware defect management.
(mmc5r03c.pdf 6.5.4.2.1.2)
01h can convert payload capacity into spare blocks for defect managment.
01h can convert payload capacity into spare blocks for defect management.
There is no way to increase payload capacity by format 01h.
(mmc5r03c.pdf 6.5.4.2.2.1)
@ -895,7 +895,8 @@ The term "superblock" shall depict the first 64 KiB after the sbsector address.
ISO 9660 multi-session depends on typical TOC information in two ways:
It needs the superblock address MSC1 of the most recently recorded session and
it needs the Next Writeable Address NWA for which to prepare the adress offset.
it needs the Next Writeable Address NWA for which to prepare the address
offset.
The following is learned from growisofs and from ECMA-119:
http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-119.pdf

View File

@ -54,7 +54,7 @@ PROJECT_LOGO =
# If a relative path is entered, it will be relative to the location
# where doxygen was started. If left blank the current directory will be used.
OUTPUT_DIRECTORY = @abs_top_builddir@
OUTPUT_DIRECTORY =
# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create
# 4096 sub-directories (in 2 levels) under the output directory of each output
@ -1477,18 +1477,6 @@ GENERATE_XML = NO
XML_OUTPUT = xml
# The XML_SCHEMA tag can be used to specify an XML schema,
# which can be used by a validating XML parser to check the
# syntax of the XML files.
XML_SCHEMA =
# The XML_DTD tag can be used to specify an XML DTD,
# which can be used by a validating XML parser to check the
# syntax of the XML files.
XML_DTD =
# If the XML_PROGRAMLISTING tag is set to YES Doxygen will
# dump the program listings (including syntax highlighting
# and cross-referencing information) to the XML output. Note that

View File

@ -34,7 +34,7 @@ CD-ROM media (0x08) cannot be inquired by command 43h READ TOC/PMA/ATIP.
in 6.26.3.6 Response Format 0100b: ATIP.
The minute, second, and frame number of lead-in can be read from byte 4 to 6
of the ATIP descriptor. The lead-out bytes are at position 8 to 10. The ATIP
descriptor is preceeded by a four byte header.
descriptor is preceded by a four byte header.
I could not find out yet whether (lead-in,lead-out) is mandatorily unique for
each particular media product.
@ -176,7 +176,7 @@ BD-R and BD-RE:
printf (" Media ID: %6.6s/%-3.3s\n",di+4+100,di+4+106);
= MMC-5 6.23.3.3.1 Format Code 00h: Disc Information (DI)
Table 288 says that Media Type Code (byte 1 of CDB) for BD media is 1.
Table 446 says that Disc Information is preceeded by 4 bytes of header.
Table 446 says that Disc Information is preceded by 4 bytes of header.
Table 448 says that bytes 0 to 1 are Disc Information Identifier "DI".
that bytes 8 to 10 are Disc Type Identifier
BDO for BD-ROM, BDW for BD-RE,
@ -1080,6 +1080,7 @@ OTCBRE 001 Optodisc Technology Corporation 1-2X HTL 25GB (12cm) [Blu]
"Moser Baer India Limited"
PHILIP R02 Moser Baer India Ltd 1-2X HTL 25GB [Blu]
PHILIP R04 Moser Baer India Ltd 1-4X HTL 25GB [Blu]
PHILIPR0 R04 TDK 4x 25 GB (own buy)
PHILIP W02 Moser Baer India Ltd 1-2X HTL 25GB [Blu]
"Philips"

84
doc/waveformat.txt Normal file
View File

@ -0,0 +1,84 @@
Sound extraction for CD-DA burning from .WAV audio file format
Using information and text snippets
from https://ccrma.stanford.edu/courses/422/projects/WaveFormat/
in may 2013. The link is now dead. An apparent copy of the page
is 2017 at: http://soundfile.sapp.org/doc/WaveFormat/
from https://en.wikipedia.org/wiki/WAV
For libburnia-project.org by Thomas Schmitt <scdbackup@gmx.net>
December 2017
The WAVE file format is an application of the Microsoft RIFF container format
for multimedia files. A RIFF file consists of Chunks which contain Subchunks.
The Chunks form a linked list within the file, the Subchunks form a linked
list inside their Chunk.
All numbers are stored in little-endian byte order.
A .WAV file consists at least of one Chunk with id "RIFF", which contains
one Subchunk with id "fmt " and one with id "data":
Offset Size Name Description
0 4 ChunkID Contains the letters "RIFF"
4 4 ChunkSize The size of the rest of the chunk following
this field. I.e. the two fields ChunkID and
ChunkSize are not included in this count.
8 4 Format Contains the letters "WAVE"
The "fmt " subchunk describes the sound data's format:
Offset Size Name Description
0 4 Subchunk1ID Contains the letters "fmt "
4 4 Subchunk1Size The size of the rest of the Subchunk following
this field. I.e. Subchunk1ID and Subchunk1Size
are not included in this count.
8 2 AudioFormat PCM = 1 (i.e. Linear quantization)
Values other than 1 indicate some
form of compression.
10 2 NumChannels Mono = 1, Stereo = 2, etc.
12 4 SampleRate 8000, 44100, etc.
16 4 ByteRate == SampleRate * NumChannels * BitsPerSample/8
20 2 BlockAlign == NumChannels * BitsPerSample/8
The number of bytes for one sample including
all channels.
22 2 BitsPerSample 8 bits = 8, 16 bits = 16, etc.
More data may follow in this Subchunk if AudioFormat is not PCM.
The "data" subchunk contains the size of the data and the actual sound:
Offset Size Name Description
0 4 Subchunk2ID Contains the letters "data"
4 4 Subchunk2Size == NumSamples * NumChannels * BitsPerSample/8
The number of audio data bytes.
8 * Data The audio data bytes.
CD-DA prescribes these "fmt " parameters:
AudioFormat == 1
SampleRate == 44100
BitsPerSample == 16
NumChannels == 2 (stereo)
(little-endian byte order)
If matching parameters are given in the .WAV file, one can directly use the
data bytes of Subchunk "data" as payload for burning a CD-DA track.
Above simple form can be expanded by other Chunks or Subchunks of Chunk "RIFF".
A .wav file appeared which beared a Subchunk "LIST" inside Chunk "RIFF".
Wikipedia mentions Chunks "INFO", "CSET", "JUNK", "PAD ".
Therefore one should expect such Chunks before Chunk "RIFF" and Subchunks
other than "fmt " and "data" inside the "RIFF" Chunk.
Multiple Chunks "RIFF" and Subchunks "fmt " or "data" per file have not been
seen yet. They would make extraction more cumbersome.

View File

@ -1,7 +1,7 @@
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
Copyright (c) 2006 - 2014 Thomas Schmitt <scdbackup@gmx.net>
Copyright (c) 2006 - 2024 Thomas Schmitt <scdbackup@gmx.net>
Provided under GPL version 2 or later.
*/
@ -122,6 +122,44 @@ struct w_list
static struct w_list *workers = NULL;
static void *fifo_worker_func(struct w_list *w);
int burn_async_manage_lock(int mode)
{
int ret;
static pthread_mutex_t access_lock;
static int mutex_initialized = 0;
static int mutex_locked = 0;
if (mode == BURN_ASYNC_LOCK_INIT) {
if (mutex_initialized)
return 2;
ret = pthread_mutex_init(&access_lock, NULL);
if (ret != 0)
return 0;
mutex_initialized = 1;
return 1;
}
if (!mutex_initialized)
return 0;
if (mode == BURN_ASYNC_LOCK_OBTAIN) {
ret = pthread_mutex_lock(&access_lock);
if (ret != 0)
return 0;
mutex_locked = 1;
} else if (mode == BURN_ASYNC_LOCK_RELEASE) {
if (!mutex_locked)
return 2;
ret = pthread_mutex_unlock(&access_lock);
if (ret != 0)
return 0;
mutex_locked = 0;
}
return 1;
}
static struct w_list *find_worker(struct burn_drive *d)
{
@ -149,9 +187,8 @@ static void add_worker(int w_type, struct burn_drive *d,
a->drive = d;
a->u = *data;
/*
memcpy(&(a->u), data, sizeof(union w_list_data));
*/
burn_async_manage_lock(BURN_ASYNC_LOCK_INIT);
/* insert at front of the list */
a->next = workers;
@ -162,6 +199,7 @@ static void add_worker(int w_type, struct burn_drive *d,
d->busy = BURN_DRIVE_SPAWNING;
#ifdef Libburn_create_detached_threadS
/* ts A71019 :
Trying to start the threads detached to get rid of the zombies
which do neither react on pthread_join() nor on pthread_detach().
@ -169,12 +207,12 @@ static void add_worker(int w_type, struct burn_drive *d,
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
attr_pt= &attr;
/*
libdax_msgs_submit(libdax_messenger, -1, 0x00020158,
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_LOW,
"add_worker(): Creating detached thread.", 0, 0);
*/
#endif
#endif /* Libburn_create_detached_threadS */
/* Worker specific locks are to be released early by the worker */
if (f == (WorkerFunc) fifo_worker_func)
burn_async_manage_lock(BURN_ASYNC_LOCK_OBTAIN);
if (pthread_create(&a->thread, attr_pt, f, a)) {
free(a);
@ -241,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;
@ -271,7 +309,7 @@ int burn_drive_scan(struct burn_drive_info *drives[], unsigned int *n_drives)
return -1;
}
/* cant be anything working! */
/* cannot be anything working! */
/* ts A61006 */
/* a ssert(!(workers && workers->drive)); */
@ -374,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
@ -456,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,
@ -614,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;
@ -704,7 +742,6 @@ ex:;
static void *fifo_worker_func(struct w_list *w)
{
int old;
#define Libburn_protect_fifo_threaD 1
@ -718,10 +755,6 @@ static void *fifo_worker_func(struct w_list *w)
pthread_sigmask(SIG_SETMASK, &sigset, &oldset);
#endif /* Libburn_protect_fifo_threaD */
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &old);
pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &old);
/* Note: Only burn_fifo_abort() shall cancel the fifo thread */
burn_fifo_source_shoveller(w->u.fifo.source, w->u.fifo.flag);
remove_worker(pthread_self());
@ -764,18 +797,19 @@ int burn_fifo_abort(struct burn_source_fifo *fs, int flag)
int ret;
pthread_t pt;
if (fs->thread_is_valid <= 0 || fs->thread_handle == NULL)
return(2);
burn_async_manage_lock(BURN_ASYNC_LOCK_OBTAIN);
#ifdef NIX
libdax_msgs_submit(libdax_messenger, -1, 0x00000002,
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH,
"Aborting running burn_source_fifo thread", 0, 0);
#endif /* NIX */
if (fs->thread_is_valid <= 0 || fs->thread_handle == NULL) {
burn_async_manage_lock(BURN_ASYNC_LOCK_RELEASE);
return 2;
}
pt = *((pthread_t *) fs->thread_handle);
burn_async_manage_lock(BURN_ASYNC_LOCK_RELEASE);
fs->do_abort = 1;
ret = pthread_join(pt, NULL);
pt= *((pthread_t *) fs->thread_handle);
remove_worker(pt);
ret = pthread_cancel(pt);
return (ret == 0);
}

View File

@ -1,5 +1,10 @@
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
Copyright (c) 2006 - 2017 Thomas Schmitt <scdbackup@gmx.net>
Provided under GPL version 2 or later.
*/
#ifndef BURN__ASYNC_H
#define BURN__ASYNC_H
@ -14,5 +19,10 @@ int burn_fifo_start(struct burn_source *source, int flag);
/* To abort a running fifo thread before the fifo object gets deleted */
int burn_fifo_abort(struct burn_source_fifo *fs, int flag);
/* ts B70126 */
#define BURN_ASYNC_LOCK_RELEASE 0
#define BURN_ASYNC_LOCK_OBTAIN 1
#define BURN_ASYNC_LOCK_INIT 2
int burn_async_manage_lock(int mode);
#endif /* BURN__ASYNC_H */

View File

@ -1,5 +1,5 @@
/* Copyright (c) 2011 Thomas Schmitt <scdbackup@gmx.net>
/* Copyright (c) 2011 - 2016 Thomas Schmitt <scdbackup@gmx.net>
Provided under GPL version 2 or later.
*/
@ -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)
@ -1259,7 +1259,7 @@ static int collect_payload(unsigned char *text_packs, int num_packs,
break;
memcpy(*payload + *payload_count, pack + 4, 12);
*payload_count += 12;
if (pack[4] & 128)
if (pack[3] & 128)
double_byte = 1;
}
(*payload)[*payload_count] = 0;
@ -1620,7 +1620,7 @@ static int burn_make_v07t(unsigned char *text_packs, int num_packs,
return 0;
}
/* Obtain first_tno and last_tno from type 0x88 if present. */
/* Obtain first_tno and last_tno from type 0x8f if present. */
if (first_tno <= 0) {
if (pack[5] > 0 && pack[5] + pack[6] < 100 &&
pack[5] <= pack[6]) {
@ -1647,6 +1647,21 @@ static int burn_make_v07t(unsigned char *text_packs, int num_packs,
/* Report content */
result_size = 0;
for (block = 0; block < 8; block++) {
/* Obtain character code, reject unknown ones */
ret = search_pack(text_packs, num_packs, 0, 0x8f, block,
&pack, &pack_no, 0);
if (ret > 0)
*char_code = pack[4];
if (*char_code != 0x00 && *char_code != 0x01 &&
*char_code != 0x80) {
sprintf(msg,
"CD-TEXT block %d with unknown character code %2.2x",
block, (unsigned int) *char_code);
libdax_msgs_submit(libdax_messenger, -1, 0x0002019f,
LIBDAX_MSGS_SEV_FAILURE,
LIBDAX_MSGS_PRIO_HIGH, msg, 0, 0);
return 0;
}
ret = report_block(text_packs, num_packs, block,
first_tno, last_tno, *char_code,
result, result_size, flag & 1);
@ -1656,16 +1671,7 @@ static int burn_make_v07t(unsigned char *text_packs, int num_packs,
continue;
result_size = ret;
}
#ifdef NIX
if (flag & 1)
return result_size;
return (int) strlen((char *) result);
#else /* NIX */
return result_size;
#endif /* ! NIX */
}

View File

@ -51,7 +51,7 @@
of two elements "GF(2)". If bytes 0 .. M are given, then bit n of byte m
is mapped to the coefficient of x exponent (n + ((M - m) * 8) + 16).
I.e. they translate the bits into a polynomial with the highest bit
becomming the coefficient of the highest power of x. Then this polynomial
becoming the coefficient of the highest power of x. Then this polynomial
is multiplied by (x exp 16).
The set of all such polynomials forms a commutative ring. Its addition

View File

@ -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:

View File

@ -1,7 +1,7 @@
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
Copyright (c) 2006 - 2014 Thomas Schmitt <scdbackup@gmx.net>
Copyright (c) 2006 - 2024 Thomas Schmitt <scdbackup@gmx.net>
Provided under GPL version 2 or later.
*/
@ -58,6 +58,9 @@
/* A90815 : for mmc_obtain_profile_name() */
#include "mmc.h"
/* B60730 : for Libburn_do_no_immed_defaulT */
#include "os.h"
#include "libdax_msgs.h"
extern struct libdax_msgs *libdax_messenger;
@ -88,6 +91,13 @@ int burn_setup_drive(struct burn_drive *d, char *fname)
d->do_stream_recording = 0;
d->stream_recording_start= 0;
d->role_5_nwa = 0;
#ifdef Libburn_do_no_immed_defaulT
d->do_no_immed = Libburn_do_no_immed_defaulT;
#else
d->do_no_immed = 0;
#endif
d->features = NULL;
d->drive_serial_number = NULL;
d->drive_serial_number_len = -1;
@ -181,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
@ -277,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 ||
@ -365,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) {
@ -419,6 +429,7 @@ int burn_drive_grab_stdio(struct burn_drive *d, int flag)
/* despite its name : last valid address, not size */
d->media_read_capacity =
read_size / 2048 - !(read_size % 2048);
d->mr_capacity_trusted = 1;
if ((stat_ret == -1 || is_rdwr) && d->devname[0]) {
ret = burn_os_stdio_capacity(d->devname, 0, &size);
if (ret > 0)
@ -440,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);
@ -545,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;
@ -872,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;
@ -887,6 +902,12 @@ void burn_disc_erase_sync(struct burn_drive *d, int fast)
#else /* Libburn_old_progress_looP */
while (1) {
/* >>> ??? ts B60730 : abort if user interrupts ?
if (d->cancel)
break;
*/
ret = d->get_erase_progress(d);
if (ret == -2 || ret > 0)
break;
@ -895,6 +916,12 @@ void burn_disc_erase_sync(struct burn_drive *d, int fast)
sleep(1);
}
while (1) {
/* >>> ??? ts B60730 : abort if user interrupts ?
if (d->cancel)
break;
*/
ret = d->get_erase_progress(d);
if(ret == -2)
break;
@ -911,7 +938,7 @@ void burn_disc_erase_sync(struct burn_drive *d, int fast)
/* ts A61125 : update media state records */
burn_drive_mark_unready(d, 0);
if (d->drive_role == 1)
if (d->drive_role == 1 && !d->cancel)
burn_drive_inquire_media(d);
d->busy = BURN_DRIVE_IDLE;
if (was_error)
@ -949,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)
@ -1108,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 callx burn_drive_get_status*() may be used
to react on messages from the libburn built-in signal handler.
*/
/* ts B00225 :
@ -1137,24 +1166,112 @@ 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;
}
int burn_drive_set_stream_recording(struct burn_drive *d, int recmode,
int start, int flag)
{
#ifndef Libburn_force_stream_recordinG
struct burn_feature_descr *descr;
#endif
if (recmode == 1) {
#ifdef Libburn_force_stream_recordinG
if (recmode == 1)
d->do_stream_recording = 1;
else if (recmode == -1)
#else /* Libburn_force_stream_recordinG */
d->do_stream_recording = 0;
d->stream_recording_start = start;
if (burn_drive_has_feature(d, 0x107, &descr, 0)) {
if ((descr->data[0] & 1) && (descr->flags & 1))
d->do_stream_recording = 1;
}
if (!d->do_stream_recording) {
libdax_msgs_submit(libdax_messenger, d->global_index,
0x000201ac,
LIBDAX_MSGS_SEV_NOTE, LIBDAX_MSGS_PRIO_HIGH,
"Drive currently does not offer Stream Recording",
0, 0);
} else if (d->current_profile != 0x12 &&
d->current_profile != 0x41 &&
d->current_profile != 0x43) {
d->do_stream_recording = 0;
libdax_msgs_submit(libdax_messenger, d->global_index,
0x000201ad,
LIBDAX_MSGS_SEV_NOTE, LIBDAX_MSGS_PRIO_HIGH,
"Stream Recording suppressed due to medium type",
0, 0);
}
#endif /* ! Libburn_force_stream_recordinG */
} else if (recmode == -1) {
d->do_stream_recording = 0;
}
if (d->do_stream_recording)
d->stream_recording_start = start;
else
d->stream_recording_start = 0;
return(1);
}
@ -1266,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 ||
@ -1365,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) {
@ -1498,7 +1615,7 @@ void burn_drive_info_free(struct burn_drive_info drive_infos[])
/* ts A60904 : This looks a bit weird. [ts A70907 : not any more]
burn_drive_info is not the manager of burn_drive but only its
spokesperson. To my knowlege drive_infos from burn_drive_scan()
spokesperson. To my knowledge drive_infos from burn_drive_scan()
are not memorized globally. */
free((void *) drive_infos);
@ -1506,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 recieves 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
@ -1535,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,
@ -1564,6 +1697,20 @@ int burn_drive_set_buffer_waiting(struct burn_drive *d, int enable,
}
int burn_drive_reset_simulate(struct burn_drive *d, int simulate)
{
if (d->busy != BURN_DRIVE_IDLE) {
libdax_msgs_submit(libdax_messenger,
d->global_index, 0x00020140,
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
"Drive is busy on attempt to write random access",0,0);
return 0;
}
d->do_simulate = !!simulate;
return 1;
}
int burn_msf_to_sectors(int m, int s, int f)
{
return (m * 60 + s) * 75 + f;
@ -1686,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;
@ -1763,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);
@ -1782,10 +1929,12 @@ int burn_drive_grab_dummy(struct burn_drive_info *drive_infos[], char *fname)
strcpy(d->current_profile_text,"stdio file");
d->current_is_cd_profile = 0;
d->current_is_supported_profile = 1;
if (read_size >= 0)
if (read_size >= 0) {
/* despite its name : last valid address, not size */
d->media_read_capacity =
read_size / 2048 - !(read_size % 2048);
d->mr_capacity_trusted = 1;
}
burn_drive_set_media_capacity_remaining(d, size);
} else
d->current_profile = 0; /* Drives return this if empty */
@ -1830,7 +1979,7 @@ ex:;
/* ts A60823 */
/** Aquire a drive with known persistent address.
/** Acquire a drive with known persistent address.
*/
int burn_drive_scan_and_grab(struct burn_drive_info *drive_infos[], char* adr,
int load)
@ -1838,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 adress 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)
@ -1943,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);
@ -2544,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,
@ -2575,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)
{
@ -2629,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 {
@ -2972,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);
@ -3214,7 +3390,7 @@ int burn_drive_equals_adr(struct burn_drive *d1, char *adr2_in, int role2)
if (stat_ret1 == -1 || stat_ret2 == -1) {
if (stat_ret1 != -1 || stat_ret2 != -1)
{ret = 0; goto ex;}
/* one adress existing, one not */
/* one address existing, one not */
/* Two non-existing file objects */
@ -3231,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 &&
@ -3312,20 +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 + 1;
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,
@ -3354,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],
@ -3573,3 +3767,89 @@ ex:
return ret;
}
int burn_drive_get_bd_r_pow(struct burn_drive *d)
{
struct burn_feature_descr *feature;
if (d->current_profile == 0x41)
if (burn_drive_has_feature(d, 0x38, &feature, 0) == 1)
if (feature->flags & 1)
return 1;
return 0;
}
int burn_drive_set_immed(struct burn_drive *drive, int enable)
{
drive->do_no_immed = !enable;
return 1;
}
int burn_drive_get_immed(struct burn_drive *drive)
{
return !drive->do_no_immed;
}
/* ts B90412 , API */
int burn_drive_get_feature(struct burn_drive *d, unsigned int feature_code,
unsigned char *flags,
unsigned char *additional_length,
unsigned char **feature_data,
char **feature_text)
{
int ret, i;
struct burn_feature_descr *descr;
*flags = 0;
*additional_length = 0;
*feature_data = NULL;
if (feature_text != NULL)
*feature_text = NULL;
if (!burn_drive_has_feature(d, feature_code, &descr, 0))
return 0;
*flags = descr->flags;
*additional_length = descr->data_lenght;
if (*additional_length > 0)
BURN_ALLOC_MEM(*feature_data, unsigned char,
*additional_length);
for (i = 0; i < *additional_length; i++)
(*feature_data)[i] = descr->data[i];
if (feature_text != NULL) {
ret = burn_make_feature_text(d, feature_code, *flags,
*additional_length, *feature_data,
feature_text, 0);
} else {
ret = 1;
}
ex:
return ret;
}
/* ts B90412 , API */
void burn_drive_get_feature_codes(struct burn_drive *d,
int *count, unsigned int **feature_codes)
{
struct burn_feature_descr *o;
int to_alloc;
*count = 0;
*feature_codes = NULL;
for (o = d->features; o != NULL; o = o->next)
(*count)++;
if (*count == 0)
return;
to_alloc = *count;
*count = 0;
BURN_ALLOC_MEM_VOID(*feature_codes, unsigned int, to_alloc);
for (o = d->features; o != NULL; o = o->next) {
(*feature_codes)[*count] = o->feature_code;
(*count)++;
}
ex:;
}

View File

@ -1,7 +1,7 @@
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
Copyright (c) 2006 - 2014 Thomas Schmitt <scdbackup@gmx.net>
Copyright (c) 2006 - 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 */

View File

@ -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

View File

@ -1,7 +1,7 @@
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
Copyright (c) 2006 - 2014 Thomas Schmitt <scdbackup@gmx.net>
Copyright (c) 2006 - 2017 Thomas Schmitt <scdbackup@gmx.net>
Provided under GPL version 2 or later.
*/
@ -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)
@ -331,8 +331,31 @@ static int fifo_set_size(struct burn_source *source, off_t size)
static void fifo_free(struct burn_source *source)
{
struct burn_source_fifo *fs = source->data;
int wait_count;
static int wait_max = 30, wait_usleep = 100000;
burn_fifo_abort(fs, 0);
for (wait_count = 0; wait_count <= wait_max; wait_count++) {
if (fs->thread_is_valid <= 0)
break;
if (wait_count < wait_max)
usleep(wait_usleep);
}
if (wait_count > wait_max) {
/* The shoveler thread might still be active. If so, it would
use invalid or inappropriate memory if the fifo would be
disposed now. A memory and resource leak is the better
option here.
*/
libdax_msgs_submit(libdax_messenger, -1,
0x000201ab,
LIBDAX_MSGS_SEV_WARNING,
LIBDAX_MSGS_PRIO_HIGH,
"Leaving burn_source_fifo object undisposed because it is possibly stuck but alive",
0, 0);
return;
}
if (fs->inp != NULL)
burn_source_free(fs->inp);
@ -356,13 +379,20 @@ int burn_fifo_source_shoveller(struct burn_source *source, int flag)
fs->thread_pid = getpid();
fs->thread_is_valid = 1;
/* Lock was obtained by async.c:add_worker() */
burn_async_manage_lock(BURN_ASYNC_LOCK_RELEASE);
bufsize = fs->chunksize * fs->chunks;
while (!fs->end_of_consumption) {
if (fs->do_abort)
goto emergency_exit;
/* wait for enough buffer space available */
wpos = fs->buf_writepos;
counted = 0;
while (1) {
if (fs->do_abort)
goto emergency_exit;
rpos = fs->buf_readpos;
diff = rpos - wpos;
trans_end = 0;
@ -405,6 +435,8 @@ int burn_fifo_source_shoveller(struct burn_source *source, int flag)
}
/* Obtain next chunk */
if (fs->do_abort)
goto emergency_exit;
if (fs->inp->read != NULL)
ret = fs->inp->read(fs->inp,
(unsigned char *) bufpt, fs->inp_read_size);
@ -430,6 +462,8 @@ int burn_fifo_source_shoveller(struct burn_source *source, int flag)
fs->put_counter++;
/* activate read chunk */
if (fs->do_abort)
goto emergency_exit;
if (ret > fs->inp_read_size)
/* beware of ill custom burn_source */
ret = fs->inp_read_size;
@ -463,8 +497,11 @@ int burn_fifo_source_shoveller(struct burn_source *source, int flag)
fs->end_of_input = 1;
/* wait for end of reading by consumer */;
while (fs->buf_readpos != fs->buf_writepos && !fs->end_of_consumption)
fifo_sleep(0);
while (fs->buf_readpos != fs->buf_writepos && !fs->end_of_consumption) {
if (fs->do_abort)
goto emergency_exit;
fifo_sleep(0);
}
/* destroy ring buffer */;
if (!fs->end_of_consumption)
@ -481,8 +518,11 @@ int burn_fifo_source_shoveller(struct burn_source *source, int flag)
((size_t) fs->chunksize) * (size_t) fs->chunks, 0);
fs->buf = NULL;
emergency_exit:;
burn_async_manage_lock(BURN_ASYNC_LOCK_OBTAIN);
fs->thread_handle= NULL;
fs->thread_is_valid = 0;
burn_async_manage_lock(BURN_ASYNC_LOCK_RELEASE);
return (fs->input_error == 0);
}
@ -524,6 +564,7 @@ struct burn_source *burn_fifo_source_new(struct burn_source *inp,
fs->thread_handle = NULL;
fs->thread_pid = 0;
fs->thread_is_valid = 0;
fs->do_abort = 0;
fs->inp = NULL; /* set later */
if (flag & 1)
fs->inp_read_size = 32 * 1024;

View File

@ -1,7 +1,7 @@
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
Copyright (c) 2006 - 2010 Thomas Schmitt <scdbackup@gmx.net>
Copyright (c) 2006 - 2017 Thomas Schmitt <scdbackup@gmx.net>
Provided under GPL version 2 or later.
*/
@ -27,8 +27,8 @@ struct burn_source_fifo {
/* The fifo stays inactive and unequipped with eventual resources
until its read() method is called for the first time.
Only then burn_fifo_start() gets called, allocates the complete
resources, starts a thread with burn_fifo_source_shuffler()
which shuffles data and finally destroys the resources.
resources, starts a thread with burn_fifo_source_shoveller()
which shovels data and finally destroys the resources.
This late start is to stay modest in case of multiple tracks
in one disc.
*/
@ -38,6 +38,9 @@ struct burn_source_fifo {
int thread_pid;
int thread_is_valid;
/* The shoveller aborts if this is 1. Resource leaks are possible. */
volatile int do_abort;
/* the burn_source for which this fifo is acting as proxy */
struct burn_source *inp;
int inp_read_size;
@ -85,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;

View File

@ -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;

View File

@ -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

View File

@ -1,7 +1,7 @@
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
Copyright (c) 2006 - 2015 Thomas Schmitt <scdbackup@gmx.net>
Copyright (c) 2006 - 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
@ -842,7 +906,7 @@ void burn_set_scsi_logging(int flag);
@param exclusive
0 = no attempt to make drive access exclusive.
1 = Try to open only devices which are not marked as busy
and try to mark them busy if opened sucessfully. (O_EXCL
and try to mark them busy if opened successfully. (O_EXCL
on GNU/Linux , flock(LOCK_EX) on FreeBSD.)
2 = in case of a SCSI device, also try to open exclusively
the matching /dev/sr, /dev/scd and /dev/st .
@ -880,7 +944,7 @@ void burn_allow_untested_profiles(int yes);
/* ts A60823 */
/** Aquire a drive with known device file address.
/** Acquire a drive with known device file address.
This is the sysadmin friendly way to open one drive and to leave all
others untouched. It bundles the following API calls to form a
@ -902,12 +966,12 @@ void burn_allow_untested_profiles(int yes);
Different than with burn_drive_scan() it is allowed to call
burn_drive_scan_and_grab() without giving up any other scanned drives. So
this call can be used to get a collection of more than one aquired drives.
The attempt to aquire the same drive twice will fail, though.
this call can be used to get a collection of more than one acquired drives.
The attempt to acquire the same drive twice will fail, though.
Pseudo-drives:
burn_drive_scan_and_grab() is able to aquire virtual drives which will
burn_drive_scan_and_grab() is able to acquire virtual drives which will
accept options much like a MMC burner drive. Many of those options will not
cause any effect, though. The address of a pseudo-drive begins with
prefix "stdio:" followed by a path.
@ -1001,7 +1065,7 @@ void burn_drive_clear_whitelist(void);
burn_drive_scan() again.
@param n_drives Returns the number of drive items in drive_infos.
@return 0 while scanning is not complete
>0 when it is finished sucessfully,
>0 when it is finished successfully,
<0 when finished but failed.
*/
int burn_drive_scan(struct burn_drive_info *drive_infos[],
@ -1291,7 +1355,7 @@ int burn_drive_get_serial_no(struct burn_drive *d, char **sno, int *sno_len);
@param d The drive to inquire.
@param sno Returns the bytes of the serial number. A trailing 0-byte
is appended for convenience. There is no warranty that
*sno contains no other byte values.
*sno contains only non-zero printable bytes.
Submit *sno as NULL or pointing to free()-able memory.
Apply free() to *sno when no longer needed.
@param sno_len Returns the number of valid bytes in returned *sno,
@ -1307,16 +1371,28 @@ int burn_drive_get_media_sno(struct burn_drive *d, char **sno, int *sno_len);
burn_drive_get_write_speed(), burn_drive_get_min_write_speed(),
burn_drive_get_start_end_lba(). The drive must be grabbed for this call.
@param drive The drive to query.
@return 1=sucess, 0=no valid ATIP info read, -1 severe error
@return 1=success, 0=no valid ATIP info read, -1 severe error
@since 0.2.6
*/
int burn_disc_read_atip(struct burn_drive *drive);
/* ts B70206 */
/** Tells whether a BD-R medium with Pseudo Overwrite (POW) formatting is in
the drive. Such a formatting may have been applied by dvd+rw-tools. It
prevents sequential multi-session.
libburn will refuse to write to such a medium.
@param drive The drive to query.
@return 1 if BD-R Pseudo Overwrite , 0 if not BD-R or not POW
@since 1.4.8
*/
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
@ -1374,9 +1450,9 @@ 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 occured
@return 1 success, <= 0 an error occurred
@since 0.7.2
*/
int burn_disc_get_cd_info(struct burn_drive *d, char disc_type[80],
@ -1400,7 +1476,7 @@ int burn_disc_get_cd_info(struct burn_drive *d, char disc_type[80],
bytes in text_packs divided by 18.
@param flag Bitfield for control purposes,
Unused yet. Submit 0.
@return 1 success, 0= no CD-TEXT found, < 0 an error occured
@return 1 success, 0= no CD-TEXT found, < 0 an error occurred
@since 1.2.0
*/
int burn_disc_get_leadin_text(struct burn_drive *d,
@ -1466,9 +1542,16 @@ 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 upcomming track reveiled that the READ TRACK INFORMATION Damage Bit
of the upcoming track reveiled that the READ TRACK INFORMATION Damage Bit
is set for this track and that no valid writable address is available.
See MMC-5 6.27.3.7 Damage Bit, 6.27.3.11 NWA_V (NWA valid)
@param d The drive to query.
@ -1638,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
@ -1692,7 +1784,7 @@ void burn_disc_erase(struct burn_drive *drive, int fast);
in state "Sequential Recording" (profile 0014h) which get formatted to
state "Restricted Overwrite" (profile 0013h). DVD+RW can be "de-iced"
by setting bit4 of flag. DVD-RAM and BD-RE may get formatted initially
or re-formatted to adjust their Defect Managment.
or re-formatted to adjust their Defect Management.
This function usually returns while the drive is still in the process
of formatting. The formatting is done, when burn_drive_get_status()
returns BURN_DRIVE_IDLE. This may be immediately after return or may
@ -1807,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
@ -1858,6 +1950,33 @@ void burn_disc_write(struct burn_write_opts *o, struct burn_disc *disc);
int burn_drive_set_stream_recording(struct burn_drive *drive, int recmode,
int start, int flag);
/* ts B60730 */
/** Enable or disable use of the Immed bit with long running SCSI commands.
If the Immed bit is used, then those SCSI commands end early and leave
the drive in not-ready state. libburn then tries periodically whether
the drive became ready again. Only then it assumes the command to be
completely done.
The default setting may depend on the operating system on which libburn
was compiled.
@param drive The drive which will be affected.
@param enable 1= use Immed bit.
0= use no Immed bit. Affected commands can last very long.
@return 1=success , <=0 failure
@since 1.4.6
*/
int burn_drive_set_immed(struct burn_drive *drive, int enable);
/* ts B60730 */
/** Inquire the current setting of usage of the Immed bit. Either the still set
system dependent default or the value set by call burn_drive_set_immed().
@return The current value.
@since 1.4.6
*/
int burn_drive_get_immed(struct burn_drive *drive);
/** Cancel an operation on a drive.
This will only work when the drive's busy state is BURN_DRIVE_READING or
BURN_DRIVE_WRITING.
@ -1880,7 +1999,7 @@ int burn_drive_wrote_well(struct burn_drive *d);
/* ts B31023 */
/** Inquire whether a write error occured which is suspected to have happened
/** Inquire whether a write error occurred which is suspected to have happened
due to a false report about DVD-RW capability to be written in write type
BURN_WRITE_TAO.
@param d The drive to inquire.
@ -2645,7 +2764,7 @@ struct burn_disc *burn_drive_get_disc(struct burn_drive *d);
@param t The track to set the data source for
@param s The data source to use for the contents of the track
@return An error code stating if the source is ready for use for
writing the track, or if an error occured
writing the track, or if an error occurred
*/
enum burn_source_status burn_track_set_source(struct burn_track *t,
@ -2660,7 +2779,7 @@ enum burn_source_status burn_track_set_source(struct burn_track *t,
announced then the track will be padded up with zeros.
@param t The track to change
@param size The size to set
@return 0=failure 1=sucess
@return 0=failure 1=success
@since 0.3.4
*/
int burn_track_set_default_size(struct burn_track *t, off_t size);
@ -2944,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
@ -2957,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.
@ -2968,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
@ -3006,6 +3187,24 @@ int burn_drive_set_buffer_waiting(struct burn_drive *d, int enable,
int min_usec, int max_usec, int timeout_sec,
int min_percent, int max_percent);
/* ts B61116 */
/** Control the write simulation mode before or after burn_write_opts get
into effect.
Beginning with version 1.4.8 a burn run by burn_disc_write() brings the
burn_drive object in the simulation state as set to the burn_write_opts
by burn_write_opts_set_simulate(). This state is respected by call
burn_random_access_write() until a new call of burn_disc_write() happens
or until burn_drive_reset_simulate() is called.
This call may only be made when burn_drive_get_status() returns
BURN_DRIVE_IDLE.
@param d The drive to control
@param simulate 1 enables simulation, 0 enables real writing
@return 1=success , 0=failure
@since 1.4.8
*/
int burn_drive_reset_simulate(struct burn_drive *d, int simulate);
/* these are for my [Derek Foreman's ?] debugging, they will disappear */
/* ts B11012 :
@ -3073,8 +3272,13 @@ void burn_write_opts_set_format(struct burn_write_opts *opts, int format);
media content and burn_disc_get_status() stay unchanged.
Note: With stdio-drives, the target file gets eventually created, opened,
lseeked, and closed, but not written. So there are effects on it.
Warning: Call burn_random_access_write() will never do simulation because
it does not get any burn_write_opts.
Note: Up to version 1.4.6 the call burn_random_access_write() after
burn_disc_write() did not simulate because it does not get any
burn_write_opts and the drive did not memorize the simulation state.
This has changed now. burn_random_access_write() will not write after
a simulated burn run.
Use burn_drive_reset_simulate(drive, 0) if you really want to end
simulation before you call burn_disc_write() with new write options.
@param opts The write opts to change
@param sim Non-zero enables simulation, 0 enables real writing
@return Returns 1 on success and 0 on failure.
@ -3215,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
@ -3267,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 rythm by which stdio pseudo drives force their output data to
/** 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
@ -3281,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
@ -3367,6 +3590,55 @@ int burn_drive_get_all_profiles(struct burn_drive *d, int *num_profiles,
int burn_obtain_profile_name(int profile_code, char name[80]);
/* ts B90414 */
/** Obtains the list of SCSI Feature Codes from feature descriptors which
were obtained from the drive when it was most recently acquired or
re-assessed.
@param d Drive to query
@param count Returns the number of allocated elements in feature_codes
@param feature_codes Returns the allocated array of feature codes.
If returned *feature_codes is not NULL, dispose it
by free() when it is no longer needed.
@since 1.5.2
*/
void burn_drive_get_feature_codes(struct burn_drive *d,
int *count, unsigned int **feature_codes);
/* ts B90414 */
/** Obtains the fields and data of a particular feature which were obtained
from the drive when it was last acquired or re-assessed. See MMC specs
for full detail.
@param d Drive to query
@param feature_code A number as learned by burn_drive_get_feature_codes()
@param flags Returns byte 2 of the feature descriptor:
bit0= Current
bit1= Persistent
bit2-5= Version
@param additional_length Returns byte 3 of descriptor.
This is the size of feature_data.
@param feature_data Returns further bytes of descriptor.
If returned *feature_data is not NULL, dispose it
by free() when it is no longer needed.
@param feature_text Returns text representation of the feature descriptor:
Code +/- : Name : Version,P/N : Hex bytes : Parsed info
Current features are marked by "+", others by "-".
Persistent features are marked by "P", others by "N".
feature_text may be submitted as NULL. In this case
no text is generated and returned.
If returned *feature_text is not NULL, dispose it
by free() when it is no longer needed.
@return 0 feature descriptor is not present
-1 out of memory
>0 success
@since 1.5.2
*/
int burn_drive_get_feature(struct burn_drive *d, unsigned int feature_code,
unsigned char *flags,
unsigned char *additional_length,
unsigned char **feature_data,
char **feature_text);
/** Gets the maximum write speed for a drive and eventually loaded media.
The return value might change by the media type of already loaded media,
again by call burn_drive_grab() and again by call burn_disc_read_atip().
@ -3517,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;
};
@ -3589,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
@ -3600,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
@ -3643,8 +3937,8 @@ void burn_version(int *major, int *minor, int *micro);
*/
#define burn_header_version_major 1
#define burn_header_version_minor 4
#define burn_header_version_micro 1
#define burn_header_version_minor 5
#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.
@ -3654,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
@ -3904,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
@ -3914,9 +4208,14 @@ int burn_is_aborting(int flag);
resulting struct burn_multi_caps elements .start_adr , .start_alignment ,
.start_range_low , .start_range_high .
Other than burn_disc_write() this is a synchronous call which returns
only after the write transaction has ended (sucessfully or not). So it is
only after the write transaction has ended (successfully or not). So it is
wise not to transfer giant amounts of data in a single call.
Important: Data have to fit into the already formatted area of the media.
If the burn_drive object is in simulation mode, then no actual write
operation or synchronization of the drive buffer will happen.
See burn_drive_reset_simulate().
@param d The drive to which to write
@param byte_address The start address of the write in byte
(1 LBA unit = 2048 bytes) (do respect media alignment)
@ -3926,7 +4225,7 @@ int burn_is_aborting(int flag);
drive buffer without further data transfer).
@param flag Bitfield for control purposes:
bit0 = flush the drive buffer after eventual writing
@return 1=sucessful , <=0 : number of transfered bytes * -1
@return 1=successful , <=0 : number of transferred bytes * -1
@since 0.4.0
*/
int burn_random_access_write(struct burn_drive *d, off_t byte_address,
@ -3935,20 +4234,29 @@ 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 media_read_acpacity-1
can be read via burn_read_data() although some of them may never have been
recorded. If tracks are recognizable then it is better to only read
LBAs which are part of some track.
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
@param capacity Will return the result if valid
@param flag Bitfield for control purposes: Unused yet, submit 0.
@return 1=sucessful , <=0 an error occured
@return 1=successful , <=0 an error occurred
@since 0.6.0
*/
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.
@ -3957,7 +4265,7 @@ int burn_get_read_capacity(struct burn_drive *d, int *capacity, int flag);
be aligned to 2048 bytes. Only data tracks with 2048 bytes per sector
can be read this way. I.e. not CD-audio, not CD-video-stream ...
This is a synchronous call which returns only after the full read job
has ended (sucessfully or not). So it is wise not to read giant amounts
has ended (successfully or not). So it is wise not to read giant amounts
of data in a single call.
@param d The drive from which to read
@param byte_address The start address of the read in byte (aligned to 2048)
@ -3973,7 +4281,7 @@ int burn_get_read_capacity(struct burn_drive *d, int *capacity, int flag);
with single block steps.
@since 0.5.2
bit3= return -2 on permission denied error rather than
issueing a warning message.
issuing a warning message.
@since 1.0.6
bit4= return -3 on SCSI error
5 64 00 ILLEGAL MODE FOR THIS TRACK
@ -3985,7 +4293,7 @@ int burn_get_read_capacity(struct burn_drive *d, int *capacity, int flag);
bit5= issue messages with severity DEBUG if they would
be suppressed by bit1.
@since 1.4.0
@return 1=sucessful , <=0 an error occured
@return 1=successful , <=0 an error occurred
with bit3: -2= permission denied error
@since 0.4.0
*/
@ -4032,7 +4340,7 @@ int burn_read_data(struct burn_drive *d, off_t byte_address,
bit5= issue messages with severity DEBUG if they would
be suppressed by bit1.
@since 1.4.0
@return 1=sucessful , <=0 an error occured
@return 1=successful , <=0 an error occurred
with bit3: -2= permission denied error
@since 1.2.6
*/
@ -4116,7 +4424,7 @@ int burn_drive_get_drive_role(struct burn_drive *d);
(role 2) or read-only (role 4) or write-only (role 5). See bit1.
@param allowed Bitfield for control purposes:
bit0= Enable roles 4 and 5 for drives which get
aquired after this call
acquired after this call
bit1= with bit0:
Test whether the file can be opened for
read-write, read-only, or write-only.
@ -4179,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).
@ -4214,7 +4522,7 @@ int libdax_audioxtr_get_id(struct libdax_audioxtr *xtr,
/** Obtain a prediction about the extracted size based on internal information
of the formatted file.
@param xtr Opaque handle to extractor
@param o Opaque handle to extractor
@param size Gets filled with the predicted size
@param flag Bitfield for control purposes (unused yet, submit 0)
@return 1 prediction was possible , 0 no prediction could be made
@ -4246,8 +4554,8 @@ int libdax_audioxtr_read(struct libdax_audioxtr *xtr,
object will have forgotten its file descriptor and libdax_audioxtr_read()
will return a usage error. One may use *fd after libdax_audioxtr_destroy()
and will have to close it via close(2) when done with it.
@param xtr Opaque handle to extractor
@param fd Eventually returns the file descriptor number
@param o Opaque handle to extractor
@param fd Returns the file descriptor number
@param flag Bitfield for control purposes
bit0= do not dup(2) and close(2) but hand out original fd
@return 1 success, 0 cannot hand out fd , -1 severe error
@ -4277,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
*/

View File

@ -50,9 +50,13 @@ burn_drive_extract_audio_track;
burn_drive_free_speedlist;
burn_drive_get_adr;
burn_drive_get_all_profiles;
burn_drive_get_bd_r_pow;
burn_drive_get_best_speed;
burn_drive_get_disc;
burn_drive_get_drive_role;
burn_drive_get_feature;
burn_drive_get_feature_codes;
burn_drive_get_immed;
burn_drive_get_media_sno;
burn_drive_get_min_write_speed;
burn_drive_get_read_speed;
@ -70,10 +74,13 @@ burn_drive_obtain_scsi_adr;
burn_drive_probe_cd_write_modes;
burn_drive_re_assess;
burn_drive_release;
burn_drive_reset_simulate;
burn_drive_scan;
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;
@ -101,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;
@ -178,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;
@ -204,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;

View File

@ -55,6 +55,7 @@ int libdax_audioxtr_new(struct libdax_audioxtr **xtr, char *path, int flag)
o->bits_per_sample= 0;
o->msb_first= 0;
o->wav_data_location= 44;
o->wav_subchunk2_size= 0;
o->au_data_location= 0;
@ -121,47 +122,123 @@ static int libdax_audioxtr_open(struct libdax_audioxtr *o, int flag)
return(1);
}
/* @param flag: bit0= sequential file, skip by reading data
*/
static int libdax_audioxtr_skip(struct libdax_audioxtr *o,
off_t *old_pos,
off_t pos, int flag)
{
int ret;
size_t to_read;
static char buf[256]; /* Thread safe because the content does not matter */
if((flag & 1) || o->fd == 0) { /* stdin */
while(pos - *old_pos > 0) {
to_read= pos - *old_pos;
if(to_read > sizeof(buf))
to_read= sizeof(buf);
ret= read(o->fd, buf, to_read);
if(ret < (int) to_read)
return(0);
*old_pos+= to_read;
}
} else {
ret= lseek(o->fd, pos, SEEK_SET);
if(ret == -1)
return(0);
*old_pos= pos;
}
return(1);
}
static int libdax_audioxtr_identify_wav(struct libdax_audioxtr *o, int flag)
{
int ret;
char buf[45];
int ret, fmt_seen= 0, data_seen= 0;
off_t pos= 0, old_pos= 0, riff_end= 0;
char buf[16];
unsigned char *ubuf;
/* check wether this is a MS WAVE file .wav */
/* info used: http://ccrma.stanford.edu/courses/422/projects/WaveFormat/ */
/* 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
*/
ubuf= (unsigned char *) buf;
if(o->fd!=0) {
ret= lseek(o->fd,0,SEEK_SET);
if(ret==-1)
/* Look for ChunkID "RIFF" , tolerate other known chunks */
while(1) {
ret= libdax_audioxtr_skip(o, &old_pos, pos, 0);
if(ret <= 0)
return(0);
ret= read(o->fd, buf, 8);
if(ret < 8)
return(0);
old_pos+= 8;
pos= old_pos + libdax_audioxtr_to_int(o, ubuf + 4, 4, 0);
if(pos > 0xffffffff || pos - old_pos < 4) /* Too large or no Format word */
return(0);
if(strncmp(buf, "RIFF", 4) == 0)
break;
/* Wikipedia mentions these known ChunkId values */
if(strncmp(buf, "INFO", 4) == 0 ||
strncmp(buf, "CSET", 4) == 0 ||
strncmp(buf, "JUNK", 4) == 0 ||
strncmp(buf, "PAD ", 4) == 0)
continue;
return(0);
}
ret= read(o->fd, buf, 44);
if(ret<44)
return(0);
buf[44]= 0; /* as stopper for any string operations */
if(strncmp(buf,"RIFF",4)!=0) /* ChunkID */
/* Read RIFF Format header */
ret= read(o->fd, buf, 4);
if(ret < 4)
return(0);
if(strncmp(buf+8,"WAVE",4)!=0) /* Format */
return(0);
if(strncmp(buf+12,"fmt ",4)!=0) /* Subchunk1ID */
return(0);
if(buf[16]!=16 || buf[17]!=0 || buf[18]!=0 || buf[19]!=0) /* Subchunk1Size */
return(0);
if(buf[20]!=1 || buf[21]!=0) /* AudioFormat must be 1 (Linear quantization) */
old_pos+= 4;
if(strncmp(buf, "WAVE", 4) != 0) /* Format */
return(0);
riff_end= pos;
strcpy(o->fmt,".wav");
o->msb_first= 0;
o->num_channels= libdax_audioxtr_to_int(o,(unsigned char *) buf+22,2,0);
o->sample_rate= libdax_audioxtr_to_int(o,(unsigned char *) buf+24,4,0);
o->bits_per_sample= libdax_audioxtr_to_int(o,(unsigned char *)buf+34,2,0);
sprintf(o->fmt_info,
".wav , num_channels=%d , sample_rate=%d , bits_per_sample=%d",
o->num_channels,o->sample_rate,o->bits_per_sample);
o->wav_subchunk2_size= libdax_audioxtr_to_int(o,(unsigned char *)buf+40,4,0);
o->data_size= o->wav_subchunk2_size;
return(1);
/* Look for SubchunkID "fmt " and "data" */
pos= old_pos;
while(old_pos < riff_end) {
ret= libdax_audioxtr_skip(o, &old_pos, pos, 0);
if(ret <= 0)
return(0);
ret= read(o->fd, buf, 8);
if(ret < 8)
return(0);
old_pos= pos + 8;
pos= old_pos + libdax_audioxtr_to_int(o, ubuf + 4, 4, 0); /* SubchunkSize */
if(strncmp(buf,"fmt ", 4) == 0) {
if(pos - old_pos < 16)
return(0);
ret= read(o->fd, buf, 16);
if(ret < 16)
return(0);
old_pos+= 16;
if(buf[0]!=1 || buf[1]!=0) /* AudioFormat (1 = Linear quantization) */
return(0);
o->msb_first= 0;
o->num_channels= libdax_audioxtr_to_int(o, ubuf + 2 , 2, 0);
o->sample_rate= libdax_audioxtr_to_int(o, ubuf + 4, 4, 0);
o->bits_per_sample= libdax_audioxtr_to_int(o, ubuf + 14, 2, 0);
sprintf(o->fmt_info,
".wav , num_channels=%d , sample_rate=%d , bits_per_sample=%d",
o->num_channels, o->sample_rate, o->bits_per_sample);
fmt_seen= 1;
} else if(strncmp(buf,"data", 4) == 0) {
o->wav_data_location= old_pos;
o->wav_subchunk2_size= pos - old_pos;
o->data_size= o->wav_subchunk2_size;
data_seen= 1;
}
if(fmt_seen && data_seen) {
strcpy(o->fmt,".wav");
return(1);
}
}
return(0);
}
@ -170,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) {
@ -256,7 +333,7 @@ static int libdax_audioxtr_init_reading(struct libdax_audioxtr *o, int flag)
o->extract_count= 0;
if(strcmp(o->fmt,".wav")==0)
ret= lseek(o->fd,44,SEEK_SET);
ret= lseek(o->fd, o->wav_data_location, SEEK_SET);
else if(strcmp(o->fmt,".au")==0)
ret= lseek(o->fd,o->au_data_location,SEEK_SET);
else

View File

@ -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).
@ -176,7 +176,10 @@ struct libdax_audioxtr {
/* Format dependent parameters */
/* MS WAVE Format */
/* info used: http://ccrma.stanford.edu/courses/422/projects/WaveFormat/ */
/* see description in: doc/waveformat.txt */
/* Offset to "data" subchunk */
unsigned int wav_data_location;
/* == NumSamples * NumChannels * BitsPerSample/8
This is the number of bytes in the data. */

View File

@ -1,7 +1,7 @@
/* libdax_msgs
Message handling facility of libdax.
Copyright (C) 2006 - 2010 Thomas Schmitt <scdbackup@gmx.net>,
Copyright (C) 2006 - 2016 Thomas Schmitt <scdbackup@gmx.net>,
provided under GPL version 2 or later.
*/
@ -34,14 +34,13 @@ static int libdax_msgs_item_new(struct libdax_msgs_item **item,
int ret;
struct libdax_msgs_item *o;
struct timeval tv;
struct timezone tz;
(*item)= o=
(struct libdax_msgs_item *) calloc(1, sizeof(struct libdax_msgs_item));
if(o==NULL)
return(-1);
o->timestamp= 0.0;
ret= gettimeofday(&tv,&tz);
ret= gettimeofday(&tv, NULL);
if(ret==0)
o->timestamp= tv.tv_sec+0.000001*tv.tv_usec;
o->process_id= getpid();

View File

@ -1,7 +1,7 @@
/* libdax_msgs
Message handling facility of libburn and libisofs.
Copyright (C) 2006-2011 Thomas Schmitt <scdbackup@gmx.net>,
Copyright (C) 2006-2021 Thomas Schmitt <scdbackup@gmx.net>,
provided under GPL version 2 or later.
*/
@ -266,8 +266,9 @@ int libdax_msgs_new(struct libdax_msgs **m, int flag);
/** Destroy a message handling facility and all its eventual messages.
The submitted pointer gets set to NULL.
Actually only the last destroy call of all offical references to the object
will really dispose it. All others just decrement the reference counter.
Actually only the last destroy call of all official references to the
object will really dispose it. All others just decrement the reference
counter.
Call this function only with official reference pointers obtained by
libdax_msgs_new() or libdax_msgs_refer(), and only once per such pointer.
@param flag Bitfield for control purposes (unused yet, submit 0)
@ -424,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
@ -554,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 accidently 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
@ -579,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
@ -612,6 +613,10 @@ Range "scdbackup" : 0x00020000 to 0x0002ffff
0x000201a8 (FAILURE,HIGH) = SCSI command yielded driver problem
0x000201a9 (FAILURE,HIGH) = Implausible length from GET CONFIGURATION
0x000201aa (FAILURE,HIGH) = No CD-TEXT packs in file
0x000201ab (WARN,HIGH) = Leaving burn_source_fifo object undisposed
0x000201ac (NOTE,HIGH) = Drive currently does not offer Stream Recording
0x000201ad (NOTE,HIGH) = WRITE commands have been repeated
0x000201ae (FAILURE,HIGH) = Track size exceeds 4 TiB - 32 KiB
libdax_audioxtr:
@ -642,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
@ -697,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

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,7 @@
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
Copyright (c) 2006 - 2014 Thomas Schmitt <scdbackup@gmx.net>
Copyright (c) 2006 - 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()
@ -85,7 +87,7 @@ int mmc_four_char_to_int(unsigned char *data);
int mmc_read_track_info(struct burn_drive *d, int trackno, struct buffer *buf,
int alloc_len);
/* ts A70812 : return 0 = ok , return BE_CANCELLED = error occured */
/* ts A70812 : return 0 = ok , return BE_CANCELLED = error occurred */
int mmc_read_10(struct burn_drive *d, int start, int amount,
struct buffer *buf);
@ -130,6 +132,12 @@ int mmc_get_leadin_text(struct burn_drive *d,
/* ts B40107 */
int mmc_get_performance(struct burn_drive *d, int descr_type, int flag);
/* ts B90414 */
int burn_make_feature_text(struct burn_drive *d, unsigned int feature_code,
unsigned char flags,
unsigned char additional_length,
unsigned char *feature_data,
char **text, int flag);
#ifdef Libburn_develop_quality_scaN
/* B21108 ts */

View File

@ -1,6 +1,6 @@
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
Copyright (c) 2006 - 2012 Thomas Schmitt <scdbackup@gmx.net>
Copyright (c) 2006 - 2017 Thomas Schmitt <scdbackup@gmx.net>
Provided under GPL version 2 or later.
*/
@ -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;
@ -89,12 +90,22 @@ int burn_write_opts_clone(struct burn_write_opts *from,
return 1;
*to = calloc(1, sizeof(struct burn_write_opts));
if (*to == NULL) {
out_of_mem:;
libdax_msgs_submit(libdax_messenger, -1, 0x00000003,
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
"Out of virtual memory", 0, 0);
return -1;
}
memcpy(*to, from, sizeof(struct burn_write_opts));
(*to)->text_packs = NULL;
(*to)->num_text_packs = 0;
if (from->text_packs != NULL && from->num_text_packs > 0) {
(*to)->text_packs = calloc(1, from->num_text_packs * 18);
if ((*to)->text_packs == NULL)
goto out_of_mem;
memcpy((*to)->text_packs, from->text_packs,
from->num_text_packs * 18);
}
(*to)->refcount= 1;
return 1;
}
@ -313,6 +324,11 @@ enum burn_write_types burn_write_opts_auto_write_type(
reasons[0] = 0;
if (burn_drive_get_bd_r_pow(d)) {
strcat(reasons,
"MEDIA: unsuitable BD-R Pseudo Overwrite formatting, ");
return BURN_WRITE_NONE;
}
if (d->status != BURN_DISC_BLANK &&
d->status != BURN_DISC_APPENDABLE){
if (d->status == BURN_DISC_FULL)
@ -520,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;
}

View File

@ -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;

View File

@ -2,14 +2,14 @@
/* os-netbsd.h
Operating system specific libburn definitions and declarations. Included
by os.h in case of compilation for
NetBSD 6
NetBSD 6 or OpenBSD 5.9
with MMC transport adapter sg-netbsd.c
>>> for OpenBSD too ?
Copyright (C) 2010 - 2014 Thomas Schmitt <scdbackup@gmx.net>
Copyright (C) 2010 - 2016 Thomas Schmitt <scdbackup@gmx.net>
provided under GPLv2+
Derived 2014 from libburn/os-solaris.c
Adapted 2016 to OpenBSD by help of SASANO Takayoshi <uaa@mx5.nisiq.net>
*/
@ -33,6 +33,33 @@
/* The number of above list items */
#define BURN_OS_SIGNAL_COUNT 20
#ifdef __OpenBSD__
/** To list all signals which shall surely not be caught */
#define BURN_OS_NON_SIGNAL_MACRO_LIST \
SIGKILL, SIGURG, SIGSTOP, SIGTSTP, SIGCONT, \
SIGCHLD, SIGTTIN, SIGTTOU, SIGIO, SIGWINCH, \
SIGINFO
/* The number of above list items */
#define BURN_OS_NON_SIGNAL_COUNT 11
/* ts B60730 */
/* Either OpenBSD or SASANO Takayoshi's LG BH14NS48 throw 2,0,0
on Immed bit with BLANK and SYNCHRONIZE CACHE.
Until it is clear that the drive is to blame, the OpenBSD default is
not to use Immed.
This may be overridden at ./configure time by
export CFLAGS
CFLAGS="$CFLAGS -DLibburn_do_no_immed_defaulT=0"
*/
#ifndef Libburn_do_no_immed_defaulT
#define Libburn_do_no_immed_defaulT 1
#endif
#else /* __OpenBSD__ */
/** To list all signals which shall surely not be caught */
#define BURN_OS_NON_SIGNAL_MACRO_LIST \
SIGKILL, SIGURG, SIGSTOP, SIGTSTP, SIGCONT, \
@ -42,6 +69,7 @@
/* The number of above list items */
#define BURN_OS_NON_SIGNAL_COUNT 12
#endif /* ! __OpenBSD__ */
/* The maximum size for a (SCSI) i/o transaction */
/* Important : MUST be at least 32768 ! */

View File

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

View File

@ -1,7 +1,7 @@
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
Copyright (c) 2006 - 2014 Thomas Schmitt <scdbackup@gmx.net>
Copyright (c) 2006 - 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);
"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,

View File

@ -114,12 +114,15 @@ int sbc_start_unit_flag(struct burn_drive *d, int flag)
scsi_init_command(c, SBC_START_UNIT, sizeof(SBC_START_UNIT));
c->retry = 1;
c->opcode[1] |= (flag & 1); /* ts A70918 : Immed */
if (d->do_no_immed && (flag & 1))
c->timeout = 1800 * 1000;
else
c->opcode[1] |= (flag & 1); /* ts A70918 : Immed */
c->dir = NO_TRANSFER;
d->issue_command(d, c);
if (c->error)
return 0;
if (!(flag & 1))
if (d->do_no_immed || !(flag & 1))
return 1;
/* ts A70918 : asynchronous */
ret = spc_wait_unit_attention(d, 1800, "START UNIT", 0);

View File

@ -1,7 +1,7 @@
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
Copyright (c) 2006 - 2015 Thomas Schmitt <scdbackup@gmx.net>
Copyright (c) 2006 - 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",
@ -912,7 +914,7 @@ void process_q(struct burn_drive *d, unsigned char *q)
}
break;
case 2:
/* XXX dont ignore these */
/* XXX do not ignore these */
break;
case 3:
/* burn_print(12, "ISRC data in mode 3 q\n");*/
@ -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);
}
}
@ -931,7 +933,7 @@ void process_q(struct burn_drive *d, unsigned char *q)
/* this needs more info. subs in the data? control/adr? */
/* ts A61119 : One should not use inofficial compiler extensions.
/* ts A61119 : One should not use unofficial compiler extensions.
>>> Some day this function needs to be implemented. At least for now
the result does not match the "mode" of cdrecord -toc.
*/

View File

@ -85,7 +85,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
*/
@ -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)
@ -223,7 +223,7 @@ int sg_is_enumerable_adr(char *adr)
/* Return 1 if the given path leads to a regular file or a device that can be
seeked, read, and possibly written with 2 kB granularity.
fseeked, read, and possibly written with 2 kB granularity.
*/
int burn_os_is_2k_seekrw(char *path, int flag)
{

View File

@ -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
@ -567,6 +567,9 @@ int sg_issue_command(struct burn_drive *d, struct command *c)
ccb->csio.dxfer_len = 0;
}
/* ts B90523 : Record effective transfer length request for debugging*/
c->dxfer_len = ccb->csio.dxfer_len;
do {
memset(&ccb->csio.sense_data, 0, sizeof(ccb->csio.sense_data));
err = cam_send_ccb(d->cam, ccb);
@ -585,6 +588,7 @@ int sg_issue_command(struct burn_drive *d, struct command *c)
}
/* XXX */
memcpy(c->sense, &ccb->csio.sense_data, ccb->csio.sense_len);
c->sense_len = ccb->csio.sense_len;
if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
if (!c->retry) {
c->error = 1;
@ -603,6 +607,8 @@ int sg_issue_command(struct burn_drive *d, struct command *c)
} else {
done = 1;
}
if (!done)
spc_register_retry(c);
} while (!done);
cam_freeccb(ccb);
return 1;
@ -641,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)

View File

@ -128,7 +128,7 @@ int sg_initialize(char msg[1024], int flag)
/* ts A91227 */
/** Performs global finalization of the SCSI transport adapter and eventually
needed operating system facilities. Releases globally aquired resources.
needed operating system facilities. Releases globally acquired resources.
@param flag unused yet, submit 0
@return 1 = success, <=0 = failure
*/
@ -873,6 +873,9 @@ int sg_issue_command(struct burn_drive *d, struct command *c)
ccb->csio.dxfer_len = 0;
}
/* ts B90523 : Record effective transfer length request for debugging*/
c->dxfer_len = ccb->csio.dxfer_len;
start_time = time(NULL);
for (i = 0; !done; i++) {
@ -985,6 +988,8 @@ int sg_issue_command(struct burn_drive *d, struct command *c)
timeout_ms, i, !!ignore_error);
if (d->cancel)
done = 1;
if (!done)
spc_register_retry(c);
} while (!done);
ret = 1;
ex:;
@ -995,7 +1000,7 @@ ex:;
/* ts B00115 */
/* Return 1 if the given path leads to a regular file or a device that can be
seeked, read and eventually written with 2 kB granularity.
fseeked, read and eventually written with 2 kB granularity.
*/
int burn_os_is_2k_seekrw(char *path, int flag)
{

View File

@ -1,7 +1,7 @@
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
/*
Copyright (c) 2009 - 2014 Thomas Schmitt <scdbackup@gmx.net>
Copyright (c) 2009 - 2016 Thomas Schmitt <scdbackup@gmx.net>
Provided under GPL version 2 or later.
*/
@ -44,8 +44,8 @@ sg_initialize() performs global initialization of the SCSI transport
facilities. Checks for compatibility of supporting
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.
@ -54,10 +54,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.
@ -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.
@ -395,7 +395,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
*/
@ -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
@ -665,6 +665,9 @@ int sg_issue_command(struct burn_drive *d, struct command *c)
e_direction = SCSI_MMC_DATA_NONE;
}
/* ts B90523 : Record effective transfer length request for debugging*/
c->dxfer_len = dxfer_len;
/* retry-loop */
start_time = time(NULL);
if (c->timeout > 0)
@ -728,6 +731,8 @@ int sg_issue_command(struct burn_drive *d, struct command *c)
start_time, timeout_ms, i, 0);
if (d->cancel)
done = 1;
if (!done)
spc_register_retry(c);
} /* end of retry-loop */
@ -763,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)
@ -840,7 +845,7 @@ static int freebsd_is_2k_seekrw(char *path, int flag)
/* Return 1 if the given path leads to a regular file or a device that can be
seeked, read, and possibly written with 2 kB granularity.
fseeked, read, and possibly written with 2 kB granularity.
*/
int burn_os_is_2k_seekrw(char *path, int flag)
{

View File

@ -1,7 +1,7 @@
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
Copyright (c) 2006 - 2014 Thomas Schmitt <scdbackup@gmx.net>
Copyright (c) 2006 - 2020 Thomas Schmitt <scdbackup@gmx.net>
Provided under GPL version 2 or later.
*/
@ -50,8 +50,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.
@ -60,10 +60,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.
@ -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
@ -201,7 +210,7 @@ static int linux_sg_auto_family = 1;
/* Set this to 1 in order to accept any TYPE_* (see scsi/scsi.h) */
/* But try with 0 first. There is hope via CDROM_DRIVE_STATUS. */
/* !!! DO NOT SET TO 1 UNLESS YOU PROTECTED ALL INDISPENSIBLE DEVICES
/* !!! DO NOT SET TO 1 UNLESS YOU PROTECTED ALL INDISPENSABLE DEVICES
chmod -rw !!! */
static int linux_sg_accept_any_type = 0;
@ -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));
@ -1041,22 +1143,18 @@ static int is_scsi_drive(char *fname, int fd_in, int *bus_no, int *host_no,
{ret = 0; goto ex;}
}
if (sid_ret == -1 || sid.scsi_id < 0) {
/* ts A61211 : employ a more general ioctl */
/* ts B11001 : re-use fd */
ret = sg_obtain_scsi_adr_fd(fname, fd, bus_no, host_no,
channel_no, target_no, lun_no);
if (ret>0) {
sid.host_no = *host_no;
sid.channel = *channel_no;
sid.scsi_id = *target_no;
sid.lun = *lun_no;
} else {
if (linux_sg_enumerate_debug)
fprintf(stderr,
"sg_obtain_scsi_adr_fd() failed\n");
{ret = 0; goto ex;}
}
/* ts A61211 : employ a more general ioctl */
/* ts B11001 : re-use fd */
/* ts B80902 : call unconditionally because host_no differs
between SG_GET_SCSI_ID and SCSI_IOCTL_GET_IDLUN
*/
ret = sg_obtain_scsi_adr_fd(fname, fd, bus_no, host_no,
channel_no, target_no, lun_no);
if (ret <= 0) {
if (linux_sg_enumerate_debug)
fprintf(stderr,
"sg_obtain_scsi_adr_fd() failed\n");
{ret = 0; goto ex;}
}
/* ts A60927 : trying to do locking with growisofs */
@ -1076,16 +1174,6 @@ static int is_scsi_drive(char *fname, int fd_in, int *bus_no, int *host_no,
sg_release_siblings(sibling_fds, sibling_fnames,
&sibling_count);
}
#ifdef SCSI_IOCTL_GET_BUS_NUMBER
if(*bus_no == -1)
*bus_no = 1000 * (sid.host_no + 1) + sid.channel;
#else
*bus_no = sid.host_no;
#endif
*host_no= sid.host_no;
*channel_no= sid.channel;
*target_no= sid.scsi_id;
*lun_no= sid.lun;
ret = 1;
ex:;
if (fd_in < 0 && fd >= 0) {
@ -1111,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;
@ -1127,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);
@ -1136,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;
}
@ -1153,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);
}
@ -1526,7 +1614,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
*/
@ -1620,6 +1708,8 @@ next_ata:;
next_proc_info:;
baseno += ata_limit;
if (burn_sg_use_family != 0) /* Only with default enumeration */
return 0;
for (i = 0; i < idx->info_count; i++) {
if ((idx->info_list)[i][0] == 0)
continue;
@ -1679,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.
*/
@ -1734,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];
@ -1859,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.
@ -1957,9 +2047,15 @@ static int evaluate_transport_success(struct burn_drive *d, struct command *c,
(unsigned int) host_status, host_problem);
sev = LIBDAX_MSGS_SEV_FAILURE;
if (do_retry && !give_up_drive)
sev = LIBDAX_MSGS_SEV_DEBUG;
sev = LIBDAX_MSGS_SEV_NOTE;
libdax_msgs_submit(libdax_messenger, d->global_index,
0x000201a7, sev, LIBDAX_MSGS_PRIO_HIGH, msg, 0, 0);
strcpy(msg, "Command: ");
if (spc_human_readable_cmd(c, msg + strlen(msg),
160 - strlen(msg), 0) > 0)
libdax_msgs_submit(libdax_messenger, d->global_index,
0x000201a7, sev, LIBDAX_MSGS_PRIO_HIGH,
msg, 0, 0);
sprintf(msg, "--- SG_IO: host_status= 0x%x %s",
(unsigned int) host_status, host_problem);
scsi_log_message(d, fp, msg, 0);
@ -2013,9 +2109,15 @@ static int evaluate_transport_success(struct burn_drive *d, struct command *c,
driver_problem, driver_sugg);
sev = LIBDAX_MSGS_SEV_FAILURE;
if (do_retry && !give_up_drive)
sev = LIBDAX_MSGS_SEV_DEBUG;
sev = LIBDAX_MSGS_SEV_NOTE;
libdax_msgs_submit(libdax_messenger, d->global_index,
0x000201a8, sev, LIBDAX_MSGS_PRIO_HIGH, msg, 0, 0);
strcpy(msg, "Command: ");
if (spc_human_readable_cmd(c, msg + strlen(msg),
160 - strlen(msg), 0) > 0)
libdax_msgs_submit(libdax_messenger, d->global_index,
0x000201a8, sev, LIBDAX_MSGS_PRIO_HIGH,
msg, 0, 0);
sprintf(msg, "--- SG_IO: driver_status= 0x%x %s / %s",
(unsigned int) driver_status,
driver_problem, driver_sugg);
@ -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
@ -2175,6 +2277,9 @@ int sg_issue_command(struct burn_drive *d, struct command *c)
}
s.usr_ptr = c;
/* ts B90523 : Record effective transfer length request for debugging*/
c->dxfer_len = s.dxfer_len;
start_time = time(NULL);
for(i = 0; !done; i++) {
@ -2211,6 +2316,19 @@ int sg_issue_command(struct burn_drive *d, struct command *c)
(unsigned int) s.host_status,
(unsigned int) s.driver_status);
scsi_log_message(d, fp, msg, 0);
libdax_msgs_submit(libdax_messenger,
d->global_index, 0x0002010c,
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
msg, 0, 0);
sprintf(msg, "Attempted command: ");
spc_human_readable_cmd(c, msg + strlen(msg),
160 - strlen(msg), 0);
libdax_msgs_submit(libdax_messenger,
d->global_index, 0x0002010c,
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
msg, 0, 0);
react_on_drive_loss(d, c, fp);
{ret = -1; goto ex;}
}
@ -2229,6 +2347,13 @@ int sg_issue_command(struct burn_drive *d, struct command *c)
if (d->cancel)
break;
/* if ! done : loop for retry */;
if (!done) {
spc_register_retry(c);
if (burn_sg_log_scsi & 3) {
scsi_log_text("+++ Repeating command", fp, 0);
scsi_log_cmd(c, fp, 0);
}
}
}
ret = 1;
@ -2253,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;
@ -2322,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)
@ -2353,7 +2478,7 @@ ex:;
/* ts B00115 */
/* Return 1 if the given path leads to a regular file or a device that can be
seeked, read, and possibly written with 2 kB granularity.
fseeked, read, and possibly written with 2 kB granularity.
*/
int burn_os_is_2k_seekrw(char *path, int flag)
{

View File

@ -1,13 +1,15 @@
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
/*
Copyright (c) 2010 - 2014 Thomas Schmitt <scdbackup@gmx.net>
Copyright (c) 2010 - 2016 Thomas Schmitt <scdbackup@gmx.net>
Provided under GPL version 2 or later.
Derived 2014 from libburn/sg-solaris.c with information learned from
dvd+rw-tools, http://fxr.watson.org/fxr/source/sys/scsiio.h?v=NETBSD,
http://netbsd.gw.com/cgi-bin/man-cgi?scsi+4+NetBSD-current,
and experiments made by Freddy Fisker.
Adapted 2016 to OpenBSD by help of SASANO Takayoshi <uaa@mx5.nisiq.net>.
*/
@ -17,7 +19,7 @@ This is the main operating system dependent SCSI part of libburn. It implements
the transport level aspects of SCSI control and command i/o.
Present implementation: NetBSD 6, ioctl SCIOCCOMMAND
>>> ??? for OpenBSD too ?
OpenBSD 5.9, ioctl SCIOCCOMMAND
PORTING:
@ -49,8 +51,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.
@ -59,10 +61,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.
@ -70,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.
@ -210,7 +212,7 @@ static void enumerate_common(char *fname,
/* PORTING: ------------------- non portable part --------------- */
/* Transport adapter is NetBSD SCIOCCOMMAND */
/* Transport adapter is NetBSD/OpenBSD ioctl SCIOCCOMMAND */
/* Adapter specific handles and data */
out.fd = -1;
@ -312,7 +314,11 @@ static int guess_size_by_seek_set(int fd, off_t *bytes, int flag)
*/
int sg_id_string(char msg[1024], int flag)
{
#ifdef __OpenBSD__
sprintf(msg, "internal OpenBSD SCIOCCOMMAND adapter sg-netbsd");
#else
sprintf(msg, "internal NetBSD SCIOCCOMMAND adapter sg-netbsd");
#endif
return 1;
}
@ -331,7 +337,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
*/
@ -519,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
@ -581,6 +587,9 @@ int sg_issue_command(struct burn_drive *d, struct command *c)
req.datalen = 0;
}
/* ts B90523 : Record effective transfer length request for debugging*/
c->dxfer_len = req.datalen;
/* retry-loop */
start_time = time(NULL);
for(i = 0; !done; i++) {
@ -662,6 +671,8 @@ if (c->opcode[0] == 0x5a) {
start_time, timeout_ms, i, 0);
if (d->cancel)
done = 1;
if (!done)
spc_register_retry(c);
} /* end of retry-loop */
return 1;
@ -687,10 +698,21 @@ int sg_obtain_scsi_adr(char *path, int *bus_no, int *host_no, int *channel_no,
{ret = 0; goto ex;}
if (addr.type != TYPE_SCSI)
{ret = 0; goto ex;}
#ifdef __OpenBSD__
*bus_no = *host_no = addr.scbus;
*target_no = addr.target;
*lun_no = addr.lun;
#else /* __OpenBSD__ */
*bus_no = *host_no = addr.addr.scsi.scbus;
*channel_no = 0;
*target_no = addr.addr.scsi.target;
*lun_no = addr.addr.scsi.lun;
#endif /* ! __OpenBSD__ */
ret = 1;
ex:;
if (fd != -1)
@ -699,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)
@ -724,7 +746,7 @@ int sg_is_enumerable_adr(char* adr)
/* Return 1 if the given path leads to a regular file or a device that can be
seeked, read, and possibly written with 2 kB granularity.
fseeked, read, and possibly written with 2 kB granularity.
*/
int burn_os_is_2k_seekrw(char *path, int flag)
{

View File

@ -1,7 +1,7 @@
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
/*
Copyright (c) 2010 - 2014 Thomas Schmitt <scdbackup@gmx.net>
Copyright (c) 2010 - 2016 Thomas Schmitt <scdbackup@gmx.net>
Provided under GPL version 2 or later.
*/
@ -44,8 +44,8 @@ sg_initialize() performs global initialization of the SCSI transport
facilities. Checks for compatibility of supporting
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.
@ -54,10 +54,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.
@ -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.
@ -497,7 +497,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
*/
@ -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
@ -754,6 +754,9 @@ int sg_issue_command(struct burn_drive *d, struct command *c)
cgc.uscsi_rqlen = sizeof(c->sense);
cgc.uscsi_rqbuf = (caddr_t) c->sense;
/* ts B90523 : Record effective transfer length request for debugging*/
c->dxfer_len = cgc.uscsi_buflen;
/* retry-loop */
start_time = time(NULL);
for(i = 0; !done; i++) {
@ -799,6 +802,8 @@ int sg_issue_command(struct burn_drive *d, struct command *c)
start_time, timeout_ms, i, 0);
if (d->cancel)
done = 1;
if (!done)
spc_register_retry(c);
} /* end of retry-loop */
@ -832,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.
*/
@ -881,7 +886,7 @@ int sg_is_enumerable_adr(char* adr)
/* Return 1 if the given path leads to a regular file or a device that can be
seeked, read, and possibly written with 2 kB granularity.
fseeked, read, and possibly written with 2 kB granularity.
*/
int burn_os_is_2k_seekrw(char *path, int flag)
{

View File

@ -1,7 +1,7 @@
/* sg.c
Switcher for operating system dependent transport level modules of libburn.
Copyright (C) 2009 - 2014 Thomas Schmitt <scdbackup@gmx.net>,
Copyright (C) 2009 - 2016 Thomas Schmitt <scdbackup@gmx.net>,
provided under GPLv2+
*/
@ -11,12 +11,6 @@
#endif
/* <<< Until it is known whether this adapter would work on OpenBSD too */
#ifdef __NetBSD__
#define Libburn_use_sg_netbsD
#endif
#ifdef Libburn_use_sg_dummY
#include "sg-dummy.c"
@ -27,8 +21,12 @@
#include "sg-libcdio.c"
#else
#ifdef Libburn_use_sg_netbsD
/* To become: # ifdef __NetBSD__ */
#ifdef __NetBSD__
#include "sg-netbsd.c"
#else
#ifdef __OpenBSD__
#include "sg-netbsd.c"
@ -88,7 +86,8 @@ static int intentional_compiler_warning(void)
#endif /* ! __linux */
#endif /* ! __FreeBSD_kernel__ */
#endif /* ! __FreeBSD__ */
#endif /* ! Libburn_use_sg_netbsD */
#endif /* ! __OpenBSD__ */
#endif /* ! __NetBSD__ */
#endif /* ! Libburn_use_libcdiO */
#endif /* ! Libburn_use_sg_dummY */

View File

@ -62,7 +62,7 @@ int sg_initialize(char msg[1024], int flag);
/* ts A91227 */
/** Performs global finalization of the SCSI transport adapter and eventually
needed operating system facilities. Releases globally aquired resources.
needed operating system facilities. Releases globally acquired resources.
@param flag unused yet, submit 0
@return 1 = success, <=0 = failure
*/

View File

@ -1,7 +1,7 @@
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
Copyright (c) 2006 - 2014 Thomas Schmitt <scdbackup@gmx.net>
Copyright (c) 2006 - 2019 Thomas Schmitt <scdbackup@gmx.net>
Provided under GPL version 2 or later.
*/
@ -75,10 +75,16 @@ int scsi_init_command(struct command *c, unsigned char *opcode, int oplen)
c->dir = NO_TRANSFER;
c->dxfer_len = -1;
memset(c->sense, 0, sizeof(c->sense));
c->sense_len = 0;
c->error = 0;
c->retry = 0;
c->page = NULL;
c->timeout = Libburn_scsi_default_timeouT;
c->start_time = c->end_time = 0.0;
c->retry_count = 0;
c->last_retry_key = 0;
c->last_retry_asc = 0;
c->last_retry_ascq = 0;
return 1;
}
@ -153,14 +159,20 @@ int spc_wait_unit_attention(struct burn_drive *d, int max_sec, char *cmd_text,
int i, ret = 1, key = 0, asc = 0, ascq = 0, clueless_start = 0;
static double tests_per_second = 2.0;
int sleep_usecs, loop_limit, clueless_timeout, progress;
char *msg = NULL;
char *msg = NULL, *cmd_name = NULL, *cmd_cpt;
unsigned char sense[14];
BURN_ALLOC_MEM(msg, char, 320);
BURN_ALLOC_MEM(cmd_name, char, 320);
clueless_timeout = 5 * tests_per_second + 1;
loop_limit = max_sec * tests_per_second + 1;
sleep_usecs = 1000000 / tests_per_second;
strcpy(cmd_name, cmd_text);
cmd_cpt = strchr(cmd_name, ':');
if (cmd_cpt != NULL)
*cmd_cpt = 0;
if (!(flag & 1))
usleep(sleep_usecs);
@ -183,14 +195,14 @@ 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:;
/* ts A90213 */
sprintf(msg,
"Asynchronous SCSI error on %s: ", cmd_text);
"Asynchronous SCSI error on %s: ", cmd_name);
sense[0] = 0x70; /* Fixed format sense data */
sense[2] = key;
sense[12] = asc;
@ -201,6 +213,14 @@ handle_error:;
0x0002014d,
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
msg, 0, 0);
if (cmd_cpt != NULL) {
sprintf(msg, "Attempted SCSI CDB: %s",
cmd_cpt + 1);
libdax_msgs_submit(libdax_messenger,
d->global_index, 0x0002014d,
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
msg, 0, 0);
}
d->cancel = 1;
break;
} else if (ascq == 0x00) { /* CAUSE NOT REPORTABLE */
@ -214,6 +234,16 @@ handle_error:;
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH,
"Ended clueless NOT READY cycle",
0, 0);
if (cmd_cpt != NULL) {
sprintf(msg, "Attempted SCSI CDB: %s",
cmd_cpt + 1);
libdax_msgs_submit(libdax_messenger,
d->global_index,
0x00000002,
LIBDAX_MSGS_SEV_DEBUG,
LIBDAX_MSGS_PRIO_HIGH,
msg, 0, 0);
}
ret = 1; /* medium not present = ok */
break;
}
@ -225,7 +255,7 @@ slumber:;
}
if (ret <= 0 || !(flag & 2)) {
sprintf(msg, "Async %s %s after %d.%d seconds",
cmd_text, (ret > 0 ? "succeeded" : "failed"),
cmd_name, (ret > 0 ? "succeeded" : "failed"),
i / 10, i % 10);
libdax_msgs_submit(libdax_messenger, d->global_index,
0x00020150, LIBDAX_MSGS_SEV_DEBUG,
@ -236,12 +266,19 @@ slumber:;
{ret = (ret > 0); goto ex;}
sprintf(msg, "Timeout (%d s) with asynchronous SCSI command %s\n",
max_sec, cmd_text);
max_sec, cmd_name);
libdax_msgs_submit(libdax_messenger, d->global_index, 0x0002014f,
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH, msg, 0, 0);
if (cmd_cpt != NULL) {
sprintf(msg, "Attempted SCSI CDB: %s", cmd_cpt + 1);
libdax_msgs_submit(libdax_messenger, d->global_index,
0x0002014f, LIBDAX_MSGS_SEV_SORRY,
LIBDAX_MSGS_PRIO_HIGH, msg, 0, 0);
}
ret = 0;
ex:;
BURN_FREE_MEM(msg);
BURN_FREE_MEM(cmd_name);
return ret;
}
@ -1019,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;
@ -1034,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;
}
@ -1081,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) {
@ -1409,21 +1446,28 @@ 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;
case 0x29:
if (*ascq == 0)
sprintf(msg,
"Power on, reset, or bus device reset occured");
"Power on, reset, or bus device reset occurred");
else if (*ascq == 1)
sprintf(msg, "Power on occured");
sprintf(msg, "Power on occurred");
else if (*ascq == 2)
sprintf(msg, "Bus reset occured");
sprintf(msg, "Bus reset occurred");
else if (*ascq == 3)
sprintf(msg, "Bus device reset function occured");
sprintf(msg, "Bus device reset function occurred");
else if (*ascq == 4)
sprintf(msg, "Device internal reset");
else
@ -1459,6 +1503,16 @@ enum response scsi_error_msg(struct burn_drive *d, unsigned char *sense,
"Cannot format medium, incompatible medium");
else if (*ascq == 7)
sprintf(msg, "Cleaning failure");
else if (*ascq == 8)
sprintf(msg,
"Cannot write, application code mismatch");
else if (*ascq == 9)
sprintf(msg, "Current session not fixated for append");
else if (*ascq == 10)
sprintf(msg, "Medium not formatted");
else if (*ascq == 11)
sprintf(msg,
"Cannot write medium, unsupported medium version");
else
break;
goto return_fail;
@ -1534,6 +1588,28 @@ enum response scsi_error_msg(struct burn_drive *d, unsigned char *sense,
else
break;
goto return_fail;
case 0x6F:
if (*ascq == 0)
sprintf(msg, "Copy protection key exchange failure Authentication failure");
else if (*ascq == 1)
sprintf(msg, "Copy protection key exchange failure Key not present");
else if (*ascq == 2)
sprintf(msg, "Copy protection key exchange failure Key not established");
else if (*ascq == 3)
sprintf(msg, "Read of scrambled sector without authentication");
else if (*ascq == 4)
sprintf(msg, "Media region code is mismatched to logical unit region");
else if (*ascq == 5)
sprintf(msg, "Logical unit region must be permanent / Region reset count error");
else if (*ascq == 6)
sprintf(msg, "Insufficient block count for binding nonce recording");
else if (*ascq == 7)
sprintf(msg, "Conflict in binding nonce recording");
else if (*ascq == 8)
sprintf(msg, "Insufficient permission");
else
break;
goto return_fail;
case 0x72:
if (*ascq == 0)
sprintf(msg, "Session fixation error");
@ -1688,6 +1764,67 @@ static char *scsi_command_name(unsigned int c, int flag)
}
/* ts B90206: Avoid publishing more inner API functions which begin by scsi_ */
char *spc_command_name(unsigned int c, int flag)
{
return(scsi_command_name(c, flag));
}
/* ts B90616 */
void spc_register_retry(struct command *c)
{
c->retry_count++;
spc_decode_sense(c->sense, c->sense_len, &c->last_retry_key,
&c->last_retry_asc, &c->last_retry_ascq);
}
/* ts B90511 */
/* @param flag bit0= do not prepend command name
bit1= do not append dxfer_len
*/
int spc_human_readable_cmd(struct command *c, char *msg, int msg_max, int flag)
{
int j, l, lname;
if ((flag & 1) && c->retry_count <= 0) {
msg[0] = 0;
} else {
if (msg_max < 60)
return -1;
strcpy(msg, spc_command_name( (unsigned int) c->opcode[0], 0));
if (c->retry_count > 0) {
sprintf(msg + strlen(msg), " #%d", c->retry_count + 1);
if (c->last_retry_key > 0)
sprintf(msg + strlen(msg), ",[%X %2.2X %2.2X]",
c->last_retry_key, c->last_retry_asc,
c->last_retry_ascq);
}
strcat(msg, " : ");
}
lname = l = strlen(msg);
for (j = 0; j < 16 && j < c->oplen; j++) {
if (l > msg_max - 3) {
if (msg_max - 4 >= lname) {
l = msg_max - 4;
sprintf(msg + strlen(msg), "... ");
}
return 0;
}
sprintf(msg + l, "%2.2x ", c->opcode[j]);
l += 3;
}
if (c->dir != NO_TRANSFER && c->page != NULL && !(flag & 2)) {
if (l > msg_max - 24)
return 0;
sprintf(msg + l, " : dxfer_len= %d", c->dxfer_len);
l = strlen(msg);
}
return 1;
}
/* ts A61030 - A61115 */
/* @param flag bit0= do report conditions which are considered not an error
bit1= report with severity FAILURE rather than DEBUG
@ -1725,7 +1862,16 @@ int scsi_notify_error(struct burn_drive *d, struct command *c,
ret = libdax_msgs_submit(libdax_messenger, d->global_index, 0x0002010f,
(flag & 2) && d->silent_on_scsi_error != 3 ?
LIBDAX_MSGS_SEV_FAILURE : LIBDAX_MSGS_SEV_DEBUG,
LIBDAX_MSGS_PRIO_HIGH, msg,0,0);
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,
0x0002010f,
(flag & 2) && d->silent_on_scsi_error != 3 ?
LIBDAX_MSGS_SEV_FAILURE : LIBDAX_MSGS_SEV_DEBUG,
LIBDAX_MSGS_PRIO_HIGH, msg, 0, 0);
}
ex:;
BURN_FREE_MEM(msg);
BURN_FREE_MEM(scsi_msg);
@ -1972,6 +2118,8 @@ int scsi_eval_cmd_outcome(struct burn_drive *d, struct command *c, void *fp,
if (burn_sg_log_scsi & 3)
scsi_log_err(d, c, fp, sense, sense_len,
(sense_len > 0) | (flag & 2));
if (sense == c->sense)
c->sense_len = sense_len;
if (sense_len <= 0)
{done = 1; goto ex;}
@ -2003,6 +2151,13 @@ int scsi_eval_cmd_outcome(struct burn_drive *d, struct command *c, void *fp,
0x0002018a,
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
msg, 0, 0);
strcpy(msg, "Command: ");
if (spc_human_readable_cmd(c, msg + strlen(msg),
320 - strlen(msg), 0) > 0)
libdax_msgs_submit(libdax_messenger,
d->global_index, 0x0002018a,
LIBDAX_MSGS_SEV_SORRY,
LIBDAX_MSGS_PRIO_HIGH, msg, 0, 0);
goto err_ex;
}
if (d->cancel)

View File

@ -1,7 +1,7 @@
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
Copyright (c) 2006 - 2014 Thomas Schmitt <scdbackup@gmx.net>
Copyright (c) 2006 - 2019 Thomas Schmitt <scdbackup@gmx.net>
Provided under GPL version 2 or later.
*/
@ -114,6 +114,16 @@ int scsi_log_message(struct burn_drive *d, void *fp, char * msg, int flag);
int spc_decode_sense(unsigned char *sense, int senselen,
int *key, int *asc, int *ascq);
/* ts B90206 */
char *spc_command_name(unsigned int c, int flag);
/* ts B90511 */
int spc_human_readable_cmd(struct command *c, char *msg, int msg_max,
int flag);
/* ts B90616 */
void spc_register_retry(struct command *c);
/* ts B00808 */
/** Evaluates outcome of a single SCSI command, eventually logs sense data,
and issues DEBUG error message in case the command is evaluated as done.
@ -156,17 +166,23 @@ int spc_confirm_cd_drive(struct burn_drive *d, int flag);
/* RESERVE TRACK */
#define Libburn_mmc_reserve_timeouT 200000
/* CLOSE TRACK/SESSION (with Immed bit) */
/* CLOSE TRACK/SESSION with Immed bit */
#define Libburn_mmc_close_timeouT 200000
/* CLOSE TRACK/SESSION without Immed bit */
#define Libburn_mmc_close_noim_timeouT 3600000
/* BLANK , FORMAT UNIT (with Immed bit) */
/* BLANK , FORMAT UNIT with Immed bit */
#define Libburn_mmc_blank_timeouT 200000
/* BLANK , FORMAT UNIT without Immed bit */
#define Libburn_mmc_blank_noim_timeouT 18000000
/* SEND OPC INFORMATION */
#define Libburn_mmc_opc_timeouT 200000
/* MMC_SYNC_CACHE */
/* MMC_SYNC_CACHE with Immed bit */
#define Libburn_mmc_sync_timeouT 200000
/* MMC_SYNC_CACHE without Immed bit */
#define Libburn_mmc_sync_noim_timeouT 3600000
/* START STOP UNIT with Start bit and Load bit set */
#define Libburn_mmc_load_timeouT 300000

View File

@ -1,6 +1,6 @@
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
Copyright (c) 2006 - 2014 Thomas Schmitt <scdbackup@gmx.net>
Copyright (c) 2006 - 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;
}
@ -1647,7 +1727,7 @@ out_of_mem:;
if (crs->file_source != NULL) {
libdax_msgs_submit(libdax_messenger, -1, 0x00020192,
LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH,
"In cue sheet file: Multiple occurences of FILE",
"In cue sheet file: Multiple occurrences of FILE",
0, 0);
ret = 0; goto ex;
}

View File

@ -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 */

View File

@ -1,7 +1,7 @@
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
Copyright (c) 2006 - 2015 Thomas Schmitt <scdbackup@gmx.net>
Copyright (c) 2006 - 2024 Thomas Schmitt <scdbackup@gmx.net>
Provided under GPL version 2 or later.
*/
@ -61,6 +61,7 @@ struct command
int dir;
int dxfer_len;
unsigned char sense[128];
int sense_len;
int error;
int retry;
struct buffer *page;
@ -69,6 +70,10 @@ struct command
double start_time;
double end_time;
int retry_count;
int last_retry_key;
int last_retry_asc;
int last_retry_ascq;
};
struct burn_scsi_inquiry_data
@ -256,12 +261,12 @@ struct burn_drive
/* ts B51016 : Result from feature 108h : Drive Serial Number
*/
char *drive_serial_number;
char drive_serial_number_len;
int drive_serial_number_len;
/* ts B51016 : Result from command AB READ MEDIA SERIAL NUMBER
*/
char *media_serial_number;
char media_serial_number_len;
int media_serial_number_len;
/* ts B10524 : whether the damage bit was set for the future track.
bit0= damage bit , bit1= nwa valid bit
@ -272,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
@ -324,18 +329,20 @@ struct burn_drive
int silent_on_scsi_error;
/* ts B21023 */
/* bit0= 5 64 00 occured with READ10 in mmc_read_10()
/* bit0= 5 64 00 occurred with READ10 in mmc_read_10()
*/
int had_particular_error;
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;
int end_lba;
/* ts B61116 */
int do_simulate;
/* ts A70131 : from 51h READ DISC INFORMATION Number of Sessions (-1)*/
int complete_sessions;
@ -364,20 +371,30 @@ 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 B10314 : Next Writeable Adress for drive_role == 5 */
int role_5_nwa;
/* 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 / C40302 : Next Writeable Address for drive_role == 5 */
off_t role_5_nwa;
/* ts B60730 */
int do_no_immed;
int toc_temp;
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
@ -420,6 +437,19 @@ struct burn_drive
/* ts B00225 */
pthread_t thread_tid;
/* ts B90513 */
unsigned int write_retry_count;
/* ts C00806 */
/* 0=no change, 1=change, -1=already urged OS to revalidate medium */
int medium_state_changed;
/* ts C00822 */
/* If set, use Exact bit with SET STREAMING and use SET STREAMING
even if the medium is a CD.
*/
int set_streaming_exact_bit;
int set_streaming_err;
/* transport functions */
int (*grab) (struct burn_drive *);
@ -437,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 *);

View File

@ -195,7 +195,8 @@ char *burn_guess_manufacturer(int prf,
{"RITEK", 5, "Ritek Corp"},
{"SONY", 4, "Sony Corporation"},
{"TDK", 3, "TDK Corporation"},
{"TT", 8, "TDK Corporation"},
{"TTG", 3, "TDK Corporation"},
{"TTH", 3, "TDK Corporation"},
{"TY", 8, "Taiyo Yuden Company Limited"},
{"TYG", 3, "Taiyo Yuden Company Limited"},
{"UME", 3, "UmeDisc Limited"},

View File

@ -1,7 +1,7 @@
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
Copyright (c) 2006 - 2012 Thomas Schmitt <scdbackup@gmx.net>
Copyright (c) 2006 - 2024 Thomas Schmitt <scdbackup@gmx.net>
Provided under GPL version 2 or later.
*/
@ -440,7 +440,7 @@ static int add_isrc_cue(struct cue_sheet *sheet, unsigned char ctladr, int tno,
{
unsigned char *unit;
int i, ret;
char text[8];
char text[8 + 21]; /* should suffice for 64 bit oversize */
ret = new_cue(sheet, 2, 0);
if (ret <= 0)
@ -454,6 +454,9 @@ static int add_isrc_cue(struct cue_sheet *sheet, unsigned char ctladr, int tno,
unit[5] = isrc->owner[1];
unit[6] = isrc->owner[2];
sprintf(text, "%-2.2u%-5.5u", (unsigned int) isrc->year, isrc->serial);
sprintf(text, "%-2.2u", (unsigned int) isrc->year);
sprintf(text + 2, "%-5.5u", isrc->serial);
text[7] = 0;
unit[7] = text[0];
for (i = 1; i < 7; i++)
unit[9 + i] = text[i];
@ -627,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);
@ -720,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.
*/
@ -789,7 +794,7 @@ XXX this is untested :)
rem += burn_track_get_shortage(tar[i]);
/* ts A61101 : I doubt that linking would yield a
desireable effect. With TAO it is
desirable effect. With TAO it is
counterproductive in any way.
*/
if (o->write_type == BURN_WRITE_TAO)
@ -1022,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;
@ -1069,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;
@ -1174,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,
@ -1200,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)
@ -1351,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;
@ -1376,6 +1383,7 @@ int burn_disc_init_write_status(struct burn_write_opts *o,
ret = burn_write_opts_clone(o, &(d->write_opts), 0);
if (ret <= 0)
return ret;
d->write_retry_count = 0;
d->busy = BURN_DRIVE_WRITING;
@ -1419,7 +1427,7 @@ int burn_precheck_write(struct burn_write_opts *o, struct burn_disc *disc,
enum burn_write_types wt;
struct burn_drive *d = o->drive;
char *msg = NULL, *reason_pt;
int no_media = 0, ret, has_cdtext;
int no_media = 0, ret, has_cdtext, is_bd_pow = 0;
reason_pt= reasons;
reasons[0] = 0;
@ -1497,6 +1505,20 @@ int burn_precheck_write(struct burn_write_opts *o, struct burn_disc *disc,
sequential stdio "drive" */
if (o->start_byte >= 0)
strcat(reasons, "write start address not supported, ");
is_bd_pow = burn_drive_get_bd_r_pow(d);
if (is_bd_pow && !silent)
libdax_msgs_submit(libdax_messenger, d->global_index,
0x0002011e,
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
"Unsuitable media detected: BD-R formatted to POW.",
0, 0);
if (is_bd_pow) {
strcat(reasons,
"unsuitable media formatting POW detected, ");
return 0;
}
} else {
unsuitable_profile:;
msg = calloc(1, 160);
@ -1548,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)
@ -1573,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))
@ -1608,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)
@ -1622,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
@ -1632,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",
@ -1688,7 +1704,7 @@ int burn_disc_close_track_dvd_minus_r(struct burn_write_opts *o, int tnum)
int burn_disc_finalize_dvd_plus_r(struct burn_write_opts *o)
{
struct burn_drive *d = o->drive;
char msg[80];
char msg[40 + 80]; /* filltext + profile */
sprintf(msg, "Finalizing %s ...",
d->current_profile_text);
@ -1881,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 */
@ -1911,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 */
@ -2079,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.
@ -2106,7 +2127,7 @@ int burn_dvd_write_session(struct burn_write_opts *o,
libdax_msgs_submit(libdax_messenger, d->global_index,
0x00020171,
LIBDAX_MSGS_SEV_NOTE, LIBDAX_MSGS_PRIO_HIGH,
"Closing BD-R with accidently open session",
"Closing BD-R with accidentally open session",
0, 0);
d->close_track_session(d, 3, 0); /* CLOSE SESSION, 110b */
d->state_of_last_session = 3; /* mark as complete session */
@ -2212,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,
@ -2314,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,
@ -2405,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) {
@ -2589,6 +2619,8 @@ int burn_stdio_write(int fd, char *buf, int count, struct burn_drive *d,
if (d->cancel || count <= 0)
return 0;
if(d->do_simulate)
return 1;
todo = count;
done = 0;
@ -2619,6 +2651,7 @@ fprintf(stderr, "libburn_DEBUG: write(%d, %lX, %d)\n",
d->cancel = 1;
ret = 0; goto ex;
}
ret = 1;
ex:;
BURN_FREE_MEM(msg);
return ret;
@ -2626,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;
@ -2669,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)
@ -2741,31 +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;
struct timezone dummy_tz;
double to_wait;
double to_wait, goal, corr;
int abs_max_corr;
if (flag & 1) {
gettimeofday(prev_time, &dummy_tz);
gettimeofday(prev_time, NULL);
*us_corr = 0;
return 1;
}
if(d->nominal_write_speed <= 0)
if (kb_per_second <= 0)
return 2;
gettimeofday(&tnow, &dummy_tz);
to_wait = ( ((double) amount) / (double) d->nominal_write_speed ) -
(double) ( tnow.tv_sec - prev_time->tv_sec ) -
(double) ( tnow.tv_usec - prev_time->tv_usec ) / 1.0e6
- 0.001; /* best would be 1 / kernel granularity HZ */
if (to_wait >= 0.0001) {
usleep((int) (to_wait * 1000000.0));
if (max_corr < -1.0e9 || max_corr > 1.0e9)
abs_max_corr = 1000000000;
else
abs_max_corr = abs(max_corr);
gettimeofday(&tnow, NULL);
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, &dummy_tz);
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;
}
@ -2774,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);
@ -2795,9 +2857,13 @@ int burn_stdio_write_track(struct burn_write_opts *o, struct burn_session *s,
d->write = burn_stdio_mmc_dummy_write;
else
d->write = burn_stdio_mmc_write;
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))
@ -2810,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) */
@ -2905,7 +2982,7 @@ void burn_disc_write_sync(struct burn_write_opts *o, struct burn_disc *disc)
struct buffer *buffer_mem = o->drive->buffer;
struct burn_session *s;
struct burn_track *lt, *t;
int first = 1, i, ret, lba, nwa = 0, multi_mem;
int first = 1, i, ret, lba, nwa = 0, multi_mem, stream_recording_start;
off_t default_size;
char msg[80];
@ -2917,12 +2994,13 @@ void burn_disc_write_sync(struct burn_write_opts *o, struct burn_disc *disc)
/* ts A61224 */
burn_disc_init_write_status(o, disc); /* must be done very early */
/* ts A80412 , A90227 */
d->do_stream_recording = !!o->do_stream_recording;
/* ts A80412 , A90227 , B90411 */
if (o->do_stream_recording >= 16)
d->stream_recording_start = o->do_stream_recording;
stream_recording_start = o->do_stream_recording;
else
d->stream_recording_start = 0;
stream_recording_start = 0;
burn_drive_set_stream_recording(d, !!o->do_stream_recording,
stream_recording_start, 0);
/* ts A91122 : Get buffer suitable for sources made by
burn_os_open_track_src() */
@ -3052,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);
@ -3173,6 +3252,14 @@ ex:;
burn_write_opts_free(d->write_opts);
d->write_opts = NULL;
}
if (d->write_retry_count > 0) {
sprintf(msg, "WRITE command repetition happened %u times",
d->write_retry_count);
libdax_msgs_submit(libdax_messenger, d->global_index,
0x000201ad,
LIBDAX_MSGS_SEV_NOTE, LIBDAX_MSGS_PRIO_HIGH,
msg, 0, 0);
}
return;
}
@ -3290,7 +3377,9 @@ int burn_random_access_write(struct burn_drive *d, off_t byte_address,
rpt += d->buffer->bytes;
d->buffer->sectors = chunksize;
d->nwa = start;
if(d->drive_role == 1) {
if(d->do_simulate) {
err = 0;
} else if(d->drive_role == 1) {
err = d->write(d, d->nwa, d->buffer);
} else {
ret = burn_stdio_write(fd, (char *) d->buffer->data,
@ -3310,7 +3399,9 @@ int burn_random_access_write(struct burn_drive *d, off_t byte_address,
if(d->drive_role == 1)
d->needs_sync_cache = 1;
if(flag & 1) {
if(d->drive_role == 1)
if(d->do_simulate) {
;
} else if(d->drive_role == 1)
d->sync_cache(d);
else
burn_stdio_sync_cache(fd, d, 2);

View File

@ -1,6 +1,6 @@
/* test/libburner.c , API illustration of burning data or audio tracks to CD */
/* Copyright (C) 2005 - 2015 Thomas Schmitt <scdbackup@gmx.net> */
/* Copyright (C) 2005 - 2016 Thomas Schmitt <scdbackup@gmx.net> */
/* Provided under GPL, see also "License and copyright aspects" at file end */
@ -24,17 +24,17 @@
and provide some signal and abort handling, e.g. by the builtin handler, by
burn_set_signal_handling("libburner : ", NULL, 0x0)
as it is done in main() at the end of this file.
Then you aquire a drive in an appropriate way conforming to the API. The twoi
Then you acquire a drive in an appropriate way conforming to the API. The two
main approaches are shown here in application functions:
libburner_aquire_by_adr() demonstrates usage as of cdrecord traditions
libburner_aquire_by_driveno() demonstrates a scan-and-choose approach
With that aquired drive you can blank a CD-RW or DVD-RW as shown in
With that acquired drive you can blank a CD-RW or DVD-RW as shown in
libburner_blank_disc()
or you can format a DVD-RW to profile "Restricted Overwrite" (needed once)
or an unused BD to default size with spare blocks
libburner_format()
With the aquired drive you can burn to CD, DVD, BD. See
With the acquired drive you can burn to CD, DVD, BD. See
libburner_payload()
These three functions switch temporarily to a non-fatal signal handler
@ -98,7 +98,7 @@ static unsigned int drive_count;
finally released */
static int drive_is_grabbed = 0;
/** A number and a text describing the type of media in aquired drive */
/** A number and a text describing the type of media in acquired drive */
static int current_profile= -1;
static char current_profile_name[80]= {""};
@ -111,7 +111,7 @@ int libburner_aquire_by_driveno(int *drive_no);
/* ------------------------------- API gestures ---------------------------- */
/** You need to aquire a drive before burning. The API offers this as one
/** You need to acquire a drive before burning. The API offers this as one
compact call and alternatively as application controllable gestures of
whitelisting, scanning for drives and finally grabbing one of them.
@ -239,14 +239,14 @@ int libburner_aquire_by_driveno(int *driveno)
and to restart when the choice has been made. The list of selectable
drives should also hold persistent drive addresses as obtained
above by burn_drive_get_adr(). By such an address one may use
burn_drive_scan_and_grab() to finally aquire exactly one drive.
burn_drive_scan_and_grab() to finally acquire exactly one drive.
A not yet tested shortcut should be to call burn_drive_info_free()
and to call either burn_drive_scan() or burn_drive_scan_and_grab()
before accessing any drives again.
In both cases you have to be aware that the desired drive might get
aquired in the meantime by another user or libburn process.
acquired in the meantime by another user or libburn process.
*/
/* We already made our choice via command line. (default is 0)
@ -784,7 +784,7 @@ int main(int argc, char **argv)
/** Note: driveno might change its value in this call */
ret = libburner_aquire_drive(drive_adr, &driveno);
if (ret<=0) {
fprintf(stderr,"\nFATAL: Failed to aquire drive.\n");
fprintf(stderr,"\nFATAL: Failed to acquire drive.\n");
{ ret = 34; goto finish_libburn; }
}
if (ret == 2)

View File

@ -1,6 +1,6 @@
/* test/telltoc.c , API illustration of obtaining media status info */
/* Copyright (C) 2006 - 2015 Thomas Schmitt <scdbackup@gmx.net>
/* Copyright (C) 2006 - 2016 Thomas Schmitt <scdbackup@gmx.net>
Provided under GPL */
/** Overview
@ -18,12 +18,12 @@
Before you can do anything, you have to initialize libburn by
burn_initialize()
as it is done in main() at the end of this file. Then you aquire a
as it is done in main() at the end of this file. Then you acquire a
drive in an appropriate way conforming to the API. The two main
approaches are shown here in application functions:
telltoc_aquire_by_adr() demonstrates usage as of cdrecord traditions
telltoc_aquire_by_driveno() demonstrates a scan-and-choose approach
With that aquired drive you can call
With that acquired drive you can call
telltoc_media() prints some information about the media in a drive
telltoc_toc() prints a table of content (if there is content)
telltoc_msinfo() prints parameters for mkisofs option -C
@ -86,7 +86,7 @@ static int cd_is_audio = 0; /* 0 = undecided , -1 = no , 1 = yes */
/* ------------------------------- API gestures ---------------------------- */
/** You need to aquire a drive before burning. The API offers this as one
/** You need to acquire a drive before burning. The API offers this as one
compact call and alternatively as application controllable gestures of
whitelisting, scanning for drives and finally grabbing one of them.
@ -128,7 +128,7 @@ int telltoc_aquire_by_adr(char *drive_adr)
return 0;
}
fprintf(stderr,"Aquiring drive '%s' ...\n", libburn_drive_adr);
fprintf(stderr,"Acquiring drive '%s' ...\n", libburn_drive_adr);
ret = burn_drive_scan_and_grab(&drive_list, libburn_drive_adr, 1);
if (ret <= 0) {