Compare commits

..

1114 Commits

Author SHA1 Message Date
4c0ebf1a15 Mentioned bug fix and pl01 2019-11-25 19:44:20 +01:00
30c9f6de38 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 19:39:31 +01:00
3a940300e2 Committed forgotten header file 2019-10-26 17:10:03 +02:00
a6fdbc7a25 Updated change log 2019-10-26 17:04:11 +02:00
ce2ddab081 Updated cdrskin tarball generator 2019-10-26 17:01:24 +02:00
2298dfd08a Made number transition to 1.5.2 2019-10-26 16:59:53 +02:00
354d45e640 Bug fix: TDK Corporation was not recognized as manufacturer of DVD-R "TTH02". Thanks Steve. 2019-09-20 12:37:59 +02:00
6905bb447a Showing more info in case of drive errors and transport problems 2019-07-05 15:36:42 +02:00
0e73afd17c New cdrskin option --list_features 2019-04-17 11:58:32 +02:00
c5bc9f6de7 New API calls burn_drive_get_feature_codes(), burn_drive_get_feature() 2019-04-17 11:23:59 +02:00
610e213f70 Putting out more info in case of failed Linux SG_IO ioctl 2019-04-17 11:00:03 +02:00
4d5486acf5 Applying stream recording only to DVD-RAM, BD-R, BD-RE media 2019-04-13 19:36:31 +02:00
39f2712bb7 Bug fix: Stream recording was applied regardless whether the drive offers it 2019-04-13 19:34:31 +02:00
9ac8efa61e Disabled autotools macro AM_MAINTAINER_MODE on advise of Ross Burton 2019-04-07 10:45:44 +02:00
1c06669465 Made libburn ready for building out-of-source. Thanks Ross Burton. 2019-04-05 17:49:17 +02:00
d72fb13225 Emitting cleartext for errors with ASC 6F (CSS problems) 2018-12-12 13:55:54 +01:00
7282eaab2c Silenced gcc warnings about printf target buffer 2018-10-11 09:41:04 +02:00
042fe178bf Bug fix: No lock was obtained for setting up a fifo object 2018-10-10 18:03:24 +02:00
af65852dc8 Silenced gcc warnings about switch-cases and printf target buffers 2018-10-10 18:01:00 +02:00
f52507116b Updated change log 2018-09-16 15:55:23 +02:00
04f9a30787 Made number transition to 1.5.1 2018-09-16 15:53:33 +02:00
c2bcf78c81 Added to cdrskin standalone scripts a compile run for unite_html_b_line.c 2018-09-15 13:48:46 +02:00
ef3609e021 Fixed a typo that was made during version leap 2018-09-15 13:29:42 +02:00
9ee80eec9a Updated change log 2018-09-15 12:01:06 +02:00
255afdde45 Updated cdrskin tarball generator 2018-09-15 11:56:34 +02:00
c75ad3162c Made number transition to 1.5.0 2018-09-15 11:52:05 +02:00
d32bb30e79 With --enable-track-src-odirect, do not report error 22 due to unaligned EOF 2018-09-06 12:08:04 +02:00
3fdf11817d Bug fix: Device file comparison parameters were recorded wrong with Linux sg 2018-09-02 22:02:02 +02:00
2fe4b3ca2a Restricted enforcement of minimum track size to CD media profiles 2018-08-26 16:16:53 +02:00
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
e35995b85e Updated change log 2018-02-05 13:39:03 +01:00
c84889bb81 Reporting in SCSI log when commands get repeated 2018-02-05 11:37:20 +01:00
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
95f5b1ce2b Added missing header file for previous commit 2017-12-31 12:48:16 +01:00
ef2fa1d99d Adapting to surplus chunks and subchunks in .wav files 2017-12-31 12:15:36 +01:00
b5b5cc1fb2 Reacted on compiler warning about theoretical overflow of an sprintf 2017-09-16 12:57:29 +02:00
99e828c72f Reacted on compiler warning about theoretical overflow of an sprintf 2017-09-16 12:51:59 +02:00
2886b82bf0 Reacted on compiler warning about theoretical overflow of an sprintf 2017-09-16 11:50:35 +02:00
ef0d713b25 Updated change log 2017-09-13 10:19:38 +02:00
f1fc16bb8a Made number transition to 1.4.9 2017-09-13 10:10:11 +02:00
260fc2983d Updated change log 2017-09-12 13:39:54 +02:00
ea486a109f Updated cdrskin tarball generator 2017-09-12 13:37:57 +02:00
516dc2ca76 Made number transition to 1.4.8 2017-09-12 13:36:08 +02:00
113f5873cb Fixed the block count in error message about read attempt after medium end 2017-07-15 21:42:27 +02:00
2bb8bf470d Reporting POW formatted BD-R as unusable 2017-02-06 17:15:03 +01:00
a4b688ab52 Refusing to write to BD-R if formatted to Pseudo Overwrite 2017-02-06 15:12:41 +01:00
d71d80d1a1 New API call burn_drive_get_bd_r_pow() 2017-02-06 14:58:39 +01:00
858e42d696 Corrected harmless typos found by lintian 2017-01-28 21:08:32 +01:00
724d518dbc Giving up use of function pthread_cancel() 2017-01-28 21:02:17 +01:00
6f6bf688d9 Small adjustement for previous commit 2017-01-27 16:05:37 +01:00
6b020a3ab7 Detecting Linux systems without generic SCSI support by scsi/scsi.h 2017-01-27 12:05:35 +01:00
074f88fe98 Corrected documentation of bytes/second value of 1x CD speed 2017-01-11 12:28:19 +01:00
19a1b8e768 Bug fix: Option -dummy did not affect writing by direct_write_amount= 2016-11-18 14:24:13 +01:00
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
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
2a2d60d95d Updated change log 2016-09-16 19:13:05 +00:00
b5a84e7f01 Updated cdrskin tarball generator 2016-09-16 19:10:44 +00:00
261538cea7 Made number transition to 1.4.7 2016-09-16 19:09:18 +00:00
607f339501 Added a few ASCQ texts to error code 5,30,X 2016-09-10 08:30:36 +00:00
b9f67a86a1 Removed @abs_top_builddir@ from doxygen.conf.in where it hampered reproducibe build 2016-08-28 14:51:37 +00:00
e1d8d11c5f Eased re-enabling of libtool --silent at bootstrap time 2016-08-23 19:39:00 +00:00
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
7cc62d99e9 Enabled overriding of OpenBSD default for Immed usage 2016-07-30 20:05:39 +00:00
ed6bf59026 Forgot to commit the libburn.ver file with the new API symbols 2016-07-30 16:35:19 +00:00
0731eaa3e0 New cdrskin option use_immed_bit= 2016-07-30 14:08:29 +00:00
740e726ffe New API call burn_drive_set_immed() 2016-07-30 14:03:10 +00:00
2e8dec42e5 Reacted on some of the complaints of codespell 2016-07-23 10:40:43 +00:00
ba7422b2b6 Mentioned OpenBSD in adapter files 2016-07-21 17:50:48 +00:00
2e76a4dfdf Fixed a macro typo in rev 5720. Thanks again to SASANO Takayoshi. 2016-07-21 14:12:02 +00:00
078f75c2a7 Enabled SCSI command execution on OpenBSD. Thanks to SASANO Takayoshi. 2016-07-21 10:29:15 +00:00
6f072d870d Fixed three spelling errors found by lintian 2016-07-03 19:16:08 +00:00
f312d00a73 Updated change log 2016-07-01 19:23:35 +00:00
d5d802a226 Updated cdrskin tarball generator 2016-07-01 19:17:23 +00:00
daa9160df7 Made number transition to 1.4.5 2016-07-01 19:15:33 +00:00
4189a000fe Removed option --silent from libtool runs 2016-04-27 14:51:56 +00:00
e631f2d977 Prevented option --version-script with linker runs of binaries. By Matthias Klose. 2016-04-19 07:05:36 +00:00
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
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
37c53a22c8 Updated change log 2016-03-30 19:25:18 +00:00
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
f4ce749188 Bug fix: burn_make_input_sheet_v07t() falsly recognized double byte encoding 2016-03-30 11:33:20 +00:00
9e852c2b7c Updated change log 2016-03-18 14:38:32 +00:00
f61caa7feb Bug fix: Linux /proc/sys/dev/cdrom/info overrode SCSI dev family conversion 2016-03-17 20:33:15 +00:00
94f02caddb Replaced unused timezone parameter of gettimeofday() by NULL 2016-03-10 19:56:14 +00:00
69d12929e3 Trying to find out whether READ CAPACITY on CD media includes 2 TAO end blocks 2016-03-08 07:33:45 +00:00
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
92e29de695 Fixed a typo found by lintian 2016-02-05 13:03:40 +00:00
02d06cffbc Fixed a typo found by lintian 2016-02-05 13:00:41 +00:00
2f4613fd26 Updated README and change log 2016-01-29 12:37:17 +00:00
541ea7aa09 Updated change log 2016-01-28 10:05:36 +00:00
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
80225c93a9 Checking for availability of LIBBURN_ARCH_LIBS 2015-12-10 19:24:06 +00:00
7f35793928 Updated change log 2015-11-28 21:10:01 +00:00
91c4ba0179 Updated cdrskin tarball generator 2015-11-28 21:05:25 +00:00
80ebe2923a Made number transition to 1.4.3 2015-11-28 21:04:27 +00:00
f2c2e5e59c Fixed a theoretical memory leak in actually unused code. Reported by cppcheck. 2015-11-25 09:34:07 +00:00
d428bae0fa Completed revision 5527. Coverity CID 21823. 2015-11-02 15:13:26 +00:00
cd94630dec Corrected misperception of telltoc --read_and_print 1:. 2015-11-02 15:11:45 +00:00
774336bbe9 Completed revision 5527. Coverity CID 21823. 2015-11-01 19:53:08 +00:00
43e113ae54 Took into respect that burn_session_by_cue_file() parameter text_packs may be NULL. 2015-11-01 19:49:17 +00:00
be8834a564 Closed a memory leak with error around C-TEXT. Another try on Coverity CID 21818. 2015-11-01 18:47:52 +00:00
71ee6246a6 Corrected a mistake made in rev 5542. Coverity CID 28636. 2015-11-01 12:55:51 +00:00
e62426c705 Unified the tests against rogue GET CONFIGURATION replies. Coverity CID 21794. 2015-11-01 10:27:00 +00:00
d8cb782cfb Reacting on (improbable) failure of burn_disc_pretend_full(). Coverity CID 21847. 2015-10-31 12:22:50 +00:00
ae9cd95cf1 Removed a surplus development variable. Coverity CID 21795. 2015-10-29 10:53:49 +00:00
1d15b0845f Handling failure to write to disk file. Coverity CID 21786. 2015-10-29 10:16:12 +00:00
8d8d0b97a7 Forgot to put burn_drive_get_serial_no and burn_drive_get_media_sno into API 2015-10-29 08:36:09 +00:00
acfaa6e15a Removed useless and faulty test/structest.c. Coverity CID 21785. 2015-10-29 08:29:32 +00:00
352a33d287 Cared for an improbable error case. Coverity CID 21784. 2015-10-29 08:19:32 +00:00
ef662655bb Prevented a quite unlikely buffer overflow by argument. Coverity CID 21831. 2015-10-28 19:59:58 +00:00
d32dbe37fe Prevented a quite unlikely buffer overflow by argument. Coverity CID 21827. 2015-10-28 19:22:34 +00:00
0f657077af Prevented a quite unlikely buffer overflow by argument. Coverity CID 21827. 2015-10-28 19:21:42 +00:00
bb0d0f9505 Testing all arguments of fake_au for oversize. Coverity CID 21830. 2015-10-28 19:19:01 +00:00
189a43bac9 Closed memory leak with minor cdrskin jobs. Found by valgrind. 2015-10-28 16:20:15 +00:00
232b49bc90 Removed a surplus test. Coverity CID 21796. 2015-10-28 15:37:14 +00:00
a3f86a1432 Removed overly optimistic test ocde for SUN audio. Coverity CID 21846. 2015-10-26 18:40:29 +00:00
9917a1ddeb Fixed memory waste by oversized feature descriptor objects. Coverity CID 21. 2015-10-26 18:36:05 +00:00
7993b719a7 Preventing very improbable signed 32 bit overflow with MMC speed range. Coverity CID 21823. 2015-10-26 15:45:19 +00:00
98a6284402 Corrected reaction on unsupported track modes. Coverity CID 21804. 2015-10-26 15:35:39 +00:00
6136eaf86f Added missing break statement to SG_IO error reporting. Coverity CID 21803. 2015-10-26 15:17:02 +00:00
d31a72100b Closed a file pointer leak with CUE file interpretation. Coverity CID 21821. 2015-10-26 15:03:21 +00:00
2b82095236 Closed a memory leak with error opening audio input of CUE sheet. Coverity CID 21820. 2015-10-26 14:57:34 +00:00
8ba554a60d Distinguishing between self-opened and inherited file descriptors as track input. Coverity CID 21819. 2015-10-26 14:51:18 +00:00
d9206d7fdb Clarified the scope of an allocated variable. Coverity CID 21818. 2015-10-26 10:55:45 +00:00
ccefc2daa1 Avoiding to allocate empty buffer for texp packs. Indirectly Coverity CID 21818. 2015-10-26 10:51:15 +00:00
726351f211 Closed memory leak in case of burn failure. Coverity CID 21817. 2015-10-26 10:22:43 +00:00
20d01446d1 Closed file pointer leak in case of error with audio source. Coverity CID 21816. 2015-10-26 09:27:34 +00:00
0f5b28ee64 Closed various memory leaks in libburner. Coverity CID 21814, CID 21815. 2015-10-24 14:07:49 +00:00
142e138543 Closing output file pointer of telltoc --read_and_print. Coverity CID 21813. 2015-10-24 10:03:14 +00:00
ead8735d2e Updated telltoc to BD and other old novelties. 2015-10-24 08:50:11 +00:00
cbc21aef76 Closed memory leak in telltoc. Coverity CID 21812. 2015-10-24 08:03:44 +00:00
955525c60c Closed memory leak with errors while attaching fifo. Coverity CID 21811. 2015-10-24 07:51:18 +00:00
b212205b0b Closed a potential memory leak with writing to stdio pseudo drives. Coverity CID 21810. 2015-10-23 16:47:30 +00:00
dfeefaa5fc Closed a potential memory leak with CD-TEXT production. Coverity CID 21809. 2015-10-23 16:24:55 +00:00
53c279be18 Avoided a potential memory leak with debug messages. Coverity CID 21808. 2015-10-23 16:03:47 +00:00
caf04416ea Enabled display of pacifier state "formatting" in cdrskin. Coverity CID 21793. 2015-10-23 14:05:28 +00:00
8416310ba6 Moved unused variable into its ifdef case. Coverity CID 21799. 2015-10-23 13:53:24 +00:00
330fb2cd20 Previous commit was rather: Completed initialization of struct sigaction in test/poll.c. Coverity CID 21845. 2015-10-23 13:41:58 +00:00
1602c51a26 Removed surplus code statement which used uninitialized variable. Coverity CID 21843. 2015-10-23 13:40:05 +00:00
d762c6b9dd Removed surplus code statement which used uninitialized variable. Coverity CID 21843. 2015-10-23 13:05:09 +00:00
6c7822b5bc Prevented use of an uninitialized variable. Coverity CID 21842. 2015-10-23 12:44:13 +00:00
22719b880e Checking program arguments of test/fake_au. Coverity CID 21832. 2015-10-23 12:37:34 +00:00
ab11ce2a0e Bug fix: Endless loop if transport error occurs while waiting for drive ready 2015-10-23 12:25:37 +00:00
793157c26b Completed rev 5498, which is a reaction on Coverity CID 21805. 2015-10-23 12:12:26 +00:00
1a6fd3ad95 Made sure that only existent CDB bytes get accessed by SCSI command logging. Coverity CID 21806. 2015-10-23 10:35:42 +00:00
d06138d6b2 Prevented potential use of file pointer after fopen() failed 2015-10-23 10:10:19 +00:00
d26dc809d7 Bug fix: Media summary session count of blank and closed media was short by 1 2015-10-19 17:43:07 +00:00
2d71ea303c New -toc output lines "Drive id" and "Media id" 2015-10-18 13:31:38 +00:00
60e2e7df28 New API calls burn_drive_get_serial_no() and burn_drive_get_media_sno() 2015-10-18 12:52:08 +00:00
d7e762b9be Mutally mentioned the other demo program in their introdution comments 2015-09-23 11:07:24 +00:00
368b0590e2 Bug fix: burn_disc_get_multi_caps() returned 2048 bytes too many in .start_range_high 2015-09-23 10:59:45 +00:00
29c0be903d Recognizing again Debian GNU/kFreeBSD, regression by rev 5437 2015-09-17 16:01:00 +00:00
0dd3ff606c More hunt for "allow to" 2015-09-01 06:59:24 +00:00
df52e79df6 Avoiding to trigger lintian check "allows to allows one to" 2015-08-31 06:57:40 +00:00
a46cbdcccd Fixed typos reported by J.S.Junior 2015-08-30 20:34:46 +00:00
e1c12bbf57 New paramaters for option modesty_on_drive= timeout_sec, min_usec, max_usec 2015-08-30 18:57:44 +00:00
300b9e7016 Small change in API documentation about burn_drive_set_buffer_waiting() 2015-08-30 18:52:39 +00:00
2d5bf266f7 Reacting on changes in the output of my local man -H 2015-08-02 14:16:01 +00:00
6a927ae867 Changed wrong use of "resp." in docs 2015-08-01 13:58:24 +00:00
3dcee0dcc9 Removed unused macro definitions 2015-06-25 19:24:23 +00:00
bbbb9a1eb3 Mentioned option -use_libcdio of cdrskin/compile_cdrskin.sh 2015-06-25 19:22:45 +00:00
3c6a36546a Bug fix: burn_disc_get_media_id() returned BD identifiers 2 chars too long 2015-05-26 05:43:29 +00:00
2326a36250 Registered BD-R producer Millenniata. Thanks to Lucjan Bryndza. 2015-05-25 20:44:45 +00:00
5a719c54c8 Trying to become suitable for Debian reproducible builds 2015-05-18 17:34:56 +00:00
2f194084b8 Updated change log 2015-05-17 20:08:30 +00:00
decefbede5 Updated cdrskin tarball generator 2015-05-17 20:05:31 +00:00
cdf00267b0 Made number transition to 1.4.1 2015-05-17 20:03:59 +00:00
e0167f9385 Made sure that cdrskin on Solaris gets linked with libvolmgt 2015-05-17 19:38:37 +00:00
516df39cc7 Corrected outdated references to function name burn_get_media_product_id() 2015-05-17 08:35:10 +00:00
406a0e7747 Human readable error message for 3 32 00 2015-03-08 07:38:56 +00:00
44f064fea0 Fixed a typo in message of make install. Thanks to Jakub Wilk. 2014-12-29 11:00:59 +00:00
5c154a478e Using libvolmgt on older Solaris 2014-12-21 22:14:34 +00:00
4670984dec Added debugging messages for drive recognition on Solaris 2014-12-06 17:53:00 +00:00
0b110821f6 Equipped all non-system-dependent open(2) calls with O_BINARY 2014-11-26 16:42:56 +00:00
ad688b85eb Bug fix: Double free with cdrskin -vvv. Introduced with rev 5065, version 1.3.1 2014-11-23 19:11:18 +00:00
3877fc6bea Fixed a bug introduced with previous revision 2014-09-01 18:40:31 +00:00
77aeeba934 New flag bit5 with burn_read_data() and burn_read_audio() 2014-09-01 16:13:19 +00:00
cfa6ee1498 Removed obsolete conditional code 2014-08-31 12:15:22 +00:00
a9affdc82a Reduced number of GET CONFIGURATION transactions 2014-08-31 11:56:46 +00:00
1286079d3d Small correction of rev5369 2014-08-14 08:59:47 +00:00
3b5906b30c Improved error message for erase failures 2014-08-14 08:57:01 +00:00
0c9293f9c6 Keeping GET CONFIGURATION from requesting more than 4 KB of data 2014-07-31 12:32:06 +00:00
3c4dccc966 Debugging macro Libburn_debug_dxferP to check sg_io_hdr_t.dxferp 2014-07-31 12:28:44 +00:00
f3fd5fbc99 New internal function for SCSI-logging arbitrary texts 2014-07-31 11:59:23 +00:00
f4a49078c8 Fixed a wrong read access to memory. Reported by valgrind of lian jianfei, 2014-07-14 18:02:14 +00:00
193c2b14d5 Updated copyright date 2014-07-06 06:53:22 +00:00
a3b8c3c659 Documented changes and release timestamp 2014-06-28 06:37:25 +00:00
73bd0547e2 Updated cdrskin tarball generator 2014-06-28 06:34:11 +00:00
da874ca4f8 Made number transition to 1.3.9 2014-06-28 06:33:13 +00:00
69b282a5ba Reacted on compiler warning of gcc on NetBSD-current 2014-06-20 14:53:11 +00:00
193c260285 Fixed a SIGSEGV introduced by previous revision 2014-06-10 13:08:12 +00:00
ca532f7623 Improved drive capacity estimation for sparse regular files 2014-06-10 07:37:40 +00:00
61e2176d03 Bug fix: A failed MMC BLANK command did not cause error indication by libburn 2014-05-03 10:37:07 +00:00
91eca50221 Bug fix: Wrong stack usage caused SIGBUS on sparc when compiled by gcc -O2 2014-04-29 06:18:41 +00:00
e54f6ebd68 Improved read retrying with DVD and BD media 2014-04-19 11:48:46 +00:00
856081559c Retrying write(2) if it returns a short non-negative write count 2014-04-14 10:33:58 +00:00
511d23f574 Restoring capability of burn_random_access_write() to fsync() (lost in rev 5302) 2014-04-13 12:09:34 +00:00
f17d5ee7d1 Bug fix: A final fsync(2) was performed with stdio drives, even if not desired 2014-04-09 15:22:20 +00:00
d08658833a Bug fix: Minimum drive buffer fill was measured before the buffer could get full 2014-04-06 11:10:29 +00:00
a8a2d54c25 Bug fix: Compilation warning for unsupported systems mutated into an error 2014-03-17 22:18:39 +00:00
9accc668fa Updated change log 2014-03-14 10:05:13 +00:00
33e20f9e49 Bug fix: CD TAO with multiple tracks could cause a buffer overrun 2014-03-14 09:55:11 +00:00
48db3adaf6 Documented changes and release timestamp 2014-03-04 16:26:23 +00:00
ac46978d63 Updated cdrskin tarball generator 2014-03-04 16:23:22 +00:00
2aba5b4dd7 Made number transition to 1.3.7 2014-03-04 16:22:27 +00:00
6e5c50bde4 Improved emulation of mode page 2A 2014-03-01 10:16:03 +00:00
174c22aeb7 Removed Linux compilability mock-up from sg-netbsd.c 2014-02-19 11:11:50 +00:00
31abdedade Inquiring GET PERFORMANCE independently of existence of mode page 2A 2014-02-16 20:41:57 +00:00
b6afe92e47 Improved workaround for missing mode page 2A 2014-02-14 20:03:01 +00:00
1d616b5944 Corrected size determination of NetBSD block devices 2014-02-13 20:55:27 +00:00
070ac64459 Mentioned support for NetBSD 2014-02-12 18:58:17 +00:00
ad95f1ff2b Silenced warnings about -Wchar-subscripts, added /usr/local for NetBSD 2014-02-11 08:28:44 +00:00
3edde5dc9d Introduced netbsd system adapter in tarball generator 2014-02-10 22:04:43 +00:00
cf5c7aa84f Inmplemented a system adapter for NetBSD 2014-02-10 21:36:34 +00:00
d40ab32360 Being more rugged towards missing MODE SENSE info 2014-02-10 21:33:50 +00:00
43e1daab23 Avoiding to have two file descriptors open to the same stdio drive 2014-02-07 18:08:28 +00:00
6e4d1cc53e Prepared for possible demise of mode page 2A 2014-02-05 19:20:08 +00:00
cdbbcbb923 Fixed bugs introduced with previous commit 2014-02-05 19:00:01 +00:00
7f31c9e985 Trying to better handle MMC violating replies of MODE SENSE (Block Descriptors) 2014-02-05 12:49:41 +00:00
dd0ceb6720 Implemented a generic verification whether a SPC device is a MMC device 2014-02-04 11:31:12 +00:00
5676a1953d Improved handling of stdio pseudo-drives after aborted burn runs 2014-01-15 17:50:33 +00:00
78627934f3 Updated copyright claim in sg-linux.c 2014-01-15 17:49:04 +00:00
217289f71a Adapted Linux SG_IO adapter to scsi/sg.h of git.kernel.org 2014-01-09 21:50:17 +00:00
1c6f6c084f Interpreting feature 0x107 when deciding from where to get speed info 2014-01-09 13:23:23 +00:00
658851a497 Registering all drive-media feature descriptors in burn_drive 2014-01-07 12:01:18 +00:00
2aa10d1099 Documented changes and release timestamp 2013-12-12 14:58:22 +00:00
ba8b1b5e17 Updated cdrskin tarball generator 2013-12-12 14:54:37 +00:00
ef17544eb9 Made number transition to 1.3.5 2013-12-12 14:52:30 +00:00
7f99a8e70e Better reaction on drive errors during burn_drive_scan_and_grab() 2013-11-21 09:21:29 +00:00
5f6281261d Corrected bugs introduced with rev 5180 2013-11-17 15:27:08 +00:00
04afd1c958 Resetting the drive failure status before starting random-access writing 2013-11-17 10:25:01 +00:00
83eac67cf5 Prevented a memory leak that in most cases was closed by a race condition 2013-11-16 17:05:40 +00:00
d09ecac4a8 Enforcing reasonable minimum read speeds even if the drive is lying 2013-11-15 10:24:31 +00:00
404f239207 Improved reaction on Linux SG_IO transport problems 2013-11-14 10:17:48 +00:00
0cd21eed54 Updated change log 2013-11-11 17:20:30 +00:00
119c0cf76d Bug fix: Drive LG BH16NS40 stalled on inspection of unformatted DVD+RW 2013-11-11 16:10:36 +00:00
edc90b880c New API call burn_disc_pretend_full_uncond() 2013-11-10 16:35:17 +00:00
ae4d296a60 Enforcing reasonable maximum read speeds even if the drive is lying 2013-11-08 09:54:15 +00:00
4880ca3b93 Closed potential memory leak introduced by rev 5168 2013-11-08 09:53:13 +00:00
429fed00c1 Closed potential memory leak introduced by rev 5168 2013-11-08 09:51:33 +00:00
87ab352d6f New API calls burn_drive_was_feat21_failure(), burn_write_opts_set_fail21h_sev() 2013-10-28 10:51:05 +00:00
6e372c9a6d Bug fix: Drive error reports were ignored during blanking and formatting 2013-10-10 16:20:39 +00:00
1f7dfb84fc Forgot to disable a debugging message 2013-10-09 13:46:47 +00:00
844dc958be Separately determining the maximum speeds for writing and reading 2013-10-09 09:24:09 +00:00
f6132a97a0 Made -version message more acceptable for K3B. Proposal of Omegaweapon. 2013-10-03 10:01:15 +00:00
642406b92e Reacted on warning of Debian buildd with clang 2013-09-16 17:28:55 +00:00
cc8ac3aefb Reacted on warnings of PLD Linux build log 2013-09-05 08:49:31 +00:00
2a8ae1be42 Reacted on warnings of PLD Linux 2013-09-04 14:18:08 +00:00
8d2e14a0b9 Closed a small memory leak with cdrskin -msinfo 2013-09-04 11:16:12 +00:00
9e02c17004 Closed a small memory leak with cdrskin -msinfo 2013-09-04 11:10:05 +00:00
669ccb9b43 Catching and defaulting mad responses to READ BUFFER CAPACITY 2013-09-04 11:00:30 +00:00
05ae7e51e4 Updated change log 2013-08-07 13:56:37 +00:00
db2ec50deb Updated cdrskin tarball generator 2013-08-07 13:52:34 +00:00
6b93e66cfd Made number transition to 1.3.3 2013-08-07 13:51:09 +00:00
9afa5379e5 Update of doxygen configuration for version 1.8.4 provided by George Danchev 2013-08-04 20:03:57 +00:00
b08075479e Reacted on advise from Helmut Grohne to avoid confusion of doxygen 2013-08-04 12:45:31 +00:00
2b74f6fa63 Changed default write chunk size for BD to 64 KiB 2013-08-04 10:03:21 +00:00
8f60105c8d Reacted on warnings of Debian build service about doxygen flaws 2013-07-29 09:14:51 +00:00
f8be7e46ab Bug fix: The signal handler aborted on SIGCONT, SIGTSTP, SIGTTIN, SIGTTOU 2013-07-21 17:07:53 +00:00
f9793c54c2 New option --pacifier_with_newline 2013-07-08 15:19:45 +00:00
870b71377d Corrected typo in a comment 2013-07-08 14:56:30 +00:00
8eed2e9558 New mode bit8 with burn_set_signal_handling() to particularly ignore SIGPIPE 2013-07-01 16:00:28 +00:00
abe560a6ec Removed an obsolete note message from cdrskin --devices 2013-06-28 10:43:47 +00:00
2a991bbab3 Making sure in cdrskin that off_t is large enough before starting libburn 2013-06-28 10:42:04 +00:00
b46f7157de Removed inactive test code from telltoc.c 2013-06-24 15:07:45 +00:00
9aaca05499 Updated change log 2013-06-12 10:43:07 +00:00
bd381583de Some polishing of SCSI log time measurement 2013-06-09 16:31:28 +00:00
e2188fb9f7 Prepared for optional use of clock_gettime() 2013-06-09 15:43:02 +00:00
fd8f4d48b8 Improved granularity of SCSI log time measurement and added absolute timestamp 2013-06-09 15:26:32 +00:00
0eb24d293f Mentioned bug fix and pl01 2013-05-31 10:09:00 +00:00
f1ef0a1995 Updated change log 2013-05-30 13:34:32 +00:00
0178c42c20 Bug fix: cdrskin -msinfo on DVD and BD reported old session start == next writable address. Regression introduced by version 1.2.8 (rev 4956). 2013-05-30 13:31:06 +00:00
21511e3fdf Luring K3B into using -xa rather than -xa1 2013-05-26 19:00:13 +00:00
744da88c3c Updated documentation about CD-TEXT 2013-05-23 19:37:08 +00:00
3ab91cb93b Updated change log 2013-05-23 15:55:39 +00:00
19cbdde95f New cdrskin options extract_audio_to= , extract_tracks= , extract_basename= , --extract_dap 2013-05-23 15:48:04 +00:00
167d73e268 New API calls burn_drive_extract_audio(), burn_drive_extract_audio_track() 2013-05-23 15:43:19 +00:00
1887b0b938 Defaulting -sao -multi to -tao -multi if -sao -multi is not possible 2013-05-21 08:18:48 +00:00
0b932e5f7d Updated change log 2013-05-20 14:13:57 +00:00
ecd303149f Closed memory leak introduced by rev 5063 2013-05-20 12:45:48 +00:00
8f500d90df Bug fixes with new API call burn_make_input_sheet_v07t() 2013-05-20 12:45:12 +00:00
644feceb5c Allowed option input_sheet_v07t= to read multiple blocks from same file 2013-05-20 11:01:57 +00:00
eb03488f52 API call burn_session_input_sheet_v07t(): read multiple blocks from same file 2013-05-20 10:48:40 +00:00
a252038113 New options cdtext_to_textfile= and cdtext_to_v07t= 2013-05-19 15:49:05 +00:00
ca3f994dcb New option textfile_to_v07t= 2013-05-19 11:49:24 +00:00
7f8d8a04d0 New API call burn_make_input_sheet_v07t() 2013-05-19 11:47:10 +00:00
2fd5af75eb Updated change log 2013-05-17 18:12:12 +00:00
cf363b27fa Made number transition to 1.3.1 2013-05-17 18:08:48 +00:00
469ab7bf21 Updated cdrskin tarball generator 2013-05-17 18:04:46 +00:00
ac2bfec065 Updated change log 2013-05-10 07:30:48 +00:00
c566ea03cf Added new item to list of error codes 2013-05-10 07:26:11 +00:00
3632e1be4e Bug fix: DVD+R with damaged TOC were reported by -minfo with wrong end address 2013-05-10 06:41:53 +00:00
f18b832a82 Updated change log 2013-04-01 12:56:35 +00:00
1f92419cb4 Bug fix: Formatting of BD-RE used certification regardless of drive capabilities 2013-04-01 12:19:14 +00:00
d6e15a0139 Forgot to increment cdrskin version number 2013-04-01 12:17:05 +00:00
e0db790103 Updated change log 2013-03-18 21:21:35 +00:00
9bc362f59b Made number transition to 1.2.9 2013-03-18 21:09:13 +00:00
44d5f3ce4e Updated cdrskin tarball generator 2013-03-18 08:31:34 +00:00
0f43a39a45 Made number transition to 1.2.8 2013-03-18 08:29:37 +00:00
0a1a085471 Avoiding SYNCHRONIZE CACHE if DVD track preparation has failed 2013-03-12 11:48:07 +00:00
a1fdfe1519 Always considering mode page 2A when looking for min and max speed 2013-03-05 18:55:03 +00:00
bbb6315af0 Always considering mode page 2A when looking for min and max speed 2013-03-05 18:54:19 +00:00
40d83b2314 Updated change log 2013-03-05 12:51:03 +00:00
c82ac0a825 Mentioned --list_speeds in manual page 2013-03-05 12:47:56 +00:00
46b598abd2 New cdrskin option --list_speeds 2013-03-05 12:45:37 +00:00
c7784b79b7 Still correcting the bug fix of rev 4975 2013-03-05 12:42:41 +00:00
f1b3184531 Corrected previous bug fix which caused speed descriptors to appear twice 2013-03-04 23:25:27 +00:00
a18c862e84 Bug fix: On some drives the request for minimum speed yielded maximum speed 2013-03-04 21:13:32 +00:00
c2903ab717 Corrected wrong use of sizeof 2013-02-26 08:01:51 +00:00
04ccaebff7 Updated cdrskin copyright message 2013-01-16 18:12:41 +00:00
2e83dc554b Updated change log 2013-01-16 18:05:44 +00:00
3a17a8a014 Bug fix: All CD tracks were reported with the sizes of the tracks in the first session. Regression introduced with version 1.2.0 (rev 4552). 2013-01-15 10:42:21 +00:00
ffca3e89dd Made use of new API features to handle incomplete sessions 2013-01-12 19:54:59 +00:00
676231c362 New API call burn_disc_get_incomplete_sessions(), new burn_toc_entry.track_status_bits 2013-01-12 19:51:21 +00:00
d76c715df7 Updated change log 2013-01-08 14:56:13 +00:00
9aa47792e0 Updated cdrskin tarball generator 2013-01-08 14:53:46 +00:00
f4cfe9b267 Made number transition to 1.2.7 2013-01-08 14:52:30 +00:00
6f19122672 Small change to burn cookbook about ISO multi-session emulation 2012-12-14 15:33:09 +00:00
057f24d5b9 New API call burn_list_sev_texts() 2012-12-14 14:51:46 +00:00
a843727bc7 Made telltoc ready for reading CD audio 2012-11-30 19:40:37 +00:00
bb409500ed New API call burn_read_audio 2012-11-30 19:34:33 +00:00
1a74a05965 Let mmc_format_unit issue failure message on SCSI error 2012-11-29 11:26:53 +00:00
2df7f3d5d5 Forgot mcc.c with the previous commit 2012-11-29 11:25:54 +00:00
0728d855d5 Beginning to create new API call burn_read_audio 2012-11-29 11:14:33 +00:00
100be5078c Better reaction on non-plausible ATIP info from CD-ROM 2012-11-24 18:14:36 +00:00
5139bf922a Preserving an immature sketch of media quality scanning 2012-11-18 18:47:09 +00:00
a2b4361d69 Preserving an immature sketch of media quality scanning 2012-11-18 18:46:05 +00:00
d216764867 Corrected error handling which was spoiled by rev 4852 2012-10-25 17:35:10 +00:00
4c74cbf7b3 New flag bit4 of burn_read_data() for better handling of TAO end blocks 2012-10-25 12:39:50 +00:00
7ed8619a9e Reporting (still cryptic) details about refusal to blank 2012-10-24 09:58:25 +00:00
fa2508bfd5 Configuration for use of libcdio on cygwin. Thanks Rocky Bernstein. 2012-10-02 13:49:26 +00:00
72ae8e3b5a Updated change log 2012-09-13 08:59:00 +00:00
fa95326bac Bug fix: Speed setting had no effect on BD media. Thanks to Dennis Vshivkov. 2012-09-13 08:57:31 +00:00
eb86e5298a Removed buggy burn_strdup() and burn_strndup(). Thanks to Rich Felker. 2012-08-28 16:20:45 +00:00
4cfa8170ee Small grammatical correction in CD-TEXT documentaion 2012-08-01 06:36:53 +00:00
d885d9a408 Updated change log 2012-07-26 19:48:05 +00:00
6a23213113 New option --no_load 2012-07-26 12:30:06 +00:00
89edfaf875 Updated change log 2012-07-20 16:53:09 +00:00
1297525889 Updated cdrskin tarball generator 2012-07-20 16:51:22 +00:00
5397f85d38 Made number transition to 1.2.5 2012-07-20 16:49:40 +00:00
5ab84314c0 Bug fix: CD tracks were perceived 2 sectors too short. Nice with TAO, bad with SAO. 2012-07-08 10:29:20 +00:00
577d34e931 Improved reported number of missing bytes in case of track source shortage 2012-06-17 17:33:26 +00:00
8ce54bcb28 Bug fix: CD SAO sessions with data tracks started by an audio pause 2012-05-30 20:22:07 +00:00
6956a3b3d3 Corrections of CRC-32 algorithm for 32 bit systems. Mentioning of start value. 2012-05-08 08:04:13 +00:00
85820e9fc0 Small change in cookbook.txt about DVD-R DL 2012-04-18 10:41:24 +00:00
f34d3100be Augmented CD-TEXT documentation by a complete example of packs 2012-04-18 10:21:16 +00:00
f81990c703 Compile time option for obs_pad 2012-04-13 20:26:35 +00:00
f77094073a Small correction in cdrskin man page 2012-04-13 11:28:09 +00:00
31c4fe16e1 Now recognizing long options with double dash 2012-04-10 18:12:10 +00:00
492e3d7895 New option --obs_pad 2012-04-08 11:27:54 +00:00
529c4a2d2e New API call burn_write_opts_set_obs_pad() 2012-04-08 11:26:35 +00:00
31a4d2c1e1 Reacted on warning of Debian buildd 2012-04-04 18:38:39 +00:00
564ccc36f5 Bug fix: cdrskin SIGSEGV if track source was added when no drive was available 2012-04-04 10:10:55 +00:00
7a7591aec5 Updated change log 2012-04-02 17:30:19 +00:00
b5d9b01909 Updated cdrskin tarball generator 2012-04-02 17:27:39 +00:00
0000bbc13a Made number transition to 1.2.3 2012-04-02 17:26:28 +00:00
cda1817079 Reacted on warning of cppcheck 2012-03-21 19:33:12 +00:00
72c0e6236d Added to DVD manufacturer list: "UmeDisc Limited" 2012-02-22 10:30:40 +00:00
2e4cf980c3 Re-implemented the CRC functions under own copyright 2012-02-19 10:10:11 +00:00
40db9f1d81 Added LG drive sense code 2 06 00 to error list (officially listed is 3 06 00) 2012-02-13 10:28:26 +00:00
1b15b71905 Mathematical description of crc_ccitt() versus crc_11021() 2012-02-11 17:12:16 +00:00
cc95c408ec Small corrections in CD-TEXT documentation 2012-02-08 10:09:16 +00:00
20229d9f49 Small corrections in CD-TEXT documentation 2012-02-06 16:20:47 +00:00
7c158963c1 Reacted on warnings of Debian buildd 2012-02-02 19:07:15 +00:00
38fcbec963 One of the flaws was phony. Corrected back. 2012-01-27 19:09:30 +00:00
fcad54ae01 Corrected small flaws of libburn release tarball 2012-01-27 19:00:54 +00:00
b9c7cc4eeb Updated change log 2012-01-27 15:15:46 +00:00
a64773cd15 Updated cdrskin tarball generator 2012-01-27 15:14:07 +00:00
9664d1a315 Made number transition to 1.2.1 2012-01-27 15:12:50 +00:00
bfb798b51b Removed overdone part of rev 4593 2012-01-25 09:26:55 +00:00
72645c8fba Fixed an endless loop with cdrskin signal handling 2012-01-23 16:43:52 +00:00
f338575f41 Updated cdrskin wiki text 2012-01-23 12:54:57 +00:00
cc3ff147fe Updated change log 2012-01-23 12:53:26 +00:00
dcd1eab82d Updated change log 2012-01-23 11:59:40 +00:00
3ea4892040 Corrected some minor differences between SVN and local development tree 2012-01-23 10:27:13 +00:00
e0d7eb4820 Bug fix: cdrskin produced a memory fault if interupted before writing began 2012-01-23 10:17:26 +00:00
daf744276e Disabled dangerous abort handler actions while BURN_DRIVE_GRABBING 2012-01-23 10:15:01 +00:00
8963905bbc Improved reaction time on interrupt during writing of lead-in 2012-01-23 10:13:08 +00:00
88da4e9ead Prevented SIGSEGV with testing drive for being prepared for writing 2012-01-23 10:10:19 +00:00
cc9ec8666c Revoked an aspect of rev 4465 which aborted operation before drive is ready 2012-01-23 10:09:04 +00:00
7ce13c6dd3 Allowing SCSI read operations > 32 kB 2012-01-23 10:06:52 +00:00
6549072dcd Introduced burn_offst_source_new() flag bit0 which bans size changes 2012-01-23 09:56:53 +00:00
a88039e222 Counting post-gap as part of track with burn_track_get_sectors() 2012-01-23 09:54:20 +00:00
a75a838af9 Introduced burn_offst_source_new() flag bit0 which bans size changes 2012-01-23 09:36:47 +00:00
024701c220 Counting post-gap as part of track with burn_track_get_sectors() 2012-01-23 09:30:48 +00:00
72c31e89b2 Made conversion of ASC ASCQ to text independent of key and its text 2012-01-18 14:20:25 +00:00
2f548e046d Detecting address sequence errors with .cue command INDEX 2012-01-18 12:04:30 +00:00
9f8e4fb36b Preventing CD-TEXT with sessions that are not pure audio 2012-01-16 11:23:04 +00:00
645d41fdd2 Corrected a comment 2012-01-16 11:20:49 +00:00
853928815a Updated SAO cookbook about indice, pre-gap, post-gap 2012-01-15 09:09:37 +00:00
38bbbf2496 Implemented index reporting for struct burn_progress 2012-01-13 17:10:06 +00:00
6a13187e03 Corrected total size summary of cdrskin before burn start 2012-01-13 15:11:24 +00:00
ce0f35831b Removed development macro which sneaked in with previous revision 2012-01-13 15:09:47 +00:00
0e9a79e352 Corrected write count for tracks with post-gap 2012-01-13 14:27:21 +00:00
0c01912143 Corrected type and sector size for .cue generated tracks 2012-01-13 14:15:20 +00:00
66639c6e11 Flushing buffer to MMC before a new track begins 2012-01-13 12:22:07 +00:00
a0540651eb Avoided display of negative speed numbers at track change 2012-01-13 10:18:52 +00:00
34195c3037 New cdrskin options sao_pregap=, sao_postgap= 2012-01-12 19:12:10 +00:00
9623a04ce9 Interpreting .cue file command POSTGAP 2012-01-12 12:03:47 +00:00
ef7999342b New API call burn_track_set_postgap_size() 2012-01-12 08:44:34 +00:00
cb8c85579d Clarified meaning of parameter trackno with call burn_disc_track_lba_nwa() 2012-01-11 13:29:46 +00:00
ebf2fe5c28 Corrected track number of blank track reported by cdrskin -minfo 2012-01-11 13:29:13 +00:00
66eba145d3 Obtaining more accurate track sizes for CD with pre-gap 2012-01-11 12:25:06 +00:00
5cd7b09d5c Interpreting .cue file command PREGAP 2012-01-11 12:22:52 +00:00
ac7f4e90a4 Reacted on compiler warning 2012-01-11 12:20:35 +00:00
2c10b444a1 Enabled pre-gap size for tracks other than the first one 2012-01-11 11:16:18 +00:00
ea1160f077 Removed a development test contraption introduced by previous revision 2012-01-10 12:49:34 +00:00
d4c4430a40 New API call burn_track_set_pregap_size() 2012-01-10 12:20:23 +00:00
a2493b97e4 New cdrskin option cd_start_tno= 2012-01-08 19:14:42 +00:00
4d70043e78 Corrected display of track number offset with -toc and -minfo 2012-01-08 15:48:47 +00:00
c9a44d0128 While writing: Reporting track numbers with correct start number offset 2012-01-08 14:11:11 +00:00
a9b400833c New API call burn_session_get_start_tno() 2012-01-08 14:10:24 +00:00
0446226aa6 Implemented track number starts > 1 with .cue and v07t.txt files 2012-01-08 13:23:16 +00:00
18efcd6299 New API call burn_session_set_start_tno() 2012-01-07 19:09:15 +00:00
775eb175b6 Implemented data extraction from cue sheet FILE type WAVE 2012-01-06 12:59:20 +00:00
b8b6734cd1 Reacted on compiler warning about rev 4519 2012-01-05 14:09:35 +00:00
688a6fccca Updated change log and web page 2012-01-05 12:31:30 +00:00
792a5896e7 Reacted on compiler warnings about rev 4535 2012-01-05 12:02:44 +00:00
c1bd3ced61 Bug fix: Progress report with blanking and formatting could be bogus 2012-01-05 11:55:22 +00:00
dcb6f8344b Implemented option index= 2012-01-04 13:18:11 +00:00
83fa2ce51b New API calls burn_track_set_index(), burn_track_clear_indice() 2012-01-03 19:43:26 +00:00
b8eb8b35d9 Changed debug messages about CUE SHEET MSF from hex to decimal 2012-01-02 16:41:15 +00:00
c851520684 Reporting line number in case of cue sheet file problems 2012-01-02 14:37:35 +00:00
4c9783d7ae Implemented cue sheet file commands ARRANGER, COMPOSER, MESSAGE 2012-01-01 17:35:20 +00:00
8ac3ee15f1 New cdrskin options --four_channel --two_channel 2012-01-01 13:50:26 +00:00
e5742f724a Implemented options -scms -copy -nocopy -preemp -nopreemp 2012-01-01 12:55:41 +00:00
0c3fa9b341 Interpreting CDRWIN command FLAGS 2012-01-01 12:46:50 +00:00
a1f18ad44e Fixed a wrong assumption about track.mode 2012-01-01 12:44:25 +00:00
3845e1af05 Writing SCMS into mode page 5 if TAO 2012-01-01 12:43:36 +00:00
23d7867331 Corrected CTL of lead-in CUE SHEET entry 2012-01-01 12:41:24 +00:00
38aaa2f8aa New track mode modifier BURN_SCMS 2011-12-31 12:00:14 +00:00
ce29b4b38c Corrected precedence of media catalog and ISRC options 2011-12-30 17:44:19 +00:00
f1ae493c57 Coordinated option cuefile= with option input_sheet_v07t= 2011-12-30 16:47:57 +00:00
4afaaf3fb6 Reduced waiting time between retries of WRITE commands 2011-12-30 14:27:45 +00:00
8f725bab11 Improved reaction on failure of SEND CUE SHEET 2011-12-28 15:23:24 +00:00
7b5040af17 Implemented options mcn= and isrc= 2011-12-28 10:45:38 +00:00
47e5ce5da2 Transmitting CATALOG by mode page 5. ISRC too, if TAO. 2011-12-28 10:41:05 +00:00
cdaa2971db Writing CATALOG and ISRC into Q sub-channel of CD SAO sessions 2011-12-27 13:38:39 +00:00
67ae1413e3 New API call burn_track_set_isrc_string() 2011-12-27 11:56:54 +00:00
6716f7041d Updated doc/cdtext.txt 2011-12-26 09:57:02 +00:00
94c50a0145 Reacted on compiler warnings about uninitialized variables 2011-12-25 11:04:44 +00:00
74fa33bc42 Partly implemented options cuefile= and -text 2011-12-25 10:51:01 +00:00
8cdba24ff9 New API calls burn_cdtext_from_packfile() and burn_session_by_cue_file() 2011-12-25 10:39:05 +00:00
c8debb85a3 Changed libburn print threshold of cdrskin -v to severity NOTE 2011-12-22 11:21:50 +00:00
eeef039aab New options --cdtext_dummy and --cdtext_verbose 2011-12-18 16:11:47 +00:00
1cc7c7f8b2 Moved a function from cdtext.c to util.c 2011-12-16 11:13:11 +00:00
8f40e66fa4 Moved a function from cdtext.c to util.c 2011-12-16 10:53:43 +00:00
a34596d7b7 Moved burn_cdtext_from_session() from write.c to cdtext.c 2011-12-15 17:49:29 +00:00
e15e949a20 Documented new API call 2011-12-15 16:14:12 +00:00
8e8ed3e682 Moved reading of Sony Input Sheet v07 from cdrskin to libburn 2011-12-15 15:56:49 +00:00
52798b0b4a New API call burn_session_input_sheet_v07t() 2011-12-15 15:48:27 +00:00
de6d193eec Refusing to burn CD-TEXT if non-audio tracks are present 2011-12-15 10:43:07 +00:00
d774aa0b35 Included doc/cdtext.txt in libburn tarball 2011-12-15 09:15:11 +00:00
350971a34e Improved cdrskin man page and web page 2011-12-14 14:27:27 +00:00
64b90c1da6 Updated change log 2011-12-14 13:39:43 +00:00
398ee89348 New option input_sheet_v07t= 2011-12-14 13:26:06 +00:00
c3a02f8631 Changed default CD-TEXT for tracks from track number text to empty text 2011-12-14 12:49:16 +00:00
89e5450fb8 More macros for CD-TEXT genre and language names 2011-12-13 16:43:46 +00:00
e05285e246 Enabled repetition of track texts by TAB character 2011-12-12 18:14:16 +00:00
9ab0edae71 New macros for CD-TEXT genre and language names 2011-12-12 16:45:10 +00:00
8a9c6176c2 not needed since:
we would be better off building on the given OS/arch instead of playing with preprocessor directives;
all releng tests are gathered in libisoburn tree
2011-12-12 12:58:08 +00:00
620871c91d New API calls for composing CD-TEXT 2011-12-12 09:26:41 +00:00
2063dc2ca7 Pointing from man cdrskin to doc/cdtext.txt for CD-TEXT details 2011-12-12 09:13:27 +00:00
358ebaf458 Outsourced cdtext.txt from cookbook.txt 2011-12-12 08:52:40 +00:00
38387c0cb0 Some polishing in cookbook 2011-12-10 13:23:38 +00:00
f594e30f39 Updated documentation of CD-TEXT pack types 0x88 and 0x89 2011-12-10 12:38:27 +00:00
39bdf8c725 Tolerating trailing zero of Sony CDTEXT files 2011-12-09 09:22:02 +00:00
8a8a84b0f6 Updated documentation of CD-TEXT pack types 0x86, 0x8d, 0x8e 2011-12-08 19:49:45 +00:00
3b0f6b742f Updated documentation of CD-TEXT pack types 0x87 and 0x8f 2011-12-08 12:46:30 +00:00
0e5149d716 Removed version.h from list of source files because generated by configure 2011-12-07 07:50:45 +00:00
c085581224 Documented CD-TEXT pack type 0x8f 2011-12-06 14:00:32 +00:00
c84ba30220 Reacted on compiler warning about uninitialized variable in rev 4476 2011-12-06 13:47:52 +00:00
7b0a23d553 Implemented cdrskin option textfile= 2011-12-05 20:38:36 +00:00
7be652ac6b New API call burn_write_opts_set_leadin_text() 2011-12-05 20:36:31 +00:00
b385a3863e Added ./bootstrap script to release tarball 2011-12-03 12:11:59 +00:00
25d61ceba0 Removing cdrskin/.libs and test/.libs witch make clean 2011-12-03 12:11:04 +00:00
9aa23d6695 Corrected a style deviation in code of mmc.c 2011-12-03 11:33:59 +00:00
94a66f72d4 Clarified meaning of Character Position byte of burn_disc_get_leadin_text() 2011-12-02 20:45:24 +00:00
48e6a5975c Storing CD-TEXT as cdtext.dat with cdrskin option -toc -vv, reporting with -vvv 2011-12-02 17:17:28 +00:00
1d5ee82c16 New API call burn_disc_get_leadin_text() 2011-12-02 17:15:14 +00:00
56c02fa394 Bug fix: Interrupting libburn while drive tray is loading led to endless loop 2011-12-02 10:02:25 +00:00
7a5f1ab35c Improved debugging of drive feature list 2011-11-30 13:16:38 +00:00
6b7e0f134a Made SCSI timeout settable at level of SPC, SBC, MMC functions 2011-11-30 08:11:52 +00:00
417a4cc0bf Bug fix: Solaris adapter mishandled write commands which failed on first try 2011-11-26 15:32:03 +00:00
041f0e357e Reporting about failure to open existing /dev/sr or /dev/scd on Linux 2011-11-23 10:50:05 +00:00
6629d05eea Reacted on compiler warning of Debian buildd 2011-11-22 19:16:59 +00:00
8d6c28b6c5 Updated change log 2011-11-20 21:59:53 +00:00
4814e8c13a Updated cdrskin tarball generator 2011-11-20 21:57:15 +00:00
2718016de6 Made number transition to 1.1.9 2011-11-20 21:56:13 +00:00
dff3e97daa Bug fix: licdio adapter reacted inconsistently on symbolic links to drives 2011-11-18 15:54:53 +00:00
83e2d20322 Distinguished failure messages about write(2) and fsync(2) 2011-11-16 09:44:59 +00:00
303a2670be Clarified a remark in libburn/libdax_msgs.h 2011-11-16 09:43:03 +00:00
3b96910327 Clarified a remark in libburn/sg-linux.c 2011-11-14 17:07:01 +00:00
6c9b5a4419 Logging of early SCSI commands of Linux system adapter to stderr 2011-11-10 15:37:32 +00:00
cf181bdcd6 Removed remark about SCSI logging being restricted to Linux system adapter 2011-11-10 13:45:23 +00:00
cc65aa9df6 Enabled recognition of CD drive at /dev/vda of Linux guest on qemu virtio 2011-11-09 11:17:19 +00:00
b4ff95c2e7 Bug fix: Misinterpreted mode page 2A if block descriptors are present 2011-11-03 13:08:44 +00:00
a1158a118b Corrected a bug with obtaining Physical Interface Standard information 2011-11-02 13:07:56 +00:00
afe242f920 Avoiding on Linux to list drives from /proc if device family is non-default 2011-11-02 07:43:58 +00:00
854ebd647c Small correction of rev 4416 2011-11-01 22:17:49 +00:00
42b6c22dca Enabled recognition of QEMU DVD-ROM 0.12 as ATAPI drive 2011-10-31 16:43:02 +00:00
a247f7e7e9 Enabled optional reporting of drive replies in Solaris adapter 2011-10-27 16:14:13 +00:00
cad8abef74 Enabled optional reporting of drive replies in libcdio adapter 2011-10-27 09:47:29 +00:00
a504de4b58 Silenced a warnings in libcdio adapter 2011-10-27 09:10:43 +00:00
126e73d19d Added madatory library initialization to test/structest.c 2011-10-12 10:02:29 +00:00
ac4bfb128c Gave up use of burn_print() in libburn 2011-10-12 10:01:28 +00:00
8e97da0078 Avoided release-grab cycles between tasks of a cdrskin run 2011-10-11 16:39:57 +00:00
d6c8792a24 Avoided release-grab cycle in cdrskin -msinfo 2011-10-11 14:58:28 +00:00
dcf6f74e5a Avoided release-grab cycle in cdrskin -msinfo 2011-10-11 14:13:40 +00:00
39df1cdc4e Changed debug message which called "stdio:" addresses enumerable 2011-10-10 13:01:00 +00:00
3862b8d339 Changed term "persistent address" to "device file address" 2011-10-10 13:00:20 +00:00
02255c89be Reacted on nitpicking of cppcheck 2011-10-09 16:24:25 +00:00
3c7e723114 Reacted on warning of cppcheck about burn_disc_get_cd_info() 2011-10-09 15:54:47 +00:00
63c04b8c9b Replaced HTML minus by a flat ASCII minus in HTML man page generator 2011-10-08 12:11:38 +00:00
7d1c712c09 Avoided to release drive prematurely if interrupted while grabbing drive 2011-10-07 07:51:55 +00:00
6b821fcd92 Now unconditional: Cdrskin_libburn_from_pykix_svN 2011-10-06 12:13:46 +00:00
29f202a6fe Removed outdated code and Cdrskin_oldfashioned_api_usE 2011-10-06 12:00:52 +00:00
2cae912040 Removed obsolete macro case 2011-10-06 11:40:40 +00:00
3f7a92cc84 Now unconditional: Cdrskin_all_tracks_with_sector_paD 2011-10-06 11:34:32 +00:00
5faa1c25b0 Now unconditional: Cdrskin_libburn_does_ejecT 2011-10-06 11:32:25 +00:00
f986fe83ff Now unconditional: Cdrskin_libburn_has_drive_get_adR 2011-10-06 11:28:31 +00:00
15192c2bfa Now unconditional: Cdrskin_progress_track_does_worK 2011-10-06 11:25:48 +00:00
9b042009fb Now unconditional: Cdrskin_is_erasable_on_load_does_worK 2011-10-06 11:23:48 +00:00
15c6c539db Now unconditional: Cdrskin_grab_abort_does_worK 2011-10-06 11:21:36 +00:00
824e610824 Now unconditional: Cdrskin_allow_libburn_taO 2011-10-06 11:18:48 +00:00
dbd2e28366 Now unconditional: Cdrskin_libburn_has_is_enumerablE 2011-10-06 11:13:36 +00:00
6cc3012284 Now unconditional: Cdrskin_libburn_has_convert_fs_adR 2011-10-06 11:12:04 +00:00
ff1e0eb54e Now unconditional: Cdrskin_libburn_has_convert_scsi_adR 2011-10-06 11:00:18 +00:00
cbcae473ad Now unconditional: Cdrskin_libburn_has_burn_msgS 2011-10-06 10:59:25 +00:00
fb841a7d08 Now unconditional: Cdrskin_libburn_has_burn_aborT 2011-10-06 10:53:38 +00:00
207a702767 Now unconditional: Cdrskin_libburn_has_cleanup_handleR 2011-10-06 10:45:58 +00:00
4c10e60dae Now unconditional: Cdrskin_libburn_has_audioxtR 2011-10-06 10:43:26 +00:00
7c1666cdce Now unconditional: Cdrskin_libburn_has_get_start_end_lbA 2011-10-06 10:41:12 +00:00
da3aba8ef5 Now unconditional: Cdrskin_libburn_has_burn_disc_unsuitablE 2011-10-06 10:39:05 +00:00
822bdf8b7b Now unconditional: Cdrskin_libburn_has_read_atiP 2011-10-06 10:37:19 +00:00
880c95d9a4 Now unconditional: Cdrskin_libburn_has_buffer_progresS 2011-10-06 10:35:21 +00:00
d12589771b Now unconditional: Cdrskin_libburn_has_pretend_fulL 2011-10-06 10:34:19 +00:00
b7ecdb1014 Now unconditional: Cdrskin_libburn_has_multI 2011-10-06 10:32:03 +00:00
fdb981db72 Now unconditional: Cdrskin_libburn_has_buffer_min_filL 2011-10-06 10:29:10 +00:00
16724f3eef Now unconditional: Cdrskin_atip_speed_is_oK 2011-10-06 10:26:51 +00:00
8cc1fc1ca7 Now unconditional: Cdrskin_libburn_has_get_profilE 2011-10-06 10:22:41 +00:00
421870ae51 Now unconditional: Cdrskin_libburn_has_set_start_bytE 2011-10-06 10:19:53 +00:00
006d1a32fb Now unconditional: Cdrskin_libburn_has_wrote_welL 2011-10-06 10:15:39 +00:00
7ed9f978a8 Now unconditional: Cdrskin_libburn_has_bd_formattinG 2011-10-06 10:14:05 +00:00
b7c07ef18f Now unconditional: Cdrskin_libburn_has_burn_disc_formaT 2011-10-06 10:06:09 +00:00
1c66174a2e Now unconditional: Cdrskin_libburn_has_get_msc1 2011-10-06 09:53:57 +00:00
43b2f73217 Now unconditional: Cdrskin_libburn_has_toc_entry_extensionS 2011-10-06 09:52:26 +00:00
2c282adafb Now unconditional: Cdrskin_libburn_has_get_multi_capS 2011-10-06 09:23:55 +00:00
1d64ff428e Now unconditional: Cdrskin_libburn_has_set_filluP 2011-10-06 09:22:41 +00:00
c813de47c2 Now unconditional: Cdrskin_libburn_has_set_filluP 2011-10-06 09:20:20 +00:00
d39843a974 Now unconditional: Cdrskin_libburn_has_get_spacE 2011-10-06 09:18:01 +00:00
8c25db0148 Now unconditional: Cdrskin_libburn_write_mode_ruleS 2011-10-06 09:14:47 +00:00
46719fbc5c Now unconditional: Cdrskin_libburn_has_allow_untested_profileS 2011-10-06 09:06:56 +00:00
93b65ac4e5 Now unconditional: Cdrskin_libburn_has_set_forcE 2011-10-06 09:05:05 +00:00
3e58712c36 Now unconditional: Cdrskin_libburn_preset_device_familY 2011-10-06 09:02:53 +00:00
f6fc14de13 Now unconditional: Cdrskin_libburn_has_track_set_sizE 2011-10-06 08:59:52 +00:00
4bba05f186 Now unconditional: Cdrskin_libburn_has_set_waitinG 2011-10-06 08:57:50 +00:00
82697b2b8b Now unconditional: Cdrskin_libburn_has_get_best_speeD 2011-10-06 08:55:16 +00:00
ae91e331a7 Now unconditional: Cdrskin_libburn_has_random_access_rW 2011-10-06 08:41:04 +00:00
df41e7b9ff Now unconditional: Cdrskin_libburn_has_get_drive_rolE 2011-10-06 08:33:28 +00:00
49e91d491d Now unconditional: Cdrskin_libburn_has_stream_recordinG 2011-10-06 08:31:00 +00:00
a0a230e38b Now unconditional: Cdrskin_libburn_has_stream_recordinG 2011-10-06 08:27:46 +00:00
e05e813234 New API call burn_drive_re_assess() 2011-10-05 07:56:23 +00:00
c5718b7a4c Avoided one more open()-close() cycles during drive scan and grab on Linux 2011-10-02 17:20:39 +00:00
b81585e082 Avoided open()-close() cycles during drive scan and grab on Linux 2011-10-02 13:41:21 +00:00
91e2256ffb Updated change log 2011-09-27 12:57:21 +00:00
38b30d5e5f Updated cdrskin tarball generator 2011-09-27 12:52:55 +00:00
44b0314449 Made number transition to 1.1.7 2011-09-27 12:50:12 +00:00
3a993efb9f Corrected outdated sentence in documented workaround for udev 2011-09-21 13:42:19 +00:00
d9e6bde437 Improved and documented workaround for udev 2011-09-21 13:34:21 +00:00
71c9dc9f28 Slowing down test cycle while waiting for drive to become ready 2011-09-20 13:25:21 +00:00
35e553a808 Working around collision with udev by closing and re-opening device file 2011-09-20 13:19:47 +00:00
fe812ffde2 Simulation of large disks 2011-09-20 13:17:38 +00:00
a2965e9993 More generous ignoring of failure of fsync() on inappropriate fd 2011-08-29 21:33:43 +00:00
d073709328 Reacted on compiler warning about previous revision 2011-08-17 16:22:14 +00:00
7e6dadeb02 Bug fix: stdio sizes > 4 TB - 32 kB caused integer rollover 2011-08-17 16:09:05 +00:00
fe5efd7b37 Documented changes and release timestamp 2011-08-08 12:25:39 +00:00
7778536f45 Updated cdrskin tarball generator 2011-08-08 12:23:50 +00:00
60dde60ebd Made number transition to 1.1.5 2011-08-08 12:20:01 +00:00
76c4c76722 Forgot to upload the header which defines mmc_get_phys_format_info 2011-08-01 15:34:08 +00:00
2e20a4f888 New API call burn_disc_get_phys_format_info() 2011-08-01 12:54:24 +00:00
62944e3b21 Bug fix: Some drives return -150 as NWA of blank CD, rather than 0 2011-07-31 08:31:11 +00:00
b0a4b7c15c Bug fix: Some drives returned wrong CD sizes after having burnt DVD-R 2011-07-31 08:03:51 +00:00
ecc8bbc71f New option --device_links 2011-07-28 19:16:06 +00:00
b47a0e6884 New API call burn_lookup_device_link() 2011-07-28 19:13:39 +00:00
64f7f5d609 Reacted on warning of cppcheck about libburn/sg-freebsd.c 2011-07-15 08:13:46 +00:00
4e287dbfed Fixed possible uninitialized variable use introduced by rev 4152 2011-07-14 16:22:27 +00:00
13895a6518 Reacted on warning of cppcheck about libburn/sg-solaris.c 2011-07-12 17:38:01 +00:00
f12ce229ae Bug fix: Empty ROM drive was mistaken to hold an unsuitable disc 2011-07-12 15:54:42 +00:00
58d8f3b3c2 Improved -atip and -minfo with empty drive 2011-07-12 15:53:56 +00:00
34c86e88d9 Reacted on warning of cppcheck about libburn/sg-libcdio.c 2011-07-12 14:22:19 +00:00
a2d2ec150b Reacted on warning of cppcheck about libburn/sg-freebsd.c 2011-07-12 14:20:52 +00:00
54325147ee Reacted on warning of cppcheck about libburn/sg-freebsd-port.c 2011-07-12 14:19:55 +00:00
7620840490 Reacted on warning of cppcheck about libburn/sg-dummy.c 2011-07-12 14:19:12 +00:00
0894f7773e Improved intentional compiler warning about lack of suitable system adapter 2011-07-12 14:17:24 +00:00
706f8b937d Reacted on warning of cppcheck about test/poll.c 2011-07-12 11:05:20 +00:00
ec9bc5678b Reacted on warning of cppcheck about libburn/read.c 2011-07-12 11:04:39 +00:00
a751af6caa Reacted on warning of cppcheck about libburn/drive.c 2011-07-12 11:03:34 +00:00
570346b3a5 Reacted on warning of cppcheck about libburn/cleanup.c 2011-07-12 11:02:47 +00:00
f73698c0cb Reacted on warning of cppcheck about libburn/async.c 2011-07-12 11:01:53 +00:00
c11378f1a0 Reacted on warning of cppcheck about cdrskin/cleanup.c 2011-07-12 11:00:27 +00:00
a734e868bd Reacted on warning of cppcheck about cdrskin/cdrfifo.c 2011-07-12 09:59:59 +00:00
653586b97e Implemented macro Libburn_use_sg_freebsd_porT 2011-07-11 14:40:02 +00:00
3cec04dbe3 Reacted on warning of cppcheck 2011-07-07 12:07:43 +00:00
2d8047afcf Silenced warning of cppcheck 2011-07-07 11:50:34 +00:00
781beb3a27 Silenced warning of cppcheck 2011-07-07 11:49:36 +00:00
79e09728ac Reacted on warnings of -Wunused-but-set-variable 2011-07-06 14:39:39 +00:00
3f7210dfff Reacted on warnings of -Wtype-limits and -Wunused-but-set-variable 2011-07-06 14:38:08 +00:00
c03149241d Reacted on warnings of -Wunused-but-set-variable 2011-07-06 14:35:55 +00:00
2433c1f68e Reacted on warnings of -Wunused-but-set-variable 2011-07-06 14:34:58 +00:00
9eb60cd8fc Reacted on warnings of -Wunused-but-set-variable 2011-07-06 14:33:35 +00:00
15e18501d9 Reacted on warnings of -Wunused-but-set-variable 2011-07-06 14:31:32 +00:00
ed8b303d62 Reacted on warnings of -Wunused-but-set-variable 2011-07-06 14:25:57 +00:00
9fbae8df29 Reacted on warnings of -Wunused-but-set-variable 2011-07-04 17:17:40 +00:00
04005adaf4 Avoiding to load speed descriptor list twice 2011-07-04 14:39:47 +00:00
45da5c9934 record stderr of several builds in log files 2011-07-02 14:49:35 +00:00
64b1ab5b3d executable bit, fix text encoding 2011-06-22 13:36:29 +00:00
404717f305 Beginning to create a test suite for libburn and cdrskin 2011-06-22 09:33:23 +00:00
e5ea8f75e6 Silenced compiler warnings about signedness 2011-06-22 09:32:25 +00:00
eb01c9c6c5 Bug fix: libburn-1.1.0 did only compile on Linux, FreeBSD, and Solaris 2011-06-19 20:36:29 +00:00
c1ff7b9812 Documented changes and release timestamp 2011-06-18 16:01:18 +00:00
d6e90bb71f Updated cdrskin tarball generator 2011-06-18 15:58:14 +00:00
ae7f38c15a Made number transition to 1.1.1 2011-06-18 15:56:15 +00:00
4abf2b75b1 Reporting SCSI error if command RESERVE TRACK fails 2011-06-14 15:29:51 +00:00
f93babeea6 Added option -I . to aclocal in bootstrap script on advise of George Danchev 2011-06-09 06:12:45 +00:00
54723c9ee3 Replaced some large local variables by other means in libburn/write.c 2011-06-08 20:04:28 +00:00
75f121d26e Introduced AC_CONFIG_MACRO_DIR() and ACLOCAL_AMFLAGS on advise of George Danchev 2011-06-08 19:41:11 +00:00
9ee4f65141 Bug fix: burn_disc_format() on DVD-RW issued wrong block size with type 00h 2011-06-08 18:13:02 +00:00
8d057e4ee4 Replaced some large local variables by other means in libburn/toc.c 2011-06-08 08:23:08 +00:00
47af302776 Replaced some large local variables by other means in libburn/structure.c 2011-06-08 08:14:35 +00:00
c96745af15 Consolidated several local struct command to a new member of struct burn_drive 2011-06-07 14:40:31 +00:00
99af1501fc Closed a small memory leak with CD SAO found by valgrind 2011-06-07 08:44:46 +00:00
aeff7957f2 Leaner implementation of macro BURN_ALLOC_MEM 2011-06-06 17:37:42 +00:00
5f743b8030 Replaced some large local variables by other means in libburn/spc.c 2011-06-06 17:31:36 +00:00
27997067c9 Reacted on warnings of gcc about mixed sign comparison 2011-06-06 10:51:52 +00:00
cf8e46ec32 Replaced some large local variables by other means in libburn/sg-solaris.c 2011-06-06 10:45:04 +00:00
bad7a81d0d Replaced some large local variables by other means in libburn/sg-linux.c 2011-06-05 17:05:38 +00:00
5e8e73d994 Replaced some large local variables by other means in libburn/sg-libcdio.c 2011-06-02 13:28:06 +00:00
5ba8c03a98 Gave up use of bzero() in FreeBSD system adapters 2011-06-02 08:39:13 +00:00
096ed00f2e New API call burn_disc_close_damaged() 2011-05-31 10:32:21 +00:00
b4aeba18f7 New API call burn_disc_next_track_is_damaged() 2011-05-26 15:01:23 +00:00
0352486f97 Improved reaction on Damage Bit and missing NWA_V of READ TRACK INFORMATION 2011-05-26 14:58:10 +00:00
edd131b1b9 Replaced some large local variables by other means in libburn/sg-freebsd-port.c 2011-05-23 18:26:02 +00:00
30f3f70dfd Replaced some large local variables by other means in libburn/sg-freebsd.c 2011-05-23 17:39:48 +00:00
806b9602e6 Replaced some large local variables by other means in libburn/sg-dummy.c 2011-05-23 16:34:53 +00:00
f116eeec64 Replaced some large local variables by other means in libburn/read.c 2011-05-23 15:51:49 +00:00
7e50165d5c Replaced some large local variables by other means in libburn/mmc.c 2011-05-23 15:39:51 +00:00
46357869fc Added options -Wextra -Wno-unused-parameter for gcc 2011-05-22 14:31:54 +00:00
f85cb8269f Added a DVD+RW product id to the list 2011-05-22 14:31:10 +00:00
8fffc74a5b Added forgotten return value to BURN_ALLOC_MEM 2011-05-15 20:31:15 +00:00
8fd81d4ec4 Replaced some large local variables by other means in libburn/drive.c 2011-05-15 19:13:57 +00:00
0c76daf2a9 Polished macro BURN_ALLOC_MEM 2011-05-15 18:16:58 +00:00
86656a9d52 Replaced some large local variables by other means in libburn/async.c 2011-05-15 10:48:59 +00:00
95e511b984 Macros BURN_ALLOC_MEM, BURN_FREE_MEM for replaceing local variables 2011-05-15 10:47:01 +00:00
7af151169d Added cookbook.txt and mediainfo.txt to tarball on request of George Danchev 2011-05-14 12:21:04 +00:00
7a9a7dfdd2 Reacted on -Wsign-compare warnings of gcc 2011-05-12 13:52:23 +00:00
0ac6a64f12 Reacted on -Wsign-compare warnings of gcc 2011-05-12 13:51:44 +00:00
8bd288e10c Reacted on -Wsign-compare warnings of gcc 2011-05-12 13:50:49 +00:00
28078d059a Reacted on -Wsign-compare warnings of gcc 2011-05-12 13:49:40 +00:00
ac665916a6 Reacted on -Wsign-compare warnings of gcc 2011-05-12 13:46:59 +00:00
e9637067f8 Including header pthread.h on request of Mats Andersson for OpenBSD 2011-05-12 12:04:43 +00:00
a058e24375 Closed tiny memory leak found by valgrind 2011-05-01 14:45:22 +00:00
f895077c3c Disabled HAVE_DOT in doxygen.conf 2011-04-15 12:55:07 +00:00
73423b8819 Documented changes and release timestamp 2011-04-09 09:29:07 +00:00
5e9c7bac3f Updated cdrskin tarball generator 2011-04-09 09:27:52 +00:00
e32bd99801 Made number transition to 1.0.7 2011-04-09 09:26:29 +00:00
e86a7f9880 Better handling of read attempt on pseudo-drive without read-permission 2011-03-24 18:21:31 +00:00
9c9b82ae61 Avoiding appendable role 5 if not explicitely enabled 2011-03-22 08:59:43 +00:00
d5cc482015 Enabled blanking of drive with role 5 2011-03-21 09:22:04 +00:00
1f14074d59 Adjustments for drive role 5, random access write-only 2011-03-21 09:04:14 +00:00
d0c6889603 Corrected nwa computation for drive role 5 2011-03-21 09:02:58 +00:00
a088a85374 Silenced an error message with input that is not aligned to 2 kB 2011-03-19 22:21:35 +00:00
a3ac6c63aa Enabled BD formatting iby index on Pioneer BDR-205 which offers no Cert or QCert 2011-03-18 15:33:15 +00:00
af41742516 Provisory introduction of drive role 5, random access write-only 2011-03-18 09:33:54 +00:00
998fcdbefa Prepared cdrskin for drive role 5 2011-03-18 09:31:24 +00:00
ed811f45e6 Changed severity of "Read attempt on write-only drive" from FATAL to FAILURE 2011-03-13 19:26:30 +00:00
240e6abff4 Using burn_allow_drive_role_4() in cdrskin 2011-03-13 13:08:58 +00:00
402f4c0b04 New API call burn_allow_drive_role_4() 2011-03-13 13:07:46 +00:00
1b166f484d Burning DVD-R DAO with 2 kB size granularity rather than 32 kB 2011-03-12 09:35:04 +00:00
b945974dc7 Updated copyright year 2011-03-12 09:33:12 +00:00
cf214650c6 Documented changes and release timestamp 2011-03-10 13:44:40 +00:00
69ec9334d1 Updated cdrskin tarball generator 2011-03-10 13:43:32 +00:00
238fde4ef1 Made number transition to 1.0.5 2011-03-10 13:30:54 +00:00
69e95016fb Bug fix: Read-only file descriptors were classified as write-only pseudo drives 2011-03-01 14:46:17 +00:00
a8e54b86d7 Corrected a flaw found by George Danchev with cpp 2011-02-24 19:17:06 +00:00
9f5e967bdf Registered new error code 2011-02-23 19:57:10 +00:00
fcaf3e9d9a Documented changes and release timestamp 2011-02-23 19:40:22 +00:00
b59429c568 Updated cdrskin tarball generator 2011-02-23 19:39:30 +00:00
1f72fe107d Made number transition to 1.0.3 2011-02-23 19:38:44 +00:00
043d9a82d8 DEBUG message with burn_drive_cancel, FAILURE with premature end-of-input 2011-02-18 16:55:42 +00:00
952c9b0432 Reacted on compiler warnings about uninitialized variables 2011-02-14 08:59:42 +00:00
4f5075d7a9 Forced role 3 on drives which stem from open file descriptors without O_RDWR 2011-02-09 11:43:10 +00:00
2b07bd0632 Using usleep() instead of nanosleep() which is not available on Solaris 9 2011-01-18 16:28:57 +00:00
0a714850d7 Documented changes and release timestamp 2011-01-16 15:21:23 +00:00
3caf176aeb Updated cdrskin tarball generator 2011-01-16 15:19:21 +00:00
43f7e7d063 Made number transition to 1.0.1 2011-01-16 15:11:34 +00:00
447a68d691 Updated change log and web page 2011-01-09 14:09:14 +00:00
0a3b34d9c1 Refusing to burn if foreseeable size exceeds media capacity 2011-01-09 13:59:19 +00:00
0b25a4d258 Allowed stdio tracks of known size to end in TAO mode on premature EOF 2011-01-03 19:51:30 +00:00
3b5aeb0f81 Allowed umask to create stdio-drive files with rw-permissions for all 2010-12-28 07:19:29 +00:00
5ec4a7419e Updated API introduction 2010-12-23 15:19:17 +00:00
bf7e4c8027 Prepending ./configure generated options to CFLAGS rather than appending them 2010-12-13 08:00:00 +00:00
682078575f Documented changes and release timestamp 2010-12-08 14:04:58 +00:00
43f3d4b70f Updated cdrskin tarball generator 2010-12-08 14:03:33 +00:00
523b59984b Made number transition to 0.9.1 2010-12-08 13:55:24 +00:00
dcf79a188a Removed outdated development macros 2010-11-16 13:12:35 +00:00
84d6cac5c1 Regression fix: SCSI reply data logging was disabled in rev 3368, 0.8.6 2010-10-29 17:45:13 +00:00
261f05eb45 Issueing error messages if cache syncing or closing fails 2010-10-29 16:41:16 +00:00
9334b3190d Documented changes and release timestamp 2010-10-20 13:38:44 +00:00
9b0772fe9c Updated cdrskin tarball generator 2010-10-20 13:37:17 +00:00
20c0ae24a8 Made number transition to 0.8.9 2010-10-20 13:36:14 +00:00
0f622def33 Issueing messages with all cases of burn canceling 2010-10-19 16:59:34 +00:00
707d6153f7 Issue warning after writing a BD-R with more than 300 sessions 2010-10-15 19:17:37 +00:00
28ae78b4f1 Avoiding to inquire spare area of unsuitable media 2010-09-28 10:11:06 +00:00
7ceb67f0b0 Polished appearance of BD spare info with --list_formats 2010-09-24 10:05:05 +00:00
e18bfe50c1 Making new API call available in dynamic library 2010-09-24 09:26:06 +00:00
4083001548 Displaying eventual BD spare area information with --list_formats 2010-09-24 09:19:44 +00:00
45353dee67 Displaying eventual BD spare area information with -minfo 2010-09-24 09:07:58 +00:00
f14b66a09b New API call burn_disc_get_bd_spare_info() 2010-09-24 09:07:05 +00:00
38c029d5e3 Better default input file for test/offst_source.c 2010-09-22 18:17:10 +00:00
287b59cfd3 Temporarily added test program for burn_offst_source_new() 2010-09-22 18:09:50 +00:00
c49995b11a New API call burn_offst_source_new() 2010-09-22 17:51:26 +00:00
f2436351ef On Linux: Run ldconfig during make install,if not --disable-ldconfig-at-install 2010-09-22 10:54:56 +00:00
71844bf8b9 Documented changes and release timestamp 2010-09-17 08:02:52 +00:00
59e0824370 Updated cdrskin tarball generator 2010-09-17 08:01:21 +00:00
b7034abcbb Made number transition to 0.8.7 2010-09-17 07:54:34 +00:00
df390ae7d3 Meaningful change log file derived by George Danchev from web site 2010-09-15 06:23:37 +00:00
c1f4063193 Centralized interpretation of SCSI command outcome 2010-09-14 12:50:06 +00:00
4cc524097b Clarified the meaning of 0x0 and 0x30 signal handlers 2010-08-28 11:29:29 +00:00
fb159b8dbd Lifted test reservation on DVD-R DL media. Thanks to Kevin Kieffer for testing. 2010-08-21 09:56:16 +00:00
c693798571 Corrected typo in macro names (which shall never be defined anyway) 2010-08-13 11:42:49 +00:00
34847fff80 Hopefully silenced a warning of doxygen on Debian buildd 2010-08-08 09:13:53 +00:00
54651df146 New SCSI comand response "GO_ON" 2010-08-08 09:13:04 +00:00
d4e4607a84 Obeying burn_set_scsi_logging() with errors of class RETRY 2010-08-03 09:11:58 +00:00
98b2e06c21 Committed Solaris system adapter which was forgotten with rev 3345 2010-08-02 14:13:08 +00:00
d5ecb382aa Added error simulation code to Linux system adapter. 2010-08-02 13:20:33 +00:00
cdcda19384 Reporting sense data with burn_set_scsi_logging() 2010-08-02 10:07:09 +00:00
b96aeece99 Removed problematic DETAILS_AT_TOP to silence warning of Debian buildd 2010-07-30 16:05:26 +00:00
7bbf99384e Detached make target "doc" from target "all". 2010-07-29 16:41:45 +00:00
9f61db5378 Recognizing sense data format 0x72 if given instead of 0x70 2010-07-29 08:35:36 +00:00
2a48b34bcd Changed all malloc() to calloc() 2010-07-12 19:37:31 +00:00
15266fb310 Changed all malloc() to calloc() 2010-07-12 19:32:41 +00:00
e2bdd521d8 Mentioned that public API calls must be in libisofs/libisofs.ver 2010-07-06 11:34:38 +00:00
7a3b871c4e Let configure perform linker test with --version-script if enabled 2010-07-06 11:33:51 +00:00
713ec46f23 Mentioned new configure option --disable-versioned-libs 2010-07-04 17:29:17 +00:00
85eb091025 Hiding all non-API symbols from the linker by use of --version-script 2010-07-04 17:01:21 +00:00
c866b6bc35 Moved public part of libdax_audioxtr.h to libburn.h 2010-07-04 13:13:09 +00:00
0250a2831d Documented changes and release timestamp 2010-06-30 11:37:11 +00:00
4c47b81a9c Updated cdrskin tarball generator 2010-06-30 11:32:38 +00:00
bb88ba5861 Made number transition to 0.8.5 2010-06-30 11:31:22 +00:00
b30a2af7c7 Allowed 64 kB max output buffer size on all OSes 2010-06-16 08:25:57 +00:00
b10cfb3d22 Incremented LT_CURRENT and LT_AGE of libburn 2010-06-15 15:58:30 +00:00
a2df41713d Let general POSIX system adapters ignore SIGWINCH and SIGURG if defined 2010-06-15 15:57:11 +00:00
86ce32d170 Avoided compiler warning about unused variable on non-Solaris systems 2010-06-15 15:55:11 +00:00
7ba30596ce New less obtrusive implementation of sg_is_enumerable_adr for Solaris 2010-06-13 19:07:52 +00:00
2f8ad976ea Documented changes and release timestamp 2010-06-11 11:02:25 +00:00
d0d37af096 Updated cdrskin tarball generator 2010-06-11 11:01:44 +00:00
81768cd4b0 Made number transition to 0.8.3 2010-06-11 10:53:56 +00:00
e9828cddd0 Mentioned Solaris and system dependent drive permission settings 2010-06-10 17:23:23 +00:00
7f0358892a Removed obsolete development remark 2010-06-10 17:09:50 +00:00
bc40ce2876 Implemented block device capacity determination fo Solaris 2010-06-08 20:04:01 +00:00
6674667b7f Handled SCSI status "BUSY" on Solaris 2010-06-08 17:50:33 +00:00
cc4d72bf8b Corrected comment 2010-06-08 17:32:44 +00:00
1eee6ab8a0 New system adapter for Solaris uscsi (tested on snv134, kernel 5.11) 2010-06-07 17:30:54 +00:00
736d8b9019 Reacted on harmless compiler warnings on Solaris 2010-06-07 17:17:53 +00:00
8345eb8a71 Avoiding to resolve /dev/rdsk/cXtYdZs2 drive addresses on Solaris libcdio 2010-06-07 17:16:40 +00:00
cc7548f1c7 Bug fix: SIGSEGV of libcdio system adapter if drive list is empty 2010-05-29 07:44:41 +00:00
edca339338 Eventually including ../config.h generated by autotools 2010-05-16 09:07:42 +00:00
9323cceff1 Bug fix: CD-ROM media got attributed random lead-in and lead-out adresses 2010-05-01 08:29:28 +00:00
8b1b3f08c6 Avoided to create track without toc_entry from "hidden first track" on CD 2010-04-30 18:04:47 +00:00
e332f4a438 Documented changes and release timestamp 2010-04-09 11:13:19 +00:00
960fe6d188 Updated cdrskin tarball generator 2010-04-09 10:59:32 +00:00
92c5f6f998 Made number transition to 0.8.1 2010-04-09 10:57:38 +00:00
2069ffa863 Reporting eventual SCSI sense in sg-linux repeat loop 2010-04-09 09:07:59 +00:00
e787d328c7 Let libburner warn programmers if they forget to set 64 bit off_t 2010-04-04 18:13:45 +00:00
fafc190fd4 Adjusted libcdio system adapter to FreeBSD peculiarities 2010-03-29 10:33:05 +00:00
e6029ae238 Trying to detect FreeBSD ahci devices and to handle others the old way 2010-03-27 17:27:50 +00:00
6e17c59f6b Avoiding to inquire NWA of unwritable media or states 2010-03-27 15:58:05 +00:00
0e777ec688 Had to make ahci change conditional for now: -DLibburn_for_freebsd_ahcI 2010-03-26 08:33:22 +00:00
8dcdb5a87f Changed sg-freebsd.c to work with ahci, advise by Alexander Motin 2010-03-25 11:36:55 +00:00
4f372c00bc Corrected initialization of configure option --enable-dvd-obs-64k 2010-03-17 18:54:10 +00:00
9f6d80d87d Small bug fix about track size with cdrskin -minfo 2010-03-17 18:53:28 +00:00
b33df8fbd5 Documented changes and release timestamp 2010-03-10 13:58:50 +00:00
b4bb522053 Updated cdrskin tarball generator 2010-03-10 13:58:03 +00:00
3289ffd1e6 Made number transition to 0.7.9 2010-03-10 13:56:58 +00:00
196ef37108 Clarifications in API description of burn_set_signal_handling() 2010-03-09 14:01:57 +00:00
cdad7fcd80 Prevented potential memory fault with burn_set_signal_handling() 2010-03-08 09:24:21 +00:00
ed6e2df81b Changed examples burn_set_signal_handling(...,48) to (...,0x30) 2010-03-07 08:15:21 +00:00
ae667ca2e8 Adapted libburner to new advise about signal handling 2010-03-06 13:52:21 +00:00
873e3f5d78 Protected blanker and formatter thread from signals 2010-03-05 18:59:21 +00:00
72f9ff8b8c Removed some debugging printing 2010-03-05 11:15:28 +00:00
eb95f7fc16 Enabled optional use of new signal action 2 with libburn built-in handler 2010-03-05 09:12:44 +00:00
3519b42c14 Introduced alternative signal handling actions 2010-03-05 09:08:16 +00:00
b4e5afd317 Changed burn_abort(0) to burn_abort(-1) 2010-03-04 17:59:42 +00:00
7446ed7daa Showing more patience with temporarily busy drives on Linux 2010-03-04 12:13:04 +00:00
2d40b098e5 Enabled static compile script compile_cdrskin.sh for FreeBSD 2010-03-03 15:29:16 +00:00
ac64aef090 Enabled static compile script compile_cdrskin.sh for FreeBSD 2010-03-03 14:43:21 +00:00
74a68adc6e Adapted cdrskin abort handler to FreeBSD peculiarities 2010-03-03 14:12:22 +00:00
937bc87bfc Enabled patience 0 within burn_abort() 2010-03-03 14:05:07 +00:00
de482489c1 Corrected spelling errors in cdrskin man page 2010-02-28 16:53:09 +00:00
295fa1d526 Bug fix: cdrskin fs=0 lead to SIGSEGV. Regression introduced by revision 2936. 2010-02-28 11:06:02 +00:00
99bba3e98e Added forgotten initialization of a variable 2010-02-28 10:38:15 +00:00
bd3016e085 Corrected optional speed curb for stdio: drives. Was damaged by revision 2903. 2010-02-25 07:04:52 +00:00
dd74364ebb Made burn_set_signal_handling() more suitable for cdrskin 2010-02-22 13:47:17 +00:00
255e5362f9 Avoided random percentage display at start of blanking 2010-02-17 14:12:23 +00:00
471a0d0058 Bug fix on FreeBSD: Piped input was falsely attributed a small fixed size 2010-02-16 19:40:07 +00:00
f5b556db47 Changed a comment in libburn/crc.h 2010-02-15 12:57:38 +00:00
c12bbff7d1 Created opportunity to omit source module libburn/crc.c 2010-02-14 17:17:04 +00:00
6db992e646 Added or adjusted copyright and license statements in single files 2010-02-14 08:45:14 +00:00
bd017a108e Changed docs and comments to "GNU/Linux" where appropriate 2010-02-12 21:26:46 +00:00
3a76f9245f Changed system adapter id and some remarks from "Linux" to "GNU/Linux" 2010-02-12 17:30:59 +00:00
580ca08cc5 Forcing use of /usr/local on FreeBSD by LDFLAGS and CPPFLAGS 2010-02-04 08:31:31 +00:00
a6bd4c24db Updated cdrskin tarball generator 2010-01-23 10:44:04 +00:00
54005cb60e Lifted ban to derive GPLv3, extended copyright range to 2010 2010-01-23 10:42:52 +00:00
15fbe0a7ea Made number transition to 0.7.7 2010-01-23 10:40:11 +00:00
da1d260753 Learned how to inquire size of disk-like FreeBSD devices 2010-01-21 10:46:04 +00:00
95865ee34d Changed man page example from -toc to -minfo 2010-01-21 10:38:56 +00:00
eb8b8faa3b Changed a comment in sg-linux.c 2010-01-18 10:32:36 +00:00
39fd8b922d New OS adapter burn_os_is_2k_seekrw() replaces S_ISBLK() with pseudo-drives 2010-01-16 12:51:24 +00:00
7ead54c8b9 Implemented adivisory FreeBSD drive locking via flock(2) 2010-01-15 18:25:14 +00:00
2a85fc7d91 Provisory rejection of FreeBSD ATAPI drives in sg-libcdio 2010-01-14 16:06:17 +00:00
1e42a76415 Giving up drive probing by mode page sending 2010-01-14 16:04:57 +00:00
734759190a Carified in libburner.c that apps must use 64 bit off_t. 2010-01-14 14:09:30 +00:00
16ffa10831 Carified in libburner.c that apps must use 64 bit off_t. 2010-01-14 14:01:13 +00:00
cdfc357064 Carified that apps must use 64 bit off_t or the lib must be tweaked. 2010-01-13 17:14:14 +00:00
df612390d3 Adaptions after encounter with FreeBSD 8.0 2010-01-13 07:45:07 +00:00
77971f3680 Experimentally regard FreeBSD /dev/da[0-9] and /dev/cd[0-9] as block device 2010-01-13 07:38:56 +00:00
5c75d583d7 Fixed typos in MMC cookbook 2010-01-12 16:51:48 +00:00
2ff03841d7 Corrected free capacity measurement of stdio: drives in regular files 2010-01-12 16:50:44 +00:00
a88745c82e Revoked asynchronous eject, as we cannot distinguish out from unready 2010-01-09 14:32:51 +00:00
96167b3d8e Better error message with unknown SCSI error codes 2010-01-09 14:25:19 +00:00
1ca38962d4 Forgot to forward sense reply to higher levels 2010-01-09 14:18:55 +00:00
80bcabfd57 Enlarged buffer size of libcdio adapter on Linux to 64k 2010-01-04 13:52:57 +00:00
d9239aeafc Avoiding stream recording on BD if not 64 kB buffer 2010-01-04 13:49:05 +00:00
758a197d06 Enabled block device size recognition with sg-libcdio on Linux 2010-01-01 12:43:15 +00:00
ed972271ec Bug fix: with non-Linux adapters there were 0 readable bytes on block devices 2010-01-01 12:39:20 +00:00
0544ac8cd3 Silenced libcdio warnings 2009-12-30 20:08:51 +00:00
12a2be8d86 Making use of new libcdio capability to obtain SCSI address tuple on Linux 2009-12-30 15:40:10 +00:00
509db68d82 Adaptions for Debian kfreebsd requested by Petr Salinger 2009-12-29 22:43:35 +00:00
00ed59f34e Experimentally enabled FreeBSD system adapter for Debian kfreebsd 2009-12-29 13:31:56 +00:00
2b8e8c2521 Corrected a mode page size computation error which for now had no bad effect 2009-12-29 11:57:21 +00:00
e3ff0bb0f6 Incremented middle .so number 2009-12-29 11:55:48 +00:00
8efb24ca6d Reporting system adapter id with cdrskin -version 2009-12-27 14:46:01 +00:00
d53c5db98e Extended sg-API by sg_shutdown(), sg_dispose_drive(), sg_id_string() 2009-12-27 14:45:05 +00:00
0320b7bf2a Shorter sg_initialize message with sg-libcdio 2009-12-27 10:22:11 +00:00
cee271f9cb Showing libburn users drive name link targets, using in libcdio its own names 2009-12-27 09:20:10 +00:00
c2a3e3677d Reacted on some doxygen warnings of Debian hurd build 2009-12-26 22:25:45 +00:00
fc3445215b Reporting burn_scsi_transport_id() in cdrskin as debug message 2009-12-26 19:35:42 +00:00
4ce8bd45cf Added os-dummy.h and sg-dummy.h to libburn tarball 2009-12-26 08:49:59 +00:00
08169d63bc New API function burn_scsi_transport_id() 2009-12-26 08:01:35 +00:00
e13b6369ba New internal sg-API function sg_initialize() 2009-12-25 22:37:57 +00:00
d3988dd74b Adapted to libcdio-0.83 and its runtime version telling 2009-12-25 20:55:37 +00:00
ef42052900 Added PKG_CHECK_MODULES for libcdio-0.82 (must become 0.83 when released) 2009-12-25 14:40:16 +00:00
240afa7c3a Resolving symbolic links in libcdio drive list 2009-12-25 14:31:55 +00:00
5b72e5d06e Commited file forgotten with rev 2960 2009-12-25 10:13:06 +00:00
4aa08e32ff Option -use_libcdio for cdrskin development compile script 2009-12-25 10:12:22 +00:00
eb34561262 Making use of libcdio function mmc_get_cmd_scsi_sense() 2009-12-24 17:04:40 +00:00
dd85e37ac8 Experimental SCSI transport adapter via GNU libcdio 2009-12-19 14:34:48 +00:00
e566340261 Moved sg_log_cmd() to spc.c scsi_log_cmd() 2009-12-19 14:23:30 +00:00
7e86db207c Corrected CDB length of command 55h MODE SELECT from 12 to 10 2009-12-19 13:59:09 +00:00
a30ecd1abb Mentioned in cookbook the change about TAO close track 2009-12-16 07:39:39 +00:00
45b28b6c31 Documented changes and release timestamp 2009-12-07 07:56:32 +00:00
afedcdd72b Updated cdrskin tarball generator 2009-12-07 07:55:25 +00:00
b8a98e0728 Made number transition to 0.7.5 2009-12-07 07:54:24 +00:00
b238ad5a51 Now default in cdrskin: use of libburn fifo with DVD and BD single track 2009-12-06 09:37:33 +00:00
28f4454a9d Some clarifications about the Linux throughput problem 2009-12-06 07:45:00 +00:00
cb8c23ed5a Some clarifications about the GH22LS30 problem 2009-12-06 07:32:38 +00:00
54bb1ab395 Converted stderr experiment messages to DEBUG messages 2009-12-05 14:35:41 +00:00
872068ba7c Made effect of macro Libburn_pioneer_dvr_216d_read_buf_caP unconditional 2009-12-05 14:22:28 +00:00
2bd800ed14 Bug fix: SIGSEGV with LG GH22LS30 when inquiring media product id 2009-12-05 11:17:13 +00:00
da0b3b3939 Gave up CLOSE TRACK with CD TAO burn runs 2009-12-02 10:29:45 +00:00
93aa6ccc6f Documented meaning of START/STOP UNIT bits 2009-11-30 10:00:34 +00:00
d6edfc9961 Using mmap() by default for allocating read buffers 2009-11-28 12:23:20 +00:00
2945ab61d7 Compiler option -use_libburn_fifo to switch non-CD from cdrfifo to libburn fifo 2009-11-26 21:12:57 +00:00
d35f7d0de1 New API calls burn_fifo_get_statistics(), burn_fifo_next_interval() 2009-11-26 14:43:38 +00:00
e335aa26b4 New API call burn_fifo_fill() 2009-11-25 16:00:33 +00:00
496d794bcd Gave up call burn_os_close_track_src() introduced by rev 2920 2009-11-25 12:21:12 +00:00
c88a428d5e Gave up cdrskin specific O_DIRECT compile option 2009-11-23 19:31:32 +00:00
dc8ecdd77e New API calls burn_os_open_track_src() , burn_os_alloc_buffer() 2009-11-23 18:56:18 +00:00
259d1cd2b7 Bug fix: DVD DAO track size was rounded up much too generously 2009-11-22 20:52:40 +00:00
7fddf9ffc5 Enabled cdrskin O_DIRECT with fs=0 2009-11-21 19:15:52 +00:00
6109a7bc08 Longer READ BUFFER CAPACITY interval with DVD/BD writing 2009-11-21 19:14:05 +00:00
9b28a9b272 Avoided use of uninitialized variable 2009-11-20 17:57:34 +00:00
f39ff2c2f6 Experiment about SG_FLAG_DIRECT_IO 2009-11-20 13:48:44 +00:00
c8e0472637 Reserving enough track space for 64 kB write chunks 2009-11-18 18:56:14 +00:00
acb2f3b173 Split automatic drive start function from mmc_function_spy() 2009-11-18 12:25:57 +00:00
504677de4f Corrected help text of cdrskin static compile script 2009-11-17 16:54:52 +00:00
ae8f65e956 Revoked usage of libburn_libburn_la_CFLAGS in Makefile.am (ugly .o names) 2009-11-17 09:34:46 +00:00
c2c10e263e Updated build instructions of libburn and cdrskin 2009-11-16 18:00:30 +00:00
43761c55ef New compile_cdrskin.sh option -dvd_obs_64k, adapted to new .o names of libburn 2009-11-16 16:55:58 +00:00
b28165f10b Configure options --enable-cdrskin-fifo-odirect, --enable-dvd-obs-64k 2009-11-16 16:53:07 +00:00
25489521bb New options dvd_obs= and stdio_fsync= 2009-11-15 16:49:04 +00:00
79a33ca2ac New API calls burn_write_opts_set_dvd_obs(), burn_write_opts_set_stdio_fsync() 2009-11-15 15:30:26 +00:00
738b83ac03 New compile_cdrskin.sh option -o_direct (Linux only) 2009-11-15 15:24:21 +00:00
677b007100 Corrected an outdated remark 2009-11-15 15:21:04 +00:00
0fc685fc85 Man page entry and help text for option -V 2009-11-12 19:34:58 +00:00
ca2cae9b0a Implemented option -V for logging of SCSI commands 2009-11-12 18:01:26 +00:00
055876d6b7 Macro Libburn_pioneer_dvr_216d_dummy_probe_wM for omitting write mode probe 2009-11-12 18:00:01 +00:00
9160b1dcbb Workaround for Pioneer DVR-216D refusal to eject 2009-11-12 17:56:18 +00:00
0f37170759 Made SCSI logger permanent and controllable via API call 2009-11-12 17:54:06 +00:00
ce3d4dbed3 Updated cdrskin home page about DVR-216D workaround 2009-11-11 10:57:30 +00:00
f9acd4ee3d Silenced a compiler warning about potentially uninitialized variable 2009-11-11 10:49:11 +00:00
d118b82a13 Reporting number of pending bytes while thanking for patience in -vvv mode 2009-11-11 10:07:03 +00:00
76a4c0ac44 Increased stdio flush interval from 1 MB to 16 MB 2009-11-11 10:05:56 +00:00
83f80364c5 Hopefully solved the endless burn problem with Pioneer DVR-216D 2009-11-10 20:32:59 +00:00
9064b56c56 Avoiding START UNIT before the drive gets released 2009-11-10 12:21:43 +00:00
405e6b020e Made SCSI command log more complete and more readable 2009-11-08 11:12:23 +00:00
ffe80264c7 Corrected allocation length with GET CONFIGURATION 2009-11-08 11:08:19 +00:00
d158e7f456 Test macros for double START UNIT and SET CD SPEED 2009-11-05 17:03:01 +00:00
4384b0c006 Test macro for SEND OPC INFORMATION before DVD-R track 2009-11-04 08:46:17 +00:00
e78353b7dd Test macro for SL_V in mode page 05 2009-11-03 18:45:08 +00:00
3c2ad1be42 Test macros for finding reason of stall problem with Pioneer DVD-216D on DVD-R 2009-10-30 13:45:26 +00:00
937a226543 Bug fix: Closed memory leak with failure to open device file under FreeBSD. Thanks to George Danchev. 2009-10-27 10:09:31 +00:00
cca24711b8 Bug fix: burn_drive->disc_id or burn_drive->disc_app_code altered by stray 0. Thanks to George Danchev. 2009-10-27 10:06:43 +00:00
e646686145 More optimizations with parity computation 2009-10-20 16:14:14 +00:00
f3070d2e71 Optimizations with parity computation, clarification about nature of logarithms 2009-10-19 11:56:25 +00:00
e0c501a59a Re-implemented ECMA-130 P-parity, Q-parity and scrambling for BURN_WRITE_RAW 2009-10-17 13:17:53 +00:00
39a7d18266 Re-implemented ECMA-130 P-parity, Q-parity and scrambling for BURN_WRITE_RAW 2009-10-17 13:17:06 +00:00
de8ecab9b4 Documented changes and release timestamp 2009-10-12 11:00:23 +00:00
e9a6b9c36d Updated cdrskin tarball generator 2009-10-12 10:59:24 +00:00
e65ccb2b5e Made number transition to 0.7.3 2009-10-12 10:52:37 +00:00
96a5a2a28a Made -minfo subtract 2 from track size if "Data" and last 2 blocks unreadable 2009-10-09 20:06:25 +00:00
ca97df9798 Made read_capacity error message of burn_read_data() depending on flag bit1 2009-10-09 20:03:06 +00:00
22905f7349 Made -minfo stupidly report overwriteable media as "erasable" and "complete" 2009-10-09 12:37:38 +00:00
a318da9463 Determining read capacity for DVD-RAM 2009-10-09 12:35:42 +00:00
3c69b684a8 Fixed CD TAO multi-track -dummy bug reported by Philippe Rouquier 2009-10-04 15:11:35 +00:00
4457061656 Restricted retry to the timeout for single SCSI commands (200 seconds) 2009-09-22 19:26:57 +00:00
758f5a5c1e Revoked instruction to retry STOP UNIT 2009-09-22 19:24:41 +00:00
c8c4da8e8e Mentioned need for 2056 byte fifo chunks with burn_track_set_cdxa_conv() 2009-09-20 11:19:11 +00:00
4fdebcae9f Refusing to read beyond media_read_capacity 2009-09-18 16:18:37 +00:00
82ee4c8788 Fixing SIGSEGV with CD SAO introduced with revision 2808 2009-09-18 16:16:56 +00:00
ad4a286736 Evaluating read capacity with role 2 drives (regular files and block devices) 2009-09-13 09:49:50 +00:00
9017f0716f Updated cdrskin web page 2009-09-12 13:42:27 +00:00
7973546a4c Interpreting options -mode2, -xa, -xa1, -xa2 but producing CD-ROM Mode 1 tracks 2009-09-11 12:08:59 +00:00
2e6f83b3b3 New API call burn_track_set_cdxa_conv() 2009-09-11 11:53:36 +00:00
fdd190b65c Removed Media summary from -minfo because of incompatible counting rules 2009-09-10 07:11:54 +00:00
97ac17512f Silenced compiler warning 2009-09-09 17:42:31 +00:00
28a1b4dcba Emulation of some -minfo output 2009-09-09 17:33:48 +00:00
b724ab2130 New struct burn_toc_entry extension for Last Recorded Address 2009-09-09 15:38:47 +00:00
567beb1d9f Correction with erasable bit of burn_disc_get_cd_info() 2009-09-09 13:39:27 +00:00
eb62395e41 New API call burn_disc_get_cd_info() 2009-09-09 12:52:07 +00:00
1d6c97c79f Avoided to read third sixpack of manufacturer bytes with DVD-R media 2009-09-06 11:20:18 +00:00
5e4c1cf967 Corrected misformatted manufacturer strings of DVD- media 2009-09-06 09:37:23 +00:00
719096b0a7 Changed new API call burn_get_media_product_id() to burn_disc_get_media_id() 2009-09-06 09:25:52 +00:00
75dca6c6e9 Made recognition of CD media codes work in burn_guess_manufacturer() 2009-09-06 09:22:26 +00:00
1ef3a24885 "Manufacturer:", "Media type:" as cdrecord, own "Product Id:" and "Producer:" 2009-09-05 16:51:57 +00:00
790b4f31ee Introduced flag bit0 for API call burn_get_media_product_id() 2009-09-05 16:50:41 +00:00
9362a0240b Re-enabled output of product id and manufacturer 2009-09-05 13:19:01 +00:00
82e884c432 Made cdrskin/compile_cdrskin.sh -libburn_0_7_0 work again 2009-09-05 12:08:43 +00:00
f6d6dcfad0 Closed a small memory leak with drive inquiry 2009-09-05 11:50:09 +00:00
970ae46cfa Silenced a valgrind warning caused by not recognizing side effects of a ioctl 2009-09-05 11:42:25 +00:00
693784cbf5 Made product ID surely a single printable word 2009-09-05 11:29:44 +00:00
3a98bc52f9 Adjusted column width of media summary message 2009-09-05 07:24:06 +00:00
6038928fe4 Adjusted column width of media info messages 2009-09-04 20:43:29 +00:00
2e547b0bba Updated media info documentation 2009-09-04 20:41:08 +00:00
e968e81409 Option -atip now reports Product Id and Manufacturer for most CD, DVD, BD types 2009-09-04 20:22:54 +00:00
557299d350 New API calls burn_get_media_product_id() and burn_guess_manufacturer() 2009-09-04 20:21:55 +00:00
6642342274 New API call burn_guess_cd_manufacturer() 2009-09-02 13:32:17 +00:00
40b3380d4d Removed lec.c from libburn 2009-09-02 13:14:23 +00:00
3b018684c7 New option --long_toc, now printing media summary at end of TOC 2009-09-01 13:34:23 +00:00
96beb44455 Aligned the output columns of cdrskin --devices 2009-09-01 11:38:57 +00:00
9805ce7534 Disabled code using libburn/lec.c, removed lec.c from libburn 2009-09-01 09:57:14 +00:00
407471898c Disabled code using libburn/lec.c, removed lec.c from libburn 2009-09-01 09:56:51 +00:00
cf9a2031a4 Disabled write mode -raw96r 2009-09-01 08:25:01 +00:00
d9fc6cc275 Documented changes and release timestamp 2009-08-27 14:41:38 +00:00
78713d8912 Updated cdrskin tarball generator 2009-08-27 14:39:33 +00:00
169963eced Made number transition to development version 0.7.1 2009-08-27 14:38:24 +00:00
22c187cd61 Implemented automatic START UNIT after STOP UNIT before any other SCSI command 2009-08-24 20:24:39 +00:00
b900831914 Made burn_drive_snooze() safe for emulated drives 2009-08-24 16:15:46 +00:00
654d71ef07 New API call burn_drive_snooze() 2009-08-24 13:10:53 +00:00
0571f4dc2e Adapted to pitfalls of U3 memory sticks which appear as CD-ROM drives 2009-08-23 13:08:19 +00:00
ff23614200 Listing all profiles with cdrskin -v -atip 2009-08-15 13:36:51 +00:00
c59300b27a New API calls burn_drive_get_all_profiles(), burn_obtain_profile_name() 2009-08-15 13:32:56 +00:00
635996a327 Added test code about output blocks size as comment. 2009-08-15 13:30:42 +00:00
93287896a6 Documented changes and release timestamp 2009-07-14 13:39:08 +00:00
4da88193fa Updated cdrskin tarball generator 2009-07-14 13:38:19 +00:00
3091eeb9c9 Made number transition and activated development documentation 2009-07-14 13:37:11 +00:00
19a668a48e Timestamp for revision 2691 2009-07-07 19:17:40 +00:00
6ceabaff32 configure options --enable-libdir-pkgconfig and --enable-pkgconfig-path=DIR 2009-07-07 19:12:18 +00:00
b65b852c15 Retrying 3 times on EBUSY drives with generous usleep intervals 2009-06-14 09:49:47 +00:00
1ccedd5572 Bug fix: No usable media was detected with old MMC-1 drives 2009-06-03 18:53:57 +00:00
473e205c9e Bug fix: Old MMC-1 drives were rejected because of mode page 2Ah length 2009-06-03 08:58:18 +00:00
2522bebfbd Avoided to enumerate faulty drive objects 2009-06-02 17:21:43 +00:00
8276611468 Avoided SIGSEGV if no drives were found by scan 2009-06-02 16:30:06 +00:00
38994b62c0 Rectified use of burn_drive.mdata->valid 2009-06-02 16:28:33 +00:00
474c4cddd7 Made -scanbus work with SCSI bus numbers like 85 (USB, kernel 2.6.18.2) 2009-05-17 14:42:52 +00:00
b0b4bc57f8 Documented changes and release timestamp 2009-05-07 18:17:54 +00:00
b97fa7a451 Updated cdrskin tarball generator 2009-05-07 18:16:55 +00:00
8aca8e9921 Made number transition and activated development documentation 2009-05-07 18:15:47 +00:00
15b31b121a Mentioned BD were it was missing 2009-05-07 18:12:32 +00:00
e5632de786 Bug fix: Device scan stalled on FreeBSD. Ticket 148 jwele 2009-04-30 07:08:23 +00:00
91e3a2f3f7 Replaced 8 blanks by a tab 2009-04-30 06:59:35 +00:00
0ffc4bd19b Marked alleged use of uninitialized memory reported by valgrind 2009-04-30 06:56:47 +00:00
9cb4e4281e Bug fix: burn_abort() did not work with broken output pipe (since rev 2514) 2009-03-18 17:25:00 +00:00
f87747802a Human readable error messages for asc=08 "Logical unit communication failure" 2009-03-18 12:45:59 +00:00
4626304e39 Get on FreeBSD pkgconfigdir=.../libdata , on Linux and others: .../lib 2009-03-16 19:07:45 +00:00
d19abc1940 Documented changes and release timestamp 2009-03-13 14:15:46 +00:00
5ef7b4b445 Updated cdrskin tarball generator 2009-03-13 14:10:09 +00:00
033107b436 Made libburn number transition to 0.6.5 2009-03-13 14:03:13 +00:00
635405da8f Reacted on compiler warnings of SchilliX-0.6.7 (based on Solaris 5.11) 2009-03-08 14:01:10 +00:00
aafa543391 Lifted the ban on operating systems other than Linux and FreeBSD 2009-03-05 14:53:00 +00:00
8594cd96bc Making optional use of statvfs() in sg-dummy 2009-03-03 09:20:53 +00:00
b07c83ed86 Added a dummy function with loud compiler warning to sg.c dummy case 2009-03-02 20:01:37 +00:00
d74b1a2008 Fixed a race condition on abort with stdio writing which could cause SIGSEGV 2009-03-02 19:33:47 +00:00
8c56ca131f New operating system adapter "dummy" for stdio on POSIX-like systems 2009-03-02 17:01:21 +00:00
53e4483460 New stream_recording mode with start number 2009-02-27 21:17:05 +00:00
591c385489 New API function burn_drive_set_stream_recording() 2009-02-27 14:30:57 +00:00
b0f1f67495 Forgotten version leap to 0.6.3 in libburn.h 2009-02-20 13:23:57 +00:00
6139fb32dd Updated cdrskin tarball generator 2009-02-20 12:52:15 +00:00
01ed4729bd Made number transition to 0.6.3 2009-02-20 12:50:12 +00:00
350ac05bfd Human readable error messages with asynchronous SCSI errors 2009-02-19 19:28:16 +00:00
5f55a436e8 Mentioned hald as possibly conflicting service 2009-02-04 10:56:11 +00:00
3baaa886be Linking with $LIBBURN_ARCH_LIBS to get -lcam on FreeBSD 2009-02-04 10:28:26 +00:00
d4147e72f0 Mentioned the need for 64 bit file i/o 2009-01-27 12:10:39 +00:00
116798e081 Updated cookbook about BD-R media 2009-01-11 13:45:09 +00:00
7cc43c44e9 Prepared eventual closing of spoiled BD-R media by a pseudo write run 2009-01-11 10:28:05 +00:00
de0b3dd469 Preventing a possible bug with a burn run of more than one session at once 2009-01-09 16:17:25 +00:00
596d5bc5b0 Recognizing BD-R media spoiled by the close bug and handling them as appendable 2009-01-09 09:59:59 +00:00
867093d7d4 Mentioned bug fix and pl01 2009-01-07 15:50:05 +00:00
47dd4d8c09 Bug fix: BD-R were not correctly finalized 2009-01-07 15:44:30 +00:00
01a825310e Clarification about one-time DVD and BD media 2009-01-07 15:36:51 +00:00
96043eddf5 Complaining and refusing more early with unformatted BD-RE 2009-01-06 13:53:01 +00:00
5a65d6fa07 Complaining and refusing more early with unformatted BD-RE 2009-01-06 12:28:20 +00:00
aca01b88f3 Error texts for ASC 73 : power calibration and program memory 2009-01-06 12:25:53 +00:00
6d667880e5 Documented changes and release timestamp 2009-01-04 11:37:05 +00:00
1a667c86bc Updated cdrskin tarball generator 2009-01-04 11:36:33 +00:00
7c64d4bc13 Made number transition to 0.6.1 2009-01-04 11:35:19 +00:00
6fea3d0a9b Updated copyright claims to year 2009 2009-01-04 11:29:37 +00:00
687bde257c Cosmetic changes 2008-12-29 10:53:58 +00:00
1de41908a8 Fixed denial of fast formatting with BD-RE introduced by revision 2280 2008-12-22 13:05:51 +00:00
8af33586e8 Clarified blank, appendable, closed burn_disc_status 2008-12-19 20:35:43 +00:00
3ea5106d68 Removed project overview and references to libisofs and libisoburn 2008-12-17 11:12:19 +00:00
0ca643d0a4 Removed project overview and references to libisofs and libisoburn 2008-12-17 09:34:53 +00:00
d50c90b7be New API function burn_get_read_capacity() 2008-12-17 09:19:34 +00:00
1b5ab0834e Updated cdrskin web page 2008-12-14 14:39:40 +00:00
147cb430d1 Updated libburner to BD-R 2008-12-14 10:45:04 +00:00
1cbe3afdcc Now producing libburn.so.4.24.0 2008-12-13 14:49:39 +00:00
817edbaeea Interpreting feature 0023h for BD-R formatting capabilities 2008-12-12 21:40:34 +00:00
6552c8267c Making format size of BD-RE and BD-R quite freely adjustable 2008-12-12 11:22:14 +00:00
82fcf62309 Catching BD-R zero spare formatting with NOTE rather than SORRY 2008-12-11 09:22:33 +00:00
c1572c271f Rejecting unformattable BD-R more early 2008-12-11 07:23:29 +00:00
83ed108298 Mentioning BD-R in documentation 2008-12-10 17:16:19 +00:00
0d669b4369 Formatting of BD-R SRM to default size and by index 2008-12-10 11:43:28 +00:00
22554efe4f Formatting of BD-R SRM to default size and by index 2008-12-10 09:26:09 +00:00
eb7e20a02c Beginning to implement write code for BD-R SRM without POW 2008-12-09 12:36:28 +00:00
a5e2729604 Beginning to implement write code for BD-R SRM without POW 2008-12-09 12:35:13 +00:00
d52ea49eb6 Documented changes and release timestamp 2008-12-07 16:04:38 +00:00
96e1cc451c Updated cdrskin tarball generator 2008-12-07 16:02:30 +00:00
bfba58b0fa 2008-12-07 16:00:45 +00:00
175061615e Defaulting sessions without leadout entry 2008-12-03 08:52:44 +00:00
717ad0f412 Circumventing BD-RE Quick Certification refusal of LG GGW-H20L YL03 2008-11-29 14:04:31 +00:00
f3ea35b9b8 Translating ASC=0x31 formatting error messages, reporting command names 2008-11-29 14:01:41 +00:00
bb9ef6b988 Changed error severity with TOC truncation to MISHAP 2008-11-27 17:21:54 +00:00
aa606552eb Truncating eventually detected damaged CD table-of-content 2008-11-27 08:11:03 +00:00
9d99e7874a Added tests against the SIGSEGV of ticket 146 2008-11-26 21:06:37 +00:00
d1483a15da Mentioned FreeBSD peculiarities in our docs 2008-11-21 21:45:23 +00:00
ed60d9a644 Removed remark that use of statvfs() was untested with FreeBSD 2008-11-15 22:07:24 +00:00
bd5d8e8991 Documented changes and release timestamp 2008-11-12 12:54:21 +00:00
bf64271c67 Updated cdrskin tarball generator 2008-11-12 12:52:22 +00:00
b0c8bbd48d Made number transition to 0.5.7 2008-11-12 12:51:07 +00:00
2fb19dd08e Avoiding warning message about implicitely declared burn_fifo_abort() 2008-11-12 07:53:01 +00:00
2ce3199241 Disabling the sigsegv provoking new debug message 2008-11-08 20:25:38 +00:00
6fe53827da Cancelling libburn fifo thread before freeing the fifo object 2008-11-08 14:18:14 +00:00
6053f3a6e3 Clarified behavior of burn_source with pipes 2008-11-08 13:48:59 +00:00
de274ddaff Bug fix: Unsuitable write modes were caught silently and later than desired 2008-11-01 12:13:26 +00:00
92b0e145d5 Fixed incomplete sentence in man cdrskin 2008-10-15 10:35:06 +00:00
4a5083739d A clarification in comment about burn_disc_format() 2008-10-15 10:33:09 +00:00
7a8040fe9f Documented changes and release timestamp 2008-10-05 12:45:10 +00:00
57df15054f Updated cdrskin tarball generator 2008-10-05 12:43:18 +00:00
a57cf121d8 Made number transition to next development cycle 2008-10-05 12:41:44 +00:00
935239b4f9 Incremented LT_CURRENT and LT_AGE to get libburn.so.4.18.0 2008-10-04 07:39:22 +00:00
e50cc04374 Mentioned new xorriso capabilities in man cdrskin 2008-10-04 07:29:28 +00:00
89c12404d0 Prevented SIGSEGV after illegal drive operations during sync write 2008-10-04 07:27:43 +00:00
78642d08ae Bug fix: /dev/sr0 was accepted as enumerable address on Linux 2.4 2008-09-29 07:35:30 +00:00
c2c2499862 Bug fix: Potential buffer overflow introduced with revision 2024 2008-09-28 19:39:00 +00:00
32252122b8 Mentioned recent releases of libisofs and libisoburn 2008-09-24 20:34:01 +00:00
63a48571af Corrected pacifier text (Ticket 141) 2008-09-16 06:04:08 +00:00
006fb98aee Gave up problematic and unused version.h 2008-09-14 17:45:11 +00:00
afded80e10 Hopefully made out-of-tree building possible 2008-09-12 19:51:19 +00:00
fb3d2de5df Described ISO 9660 multi-session on overwriteable media 2008-09-12 10:04:41 +00:00
c640c7954b Trying to avoid unnecessary access to sibling device objects 2008-09-09 13:20:08 +00:00
bc30c4201a Issueing many SCSI error messages in cleartext now 2008-08-30 10:44:45 +00:00
50b587a22c Mentioned release of libisoburn-0.2.4 2008-08-30 10:39:46 +00:00
cd99716ab5 Documented changes and release timestamp 2008-08-20 10:09:35 +00:00
13bdbd3555 Updated cdrskin tarball generator 2008-08-20 10:08:16 +00:00
711c055730 Made number transition to 0.5.3 2008-08-20 10:06:01 +00:00
f64ed23a98 Reacted on harmless compiler warning 2008-08-19 12:36:10 +00:00
730c1555ab API clarification about CD burn_toc_entries 2008-08-19 12:26:48 +00:00
acd7dbc5c6 New flag bit2 with burn_read_data() 2008-08-09 07:19:54 +00:00
6dc9ecbcad CD burn_toc_entries now bear extension_valid data 2008-08-09 07:18:53 +00:00
5a99f9c4d8 Updated for next 0.5.1 cycle 2008-08-05 18:11:09 +00:00
ea17318e18 Taking into respect drive list from /proc/sys/dev/cdrom/info 2008-08-05 18:00:37 +00:00
98d742a4ef Avoiding drive scan if single drive is given 2008-08-01 10:10:13 +00:00
332a92ac78 Documented changes and release timestamp 2008-07-16 09:14:28 +00:00
6c50416d3c Updated cdrskin tarball generator 2008-07-16 09:13:36 +00:00
91d678a503 Made number transition to 0.5.1 and activated development documentation 2008-07-16 09:12:22 +00:00
76e85e600c Followed hint of Giulio Orsero to recognize disk by /proc/ide/hdX/media 2008-07-14 16:44:59 +00:00
9d48bb6892 New API call burn_fifo_peek_data() 2008-07-14 11:38:22 +00:00
38f0399fff Did LT_CURRENT++, LT_AGE++ because of new API call 2008-07-14 11:31:16 +00:00
39198ff8cb Making visible the new NOTE and HINT about busy alleged hard disks 2008-07-14 11:30:09 +00:00
67ca4a251a Trying to avoid SORRY messages when hitting busy hard disk /dev/hdX 2008-07-14 11:28:55 +00:00
b1c6953b61 With auto device family: scd is now fallback if sr does not exist 2008-07-02 09:39:02 +00:00
eb95d89272 Inserted @since tags for all functions older than 0.2.0 2008-06-14 14:06:38 +00:00
548051e53f Updated release history 2008-06-14 14:05:47 +00:00
a72b38c116 Documented changes and release timestamp 2008-05-17 12:09:02 +00:00
a67aa2ccee Updated cdrskin tarball generator 2008-05-17 12:06:38 +00:00
2fb5ea8def Made number transition to 0.4.9 2008-05-17 12:05:36 +00:00
55061cb7cf Made inability to get format list a reason to abort the program 2008-05-14 16:52:35 +00:00
4b3ec06cc4 Added format types 0x30 and 0x32 to list in API comments 2008-05-14 16:51:40 +00:00
ad6bd91b21 Bug fix: random access addressing for DVD-RAM and BD-RE did not work 2008-05-14 16:50:27 +00:00
0e2aaa2d59 Documented changes and release timestamp 2008-05-10 13:43:12 +00:00
4244a3c141 Updated cdrskin tarball generator 2008-05-10 13:41:58 +00:00
e4d30e4762 Made number transition to 0.4.7 2008-05-10 13:40:55 +00:00
2856e9c984 Changed blank examples to blank=as_needed 2008-05-09 19:42:49 +00:00
136 changed files with 90866 additions and 0 deletions

3
AUTHORS Normal file
View File

@ -0,0 +1,3 @@
Mario Danic
Thomas Schmitt

6
CONTRIBUTORS Normal file
View File

@ -0,0 +1,6 @@
Joe Neeman
Philippe Rouquier
Gabriel Craciunescu
George Danchev
Jean-Francois Wauthy
Lorenzo Taylor

280
COPYING Normal file
View File

@ -0,0 +1,280 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Library General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS

18
COPYRIGHT Normal file
View File

@ -0,0 +1,18 @@
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-2017 Mario Danic, Thomas Schmitt
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License version 2 or later
as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA

507
ChangeLog Normal file
View File

@ -0,0 +1,507 @@
libburn-1.5.2.pl01.tar.gz Mon Nov 25 2019
===============================================================================
* Bug fix: cdrskin multi-track burning was slow and stalled after track 1.
Regression introduced in version 1.5.0 by commit 84fad99, 2018.02.05
O_DIRECT is now disabled for track sources.
libburn-1.5.2.tar.gz Sat Oct 26 2019
===============================================================================
* Bug fix: No lock was obtained for setting up a fifo object
* Bug fix: Stream recording was applied regardless whether the drive offers it.
This caused Xfburn failures with some MATSHITA laptop drives.
* Bug fix: TDK Corporation was not recognized as manufacturer of DVD-R "TTH02"
* Made libburn ready for building out-of-source. Thanks Ross Burton.
* New API calls burn_drive_get_feature_codes(), burn_drive_get_feature()
* New cdrskin option --list_features
libburn-1.5.0.tar.gz Sat Sep 15 2018
===============================================================================
* Bug fix: cdrskin threw errno 22 on data file input if libburn is
configured with --enable-track-src-odirect
* Bug fix: SIGSEGV could happen if a track ended by reaching its fixed size
while the track source still was willing to deliver bytes.
Thanks to user swordragon.
* Bug fix: Device file comparison parameters were recorded wrong with Linux sg
libburn-1.4.8.tar.gz Tue Sep 12 2017
===============================================================================
* Bug fix: Option -dummy did not affect writing by direct_write_amount=
* New API call burn_drive_reset_simulate()
* New API call burn_drive_get_bd_r_pow()
* Refusing to write to BD-R if formatted to Pseudo Overwrite
libburn-1.4.6.tar.gz Fri Sep 16 2016
===============================================================================
* Bug fix: SAO CD could be perceived 2 blocks to short.
Regression in 1.4.4 by rev 5672.
* Now operating optical drives on OpenBSD. Thanks to SASANO Takayoshi.
* New API call burn_drive_set_immed()
* New cdrskin option use_immed_bit=
libburn-1.4.4.tar.gz Fri Jul 01 2016
===============================================================================
* Bug fix: Option drive_scsi_dev_family=sg did not convert /dev/sr* to /dev/sg*
* Bug fix: burn_make_input_sheet_v07t() falsly recognized double byte encoding.
Affected cdrskin option: cdtext_to_v07t=
* Bug fix: Double free at end of run if burn_write_opts_set_leadin_text() is
used. Affected cdrskin option: textfile=
* Bug fix: DVD book type of DVD+RW DL and DVD+R DL was reported wrong.
Thanks to Etienne Bergeron.
libburn-1.4.2.pl01.tar.gz Fri Jan 29 2016
===============================================================================
* Bug fix: cdrskin "failed to attach fifo" when burning from stdin.
Regression of 1.4.2, rev 5522.
libburn-1.4.2.tar.gz Sat Nov 28 2015
===============================================================================
* Bug fix: burn_disc_get_media_id() returned BD identifiers 2 chars too long
* Bug fix: burn_disc_get_multi_caps() returned 2048 bytes too many in
caps.start_range_high
* Bug fix: Media summary session count of blank and closed media was short by 1
* Bug fix: Endless loop if transport error occurs while waiting for drive ready
* New API calls burn_drive_get_serial_no() and burn_drive_get_media_sno()
* Result of a Coverity audit: 40+ code changes, but no easy-to-trigger bugs
libburn-1.4.0.tar.gz Sun May 17 2015
===============================================================================
* Bug fix: Double free with cdrskin -vvv.
Introduced with rev 5065, version 1.3.1
* Bug fix: Wrong read access to memory. Reported by valgrind of lian jianfei.
libburn-1.3.8.tar.gz Sat Jun 28 2014
===============================================================================
* Bug fix: Wrong stack usage caused SIGBUS on sparc when compiled by gcc -O2
* Bug fix: Minimum drive buffer fill was measured by cdrskin before the buffer
could get full
* Bug fix: A failed MMC BLANK command did not cause error indication by libburn
* Bug fix: A final fsync(2) was performed with stdio drives, even if not
desired
libburn-1.3.6.pl01.tar.gz Tue Mar 18 2013
===============================================================================
* Bug fix: CD TAO with multiple tracks could cause a buffer overrun
* Bug fix: Compilation warning for unsupported systems mutated into an error
libburn-1.3.6.tar.gz Tue Mar 04 2013
===============================================================================
* New system adapter for NetBSD
libburn-1.3.4.tar.gz Thu Dec 12 2013
===============================================================================
* Bug fix: Drive error reports were ignored during blanking and formatting
* Bug fix: Drive LG BH16NS40 stalls on inspection of unformatted DVD+RW
* New API call burn_disc_pretend_full_uncond()
libburn-1.3.2.tar.gz Wed Aug 07 2013
===============================================================================
* Bug fix: cdrskin -msinfo on DVD and BD reported
old session start = next writable address.
Regression introduced by version 1.2.8 (rev 4956).
* Bug fix: The signal handler aborted on SIGCONT, SIGTSTP, SIGTTIN, SIGTTOU
* New API call burn_make_input_sheet_v07t()
* API call burn_session_input_sheet_v07t(): read multiple blocks from same file
* New API calls burn_drive_extract_audio(), burn_drive_extract_audio_track()
* New cdrskin option textfile_to_v07t=
* New cdrskin options cdtext_to_textfile= and cdtext_to_v07t=
* New cdrskin options extract_audio_to= , extract_tracks= , extract_basename= ,
--extract_dap
* New cdrskin option --pacifier_with_newline
* Improved granularity of SCSI log time measurement, now with timestamp
* Optional "make doc" now demands doxygen 1.8.4
libburn-1.3.0.pl01.tar.gz Fri May 31 2013
===============================================================================
* Bug fix: cdrskin -msinfo on DVD and BD reported
old session start = next writable address.
Regression introduced by version 1.2.8.
libburn-1.3.0.tar.gz Fri May 17 2013
===============================================================================
* Bug fix: Full formatting of BD-RE used certification regardless of drive
capabilities
* Bug fix: DVD+R with damaged TOC were reported by -minfo with wrong end
address
libburn-1.2.8.tar.gz Mon Mar 18 2013
===============================================================================
* Bug fix: All CD tracks were reported with the sizes of the tracks in the
first session. Regression introduced with version 1.2.0 (rev 4552).
* Bug fix: On some drives the request for minimum speed yielded maximum speed
* New cdrskin option --list_speeds
* -toc and -minfo now report about tracks in the incomplete session
* New API call burn_disc_get_incomplete_sessions()
* New burn_toc_entry component .track_status_bits
libburn-1.2.6.tar.gz Tue Jan 08 2013
===============================================================================
* Bug fix: Speed setting had no effect on BD media
* New cdrskin option --no_load
* New API call burn_read_audio()
* New API call burn_list_sev_texts()
libburn-1.2.4.tar.gz Fri Jul 20 2012
===============================================================================
* Bug fix: CD SAO sessions with data tracks started by an audio pause
* Bug fix: CD tracks were perceived 2 sectors too short.
Nice with TAO, bad with SAO.
* Bug fix: cdrskin SIGSEGV if track source was added when no drive was available
* New API call burn_write_opts_set_obs_pad(), ./configure --enable-dvd-obs-pad
* New cdrskin option --obs_pad
libburn-1.2.2.tar.gz Mon Apr 02 2012
===============================================================================
* Small internal refinements
libburn-1.2.0.tar.gz Sat Jan 28 2012
===============================================================================
* Bug fix: cdrskin produced a memory fault if interupted before writing began
* Bug fix: Solaris adapter mishandled write commands which failed on first try
* Bug fix: Interrupting libburn while drive tray is loading led to endless loop
* Bug fix: Progress report with blanking and formatting could be bogus
* New API calls burn_disc_get_leadin_text(), burn_write_opts_set_leadin_text()
* New API calls for composing CD-TEXT, see doc/cdtext.txt
* New API call burn_session_by_cue_file() for reading CDRWIN .cue files
* New API call burn_track_set_isrc_string()
* New API calls burn_track_set_index(), burn_track_clear_indice()
* New API calls burn_session_set_start_tno(), burn_session_get_start_tno()
* New API calls burn_track_set_pregap_size(), burn_track_set_postgap_size()
* Implemented cdrskin option textfile=
* Implemented cdrskin option combination -vv -toc for cdtext.dat production
* Implemented cdrskin options mcn= and isrc=
* Implemented cdrskin options -scms -copy -nocopy -preemp -nopreemp
* Implemented cdrskin option index=
* Partly implemented cdrskin options cuefile= and -text
* New cdrskin option input_sheet_v07t= for CD-TEXT definition
* New cdrskin options --cdtext_dummy and --cdtext_verbose
* New cdrskin options --four_channel --two_channel
* New cdrskin option cd_start_tno=
* New cdrskin options sao_pregap=, sao_postgap=
libburn-1.1.8.tar.gz Mon Nov 21 2011
===============================================================================
* Bug fix: Misinterpreted mode page 2A if block descriptors are present
* Enabled recognition of QEMU DVD-ROM 0.12
* Avoiding to intermediately close and open drive device file
* New API call burn_drive_re_assess()
libburn-1.1.6.tar.gz Tue Sep 27 2011
===============================================================================
* Bug fix: stdio sizes > 4 TB - 32 kB caused integer rollover
* Worked around a collision with Linux udev which lets links vanish
libburn-1.1.4.tar.gz Sun Aug 07 2011
===============================================================================
* Bug fix: Some drives return -150 as NWA of blank CD, rather than 0.
libburn forwarded this misleading information to the application.
* Bug fix: Some drives returned wrong CD sizes after having burned DVD-R
* Bug fix: Empty ROM drive was mistaken to hold an unsuitable disc
* Bug fix: Avoiding to load speed descriptor list twice
* New API call burn_lookup_device_link()
* New API call burn_disc_get_phys_format_info()
* New cdrskin option --device_links
Release 1.1.2 was skipped to get back in sync with libisoburn.
libburn-1.1.0.pl01.tar.gz Mon Jun 20 2011
===============================================================================
* Bug fix: libburn-1.1.0 compiled only on Linux, FreeBSD, and Solaris
libburn-1.1.0.tar.gz Sat Jun 18 2011
===============================================================================
* Bug fix: burn_disc_format() on DVD-RW issued wrong block size with type 00h
* New API call burn_disc_next_track_is_damaged()
* New API call burn_disc_close_damaged()
* Dropped suffix .plXY from tarball name
Release 1.0.8 was skipped to get back in sync with libisofs and libisoburn.
libburn-1.0.6.pl00.tar.gz Sat Apr 9 2011
===============================================================================
* Burning DVD-R DAO with 2 kB size granularity rather than 32 kB
* New API call burn_allow_drive_role_4()
libburn-1.0.4.pl00.tar.gz Thu Mar 3 2011
===============================================================================
* Bug fix: Read-only file descriptors were classified as write-only pseudo
drives
libburn-1.0.2.pl00.tar.gz Wed Feb 23 2011
===============================================================================
* Removed compilation obstacles on Solaris 9.
* Improved recognition of non-seekable stdio pseudo-drives.
libburn-1.0.0.pl00.tar.gz Sun Jan 16 2011
===============================================================================
* Allowed umask to create stdio-drive files with rw-permissions for all
* cdrskin now refuses to burn if the foreseeable size exceeds media capacity
libburn-0.9.0.pl00.tar.gz Wed Dec 08 2010
===============================================================================
* Regression fix: SCSI reply data logging was disabled in release 0.8.6
libburn-0.8.8.pl00.tar.gz Wed Oct 20 2010
===============================================================================
* New API call burn_offst_source_new()
* New API call burn_disc_get_bd_spare_info()
libburn-0.8.6.pl00.tar.gz Fri Sep 17 2010
===============================================================================
* Lifted test reservation on DVD-R DL media.
* Hiding all non-API symbols from the linker by use of --version-script
* Now with history of release notes in ./ChangeLog file.
libburn-0.8.4.pl00.tar.gz Wed Jun 30 2010
===============================================================================
* General POSIX system adapters ignore SIGWINCH and SIGURG if defined
* Allowed 64 kB max output buffer size on all OSes
libburn-0.8.2.pl00.tar.gz Fri Jun 11 2010
===============================================================================
* New system adapter for Solaris uscsi (tested on snv134, kernel 5.11)
* Bug fix: CD TOC was not read if the first track did not start at LBA 0
* Bug fix: CD-ROM media got attributed random lead-in and lead-out adresses
* Bug fix: SIGSEGV of experimental libcdio system adapter if drive list is
empty
libburn-0.8.0.pl00.tar.gz Fri Apr 09 2010
===============================================================================
* libburn now works with ahci driver on FreeBSD 8-STABLE.
libburn-0.7.8.pl00.tar.gz Wed Mar 10 2010
===============================================================================
* Bug fix: On FreeBSD, piped input was falsely attributed a small fixed size.
* Built-in abort handling is more suitable for FreeBSD now.
cdrskin novelties:
* Bug fix: Option fs=0 led to SIGSEGV. Regression introduced by version 0.7.4
in december 2009.
* Abort handling is more suitable for FreeBSD now.
libburn-0.7.6.pl00.tar.gz Sat Jan 23 2010
===============================================================================
* Bug fix: System adapter for generic X/Open was missing in libburn release
tarball
* Bug fix: with non-Linux adapters there were 0 readable bytes on block devices
* Made FreeBSD system adapter safe from mutal burn spoiling and drive deadlock
* Enabled FreeBSD system adapter for Debian kfreebsd
* Experimental SCSI transport adapter via GNU libcdio 0.83git
cdrskin novelties:
* none
libburn-0.7.4.pl01.tar.gz Sat Dec 26 2009
===============================================================================
* Bug fix: Added missing system adapter for generic X/Open to libburn release
tarball
Libburn 0.7.4.pl00 Mon Dec 07 2009
===============================================================================
* Bug fix: SIGSEGV from NULL pointer with media product id inquiry on LG
GH22LS30
* Bug fix: DVD DAO track size was rounded up much too generously
* Workaround for Pioneer DVR-216D which got stuck on DVD-R burns.
(already fixed in 0.7.2.pl01)
* Workaround for Pioneer DVR-216D refusal to eject.
(already fixed in 0.7.2.pl01)
* Configure options --enable-dvd-obs-64k, --enable-track-src-odirect
* New API calls burn_write_opts_set_dvd_obs(),
burn_write_opts_set_stdio_fsync()
* New API call burn_set_scsi_logging()
* New API calls burn_fifo_get_statistics(), burn_fifo_next_interval(),
burn_fifo_fill()
* Re-implemented ECMA-130 P-parity, Q-parity and scrambling for BURN_WRITE_RAW
cdrskin novelties:
* cdrskin option -V for logging of SCSI commands
* New cdrskin options dvd_obs= and stdio_fsync=
* New compile_cdrskin.sh option -dvd_obs_64k
libburn-0.7.2.pl01.tar.gz Fri Nov 13 2009
===============================================================================
* Workaround for Pioneer DVR-216D which got stuck on DVD-R burns.
* Workaround for Pioneer DVR-216D refusal to eject.
Libburn 0.7.2.pl00 Mon Oct 12 2009
===============================================================================
* Bug fix: CD TAO sessions with multiple tracks did not work in -dummy mode
* New API calls burn_get_media_product_id() , burn_guess_manufacturer() ,
burn_guess_cd_manufacturer()
* New API call burn_disc_get_cd_info()
* New API call burn_track_set_cdxa_conv()
cdrskin novelties:
* Better interpretation of options -mode2, -xa, -xa1, -xa2
* New option --xa1-ignore
* New -atip report lines "Product Id:" and "Producer:"
libburn-0.7.0.pl00.tar.gz Thu Aug 27 2009
===============================================================================
* New API calls burn_drive_get_all_profiles(), burn_obtain_profile_name() allow
to inquire and process the list of supported media types. cdrskin lists all
supported profiles with option -atip -v
* New API call burn_drive_snooze() allows to calm down a drive when no i/o is
expected for a while.
* Bug fix: Some SCSI commands stalled on U3 memory sticks which appear as a hub
with a memory stick and a CD-ROM drive containing a small CD. These commands
make not much sense with a CD-ROM and are now avoided for this media
situation.
libburn-0.6.8.pl00.tar.gz Tue Jul 14 2009
===============================================================================
* Bug fix: Old MMC-1 drives were rejected because of mode page 2Ah length.
* cdrskin -scanbus now works with high SCSI bus numbers.
libburn-0.6.6.pl00.tar.gz Fri May 8 2009
===============================================================================
* Bug fix: Improper abort handling with broken pipe during outputto a stdio:
pseudo-drive.
* Bug fix: Device scan stalled on FreeBSD with non-burner USB device
libburn-0.6.4.pl00.tar.gz Fri Mar 13 2009
===============================================================================
* New operating system adapter "dummy" for stdio on general X/Open systems
* New API function burn_drive_set_stream_recording() allows to write the
crucial start blocks of a filesystem with slow BD-RE Defect Management and to
write the bulk of data with full nominal speed.
libburn-0.6.2.pl00.tar.gz Fri Feb 20 2009
===============================================================================
* Improvements with build system for FreeBSD
libburn-0.6.0.pl01.tar.gz Wed Jan 07 2009
===============================================================================
* Bug fix: BD-R were not correctly finalized
libburn-0.6.0.pl00.tar.gz Sun Jan 04 2009
===============================================================================
* Formatting and writing of BD-R media
* New API function burn_get_read_capacity()
libburn-0.5.8.pl00.tar.gz Mon Dec 08 2008
===============================================================================
* Bug fix: A session without leadout entry on CD caused a SIGSEGV by NULL
* Improvements about BD-RE formatting
libburn-0.5.6.pl00.tar.gz Wed Nov 12 2008
===============================================================================
* Bug fix: libburn fifo thread was not aborted when burn run was aborted which
could lead to use of freed memory.
libburn-0.5.4.pl00.tar.gz Mon Oct 6 2008
===============================================================================
* Bug fix: On Linux 2.4 /dev/sr0 was accepted as enumerable address but then
failed to work.
libburn-0.5.2.pl00.tar.gz Wed Aug 20 2008
===============================================================================
* Larger set of possibly acceptable drive device file names
libburn-0.5.0.pl00.tar.gz Thu Jul 17 2008
===============================================================================
* Bug fix: cdrskin option drive_scsi_dev_family=scd lead to buffer overflow
* Ability to use /dev/scd as fallback if /dev/sr does not exist
* New API call burn_fifo_peek_data()
libburn-0.4.8.pl00.tar.gz Sat May 17 2008
===============================================================================
* Bug fix: Random access addressing for DVD-RAM and BD-RE did not work.
* cdrskin: Affected were options write_start_address= and
-- grow_overwriteable_iso on DVD-RAM or BD-RE.
* xorriso: Affected were sessions on DVD-RAM or BD-RE after the first one.
libburn-0.4.6.pl00.tar.gz Sun May 11 2008
===============================================================================
* Support for BD-RE media is now official
* New burn_write_opts_set_stream_recording() can speed up DVD-RAM and BD-RE
* New cdrskin option --list_formats
* New cdrskin blank types for expert formatting of DVD-RAM and BD-RE
* New cdrskin blank type blank=as_needed for automatic handling of media
libburn-0.4.4.tar.gz Thu April 10 2008
===============================================================================
* Support for DVD+R/DL media is now official
libburn-0.4.2.tar.gz Sun Feb 3 2008
===============================================================================
* Long term commitment to ABI libburn.so.4.
* ABI compatibility is guaranteed for any older feature set released since
libburn-0.3.2 about one year ago.
* libburn provides means for compile time and runtime checking of its version.
* Compile time check in cdrskin for proper version of libburn include file.
Required is at least 0.4.2.
* Runtime check in cdrskin prevents dynamic linking with outdated version of
libburn.so.4. Required is at least the version seen in the include file at
compile time.
libburn-0.4.0.tar.gz Mon Oct 29 2007
===============================================================================
* New option direct_write_amount=
* New option --grow_overwriteable_iso
* New option --allow_emulated_drives dev=stdio:<path>
* More cdrecord options supported: -format, -inq, -load, -lock, -immed, -waiti
* New option fallback_program=
* A lot of libburn API additions.
libburn-0.3.8.tar.gz Tue Jul 31 2007
===============================================================================
* Now able to cope with the peculiarities of Linux 2.4 USB
* Refusal to perform -dummy runs on media which cannot simulate burning
* New option modesty_on_drive= may help with hda -> hdb burns
* New option minbuf= , cdrecord compatible frontend of modesty_on_drive=
* New option --adjust_speed_to_drive
* Precautions against using the burner drive as track source
* Note: ABI has not been broken.
libburn-0.3.6.tar.gz Thu Apr 26 2007
===============================================================================
* On Linux kernel 2.6, /dev/sr* gets used rather than /dev/sg*.
* DVD+R now get finalized (if not -multi is given)
libburn-0.3.4.tar.gz Mon Mar 12 2007
===============================================================================
* Multi-session recording on DVD+R, including -toc, -msinfo
* Options --tell_media_space , assert_write_lba=
* Bug fix of rare multi track fifo stall
libburn-0.3.2.tar.gz Feb 11 2007
===============================================================================
* Burnfree enabled by default
* Multi-session recording on sequential DVD-R[W], including -toc, -msinfo
* DVD-R[W] Disk-at-once recording
libburn-0.3.0.1.tar.gz Tue Jan 30 2007
===============================================================================
* Improved recognition of unsuitable media types
* Replaced ban of chmod u+s by loud warning
* detailed man page for cdrskin
* Burning of DVD+RW and DVD-RAM media as single-track TAO-like initial session
* Formatting and then burning to DVD-RW like to DVD+RW
* New option -msifile=path from cdrkit/wodim
* 0.3.0.1 release notes *
* Bug fix enabling tracks >= 1.3 GB from disk file
libburn-0.2.6.3.tar.gz Fri Dec 29 2006
===============================================================================
* 0.2.6 release notes (Wed Nov 22 2006)
* After a lot of time with dedication to this project, we proudly present you
libburn 0.2.6. It is the first version of cdrskin and libburn after they have
been split from genisofs and libisofs. Main new features are write mode TAO
and support for multi session.
* 0.2.6.1 release notes (Fri Nov 24 2006)
* Point release to fix misleading version numbers in messages and documentation
* 0.2.6.2 release notes (Sat Dec 16 2006)
* cdrskin man page backported from development version 0.2.7.
* 0.2.6.3 release notes (Fri Dec 29 2006)
* Point release to fix build system problems people have experienced with the
past release.
libburn-0.2.3.snapshot02.tar.gz Thu Nov 02 2006
===============================================================================
* Stabilized snapshot including release 0.2.4.pl01 of cdrskin
* cdrskin 0.2.4 release notes
* Compatibility with cdrecord has been improved in respect to drive addresses,
audio extraction from .wav, -scanbus, -toc, drive buffer fill indicator.
* Note: The previous snapshot01 with the same source base is handicapped by a
broken ./configure setup. It works well on Intel compatible CPUs but is
supposed to be unusable on big-endian architectures.
libburn-0.2.2.tar.gz Wed Sep 20 2006
===============================================================================
Initial release of libburnia's libburn combined with cdrskin.

234
INSTALL Normal file
View File

@ -0,0 +1,234 @@
Installation Instructions
*************************
Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005,
2006 Free Software Foundation, Inc.
This file is free documentation; the Free Software Foundation gives
unlimited permission to copy, distribute and modify it.
Basic Installation
==================
Briefly, the shell commands `./configure; make; make install' should
configure, build, and install this package. The following
more-detailed instructions are generic; see the `README' file for
instructions specific to this package.
The `configure' shell script attempts to guess correct values for
various system-dependent variables used during compilation. It uses
those values to create a `Makefile' in each directory of the package.
It may also create one or more `.h' files containing system-dependent
definitions. Finally, it creates a shell script `config.status' that
you can run in the future to recreate the current configuration, and a
file `config.log' containing compiler output (useful mainly for
debugging `configure').
It can also use an optional file (typically called `config.cache'
and enabled with `--cache-file=config.cache' or simply `-C') that saves
the results of its tests to speed up reconfiguring. Caching is
disabled by default to prevent problems with accidental use of stale
cache files.
If you need to do unusual things to compile the package, please try
to figure out how `configure' could check whether to do them, and mail
diffs or instructions to the address given in the `README' so they can
be considered for the next release. If you are using the cache, and at
some point `config.cache' contains results you don't want to keep, you
may remove or edit it.
The file `configure.ac' (or `configure.in') is used to create
`configure' by a program called `autoconf'. You need `configure.ac' if
you want to change it or regenerate `configure' using a newer version
of `autoconf'.
The simplest way to compile this package is:
1. `cd' to the directory containing the package's source code and type
`./configure' to configure the package for your system.
Running `configure' might take a while. While running, it prints
some messages telling which features it is checking for.
2. Type `make' to compile the package.
3. Optionally, type `make check' to run any self-tests that come with
the package.
4. Type `make install' to install the programs and any data files and
documentation.
5. You can remove the program binaries and object files from the
source code directory by typing `make clean'. To also remove the
files that `configure' created (so you can compile the package for
a different kind of computer), type `make distclean'. There is
also a `make maintainer-clean' target, but that is intended mainly
for the package's developers. If you use it, you may have to get
all sorts of other programs in order to regenerate files that came
with the distribution.
Compilers and Options
=====================
Some systems require unusual options for compilation or linking that the
`configure' script does not know about. Run `./configure --help' for
details on some of the pertinent environment variables.
You can give `configure' initial values for configuration parameters
by setting variables in the command line or in the environment. Here
is an example:
./configure CC=c99 CFLAGS=-g LIBS=-lposix
*Note Defining Variables::, for more details.
Compiling For Multiple Architectures
====================================
You can compile the package for more than one kind of computer at the
same time, by placing the object files for each architecture in their
own directory. To do this, you can use GNU `make'. `cd' to the
directory where you want the object files and executables to go and run
the `configure' script. `configure' automatically checks for the
source code in the directory that `configure' is in and in `..'.
With a non-GNU `make', it is safer to compile the package for one
architecture at a time in the source code directory. After you have
installed the package for one architecture, use `make distclean' before
reconfiguring for another architecture.
Installation Names
==================
By default, `make install' installs the package's commands under
`/usr/local/bin', include files under `/usr/local/include', etc. You
can specify an installation prefix other than `/usr/local' by giving
`configure' the option `--prefix=PREFIX'.
You can specify separate installation prefixes for
architecture-specific files and architecture-independent files. If you
pass the option `--exec-prefix=PREFIX' to `configure', the package uses
PREFIX as the prefix for installing programs and libraries.
Documentation and other data files still use the regular prefix.
In addition, if you use an unusual directory layout you can give
options like `--bindir=DIR' to specify different values for particular
kinds of files. Run `configure --help' for a list of the directories
you can set and what kinds of files go in them.
If the package supports it, you can cause programs to be installed
with an extra prefix or suffix on their names by giving `configure' the
option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
Optional Features
=================
Some packages pay attention to `--enable-FEATURE' options to
`configure', where FEATURE indicates an optional part of the package.
They may also pay attention to `--with-PACKAGE' options, where PACKAGE
is something like `gnu-as' or `x' (for the X Window System). The
`README' should mention any `--enable-' and `--with-' options that the
package recognizes.
For packages that use the X Window System, `configure' can usually
find the X include and library files automatically, but if it doesn't,
you can use the `configure' options `--x-includes=DIR' and
`--x-libraries=DIR' to specify their locations.
Specifying the System Type
==========================
There may be some features `configure' cannot figure out automatically,
but needs to determine by the type of machine the package will run on.
Usually, assuming the package is built to be run on the _same_
architectures, `configure' can figure that out, but if it prints a
message saying it cannot guess the machine type, give it the
`--build=TYPE' option. TYPE can either be a short name for the system
type, such as `sun4', or a canonical name which has the form:
CPU-COMPANY-SYSTEM
where SYSTEM can have one of these forms:
OS KERNEL-OS
See the file `config.sub' for the possible values of each field. If
`config.sub' isn't included in this package, then this package doesn't
need to know the machine type.
If you are _building_ compiler tools for cross-compiling, you should
use the option `--target=TYPE' to select the type of system they will
produce code for.
If you want to _use_ a cross compiler, that generates code for a
platform different from the build platform, you should specify the
"host" platform (i.e., that on which the generated programs will
eventually be run) with `--host=TYPE'.
Sharing Defaults
================
If you want to set default values for `configure' scripts to share, you
can create a site shell script called `config.site' that gives default
values for variables like `CC', `cache_file', and `prefix'.
`configure' looks for `PREFIX/share/config.site' if it exists, then
`PREFIX/etc/config.site' if it exists. Or, you can set the
`CONFIG_SITE' environment variable to the location of the site script.
A warning: not all `configure' scripts look for a site script.
Defining Variables
==================
Variables not defined in a site shell script can be set in the
environment passed to `configure'. However, some packages may run
configure again during the build, and the customized values of these
variables may be lost. In order to avoid this problem, you should set
them in the `configure' command line, using `VAR=value'. For example:
./configure CC=/usr/local2/bin/gcc
causes the specified `gcc' to be used as the C compiler (unless it is
overridden in the site shell script).
Unfortunately, this technique does not work for `CONFIG_SHELL' due to
an Autoconf bug. Until the bug is fixed you can use this workaround:
CONFIG_SHELL=/bin/bash /bin/bash ./configure CONFIG_SHELL=/bin/bash
`configure' Invocation
======================
`configure' recognizes the following options to control how it operates.
`--help'
`-h'
Print a summary of the options to `configure', and exit.
`--version'
`-V'
Print the version of Autoconf used to generate the `configure'
script, and exit.
`--cache-file=FILE'
Enable the cache: use and save the results of the tests in FILE,
traditionally `config.cache'. FILE defaults to `/dev/null' to
disable caching.
`--config-cache'
`-C'
Alias for `--cache-file=config.cache'.
`--quiet'
`--silent'
`-q'
Do not print messages saying which checks are being made. To
suppress all normal output, redirect it to `/dev/null' (any error
messages will still be shown).
`--srcdir=DIR'
Look for the package's source code in directory DIR. Usually
`configure' can determine that directory automatically.
`configure' also accepts some other, not widely useful, options. Run
`configure --help' for more details.

235
Makefile.am Normal file
View File

@ -0,0 +1,235 @@
# ts A90315 : LIBBURNIA_PKGCONFDIR is defined OS specific in acinclude.m4
# was: pkgconfigdir=$(libdir)/pkgconfig
pkgconfigdir=$(LIBBURNIA_PKGCONFDIR)
libincludedir=$(includedir)/libburn
lib_LTLIBRARIES = libburn/libburn.la
ACLOCAL_AMFLAGS = -I ./
## ========================================================================= ##
# Build libraries
libburn_libburn_la_LDFLAGS = \
-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)
libburn_libburn_la_LIBADD = $(LIBBURN_ARCH_LIBS) $(THREAD_LIBS)
libburn_libburn_la_SOURCES = \
libburn/async.c \
libburn/async.h \
libburn/back_hacks.h \
libburn/cdtext.c \
libburn/cleanup.c \
libburn/cleanup.h \
libburn/crc.c \
libburn/crc.h \
libburn/debug.c \
libburn/debug.h \
libburn/drive.c \
libburn/drive.h \
libburn/ecma130ab.c \
libburn/ecma130ab.h \
libburn/error.h \
libburn/file.c \
libburn/file.h \
libburn/init.c \
libburn/init.h \
libburn/libburn.h \
libburn/libdax_audioxtr.h \
libburn/libdax_audioxtr.c \
libburn/libdax_msgs.h \
libburn/libdax_msgs.c \
libburn/mmc.c \
libburn/mmc.h \
libburn/null.c \
libburn/null.h \
libburn/options.c \
libburn/options.h \
libburn/os.h \
libburn/read.c \
libburn/read.h \
libburn/sbc.c \
libburn/sbc.h \
libburn/sector.c \
libburn/sector.h \
libburn/sg.c \
libburn/sg.h \
libburn/source.h \
libburn/source.c \
libburn/spc.c \
libburn/spc.h \
libburn/structure.c \
libburn/structure.h \
libburn/toc.c \
libburn/toc.h \
libburn/transport.h \
libburn/util.c \
libburn/util.h \
libburn/write.c \
libburn/write.h
## libburn/sg-@ARCH@.c \
libinclude_HEADERS = \
libburn/libburn.h
install-exec-hook:
$(LIBBURNIA_LDCONFIG_CMD) "$(DESTDIR)$(libdir)" || echo 'NOTE: Explicit dynamic library configuration failed. If needed, configure manually for:' "$(DESTDIR)$(libdir)"
## ========================================================================= ##
## Build test applications
noinst_PROGRAMS = \
test/libburner \
test/offst_source \
test/telltoc \
test/dewav \
test/fake_au \
test/poll
bin_PROGRAMS = \
cdrskin/cdrskin
LIBBURN_EXTRALIBS = $(LIBBURN_ARCH_LIBS) $(THREAD_LIBS)
test_libburner_CPPFLAGS = -Ilibburn
test_libburner_LDADD = $(libburn_libburn_la_OBJECTS) $(LIBBURN_EXTRALIBS)
test_libburner_SOURCES = test/libburner.c
test_offst_source_CPPFLAGS = -Ilibburn
test_offst_source_LDADD = $(libburn_libburn_la_OBJECTS) $(LIBBURN_EXTRALIBS)
test_offst_source_SOURCES = test/offst_source.c
test_telltoc_CPPFLAGS = -Ilibburn
test_telltoc_LDADD = $(libburn_libburn_la_OBJECTS) $(LIBBURN_EXTRALIBS)
test_telltoc_SOURCES = test/telltoc.c
test_dewav_CPPFLAGS = -Ilibburn
test_dewav_LDADD = $(libburn_libburn_la_OBJECTS) $(LIBBURN_EXTRALIBS)
test_dewav_SOURCES = test/dewav.c
test_fake_au_CPPFLAGS =
test_fake_au_LDADD =
test_fake_au_SOURCES = test/fake_au.c
test_poll_CPPFLAGS = -Ilibburn
test_poll_LDADD = $(libburn_libburn_la_OBJECTS) $(LIBBURN_EXTRALIBS)
test_poll_SOURCES = test/poll.c
## cdrskin construction site - ts A60816 - B91026
cdrskin_cdrskin_CPPFLAGS = -Ilibburn
cdrskin_cdrskin_CFLAGS = -DCdrskin_libburn_1_5_2
# cdrskin_cdrskin_LDADD = $(libburn_libburn_la_OBJECTS) $(LIBBURN_EXTRALIBS)
# ts A80123, change proposed by Simon Huggins to cause dynamic libburn linking
cdrskin_cdrskin_LDADD = libburn/libburn.la $(LIBBURN_EXTRALIBS)
cdrskin_cdrskin_SOURCES = cdrskin/cdrskin.c cdrskin/cdrfifo.c cdrskin/cdrfifo.h cdrskin/cdrskin_timestamp.h
##
## Open questions: how to compute $timestamp and express -DX="$timestamp"
##
# "make clean" shall remove a few stubborn .libs directories
# which George Danchev reported Dec 03 2011.
# Learned from: http://www.gnu.org/software/automake/manual/automake.html#Clean
clean-local:
-rm -rf cdrskin/.libs test/.libs
## ========================================================================= ##
## Build documentation (You need Doxygen for this to work)
webhost = http://libburn-api.pykix.org
webpath = /
docdir = $(DESTDIR)$(prefix)/share/doc/$(PACKAGE)-$(VERSION)
doc: doc/html
doc/html: doc/doxygen.conf
if [ -f ./doc/doc.lock ]; then \
$(RM) -r doc/html; \
doxygen doc/doxygen.conf; \
fi
doc-upload: doc/html
scp -r $</* $(webhost):$(webpath)
## ts B00729
## Not by default any more.
## It is unclear who is supposed to create file ./doc/doc.lock
# all: doc
install-data-local:
if [ -f ./doc/doc.lock ]; then \
$(mkinstalldirs) $(docdir)/html; \
$(INSTALL_DATA) doc/html/* $(docdir)/html; \
fi
uninstall-local:
rm -rf $(docdir)
## ========================================================================= ##
# Indent source files
indent_files = \
$(libburn_libburn_la_SOURCES) \
$(test_poll_SOURCES)
indent: $(indent_files)
indent -bad -bap -nbbb -nbbo -nbc -bli0 -br -bls \
-cdw -ce -cli0 -ncs -nbfda -i8 -l79 -lc79 \
-lp -saf -sai -nprs -npsl -saw -sob -ss -ut \
-sbi0 -nsc -ts8 -npcs -ncdb -fca \
$^
.PHONY: indent
## ========================================================================= ##
# Extra things
nodist_pkgconfig_DATA = \
libburn-1.pc
# http://www.nada.kth.se/cgi-bin/info?(automake.info)Man%20pages
man_MANS = cdrskin/cdrskin.1
EXTRA_DIST = \
bootstrap \
libburn-1.pc.in \
version.h.in \
doc/comments \
doc/doxygen.conf.in \
doc/cookbook.txt \
doc/mediainfo.txt \
doc/cdtext.txt \
README \
AUTHORS \
CONTRIBUTORS \
COPYRIGHT \
cdrskin/README \
cdrskin/cdrecord_spy.sh \
cdrskin/compile_cdrskin.sh \
cdrskin/convert_man_to_html.sh \
cdrskin/changelog.txt \
cdrskin/cdrskin_eng.html \
cdrskin/wiki_plain.txt \
cdrskin/cleanup.h \
cdrskin/cleanup.c \
libburn/libburn.ver \
libburn/os-dummy.h \
libburn/os-freebsd.h \
libburn/os-linux.h \
libburn/os-libcdio.h \
libburn/os-solaris.h \
libburn/os-netbsd.h \
libburn/sg-dummy.c \
libburn/sg-freebsd.c \
libburn/sg-linux.c \
libburn/sg-libcdio.c \
libburn/sg-solaris.c \
libburn/sg-netbsd.c \
COPYING \
NEWS \
ChangeLog \
INSTALL \
$(man_MANS)

1
NEWS Normal file
View File

@ -0,0 +1 @@
nothing here now

847
README Normal file
View File

@ -0,0 +1,847 @@
------------------------------------------------------------------------------
libburnia-project.org
------------------------------------------------------------------------------
This all is under GPL.
(See GPL reference, our clarification and commitment at the end of this text)
------------------------------------------------------------------------------
libburnia-project.org
By Mario Danic <mario.danic@gmail.com> and Thomas Schmitt <scdbackup@gmx.net>
Copyright (C) 2006-2019 Mario Danic, Thomas Schmitt
Still containing parts of Libburn. By Derek Foreman <derek@signalmarketing.com>
and Ben Jansens <xor@orodu.net>
Copyright (C) 2002-2006 Derek Foreman and Ben Jansens
http://files.libburnia-project.org/releases/libburn-1.5.2.pl01.tar.gz
------------------------------------------------------------------------------
Build and Installation
From tarball
Obtain libburn-1.5.2.pl01.tar.gz, take it to a directory of your choice and do:
tar xzf libburn-1.5.2.pl01.tar.gz
cd libburn-1.5.2
./configure --prefix=/usr
make
To make libburn accessible for running and application development,
and to install the cdrecord compatibility binary cdrskin, do
(as Superuser):
make install
This procedure installs libburn.so.4 and cdrskin depending on it.
For a standalone cdrskin binary, see cdrskin/README.
A behavioral conflict is known between any burn software and demons like hald
which probe CD drives. This can spoil burn runs for CD-R or CD-RW.
You may have to keep your hald away from the drive. See for example
http://www.freebsd.org/gnome/docs/halfaq.html
From SVN
Our build system is based on autotools. For preparing the build of a SVN
snapshot you will need autotools of at least version 1.7.
Do in a directory of your choice:
svn co http://svn.libburnia-project.org/libburn/trunk libburn-svn
cd libburn-svn
./bootstrap
./configure --prefix=/usr
make
make install
Warning: The trunk might contain experimental features which might not
persist until next release.
Special ./configure options
make install on GNU/Linux will try to run program ldconfig with the library
installation directory as only argument. Failure to do so will not abort
installation. One may disable ldconfig by ./configure option:
--disable-ldconfig-at-install
In some situations Linux may deliver a better write performance to drives if
the track input is read with O_DIRECT (see man 2 open). The API call
burn_os_open_track_src() and the input readers of cdrskin and libburn fifo
can be told to use this peculiar read mode by:
--enable-track-src-odirect
But often libburn call burn_write_opts_set_dvd_obs(opts, 64*1024) will yield
even better performance in such a situation. 64k can be made default at
configure time by:
--enable-dvd-obs-64k
This may be combined with above --enable-track-src-odirect .
If it is desired that DVD DAO writing and stdio: writing get padded up to
a full write chunk of 32k or 64k, then use ./configure option:
--enable-dvd-obs-pad
Alternatively the transport of SCSI commands can be done via libcdio-0.83.
You may install it and re-run libburn's ./configure with option
--enable-libcdio
By use of a version script, the libburn.so library exposes no other function
names but those of the API definition in libburn/libburn.h.
If -Wl,--version-script=... makes problems with the local compiler, then
disable this encapsulation feature by
--disable-versioned-libs
Make sure to re-compile all source files after running ./configure
make clean ; make
make install
Linux only:
libburn tries to avoid a collision with udev's drive examination by waiting
0.1 seconds before opening the device file for a longer time, after udev
might have been alarmed by drive scanning activities.
The waiting time can be set at ./configure time with microsecond granularity.
E.g. 2 seconds:
CFLAGS="$CFLAGS -DLibburn_udev_wait_useC=2000000"
./configure ...options...
Waiting can be disabled by zero waiting time:
CFLAGS="$CFLAGS -DLibburn_udev_wait_useC=0"
Alternatively, libburn can try to be nice by opening the device file,
closing it immediately, waiting, and only then opening it for real:
CFLAGS="$CFLAGS -DLibburn_udev_extra_open_cyclE -DLibburn_udev_wait_useC=500000"
------------------------------------------------------------------------------
An important part of the project, libisofs, is hosted in a bzr repository at
launchpad.net :
bzr branch lp:libisofs
Another part the project, libisoburn, is hosted in the libburnia SVN, too:
svn co http://svn.libburnia-project.org/libisoburn/trunk libisoburn
See README files there.
------------------------------------------------------------------------------
Overview of libburnia-project.org
libburnia-project.org is an open-source software project for reading, mastering
and writing optical discs.
For now this means CD media, all DVD media, all BD media.
The project comprises of several more or less interdependent parts which
together strive to be a usable foundation for application development.
These are libraries, language bindings, and middleware binaries which emulate
classical (and valuable) Linux tools.
Currently it is supported on GNU/Linux with kernels >= 2.4,
on FreeBSD with ATAPI/CAM enabled in the kernel (see man atapicam),
on OpenSolaris (tested with kernel 5.11),
on NetBSD (tested with 6.1.3).
On other X/Open compliant systems there will only be pseudo drives, but no
direct MMC operation on real CD/DVD/BD drives.
For full ports to other systems we would need : login on a development machine
or a live OS on CD or DVD, advise from a system person about the equivalent
of Linux sg or FreeBSD CAM, volunteers for testing of realistic use cases.
We have a well tested code base for burning data and audio CDs, DVDs and BDs.
The burn API is quite comprehensively documented and can be used to build a
presentable application.
We have a functional application which emulates the core use cases of cdrecord
in order to prove that usability, and in order to allow you to explore
libburn's scope by help of existing cdrecord frontends.
ISO 9660 filesystems with Rock Ridge and Joliet extensions can be created
and manipulated quite freely. This capability together with our burn capability
makes possible a single binary application which covers all steps of image
composition, updating and writing. Quite unique in the Linux world.
The project components (list subject to growth, hopefully):
- libburn is the library by which preformatted data get onto optical media.
It uses either /dev/sgN (e.g. on kernel 2.4 with ide-scsi) or
/dev/srM or /dev/hdX (e.g. on kernel 2.6).
libburn is the foundation of our cdrecord emulation. Its code is
independent of cdrecord. Its DVD capabilities are learned from
studying the code of dvd+rw-tools and MMC-5 specs. No code but only
the pure SCSI knowledge has been taken from dvd+rw-tools, though.
- libisofs is the library to pack up hard disk files and directories into a
ISO 9660 disk image. This may then be brought to CD via libburn.
An own ISO 9660 extension stores ACLs, xattr, and MD5 of file
content.
- libisoburn is an add-on to libburn and libisofs which coordinates both and
also can grow ISO-9660 filesystem images on multi-session media
as well as on overwriteable media via the same API.
All media peculiarities are handled automatically.
It also contains the methods of command oriented application
xorriso and offers them via a C language API.
- cdrskin is a limited cdrecord compatibility wrapper for libburn.
cdrecord is a powerful GPL'ed burn program included in Joerg
Schilling's cdrtools. cdrskin strives to be a second source for
the services traditionally provided by cdrecord. Additionally it
provides libburn's DVD capabilities, where only -sao is compatible
with cdrecord.
cdrskin does not contain any bytes copied from cdrecord's sources.
Many bytes have been copied from the message output of cdrecord
runs, though.
See cdrskin/README for more.
- xorriso is an application of all three libraries which creates, loads,
manipulates and writes ISO 9660 filesystem images with
Rock Ridge extensions. Manipulation is not only adding or
overwriting of files but also deleting, renaming, attribute
changing, incremental backups, activating boot images, and
extracting of files from ISO images to disk. There is also a
sparse emulation of cdrecord and a more laborate one of mkisofs.
All features of xorriso are also available via a C language API
of libisoburn.
A static compilation of xorriso and the libraries is dedicated
to the GNU Operating System. See xorriso/README_gnu_xorriso .
- "test" is a collection of application gestures and examples given by the
authors of the library features. The burn API example of libburn
is named test/libburner.c . The API for media information inquiry is
demonstrated in test/telltoc.c .
Explore these examples if you look for inspiration.
We strive to be a responsive upstream.
Our libraries are committed to maintain older feature sets in newer versions.
This applies to source code headers (API) as well as to linkable objects (ABI).
The only exception from this rule is about non-release versions x.y.*[13579]
which are allowed to introduce new features, change those new features in
any way and even may revoke such new features before the next release of
x.y.*[02468]. As soon as it is released, a feature is promised to persist.
SONAMES:
libburn.so.4 (since 0.3.4, March 2007),
libisofs.so.6 (since 0.6.2, February 2008),
libisoburn.so.1 (since 0.1.0, February 2008).
Applications must use 64 bit off_t. E.g. by defining
#define _LARGEFILE_SOURCE
#define _FILE_OFFSET_BITS 64
or take special precautions to interface with the libraries by 64 bit integers
where the .h files prescribe off_t. To reduce libburn's off_t size to 32 bit
will keep it from processing tracks of more than 2 GB size.
------------------------------------------------------------------------------
Project history as far as known to me:
- Founded in 2002 as it seems. See mailing list archives
http://lists.freedesktop.org/archives/libburn/
The site of this founder team is reachable and offers download of a
(somewhat outdated) tarball and from CVS :
http://icculus.org/burn/
Copyright holders and most probably founders:
Derek Foreman and Ben Jansens.
- I came to using libburn in 2005. Founded the cdrskin project and submitted
necessary patches which were accepted or implemented better. Except one
remaining patch which prevented cdrskin from using vanilla libburn from CVS.
The cdrskin project site is reachable and offers download of the heavily
patched (elsewise outdated) tarball under the name cdrskin-0.1.2 :
http://scdbackup.sourceforge.net/cdrskin_eng.html
It has meanwhile moved to use vanilla libburn.pykix.org , though.
Version 0.1.4 constitutes the first release of this kind.
- In July 2006 our team mate Mario Danic announced a revival of libburn
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 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:
http://lists.freedesktop.org/archives/libburn/2006-August/000446.html
http://mailman-mail1.webfaction.com/pipermail/libburn-hackers/2006-August/000024.html
- Mid August 2006 project cdrskin established a branch office in
libburn.pykix.org so that all maintainers of our tools have one single place
to get the current (at least slightely) usable coordinated versions of
everything.
Project cdrskin will live forth independendly for a while but it is committed
to stay in sync with libburn.pykix.org (or some successor, if ever).
cdrskin is also committed to support icculus.org/burn if the pending fork
is made reality by content changes in that project. It will cease to maintain
a patched version of icculus.org/burn though. Precondition for a new
release of cdrskin on base of icculus.org/burn would be the pending
"whitelist patch" therefore.
I would rather prefer if both projects find consense and merge, or at least
cooperate. I have not given up hope totally, yet.
I, personally, will honor any approach.
- 2nd September 2006 the decision is made to strive for a consolidation of
copyright and a commitment to GPL in a reasonable and open minded way.
This is to avoid long term problems with code of unknown origin and
with finding consense among the not so clearly defined group of copyright
claimers and -holders.
libisofs is already claimed sole copyright Mario Danic.
cdrskin and libburner are already claimed sole copyright Thomas Schmitt.
Rewrites of other components will follow and concluded by claiming full
copyright within the group of libburn.pykix.org-copyright holders.
- 16th September 2006 feature freeze for release of libburn-0.2.2 .
- 20th September 2006 release of libburn-0.2.2 .
- 26th October 2006 feature freeze for cdrskin-0.2.4 based on libburn-0.2.3 .
This version of cdrskin is much more cdrecord compatible in repect
to drive addressing and audio features.
- 30th October 2006 release of cdrskin-0.2.4 .
- 13th November 2006 splitting releases of libburn+cdrskin from libisofs.
- 24th November 2006 release of libburn-0.2.6 and cdrskin-0.2.6 . cdrskin has
become suitable for unaware frontends as long as they perform only the core
of cdrecord use cases (including open-ended input streams, audio, and
multi-session).
- 28th November 2006 the umbrella project which encloses both, libisofs and
libburn, is now called libburnia. For the origin of this name, see
http://en.wikipedia.org/wiki/Liburnians .
- 16th January 2007 release of libburn-0.3.0 and cdrskin-0.3.0 . Now the scope
is widened to a first class of DVD media: overwriteable single layer types
DVD-RAM, DVD+RW, DVD-RW. This is not a cdrecord emulation but rather inspired
by dvd+rw-tools' "poor man" writing facility for this class of media.
Taking a bow towards Andy Polyakov.
- 11th February 2007 version 0.3.2 covers sequential DVD-RW and DVD-R with
multi-session and with DAO.
- 12th March 2007 version 0.3.4 supports DVD+R and thus covers all single layer
DVD media. Code for double layer DVD+/-R is implemented but awaits a tester
yet.
- 23th April 2007 version 0.3.6 follows the unanimous opinion of Linux kernel
people that one should not use /dev/sg on kernel 2.6.
- 31st July 2007 version 0.3.8 marks the first anniversary of libburn revival.
We look back on improved stability, a substantially extended list of media
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 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.
- 26th Januar 2008 version 0.4.2 rectifies the version numbering so that we
reliably release libburn.so.4 as should have been done since libburn-0.3.2.
cdrskin now is by default linked dynamically and does a runtime check
to ensure not to be started with a libburn which is older than itself.
- 3rd Feb 2008 libisofs-0.2.x (.so.5) has been deprecated.
- 14th Feb 2008 libisofs-0.6.2 permanently replaces the old libisofs-0.2.x.
It is the first release of new libisofs.so.6 which will guarantee future
API/ABI compatibility for its whole feature set.
- 15th Feb 2008 libisoburn-0.1.0 (.so.1) coordinates libisofs and libburn for
the purpose of ISO image reading and writing. It emulates multi-session on
overwriteable media. Application xorriso makes use of all three libraries.
- 8th Apr 2008 libburn-0.4.4 has proven to be capable of burning to DVD+R/DL
and read performance on disk file pseudo-drives has been improved.
- 27th Apr 2008 libisofs-0.6.4 can now read data file content from images
and can map pieces of disk files onto image files. Image directory iteration
has been enhanced. Input data streams and extended information have been
exposed in the API to enable future development.
- 29th Apr 2008 libisoburn-0.1.4 was made more efficient with reading of
image tree nodes. It now depends on libisofs-0.6.4 and libburn-0.4.4.
xorriso makes use of new libisofs features by performing incremental
updates of directory trees and by cutting oversized data files into
pieces. A primitive single session emulation of cdrecord and mkisofs is
provided.
- 10th May 2008 libburn-0.4.6 supports formatting and writing of BD-RE,
full nominal speed for DVD-RAM and BD-RE. cdrskin has a unified blank
type with automatic media state recognition.
- 17th May 2008 an old bug with DVD-RAM and now with BD-RE is fixed by
libburn-0.4.8. So libisoburn can now perform emulation of multisession
on those media.
- 19th May 2008 libisoburn-0.1.6 brings better table-of-content emulation
on overwriteble media and disk files.
- 1st Jun 2008 libisofs-0.6.6 fixes some problems around device files.
- 3rd Jun 2008 libisoburn-0.1.8 fixes a bug with overwriteable media.
- 23rd Jun 2008 libisoburn-0.2.0 introduces extraction of files from
ISO images.
- 16th Jul 2008 libburn-0.5.0 handles systems with no /dev/sr* but only
/dev/scd*.
- 19th Jul 2008 libisoburn/xorriso-0.2.2 can do multi-session in mkisofs
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 addressable. Enumeration is enhanced by examining
/proc/sys/dev/cdrom/info.
- 24th Aug 2008 libisoburn/xorriso-0.2.4 introduces a media readability check
with data retrieval option.
- 18th Sep 2008 libisofs-0.6.8 supports ISO 9660 Level 3 which can represent
very large data files in the image.
- 20th Sep 2008 libisoburn/xorriso-0.2.6 takes into respect the new Level 3
capabilities of libisofs.
- 6th Oct 2008 libburn-0.5.4 adjusts the changes of 0.5.2 to the needs of
Linux kernel 2.4 and introduces human readable SCSI error messages.
- 6th Oct 2008 libisofs-0.6.10 fixes two bugs which prevented adding and
manipulation of ISOLINUX boot images.
- 15th Oct 2008 libisoburn/xorriso-0.2.8 can activate and maintain an
ISOLINUX boot image by an EL Torito boot record.
- 12th Nov 2008 libburn-0.5.6 fixes usage of freed memory by the fifo thread
of an aborted burn run.
- 26th Nov 2008 libisofs-0.6.12 can produce a ISOLINUX isohybrid MBR on the fly
and can produce ISO images which resemble old mkisofs images.
- 2nd Dec 2008 libisoburn-0.3.0. xorriso now is ready for exotic character
sets, for legacy FreeBSD systems which expect an outdated Rock Ridge
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 weird CD table-of-content
and improves BD-RE formatting.
- 9th Dec 2008 Our project received a donation from Thomas Weber.
- 2nd Jan 2009 libburn-0.6.0 learned to format BD-R and write to either
formatted or unformatted BD-R.
- 6th Jan 2009 libisoburn-0.3.2. xorriso can produce and execute commands for
mounting older sessions from all kinds of media. Pseudo-drives outside the
/dev/ tree can be addressed without prefix "stdio:".
- 20th Feb 2009 libburn-0.6.2 source release now compiles out of the box
on FreeBSD.
- 28 Feb 2009 libisofs-0.6.14 can record ACLs and Extended Attributes xattr
in its ISO images.
- 01 Mar 2009 libisoburn-0.3.4. xorriso makes use of the ACL and xattr
capabilities provided by libisofs for xorriso backup features.
- 11 Mar 2009 libisofs-0.6.16 of libisofs fixes two bugs which on Solaris
prevented to navigate the ISO images by ".." and to recognize the Rock Ridge
extensions of ISO images. The ban to build libisofs on operating systems
other than Linux and FreeBSD has been lifted.
- 13 Mar 2009 libburn-0.6.4 got a dummy adapter for SCSI/MMC command transport.
It will show no drives and thus libburn will only be able to perform
operations on "stdio:" pseudo drives. Nevertheless this was precondition
to lift the ban to build libburn on operating systems other than Linux
and FreeBSD.
- 16 Mar 2009 libisoburn-0.3.6: xorriso uses RRIP version 1.10 as default
in order to be mountable where mkisofs images are mountable.
- 17 Apr 2009 libisofs-0.6.18 introduces content filtering of data files.
Built-in filters implement compression to formats gzip and zisofs. External
filter processes can perform arbitrary data conversions like encryption.
- 19 Apr 2009 libisoburn-0.3.8 makes use of the new libisofs capability to
perform content filtering of data files.
- 08 May 2009 libburn-0.6.6 fixes a bug with aborting on broken output pipe
and a bug with device scan on FreeBSD.
- 31 May 2009 libisofs-0.6.20 can record hard link relations in ISO images
and offers support with restoring them to disk. Current Linux kernels will
mount images with such hard links but will attribute a unique inode number
to each file.
- 28 Jun 2009 libisoburn-0.4.0: xorriso can record and restore hard link
relations of files. Performance of data reading has been improved. Option
-find now supports logical operators with its tests.
- 14 Jul 2009 libburn-0.6.8 fixes bugs and shortcommings with old MMC-1 drives
and with large SCSI bus numbers as handed out by Linux for USB drives.
- 20 Jul 2009 libisoburn-0.4.0.pl01 fixes a regression in xorriso which caused
data loss in older sessions if xorriso was used underneath growisofs.
Affected are releases since libisoburn-0.3.2 in january 2009.
- 25 Aug 2009 libisofs-0.6.22 can record MD5 checksums for the whole session
and for each single data file. Checksum tags can be used to verify superblock
and directory tree before importing them.
- 27 Aug 2009 libburn-0.7.0 learned to calm down a drive and to inquire its
supported profiles. It works around some pitfalls with U3 enhanced memory
sticks which emulate a CD-ROM.
- 27 Aug 2009 libisoburn-0.4.0.pl00 can record MD5 checksums by which one may
verify the session or single data files in the image. When comparing image
files with files in the local filesystem, the MD5 sums avoid the need for
reading file content from the image.
- 22 Sep 2009 libisoburn-0.4.0.pl01 fixes a bug in xorriso option -cut_out.
- 08 Oct 2009 libisofs-0.6.24 fixes a bug which could cause the loss of blanks
in file names when a new session got added to an ISO image. With names
shorter than 251 characters this happened only to trailing blanks.
- 08 Oct 2009 libisoburn-0.4.0.pl02 fixes bugs with xorriso option -for_backup,
with xorrisofs -help, and with xorrecord -help.
- 12 Oct 2009 libburn-0.7.2 fixes a bug with CD TAO multi-track dummy sessions.
It can retrieve media product info and can process track input which was
prepared for CD-ROM XA Mode 2 Form 1. cdrskin now performs option -minfo.
- 28 Oct 2009 libisoburn-0.4.4 fixes a bug with cdrecord emulation and
introduces new information options about media type and ISO image id strings.
On Linux it helps with mounting two sessions of the same media
simultaneously.
- 12 Nov 2009 libburn-0.7.2.pl01 works around problems with Pioneer DVR-216D.
DVD-R runs made the drive stuck. Ejecting the tray did not work properly.
- 06 Dec 2009 libburn-0.7.4 works around problems with newer DVD burners,
provides throughput enhancements with hampered busses on Linux, and new
API calls to log SCSI commands and to control the libburn fifo.
- 09 Dec 2009 libisoburn-0.4.6 now offers performance tuning of output to DVD
drives or disk files.
- 26 Dec 2009 libburn-0.7.4.pl01 fixes the release tarball which was lacking
the files of the generic system adapter for X/Open.
- 29 Dec 2009 Our project received a donation for purchasing a fine small
computer which shall serve as OS farm for development and support.
- 20 Jan 2010 Version 0.6.26 of libisofs fixes minor bugs and shall enhance
portability.
- 22 Jan 2010 libburn-0.7.6 has an improved system adapter for FreeBSD,
fixes bugs about the generic X/Open system adapter, and can use
libcdio >= 0.83 as SCSI transport facility.
- 10 Feb 2010 libisofs-0.6.28 fixes a regression about bootable images which
was introduced by version 0.6.22 in August 2009.
- 23 Feb 2010 libisoburn-0.5.0 marks the transition of the xorriso standalone
version to an official GNU project. The name changed to "GNU xorriso" and its
license is now GPLv3+.
The licenses of libburnia libraries and applications are not affected by
this change.
- 10 Mar 2010 libburn-0.7.8 fixes bugs and improves the built-in abort handler
on FreeBSD.
- 30 Mar 2010 Release 0.5.2 of libisoburn provides xorriso documentation in
GNU Texinfo format with embedded extra data to derive a full man page.
- 09 Apr 2010 libburn-0.8.0 now works with ahci driver on FreeBSD 8-STABLE.
- 03 May 2010 Version 0.6.32 of libisofs is able to create ISO images with
multiple boot images. All boot catalog parameters described in El-Torito
specs can be set and inquired. This was needed to use GRUB boot images
for EFI.
- 04 May 2010 Release 0.5.6.pl00 of libisoburn makes use of the new libisofs
capabilities about boot images.
- 11 Jun 2010 libburn-0.8.2 now works on Solaris.
- 14 Jun 2010 By release 0.5.8.pl00 of libisoburn, xorriso becomes a public C
language API of libisoburn. The emulations of mkisofs and cdrecord have
been enhanced.
- Tue Jun 29 2010 Version 0.6.34 of libisofs provides new features about
hiding file names from directory trees.
- Wed Jun 30 2010 libburn-0.8.4 removes some restrictions on operating
systems other than Linux and FreeBSD.
- Fri Jul 02 2010 Release 0.6.0.pl00 of libisoburn adds more options to the
mkisofs emulation of xorriso. It also fixes minor bugs and shortcommings.
- Wed Sep 15 2010 Version 0.6.36 of libisofs can produce ISO images which
bear a partiton 1 with non-zero start address. They can be mounted from
USB stick via the main device file (e.g. /dev/sdb) as well as via the
partition device file (e.g. /dev/sdb1).
- Fri Sep 17 2010 libburn-0.8.6 lifts the test reservation on DVD-R DL media.
- Sat Sep 18 2010 Release 0.6.2.pl00 of libisoburn introduces a partition
with non-zero offset for ISO 9660 images on USB sticks, improves mkisofs
emulation, and fixes a regression which existed since version 0.4.2.
- Wed Oct 20 2010 libburn-0.8.8 can report the used amount of BD spare blocks.
- Sat Oct 23 2010 Version 0.6.38 of libisofs can use libjte to produce jigdo
files along with the ISO image. Further filesystem images may be appended
as MBR partitions 1 to 4. The capability was added to produce boot blocks
for computers with MIPS CPU.
- Tue Oct 26 2010 Release 0.6.4.pl00 of libisoburn and xorriso makes use of
the new libisofs capabilities.
- Wed Dec 08 2010 libburn-0.9.0 fixes a regression with SCSI command logging.
- Fri Dec 10 2010 Version 0.6.40 of libisofs makes the prediction of the
emerging image size less expensive and is able to make images bootable
for SUN SPARC systems.
- Sun Dec 12 2010 Release 0.6.6.pl00 of libisoburn and xorriso can read ISO
images which were copied to a different start address than they were prepared
for.
- Mon Jan 17 2011 we go for release 1.0.0. This does not indicate a
technological overhaul but shall emphasize the maturity of the software.
libisofs-1.0.0 fixes a bug about the length of ECMA-119 directory names and
is ready to store untranslated ECMA-119 names (violating the specs).
libburn-1.0.0.pl00 is now willing to create stdio-drive files with
rw-permissions for all, if umask really asks for it. cdrskin now refuses
to burn if the foreseeable size exceeds media capacity
libisoburn-1.0.0.pl00 can now create an ISO 9660:1999 directory tree,
improved the emulation fidelity of command -as mkisofs, lowered the default
abort threshold for xorriso batch mode, and increased that threshold for
xorriso dialog mode.
- Wed Feb 23 2011 release 1.0.2:
libisofs fixes several bugs and introduces the capability to copy files
inside the ISO filesystem.
libburn removed a compilation obstacle on Solaris 9 and improved recognition
of stdio pseudo-drives.
libisoburn and xorriso fix bugs and make use of the new libisofs capability.
xorriso improves its mkisofs emulation.
- Thu Mar 10 2011 release 1.0.4:
Several bugs were fixed in the libraries and in the mkisofs emulation of
xorriso. This emulation xorrisofs has now an own man page and info document.
- Sat Apr 09 2011 release 1.0.6:
libburn refined its representation of emulated drives. The size alignment
of DVD DAO is now 2 kB rather than 32 kB. libisofs produces Joliet names of
up to 103 characters. xorriso fixes two bugs and makes use of the library
improvements.
- Thu Apr 14 2011 release libisoburn-1.0.8:
A bug in the mkisofs emulation of xorriso could cause options to be ignored.
The problem was freshly introduced with libisoburn-1.0.6.
- Fri May 13 2011 release libisofs-1.0.8:
Fixes a few rarely occurring bugs that have been found during the last month.
- Sat Jun 18 2011 release 1.1.0:
The consumption of stack memory was reduced. Statical program analysis found
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:
libburn-1.1.0 compiled only on Linux, FreeBSD, and Solaris, but not on
other X/Open compliant systems.
- Fri Jul 08 2011 release libisofs-1.1.2 and libisoburn-1.1.2:
A severe regression was fixed in libisoburn and xorriso, which was introduced
with version 1.0.6. It caused ISO 9660 images to be unreadable if they were
written to a write-only random-access file. E.g. by: xorrisofs ... >image.iso
- Mon Aug 08 2011 release 1.1.4:
Several bugs were fixed in libburn. The most severe of them prevented xorriso
on some drives from burning mountable ISO 9660 images to CD media.
New means to list drives by their udev symbolic links help to deal with
the non-persistent drive addresses on modern GNU/Linux.
- Tue Sep 27 2011 release 1.1.6:
libisoburn now comes with a test suite. See releng/README. Bugs were fixed
in several rarely used features. Processing of ACL and extattr was enabled
on FreeBSD. Workarounds try to cope with vanishing udev links on GNU/Linux.
- Mon Nov 21 2011 release libburn-1.1.8 and libisoburn-1.1.8:
libburn avoids to close and open drive device files while operating on them.
xorriso emulation mode xorrecord now has an own manual. libburn and xorriso
were prepared to operate on qemu virtio-blk-pci devices.
- Sat Jan 28 2012 release 1.2.0:
libburn has learned to read and write CD-TEXT with CD SAO audio sessions.
It can now read CDRWIN .cue files which define pure audio or pure data
sessions. libisofs and libisoburn improved timestamp handling. Several
minor bugs were fixed.
- Mon Apr 02 2012 release 1.2.2:
The handling of intentional deviations from ECMA-119 specifications has
been improved in libisofs. libisoburn and xorriso now make use of these
improvements. Some rarely occurring bugs have been fixed.
- Fri Jul 20 2012 release 1.2.4:
libburn and libisofs got some rarely occurring bugs fixed. libisofs learned
to produce HFS+ metadata and Apple Partition Map. The capabilities of
isohybrid options --efi and --mac have been implemented (GPT and APM).
- Tue Jan 08 2013 release 1.2.6:
Small improvements were made in libburn. Minor bugs were fixed in the
libraries. xorriso improved its capabilities to serve the needs of frontend
programs. A proof of concept for a GUI frontend has been implemented:
xorriso-tcltk
- Mon Mar 18 2013 release 1.2.8:
Some rarely occurring bugs were fixed in libisofs and libburn. libburn's
handling of incomplete sessions has been improved. xorriso's mkisofs
emulation learned to set El Torito section id strings.
- Fri May 17 2013 release 1.3.0:
Several bugs were fixed in the libraries and in xorriso. The recently
introduced new boot preparation capabilities have been tested. New
boot preparation options for GRUB2 were added.
- Fri May 31 2013 patch release libburn-1.3.0.pl01:
cdrskin -msinfo on DVD and BD reported as old session start the same
number as the next writable address.
Regression introduced by version 1.2.8.
- Fri Aug 07 2013 release 1.3.2:
cdrskin has acquired the capability to copy audio tracks to .wav files.
It can extract CD-TEXT in a form that is readable for humans and for
cdrskin itself. Several small bugs were fixed in xorriso. Its capabilities
to serve frontend programs in dialog mode have been improved.
- Thu Dec 12 2013 release 1.3.4:
A long standing hidden bug was fixed, which affected inspection of
unformatted DVD+RW.
xorriso now by default puts EL Torito boot images to low block addresses.
It can report and set read speeds. Several rarely occurring bugs were fixed.
- Tue Mar 04 2014 release 1.3.6:
libburn learned to operate optical drives and media on NetBSD. libisofs got
a bug fix about HFS+ and enhancements about character set conversion.
Minor bugs were fixed in libisoburn. xorriso can now find files with names
which cannot be represented unchanged in ECMA-119, Joliet, or HFS+.
- Sat Jun 28 2014 release 1.3.8:
libburn got several bugs fixed. libisofs offers new API calls for inspection
of boot sectors in ISO 9660 filesystems. xorriso improved its support for
NetBSD, offers new features with command -find, and a command to extract
ISO 9660 file content onto standard output or into filter processes.
- Sun May 17 2015 release 1.4.0:
This release is mainly about bug fixes and a new feature of xorriso to
propose commands or as_mkisofs options which can reproduce the boot
equipment of the loaded ISO filesystem.
- Sat Nov 28 2015 release 1.4.2:
libburn got some bugs fixed and learned to inquire the drive serial number.
libisofs now sorts data file content by ECMA-119 file names for better
reproducability of ISO content. Rock Ridge filenames may be restricted to
lengths between 64 and 255 bytes. If needed, a qualified truncation happens.
xorriso now can replay boot settings when modifying ISO filesystems.
In order to avoid clogging of concurrent Linux SG_IO, xorriso got command
-modesty_on_drive to enable an old workaround from IDE master/slave days.
The source code underwent a scan by Coverity. About 150 code changes
resulted, but no easy-to-trigger bugs were found.
- Fri Jan 29 2016 patch release libburn-1.4.2.pl01:
cdrskin did not work with "-" (stdin) as input.
Regression introduced by version 1.4.2.
- Fri Jul 01 2016 release 1.4.4:
The capability to use Linux /dev/sg was revived in order to circumvent the
sr_mutex lock which hampers concurrent use of optical drives via SG_IO.
libisofs now can use appended partitions by El Torito, avoiding the need
for duplicate EFI System Partition images.
Several bugs have been fixed.
- Fri Sep 16 2016 release 1.4.6:
libburn now operates optical drives on OpenBSD. libisofs makes pseudo-random
id generation reproducible by relating it to the volume date.
xorriso interprets environment variable SOURCE_DATE_EPOCH of
reproducible-builds.org to prepare a default setting which leads to identical
ISO images on identical input and identical constant options.
Several moderately embarrassing bugs have been fixed.
- Tue Sep 12 2017 release 1.4.8:
libburn now refuses to write to SRM+POW formatted BD-R, because it would
spoil them. libisofs got several bugs fixed and offers new API calls to
support new xorriso features. libisoburn and xorriso offer more detail
control with particular boot sector types. New bugs and a regression from
version 1.4.4 were fixed.
- Sat Sep 15 2018 release 1.5.0
libisofs now can record all xattr namespaces, user defined padding was moved
after appended partitions. libisoburn and xorriso make use of the new xattr
capability of libisofs.
All three libraries got some rarely triggered bugs fixed.
- Sat Oct 26 2019 release 1.5.2
The libraries are now ready for building out-of-source. libisofs got minor
API extensions. libburn got a bug fixed which spoiled burn runs on
some MATSHITA laptop drives. It is now able to list all features which
the drive announces. xorriso can now set GPT type GUIDs with appended
partitions and the ISO partition.
All three libraries got some rarely triggered bugs fixed.
- Mon Nov 25 2019 patch release 1.5.2.pl01
cdrskin did not properly burn multiple tracks. Track 1 was slow and burning
stalled before track 2. Regression introduced by 1.5.0.
------------------------------------------------------------------------------
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License version 2 or later
as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
------------------------------------------------------------------------------
Clarification in my name and in the name of Mario Danic, upcoming copyright
holders on toplevel of libburnia. To be fully in effect after the remaining
other copyrighted code has been replaced by ours and by copyright-free
contributions of our friends:
------------------------------------------------------------------------------
We, the copyright holders, agree on the interpretation that dynamical linking
of our libraries constitutes "use of" and not "derivation from" our work in
the sense of GPL, provided those libraries are compiled from our unaltered
code or from altered code published under GPL.
So we will not raise legal protest if you link our libraries dynamically with
applications which are not under GPL, or if you distribute our libraries
and application tools in binary form, as long as you fulfill the usual
condition of GPL to offer a copy of their source code -altered or unaltered-
under GPL.
We ask you politely to use our work in open source spirit
and with the due reference to the entire open source community.
If there should really arise the case where above clarification
does not suffice to fulfill a clear and neat request in open source
spirit that would otherwise be declined for mere formal reasons,
only in that case we will duely consider to issue a special license
covering only that special case.
It is the open source idea of responsible freedom which will be
decisive and you will have to prove that you exhausted all own
means to qualify for GPL.
For now we are firmly committed to maintain one single license: GPL.
signed: Mario Danic, Thomas Schmitt
Agreement joined later by: Vreixo Formoso

172
acinclude.m4 Normal file
View File

@ -0,0 +1,172 @@
AC_DEFUN([LIBBURNIA_SET_FLAGS],
[
case $target_os in
freebsd* | netbsd*)
LDFLAGS="$LDFLAGS -L/usr/local/lib"
CPPFLAGS="$CPPFLAGS -I/usr/local/include"
;;
esac
])
AC_DEFUN([TARGET_SHIZZLE],
[
ARCH=""
LIBBURNIA_PKGCONFDIR="$libdir"/pkgconfig
AC_MSG_CHECKING([target operating system])
LIBBURNIA_LDCONFIG_CMD="echo 'No ldconfig run performed. If needed, configure manually for:'"
case $target in
*-*-linux*)
ARCH=linux
LIBBURN_ARCH_LIBS=
LIBBURNIA_LDCONFIG_CMD=ldconfig
;;
*-*-freebsd*)
ARCH=freebsd
LIBBURN_ARCH_LIBS=-lcam
LIBBURNIA_PKGCONFDIR=$(echo "$libdir" | sed 's/\/lib$/\/libdata/')/pkgconfig
;;
*-kfreebsd*-gnu*)
ARCH=freebsd
LIBBURN_ARCH_LIBS=-lcam
;;
*-solaris*)
ARCH=solaris
LIBBURN_ARCH_LIBS=-lvolmgt
;;
*)
ARCH=
LIBBURN_ARCH_LIBS=
# AC_ERROR([You are attempting to compile for an unsupported platform])
;;
esac
AC_MSG_RESULT([$ARCH])
])
dnl LIBBURN_ASSERT_VERS_LIBS is by Thomas Schmitt, libburnia project
dnl It tests whether -Wl,--version-script=... works with the compiler
AC_DEFUN([LIBBURN_ASSERT_VERS_LIBS],
[
libburnia_save_LDFLAGS="$LDFLAGS"
LDFLAGS="$LDFLAGS -Wl,--version-script=$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 = xyes
then
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
dnl
AC_DEFUN([LIBBURNIA_SET_PKGCONFIG],
[
### for testing --enable-libdir-pkgconfig on Linux
### LIBBURNIA_PKGCONFDIR="$libdir"data/pkgconfig
if test "x$LIBBURNIA_PKGCONFDIR" = "x$libdir"/pkgconfig
then
dummy=dummy
else
AC_ARG_ENABLE(libdir-pkgconfig,
[ --enable-libdir-pkgconfig Install to $libdir/pkgconfig on any OS, default=no],
, enable_libdir_pkgconfig="no")
AC_MSG_CHECKING([for --enable-libdir-pkgconfig])
if test "x$enable_libdir_pkgconfig" = xyes
then
LIBBURNIA_PKGCONFDIR="$libdir"/pkgconfig
fi
AC_MSG_RESULT([$enable_libdir_pkgconfig])
fi
libburnia_pkgconfig_override="no"
AC_ARG_ENABLE(pkgconfig-path,
[ --enable-pkgconfig-path=DIR Absolute path of directory for libisofs-*.pc],
libburnia_pkgconfig_override="yes" , enable_pkgconfig_path="none")
AC_MSG_CHECKING([for overridden pkgconfig directory path])
if test "x$enable_pkgconfig_path" = xno
then
libburnia_pkgconfig_override="no"
fi
if test "x$enable_pkgconfig_path" = x -o "x$enable_pkgconfig_path" = xyes
then
libburnia_pkgconfig_override="invalid argument"
fi
if test "x$libburnia_pkgconfig_override" = xyes
then
LIBBURNIA_PKGCONFDIR="$enable_pkgconfig_path"
AC_MSG_RESULT([$LIBBURNIA_PKGCONFDIR])
else
AC_MSG_RESULT([$libburnia_pkgconfig_override])
fi
AC_SUBST(LIBBURNIA_PKGCONFDIR)
dnl For debugging only
### AC_MSG_RESULT([LIBBURNIA_PKGCONFDIR = $LIBBURNIA_PKGCONFDIR])
])
dnl LIBBURNIA_CHECK_ARCH_LIBS is by Thomas Schmitt, libburnia project
dnl It tests whether the OS dependent libraries are available.
dnl With libisoburn they are needed only for the case that indirect linking
dnl does not work. So it is worth a try to omit them.
dnl $1 = "mandatory" or "optional" define the action if test linking fails.
AC_DEFUN([LIBBURNIA_CHECK_ARCH_LIBS],
[
libburnia_save_LIBS="$LIBS"
if test "x$LIBBURN_ARCH_LIBS" = x
then
dummy=dummy
else
LIBS="$LIBS $LIBBURN_ARCH_LIBS"
AC_TRY_LINK([#include <stdio.h>], [printf("Hello\n");],
[archlibs_test="yes"], [archlibs_test="no"])
LIBS="$libburnia_save_LIBS"
if test x$archlibs_test = xno
then
if test x"$1" = xmandatory
then
echo >&2
echo "FATAL: Test linking with mandatory library options failed: $LIBBURN_ARCH_LIBS" >&2
echo >&2
(exit 1); exit 1;
else
echo "disabled linking with $LIBBURN_ARCH_LIBS (because not found)"
LIBBURN_ARCH_LIBS=""
fi
else
echo "enabled linking with $LIBBURN_ARCH_LIBS"
fi
fi
])
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
AH_TEMPLATE([Libburn_use_sg_dummY],
[Define to compile without OS specific SCSI features])
AC_MSG_CHECKING([for missing scsi/scsi.h on Linux])
AC_TRY_COMPILE([
#ifdef __linux
#include <scsi/scsi.h>
#endif
],
[;],
[AC_MSG_RESULT([no])],
[AC_DEFINE([Libburn_use_sg_dummY], [yes])
AC_MSG_RESULT([yes])]
)
])

10
bootstrap Executable file
View File

@ -0,0 +1,10 @@
#!/bin/sh -x
aclocal -I .
libtoolize --copy --force
autoconf
# ts A61101 : libburn is not prepared for config.h
# autoheader
automake --foreign --add-missing --copy --include-deps

604
cdrskin/README Normal file
View File

@ -0,0 +1,604 @@
------------------------------------------------------------------------------
libburnia-project.org scdbackup.sourceforge.net/cdrskin_eng.html
------------------------------------------------------------------------------
cdrskin. By Thomas Schmitt <scdbackup@gmx.net>
Integrated sub project of libburnia-project.org but also published via:
http://scdbackup.sourceforge.net/cdrskin_eng.html
http://scdbackup.sourceforge.net/cdrskin-1.5.2.pl01.tar.gz
Copyright (C) 2006-2019 Thomas Schmitt, provided under GPL version 2 or later.
------------------------------------------------------------------------------
cdrskin is a limited cdrecord compatibility wrapper which allows to use
most of the libburn features from the command line.
Currently it is fully supported on GNU/Linux with kernels >= 2.4, on FreeBSD,
on OpenSolaris, and on NetBSD.
IDE drives under Linux 2.4 need kernel module ide-scsi.
ATA and SATA drives under FreeBSD need kernel module atapicam.
On other X/Open compliant systems there will only be emulated drives, but no
direct MMC operation on real CD/DVD/BD drives.
By using this software you agree to the disclaimer at the end of this text
"This software is provided as is. There is no warranty implied and ..."
Compilation, First Glimpse, Installation
Obtain cdrskin-1.5.2.pl01.tar.gz, take it to a directory of your choice and do:
tar xzf cdrskin-1.5.2.pl01.tar.gz
cd cdrskin-1.5.2
Within that directory execute:
./configure --prefix=/usr
make
This will already produce a cdrskin binary. But it will be necessary to
install libburn in order to use this binary.
In order to surely get a standalone binary, execute
cdrskin/compile_cdrskin.sh
Version identification and help texts available afterwards:
cdrskin/cdrskin -version
cdrskin/cdrskin --help
cdrskin/cdrskin -help
man cdrskin/cdrskin.1
Install (eventually as superuser) cdrskin to a directory where it can be found:
The command for global installation of both, libburn and cdrskin is
make install
If the library libburn.so.4 is not found with a test run of cdrskin, then
try whether command
ldconfig
makes it accessible. With the statically linked binary this should not matter.
With that static binary you may as well do the few necessary actions manually.
If cdrskin was already installed by a previous version, or by "make install"
in the course of this installation, then find out where:
which cdrskin
Copy your standalone binary to exactly the address which you get as reply.
E.g.:
cp cdrskin/cdrskin /usr/bin/cdrskin
Check the version timestamps of the globally installed binary
cdrskin -version
It is not necessary for the standalone cdrskin binary to have libburn
installed, since it incorporates the necessary libburn parts at compile time.
It will not collide with an installed version of libburn either.
But libpthread must be installed on the system and glibc has to match. (See
below for a way to create a totally static linked binary.)
To install the man page, you may do: echo $MANPATH and choose one of the
listed directories to copy the man-page under its ./man1 directory. Like:
cp cdrskin/cdrskin.1 /usr/share/man/man1/cdrskin.1
Note: The content of the cdrskin tarball is essentially the complete libburn
of the same version number. You may thus perform above steps in a local
SVN copy of libburn or in a unpacked libburn tarball as well.
Usage
The user of cdrskin needs rw-permission for the CD burner device.
A list of rw-accessible drives can be obtained by
cdrskin --devices
CD devices which offer no rw-permission are invisible to normal users.
The superuser should be able to see any usable drive and then set the
permissions as needed. If this hangs then there is a drive with
unexpected problems (locked, busy, broken, whatever). You might have to
guess the address of your (non-broken) burner by other means, then.
On Linux 2.4 this would be some /dev/sgN and on 2.6. some /dev/srM or /dev/hdX.
The output of cdrskin --devices might look like
0 dev='/dev/sr0' rwrwr- : '_NEC' 'DVD_RW ND-4570A'
1 dev='/dev/sr1' rwrw-- : 'HL-DT-ST' 'DVDRAM GSA-4082B'
On Linux, full and insecure enabling of both for everybody would look like
chmod a+rw /dev/sr0 /dev/hda
This is equivalent to the traditional setup chmod a+x,u+s cdrecord.
On FreeBSD, device rw-permissions are to be set in /etc/devfs.rules.
On Solaris, pfexec privileges may be restricted to "basic,sys_devices".
On NetBSD, rw-permission may be granted by chmod a+rw /dev/rcd?d.
See below "System Dependend Drive Permission Examples".
I strongly discourage to run cdrskin with setuid root or via sudo !
It is not checked for the necessary degree of hacker safety.
Better consider to grant the necessary permissions to group "floppy"
and to add users to it.
A behavioral conflict is known between any burn software and demons like hald
which probe CD drives. This can spoil burn runs for CD-R or CD-RW.
You may have to keep your hald away from the drive. See for example
http://www.freebsd.org/gnome/docs/halfaq.html
Helpful with Linux kernel 2.4 is a special SCSI feature:
It is possible to address a scsi(-emulated) drive via associated device files
which are not listed by option --devices but point to the same SCSI addresses
as listed device files. This addressing via e.g. /dev/sr0 or /dev/scd1 is
compatible with generic read programs like dd and with write program growisofs.
For finding /dev/sg1 from /dev/sr0, the program needs rw-access to both files.
Usage examples
For options and recordable media classes see
man 1 cdrskin
Get an overview of cdrecord style addresses of available devices
cdrskin -scanbus
cdrskin dev=ATA -scanbus
cdrskin --devices
Adresses reported with dev=ATA need prefix "ATA:". Address examples:
dev=0,1,0 dev=ATA:1,0,0 dev=/dev/sg1 dev=/dev/hdc dev=/dev/sr0
See also "Drive Addressing" below.
Obtain some info about the drive
cdrskin dev=0,1,0 -checkdrive
Obtain some info about the drive and the inserted media
cdrskin dev=0,1,0 -atip -v -minfo
Prepare CD-RW or DVD-RW for re-use, DVD-RAM or BD-RE for first use
cdrskin -v dev=/dev/sg1 blank=as_needed -eject
Format DVD-RW to avoid need for blanking before re-use
cdrskin -v dev=0,1,0 blank=format_overwrite
De-format DVD-RW to make it capable of multi-session again
cdrskin -v dev=/dev/sr0 blank=deformat_sequential
Burn image file my_image.iso to media
cdrskin -v dev=0,1,0 speed=12 fs=8m driveropts=burnfree padsize=300k \
-eject my_image.iso
Write multi-session to the same CD , DVD-R[W] or DVD+R[/DL]
cdrskin dev=/dev/hdc padsize=300k -multi 1.iso
cdrskin dev=/dev/hdc padsize=300k -multi 2.iso
cdrskin dev=/dev/hdc padsize=300k -multi 3.iso
cdrskin dev=/dev/hdc padsize=300k 4.iso
Get multi-session info for option -C of program mkisofs:
c_values=$(cdrskin dev=/dev/hdc -msinfo 2>/dev/null)
mkisofs ... -C "$c_values" ...
Burn a compressed afio archive to media on-the-fly
find . | afio -oZ - | cdrskin -v dev=0,1,0 fs=32m speed=8 \
driveropts=burnfree padsize=300k -
Burn 6 audio tracks from files with different formats to CD (not to any DVD).
Anything except .wav or .au files has to be converted into raw format first.
See below "Audio CD" for specifications.
ogg123 -d raw -f track01.cd /path/to/track1.ogg
oggdec -R -o track02.cd /path/to/track2.ogg
lame --decode -t /path/to/track3.mp3 track03.cd
madplay -o raw:track04.cd /path/to/track4.mp3
mppdec --raw-le /path/to/track5.mpc track05.cd
cdrskin -v dev=0,1,0 blank=fast -eject speed=48 -sao \
-audio -swab track0[1-5].cd /path/to/track6.wav
Extract audio tracks and CD-TEXT from CD into directory /home/me/my_cd:
mkdir /home/me/my_cd
cdrskin -v dev=/dev/sr0 extract_audio_to=/home/me/my_cd \
cdtext_to_v07t=/home/me/my_cd/cdtext.v07t
Restrictions
Several advanced CD related options of cdrecord are still unsupported.
See output of command
cdrskin --list_ignored_options
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 length surpass the current DVD capabilities of cdrecord.
Inspiration and Standard
cdrskin combines the command line interface standard set by cdrecord with
libburn, which is a control software for optical drives according to standard
MMC-5. For particular CD legacy commands, standards MMC-3 and MMC-1 apply.
For the original meaning of cdrecord options see :
man cdrecord
(http://cdrecord.berlios.de/old/private/man/cdrecord-2.0.html)
Do not bother Joerg Schilling with any cdrskin problems.
(Be cursed if you install cdrskin as "cdrecord" without clearly forwarding
this "don't bother Joerg" demand.)
cdrskin does not contain any bytes copied from cdrecord's sources. Many bytes
have been copied from the message output of cdrecord runs, though. I am
thankful to Joerg Schilling for every single one of them.
I have the hope that Joerg feels more flattered than annoyed by cdrskin.
Many thanks to Andy Polyakov for his dvd+rw-tools
http://fy.chalmers.se/~appro/linux/DVD+RW/tools
which provide me with examples and pointers into MMC specs for DVD writing.
Startup Files
If not --no_rc is the first argument then cdrskin attempts on startup to read
arguments from the following three files:
/etc/default/cdrskin
/etc/opt/cdrskin/rc
/etc/cdrskin/cdrskin.conf
$HOME/.cdrskinrc
The files are read in the sequence given above.
Each readable line is treated as one single argument. No extra blanks.
A first character '#' marks a comment, empty lines are ignored.
Example content of a startup file:
# This is the default device
dev=0,1,0
# Some more options
fifo_start_at=0
fs=16m
Audio CD
Lorenzo Taylor enabled option -audio in cdrskin (thanks !) and reports neat
results with audio data files which are :
headerless PCM (i.e. uncompressed)
44100 Hz sampling rate
16 bits per sample
stereo (2 channels)
little-endian byte order with option -swab, or big-endian without -swab
Files with name extension .wav get examined wether they are in Microsoft WAVE
format with above parameters and eventually get extracted by cdrskin itself.
In the same way files with name extension .au get examined wether they are
in SUN's audio format. For both formats, track format -audio and eventual
endianness option -swab are enabled automatically.
Any other formats are to be converted to format .wav with above parameters
or to be extracted as raw CD track data by commands like those given above
under "Usage examples". Those raw files need option -audio and in most cases
option -swab to mark them as little-endian/Intel/LSB-first 16-bit data.
Incorrect endianness setting results in random noise on CD.
I myself am not into audio. So libburn-hackers@pykix.org might be the
best address for suggestions, requests and bug reports.
DVD+RW , DVD-RAM , BD-RE
These random access media get treated as blank media regardless wether they
hold data or not. Options -audio and -multi are not allowed. Only one track
is allowed. -toc does not return information about the media content.
Speed is counted in DVD units (i.e. 1x = 1,385,000 bytes/second) or BD units
(1x = 4,495,625 bytes/second). Currently there is no difference between -sao
and -tao. If ever, then -tao will be the mode which preserves the current
behavior.
BD-RE media need formatting before first use. cdrskin option "blank=as_needed"
recognizes unformatted BD-RE and applies a lengthy formatting run.
During write operations DVD-RAM and BD-RE automatically apply Defect
Management. This usually slows them down to half nominal speed. If drive
and media produce flawless results anyway, then one can try to reach full
nominal speed by option "stream_recording=on".
In this case bad blocks are not detected during write and not even previously
known bad blocks are avoided. So you have to make your own readability tests
and go back to half speed as soon as the first read errors show up.
Instead of "on" one may also set a start address for stream recording.
Like "stream_recording=100m". This will write slowly to the first 100 MB of
the media and accelerate when writing to higher addresses.
Option --grow_overwriteable_iso allows -multi (although unneeded), enables
-msinfo and -toc, and makes blank=fast an invalidator for ISO filesystems
on overwriteable media.
Initial session (equivalent to growisofs -Z):
mkisofs ... | cdrskin --grow_overwriteable_iso blank=fast ...
Add-on session (equivalent to growisofs -M):
cparms=$(cdrskin dev=/dev/sr0 --grow_overwriteable_iso -msinfo)
mkisofs -C "$cparms" -M /dev/sr0 ... | \
cdrskin dev=/dev/sr0 --grow_overwriteable_iso ... -
DVD-RW , DVD-R , DVD-R DL
DVD-RW are usable if formatted to state "Restricted Overwrite" or if in state
"Sequential Recording". DVD-R are always in sequential state. DVD-R DL are
always sequential and incapable of multi-session.
"Sequential" is the state of unused media and of media previously blanked
or written by cdrecord. dvd+rw-format -blank can also achieve this state.
The according cdrskin option is blank=deformat_sequential .
If "Incremental Streaming" is available, then sequential media are capable
of multi-session like CD-R[W]. (But not capable of -audio recording.)
This means they need option -multi to stay appendable, need to be blanked
to be writeable from start, return useable info with -toc and -msinfo,
eventually perform appending automatically.
Without Incremental Streaming offered by the drive, only write mode DAO is
available with sequential DVD-R[W]. It only works with blank media, allows only
one single track, no -multi, and demands a fixely predicted track size.
(growisofs uses it with DVD-R[W] if option -dvd-compat is given.)
Overwriteable DVD-RW behave much like DVD+RW. "Restricted" refers only to the
granularity of random access and block size which have always to be aligned to
full 32 kB. Sequential DVD-RW are converted into overwriteable DVD-RW by
cdrskin dev=... -v blank=format_overwrite
(Command dvd+rw-format -force can achieve Restricted Overwrite, too.)
Formatting or first use of freshly formatted DVD-RW can produce unusual noises
from the drive and last several minutes. Depending on mutual compatibility of
drive and media, formatting can yield unusable media. It seems that those die
too on blanking by cdrecord, dvd+rw-format or cdrskin. Perils of DVD-RW.
There are three DVD-RW formatting variants with cdrskin currently:
blank=format_overwrite uses "DVD-RW Quick" formatting (MMC-type 15h)
and writes a first session of 128 MiB. This leads to media which are expandable
and random addressable by cdrskin.
blank=format_overwrite_quickest uses "DVD-RW Quick" formatting (type 15h) too,
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 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.
De-formatting options are available to make overwriteable DVD-RW sequential:
blank=deformat_sequential performs thorough blanking of all states of DVD-RW.
blank=all and blank=fast perform the same thorough blanking, but refuse to do
this with overwriteable DVD-RW, thus preserving their formatting. The specs
allow minimal blanking but the resulting media on my drives offer no
Incremental Streaming afterwards. So blank=fast will do full blanking.
blank=deformat_sequential_quickest is faster but might yield DAO-only media.
DVD+R , DVD+R DL , BD-R
From the view of cdrskin they behave much like DVD-R. Each track gets wrapped
into an own session, though.
DVD+R DL appear as extra large DVD+R. cdrskin does not allow to set the address
of the layer break where a reading drive might show some delay while switching
between both media layers.
BD-R are sold unformatted blank. If used without initial formatting then the
drive is supposed to format them to maximum payload size with no Defect
Management (see also above with BD-RE).
If Defect Management is desired then BD-R need to be formatted before the
first attempt to write a session to them.
blank=format_if_needed will detect the situation and eventually apply
default sized Defect Management formatting.
blank=format_defectmgt_* will apply non-default parameters to formatting.
Emulated Drives
cdrskin can use filesystem objects as emulated drives. Regular files or block
devices appear similar to DVD-RAM. Other file types resemble blank DVD-R.
Necessary precondition is option --allow_emulated_drives which is not accepted
if cdrskin took another user identity because of the setuid bit of its access
permissions.
Addresses of emulated drives begin with prefix "stdio:". E.g.
dev=stdio:/tmp/my_pseudo_drive
For safety reasons the superuser is only allowed to use /dev/null as emulated
drive. See man page section FILES for a way to lift that ban.
------------------------------------------------------------------------------
Special compilation variations
All following options of ./configure and cdrskin/compile_cdrskin.sh are
combinable. After runs of ./configure do as next:
make clean ; make
In some situations Linux may deliver a better write performance to drives if
the track input is read with O_DIRECT (see man 2 open). The API call
burn_os_open_track_src() and the input readers of cdrskin and libburn fifo
can be told to use this peculiar read mode by:
--enable-track-src-odirect
But often cdrskin option dvd_obs=64k will yield even better performance in
such a situation. 64k can be made default at compile time by
cdrskin/compile_cdrskin.sh -dvd_obs_64k
It can also be enabled at configure time by
./configure ... --enable-dvd-obs-64k ...
Alternatively the transport of SCSI commands can be done via libcdio-0.83.
You may install it and re-run libburn's ./configure with option
--enable-libcdio
Add option
-use_libcdio
to your run of cdrskin/compile_cdrskin.sh .
You may get a (super fat) statically linked binary by :
cdrskin/compile_cdrskin.sh -static
if your system supports static linking, at all. This will not help with kernels
which do not properly support the necessary low-level interfaces chosen by
your compile-time libraries.
A size reduced but fully functional binary may be produced by
cdrskin/compile_cdrskin.sh -do_strip
An extra lean binary with reduced capabilities is created by
cdrskin/compile_cdrskin.sh -do_diet -do_strip
It will not read startup files, will abort on option dev_translation= ,
will not have a fifo buffer, and will not be able to put out help texts or
debugging messages.
Linux only:
libburn tries to avoid a collision with udev's drive examination by waiting
0.1 seconds before opening the device file for a longer time, after udev
might have been alarmed by drive scanning activities.
The waiting time can be set at ./configure time with microsecond granularity.
E.g. 2 seconds:
CFLAGS="$CFLAGS -DLibburn_udev_wait_useC=2000000"
./configure ...options...
Waiting can be disabled by zero waiting time:
CFLAGS="$CFLAGS -DLibburn_udev_wait_useC=0"
Alternatively, libburn can try to be nice by opening the device file,
closing it immediately, waiting, and only then opening it for real:
CFLAGS="$CFLAGS -DLibburn_udev_extra_open_cyclE -DLibburn_udev_wait_useC=500000"
------------------------------------------------------------------------------
System Dependend Drive Permission Examples
Accessing the optical drives requires privileges which usually are granted
only to the superuser. Linux, FreeBSD, Solaris, NetBSD, offer quite different
approaches for avoiding the need for unrestricted privileges.
First check whether some friendly system setting already allows you to
access the drives as normal user:
cdrskin --devices
Those drives of which you see address and type strings are already usable.
If there remain drives invisible which the superuser can see by the same
command, then the following examples might help:
---------------
On all systems:
---------------
Add the authorized users of CD drives to group "floppy" in /etc/group.
If missing: create this group.
Changes to /etc/group often only affect new login sessions. So log out and in
before making the first tests.
---------
On Linux:
---------
Allow rw-access to the drives
chgrp floppy /dev/sr0 /dev/sr1
chmod g+rw /dev/sr0 /dev/sr1
It might be necessary to perform chgrp and chmod after each reboot or to
edit distro dependent device configuration files for permanent settings.
-----------
On FreeBSD:
-----------
Edit /etc/devfs.rules and make sure to have these lines
[localrules=10]
add path 'acd*' mode 0664 group floppy
add path 'cd*' mode 0664 group floppy
add path 'pass*' mode 0664 group floppy
add path 'xpt*' mode 0664 group floppy
[localrules=5]
add path 'pass*' mode 0664 group floppy
add path 'cd*' mode 0664 group floppy
add path 'xpt*' mode 0664 group floppy
add path 'acd*' mode 0664 group floppy
Edit /etc/rc.conf and add the following line if missing
devfs_system_ruleset="localrules"
This gets into effect by reboot or by command
/etc/rc.d/devfs start
-----------
On Solaris:
-----------
Run cdrskin by
pfexec cdrskin ...arguments...
The following settings will make pfexec keep original UID and EUID and prevent
most superuser powers. Be aware that you still can manipulate all device files
if you have the file permissions for that.
Full root privileges for cdrskin can then be acquired only by command su.
Edit /etc/security/exec_attr and add this line to the other "Media Backup"
lines:
Media Backup:solaris:cmd:::/usr/local/bin/cdrskin:privs=basic,sys_devices
Edit /etc/user_attr and add profile "Media Backup" to the user's line:
thomas::::profiles=Media Backup,Primary Administrator;roles=root
See also man privileges, man exec_attr, man user_attr.
Then allow the group r-access to the drives
pfexec chgrp floppy /dev/rdsk/c3t0d0s2 /dev/rdsk/c4t0d0s2
pfexec chmod g+r /dev/rdsk/c3t0d0s2 /dev/rdsk/c4t0d0s2
The last two commands have to be executed after each boot. I do not know
the relevant device configuration files yet.
----------
On NetBSD:
----------
Allow rw-access to the drives
chgrp floppy /dev/rcd[01]d
chmod g+rw /dev/rcd[01]d
------------------------------------------------------------------------------
Project aspects and legal stuff
------------------------------------------------------------------------------
Important Disclaimer :
This software is provided as is. There is no warranty implied and no
protection against possible damages. You use this on your own risk.
Don't blame me or other authors of libburn if anything goes wrong.
Actually, in case of severe trouble, nearly always the drive and the media
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 ...
------------------------------------------------------------------------------
Interested users are invited to participate in the development of cdrskin.
Contact: scdbackup@gmx.net or libburn-hackers@pykix.org .
We will keep copyright narrow but will of course acknowledge valuable
contributions in a due way.
------------------------------------------------------------------------------
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License version 2 or later
as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
------------------------------------------------------------------------------
Based on and sub project of:
libburnia-project.org
By Mario Danic <mario.danic@gmail.com> and Thomas Schmitt <scdbackup@gmx.net>
Copyright (C) 2006-2019 Mario Danic, Thomas Schmitt
libburnia-project.org is inspired by and in other components 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
See toplevel README for an overview of the current copyright situation in
libburnia-project.org.

View File

@ -0,0 +1,248 @@
#!/bin/sh
set -x
# This script documents how this cdrskin version was derived from
# a vanilla libburn version. It is not intended nor needed for any
# use of cdrskin but included here only to show the technical
# relationship between both projects - which are close friends
# and issue roughly the same software.
#
# Package maintainers are advised to cover rather libburn than
# cdrskin unless they put only emphasis on the cdrecord emulation
# provided by cdrskin. libburn contains cdrskin - cdrskin is an
# oscillating, friendly and coordinated fork of libburn.
#
# Script results are a source tarball and two binaries
# one dynamic and one static in respect to system libs.
# Both binaries are static in respect to libburn.
#
# The script is to be run in the directory above the toplevel
# directory of libburn (or cdrskin) development.
#
# The top level directory in the SVN snapshot is named
intermediate="./libburn_pykix"
# libburn source used: http://libburnia.pykix.org
# Downloaded by:
# $ svn co http://libburnia-svn.pykix.org/libburn/tags/... $intermediate
# packed up in a tarball just to save it from inadverted changes by
# $ tar czf libburn_svn.tgz $intermediate
original="./libburn_svn_release.tgz"
# Historic moments:
# original="./libburn_svn_A60815.tgz"
# original="./libburn_cdrskin_A60819.tgz"
# My changes are in $changes , mainly in $changes/cdrskin
changes="./libburn-release"
skin_release="1.5.2"
patch_level=""
# patch_level=".pl00"
skin_rev="$skin_release""$patch_level"
# The result directory and the name of the result tarballs
target="./cdrskin-${skin_release}"
cdrskin_tarball="./cdrskin-${skin_rev}.tar.gz"
cdrskin_tarball_svn="./cdrskin-${skin_rev}.svn.tar.gz"
# (This once earned me an embarrassingly blooping source tarball)
# compile_dir="$changes"
compile_dir="$target"
compile_cmd="./cdrskin/compile_cdrskin.sh"
compile_static_opts="-static"
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}-x86-suse9_0"
# 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"
then
dummy=dummy
else
echo "$0 : FATAL : no directory $changes" >&2
exit 1
fi
for i in "$target" "$intermediate"
do
if test -e "$i"
then
echo "$0 : FATAL : already existing $i" >&2
exit 2
fi
done
if test -f "$original"
then
dummy=dummy
else
echo "$0 : FATAL : no file $original" >&2
exit 3
fi
# Unpack SVN snapshot.
tar xzf "$original"
# Rename the directory to the cdrskin name
mv "$intermediate" "$target"
# Copy the changes from the development tree
#
cdrskin_dir="$changes"/cdrskin
libburn_dir="$changes"/libburn
cdrskin_target="$target"/cdrskin
libburn_target="$target"/libburn
# Create version timestamp
# timestamp="$(date -u '+%Y.%m.%d.%H%M%S')"
# echo "$timestamp"
# echo '#define Cdrskin_timestamP "'"$timestamp"'"' >"$cdrskin_dir"/cdrskin_timestamp.h
# Add the cdrskin files
if test -e "$cdrskin_target"
then
rm -rf "$cdrskin_target"
fi
cp -a "$cdrskin_dir" "$cdrskin_target"
# Remove copied vim.swp and binaries
rm "$cdrskin_target"/.*.swp
rm "$cdrskin_target"/.*.swo
rm "$cdrskin_target"/*.o
rm "$cdrskin_target"/cdrfifo
rm "$cdrskin_target"/cdrskin
rm "$cdrskin_target"/cleanup
for i in std new make old
do
if test -e "$cdrskin_target"/cdrskin_"$i"
then
rm "$cdrskin_target"/cdrskin_"$i"
fi
done
# Remove eventual SVN stuff from cdrskin directory
for i in .deps .dirstamp .libs
do
if test -e "$cdrskin_target"/"$i"
then
rm -rf "$cdrskin_target"/"$i"
fi
done
# Remove GIFs of cdrskin_eng.html
rm "$cdrskin_target"/doener_*.gif "$cdrskin_target"/doener_*.png
# Remove automatically generated HTML man page
rm "$cdrskin_target"/man_1_cdrskin.html
# Remove all add_ts_changes_to_libburn besides this one
for i in "$cdrskin_target"/add_ts_changes_to_libburn*
do
if test $(basename "$0") = $(basename "$i")
then
dummy=dummy
else
rm $i
fi
done
# Remove libcevap
rm -rf "$target"/libcevap
# Remove unwanted SVN stuff (TODO: avoid downloading it)
for i in "$target"/.svn "$target"/*/.svn
do
if test "$i" = "$target"'/*/.svn'
then
dummy=dummy
else
if test -e "$i"
then
rm -rf "$i"
fi
fi
done
# Make SVN state tarball for the libburn team
tar czf "$cdrskin_tarball_svn" "$target"
# Get over dependecy on autotools. Rely only on cc, make et. al.
# This is not the same as "make dist" but i can do it without
# having to evaluate the quality of said "make dist"
#
( cd "$target" ; ./bootstrap )
# Remove unwanted stuff after bootstrap
for i in "$target"/autom4te.cache
do
if echo "$i" | grep '\*' >/dev/null
then
dummy=dummy
else
if test -e "$i"
then
rm -rf "$i"
fi
fi
done
# Repair non-portable shell code output of ./bootstrap
(
cd "$compile_dir" || exit 1
sed -e 's/^for ac_header in$/test -z 1 \&\& for ac_header in dummy/' \
< ./configure > ./configure-repaired
if test "$?" = 0
then
echo "$0: Empty 'for ac_header in' found in configure." >&2
fi
mv ./configure-repaired ./configure
chmod a+rx,go-w,u+w ./configure
)
# Pack it up to the new libburn+cdrskin-tarball
tar czf "$cdrskin_tarball" "$target"
# Produce a static and a dynamic binary, and a HTML man page
(
cd "$compile_dir" || exit 1
./configure
make
"$compile_cmd" -O2 -do_strip
cp "$compile_result" "../$bintarget_dynamic"
if test -n "$compile_static_opts"
then
"$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" ..
)
# Remove the build area
# Disable this for debugging the merge process
rm -rf "$target"
# Show the result
./"$bintarget_dynamic" -version
./"$bintarget_static" -version
ls -l "$cdrskin_tarball"
ls -l "$bintarget_dynamic"
ls -l "$bintarget_static"
ls -l $(basename "$man_page_html")

View File

@ -0,0 +1,249 @@
#!/bin/sh
set -x
# This script documents how this cdrskin version was derived from
# a vanilla libburn version. It is not intended nor needed for any
# use of cdrskin but included here only to show the technical
# relationship between both projects - which are close friends
# and issue roughly the same software.
#
# Package maintainers are advised to cover rather libburn than
# cdrskin unless they put only emphasis on the cdrecord emulation
# provided by cdrskin. libburn contains cdrskin - cdrskin is an
# oscillating, friendly and coordinated fork of libburn.
#
# Script results are a source tarball and two binaries
# one dynamic and one static in respect to system libs.
# Both binaries are static in respect to libburn.
#
# The script is to be run in the directory above the toplevel
# directory of libburn (or cdrskin) development.
#
# The top level directory in the SVN snapshot is named
intermediate="./libburn_pykix"
# libburn source used: http://libburnia-project.org
# Downloaded by:
# $ svn co http://libburnia-project.org/libburn/tags/... $intermediate
# packed up in a tarball just to save it from inadverted changes by
# $ tar czf libburn_svn.tgz $intermediate
original="./libburn_svn.tgz"
# Historic moments:
# original="./libburn_svn_A60815.tgz"
# original="./libburn_cdrskin_A60819.tgz"
# My changes are in $changes , mainly in $changes/cdrskin
changes="./libburn-develop"
skin_release="1.5.3"
patch_level=""
skin_rev="$skin_release""$patch_level"
# The result directory and the name of the result tarballs
target="./cdrskin-${skin_release}"
cdrskin_tarball="./cdrskin-${skin_rev}.tar.gz"
cdrskin_tarball_svn="./cdrskin-${skin_rev}.svn.tar.gz"
# (This once earned me an embarrassingly blooping source tarball)
# compile_dir="$changes"
compile_dir="$target"
compile_cmd="./cdrskin/compile_cdrskin.sh"
compile_static_opts="-static"
compile_result="cdrskin/cdrskin"
man_to_html_cmd="./cdrskin/convert_man_to_html.sh"
man_page_html="cdrskin/man_1_cdrskin.html"
# bintarget_dynamic="cdrskin_${skin_rev}-amd64-suse10_2"
bintarget_dynamic="cdrskin_${skin_rev}-amd64-debian8_0"
bintarget_static="$bintarget_dynamic"-static
if test -d "$changes"
then
dummy=dummy
else
echo "$0 : FATAL : no directory $changes" >&2
exit 1
fi
for i in "$target" "$intermediate"
do
if test -e "$i"
then
echo "$0 : FATAL : already existing $i" >&2
exit 2
fi
done
if test -f "$original"
then
dummy=dummy
else
echo "$0 : FATAL : no file $original" >&2
exit 3
fi
# Unpack SVN snapshot.
tar xzf "$original"
# Rename the directory to the cdrskin name
mv "$intermediate" "$target"
# Copy the changes from the development tree
#
cdrskin_dir="$changes"/cdrskin
libburn_dir="$changes"/libburn
cdrskin_target="$target"/cdrskin
libburn_target="$target"/libburn
# Create version timestamp
timestamp="$(date -u '+%Y.%m.%d.%H%M%S')"
echo "$timestamp"
echo '#define Cdrskin_timestamP "'"$timestamp"'"' >"$cdrskin_dir"/cdrskin_timestamp.h
# Add the cdrskin files
if test -e "$cdrskin_target"
then
rm -rf "$cdrskin_target"
fi
cp -a "$cdrskin_dir" "$cdrskin_target"
# Remove copied vim.swp and binaries
rm "$cdrskin_target"/.*.swp
rm "$cdrskin_target"/.*.swo
rm "$cdrskin_target"/*.o
rm "$cdrskin_target"/cdrfifo
rm "$cdrskin_target"/cdrskin
rm "$cdrskin_target"/cleanup
for i in std new make old
do
if test -e "$cdrskin_target"/cdrskin_"$i"
then
rm "$cdrskin_target"/cdrskin_"$i"
fi
done
# Remove eventual SVN stuff from cdrskin directory
for i in .deps .dirstamp .libs
do
if test -e "$cdrskin_target"/"$i"
then
rm -rf "$cdrskin_target"/"$i"
fi
done
# Remove GIFs of cdrskin_eng.html
rm "$cdrskin_target"/doener_*.gif "$cdrskin_target"/doener_*.png
# Remove automatically generated HTML man page
rm "$cdrskin_target"/man_1_cdrskin.html
# Remove libcevap
rm -rf "$target"/libcevap
# Remove all add_ts_changes_to_libburn besides this one
for i in "$cdrskin_target"/add_ts_changes_to_libburn*
do
if test $(basename "$0") = $(basename "$i")
then
dummy=dummy
else
rm $i
fi
done
# Remove unwanted SVN stuff (TODO: avoid downloading it)
for i in "$target"/.svn "$target"/*/.svn
do
if test "$i" = "$target"'/*/.svn'
then
dummy=dummy
else
if test -e "$i"
then
rm -rf "$i"
fi
fi
done
# Make SVN state tarball for the libburn team
tar czf "$cdrskin_tarball_svn" "$target"
# Get over dependecy on autotools. Rely only on cc, make et. al.
# This is not the same as "make dist" but i can do it without
# having to evaluate the quality of said "make dist"
#
( cd "$target" ; ./bootstrap )
# Remove unwanted stuff after bootstrap
for i in "$target"/autom4te.cache
do
if echo "$i" | grep '\*' >/dev/null
then
dummy=dummy
else
if test -e "$i"
then
rm -rf "$i"
fi
fi
done
# Repair non-portable shell code output of ./bootstrap
(
cd "$compile_dir" || exit 1
sed -e 's/^for ac_header in$/test -z 1 \&\& for ac_header in dummy/' \
< ./configure > ./configure-repaired
if test "$?" = 0
then
echo "$0: Empty 'for ac_header in' found in configure." >&2
fi
mv ./configure-repaired ./configure
chmod a+rx,go-w,u+w ./configure
)
# Pack it up to the new libburn+cdrskin-tarball
tar czf "$cdrskin_tarball" "$target"
# Produce a static and a dynamic binary, and a HTML man page
(
cd "$compile_dir" || exit 1
./configure
make
"$compile_cmd" -libburn_svn -O2 -do_strip
cp "$compile_result" "../$bintarget_dynamic"
if test -n "$compile_static_opts"
then
"$compile_cmd" $compile_static_opts -libburn_svn -O2 -do_strip
cp "$compile_result" "../$bintarget_static"
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" ..
)
# Remove the build area
# Disable this for debugging the merge process
rm -rf "$target"
# Show the result
./"$bintarget_dynamic" -version
./"$bintarget_static" -version
ls -l "$cdrskin_tarball"
ls -l "$bintarget_dynamic"
ls -l "$bintarget_static"
ls -l $(basename "$man_page_html")

37
cdrskin/cdrecord_spy.sh Executable file
View File

@ -0,0 +1,37 @@
#!/bin/sh
#
# Spying on the call to cdrecord.
#
# Move $(which cdrecord) to $(dirname $(which cdrecord))/real_cdrecord .
# Install this sript instead. (Do not forget to revoke this after the test.)
#
# The report target is set in variable rt.
# The default is this file :
rt=/tmp/cdrecord_spy_log
# To use a bystanding xterm as target i find out the pty address by
# executing in that terminal
# sleep 12345
# and then running in another terminal
# ps -ef | grep 'sleep 12345'
# which answers something like
# thomas 21303 30518 0 14:02 pts/23 00:00:00 sleep 12345
# thomas 21421 30523 0 14:02 pts/24 00:00:00 grep sleep 12345
# from which i learn that pts/23 is sleeping 12345. Now sleep can be aborted.
#
# rt=/dev/pts/23
echo '------------------------------------- cdrecord_spy 0.1.0 -------' >>"$rt"
date >>"$rt"
echo '----------------------------------------------------------------' >>"$rt"
echo "$0" >>"$rt"
for i in "$@"
do
echo "$i" >>"$rt"
done
echo '------------------------------------- cdrecord_spy 0.1.0 - end -' >>"$rt"
real_cdrecord "$@"

1343
cdrskin/cdrfifo.c Normal file

File diff suppressed because it is too large Load Diff

171
cdrskin/cdrfifo.h Normal file
View File

@ -0,0 +1,171 @@
/*
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
in fd-to-fd mode. Modes are controlled by parameter flag of
Cdrfifo_try_to_work().
Provided under GPL license within cdrskin and under BSD license elsewise.
*/
#ifndef Cdrfifo_headerfile_includeD
#define Cdrfifo_headerfile_includeD
/** The fifo buffer which will smoothen the data stream from data provider
to data consumer. Although this is not a mandatory lifesaver for modern
burners any more, a fifo can speed up burning of data which is delivered
with varying bandwidths (e.g. compressed archives created on the fly
or mkisofs running at its speed limit.).
This structure is opaque to applications and may only be used via
the Cdrfifo*() methods described in cdrfifo.h .
*/
struct CdrfifO;
/** Create a fifo object.
@param ff Returns the address of the new object.
@param source_fd Filedescriptor opened to a readable data stream.
@param dest_fd Filedescriptor opened to a writable data stream.
To work with libburn, it needs to be attached to a
struct burn_source object.
@param chunk_size Size of buffer block for a single transaction (0=default)
@param buffer_size Size of fifo buffer
@param flag bit0= Debugging verbosity
@return 1 on success, <=0 on failure
*/
int Cdrfifo_new(struct CdrfifO **ff, int source_fd, int dest_fd,
int chunk_size, int buffer_size, int flag);
/** Release from memory a fifo object previously created by Cdrfifo_new().
@param ff The victim (gets returned as NULL, call can stand *ff==NULL)
@param flag Bitfield for control purposes:
bit0= do not close destination fd
*/
int Cdrfifo_destroy(struct CdrfifO **ff, int flag);
/** Close any output fds */
int Cdrfifo_close(struct CdrfifO *o, int flag);
/** Close any output fds of o and its chain peers */
int Cdrfifo_close_all(struct CdrfifO *o, int flag);
int Cdrfifo_get_sizes(struct CdrfifO *o, int *chunk_size, int *buffer_size,
int flag);
/** Set a speed limit for buffer output.
@param o The fifo object
@param bytes_per_second >0 catch up slowdowns over the whole run time
<0 catch up slowdowns only over one interval
=0 disable speed limit
*/
int Cdrfifo_set_speed_limit(struct CdrfifO *o, double bytes_per_second,
int flag);
/** Set a fixed size for input in order to cut off any unwanted tail
@param o The fifo object
@param idx index for fds attached via Cdrfifo_attach_follow_up_fds(),
first attached is 0, <0 directs limit to active fd limit
(i.e. first track is -1, second track is 0, third is 1, ...)
*/
int Cdrfifo_set_fd_in_limit(struct CdrfifO *o, double fd_in_limit, int idx,
int flag);
int Cdrfifo_set_fds(struct CdrfifO *o, int source_fd, int dest_fd, int flag);
int Cdrfifo_get_fds(struct CdrfifO *o, int *source_fd, int *dest_fd, int flag);
/** Attach a further pair of input and output fd which will use the same
fifo buffer when its predecessors are exhausted. Reading will start as
soon as reading of the predecessor encounters EOF. Writing will start
as soon as all pending predecessor data are written.
@return index number of new item + 1, <=0 indicates error
*/
int Cdrfifo_attach_follow_up_fds(struct CdrfifO *o, int source_fd, int dest_fd,
int flag);
/** Attach a further fifo which shall be processed simultaneously with this
one by Cdrfifo_try_to_work() in fd-to-fd mode.
*/
int Cdrfifo_attach_peer(struct CdrfifO *o, struct CdrfifO *next, int flag);
/** Obtain buffer state.
@param o The buffer object
@param fill Returns the number of pending payload bytes in the buffer
@param space Returns the number of unused buffer bytes
@param flag unused yet
@return -1=error , 0=inactive , 1=reading and writing ,
2=reading ended (but still writing)
*/
int Cdrfifo_get_buffer_state(struct CdrfifO *o,int *fill,int *space,int flag);
int Cdrfifo_get_counters(struct CdrfifO *o,
double *in_counter, double *out_counter, int flag);
/** reads min_fill and begins measurement interval for next min_fill */
int Cdrfifo_next_interval(struct CdrfifO *o, int *min_fill, int flag);
int Cdrfifo_get_min_fill(struct CdrfifO *o, int *total_min_fill,
int *interval_min_fill, int flag);
int Cdrfifo_get_cdr_counters(struct CdrfifO *o,
double *put_counter, double *get_counter,
double *empty_counter, double *full_counter,
int flag);
/** Inquire the eventually detected size of an eventual ISO-9660 file system
@return 0=no ISO size detected, 1=size_in_bytes is valid
*/
int Cdrfifo_get_iso_fs_size(struct CdrfifO *o, double *size_in_bytes,int flag);
/** Take over the eventually memorized blocks 16 to 31 of input (2 kB each).
The fifo forgets the blocks by this call. I.e. a second one will return 0.
After this call it is the responsibility of the caller to dispose the
retrieved memory via call free().
@param pt Will be filled either with NULL or a pointer to 32 kB of data
@return 0=nothing is buffered, 1=pt points to valid freeable data
*/
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 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().
It may also be used instead of read(). Then it returns as soon as an output
transaction would be performed. See flag:bit2.
@param o The fifo object
@param wait_usec The time in microseconds after which the function shall
return.
@param reply_buffer with bit2: Returns write-ready buffer chunk and must
be able to take at least chunk_size bytes
@param reply_count with bit2: Returns number of writeable bytes in reply_pt
@param flag Bitfield for control purposes:
bit0= Enable debug pacifier (same with Cdrfifo_debuG)
bit1= Do not write, just fill buffer
bit2= fd-to-memory mode (else fd-to-fd mode):
Rather than writing a chunk return it and its size.
No simultaneous processing of chained fifos.
bit3= With bit2: do not check destination fd for readiness
@return <0 = error , 0 = idle , 1 = did some work , 2 = all work is done
*/
int Cdrfifo_try_to_work(struct CdrfifO *o, int wait_usec,
char *reply_buffer, int *reply_count, int flag);
/** Fill the fifo as far as possible without writing to destination fd.
@param size if >=0 : end filling after the given number of bytes
@return 1 on success, <=0 on failure
*/
int Cdrfifo_fill(struct CdrfifO *o, int size, int flag);
#endif /* Cdrfifo_headerfile_includeD */

1848
cdrskin/cdrskin.1 Normal file

File diff suppressed because it is too large Load Diff

10016
cdrskin/cdrskin.c Normal file

File diff suppressed because it is too large Load Diff

577
cdrskin/cdrskin_eng.html Normal file
View File

@ -0,0 +1,577 @@
<HTML>
<HEAD>
<META NAME="description" CONTENT="cdrskin, a limited cdrecord compatibility wrapper for libburn">
<META NAME="keywords" CONTENT="cdrskin, libburn, libburnia, burn, CD, DVD, BD, linux, recording, burning, CD-R, CD-RW, DVD-R, DVD-R DL, DVD-RW, DVD+RW, DVD+R, DVD+R DL, DVD-RAM, BD-RE, BD-R, cdrecord, compatible, scdbackup">
<META NAME="robots" CONTENT="follow">
<TITLE>cdrskin homepage english</TITLE>
</HEAD>
<BODY BGCOLOR="#F5DEB3" TEXT=#000000 LINK=#0000A0 VLINK=#800000>
<FONT SIZE=+1>
<CENTER>
<A HREF="http://en.wikipedia.org/wiki/D%C3%B6ner_kebab">
<IMG SRC="doener_150x200_tr_octx.png" BORDER=0
ALT="cdrskin logo: Doener mit Scharf">
</A>
<P><H2> Homepage of </H2>
<H1> cdrskin </H1>
<H2>Limited cdrecord compatibility wrapper for libburn</H2>
</CENTER>
<P>
<H2>Purpose:</H2>
Burns preformatted data to CD, DVD, and BD media:<BR>
CD-R, DVD-R, DVD-R DL, DVD+R, DVD+R DL, BD-R, CD-RW,
DVD-RW, DVD-RAM, DVD+RW, BD-RE
</P>
<P>
<HR>
<A HREF="#download">Direct hop to download links -></A>
<P>
<H2>Hardware requirements:</H2>
About any CD, DVD, or BD recorder produced in the recent ten years.
<BR>
<A HREF="http://libburnia-project.org">libburn</A>
supports recorders which are compliant to standards MMC-1 for CD and
MMC-5 for DVD or BD. Linux, FreeBSD, Solaris, and NetBSD can communicate
with drives connected via SCSI, PATA (aka IDE, ATA), USB, or SATA.
<BR>
</P>
<P>
<H2>Software requirements :</H2>
<DL>
<DT>Linux with kernel 2.4 or higher (and libc, of course) :</DT>
<DD>With kernel 2.4 an ATA drive has to be under ide-scsi emulation.</DD>
<DD>With kernel 2.6 or higher the drive should not be under ide-scsi.</DD>
<DT>or FreeBSD (with libc, of course) :</DT>
<DD>ATA and SATA drives need atapicam running.</DD>
<DD>libcam has to be installed.</DD>
<DT>or Solaris (with libc, of course) :</DT>
<DD>Tested on kernel 5.11, hopefully suitable for older ones too.</DD>
<DT>or NetBSD (with libc, of course) :</DT>
<DD>Tested on 6.1.2 and 6.1.3</DD>
<DT>libpthread</DT>
<DD>is supposed to be a standard system component.</DD>
</DL>
</P>
<P>
<H2>
GPL software included:<BR>
</H2>
<DL>
<DT>libburn-1.5.2.pl01</DT>
<DD>(founded by Derek Foreman and Ben Jansens,
developed and maintained since August 2006 by
Thomas Schmitt from team of libburnia-project.org)
</DD>
<DD>transfers data to CD, DVD, BD</DD>
</DL>
</P>
<P>
This program system has been tested on Intel/AMD with Linux, FreeBSD,
OpenSolaris, and NetBSD based operating systems.<BR>
Ports to other usable systems are appreciated. Reports are welcome.
</P>
<HR>
<P>
<H2>Special features:</H2>
<UL>
<LI>Source code is independent of
<A HREF="http://cdrecord.berlios.de/old/private/cdrecord.html">cdrecord</A>
</LI>
</UL>
</P>
<P>
<H2>Commands:</H2>
<DL>
<DT>The most common options of cdrecord for data and audio on CD media
are provided in a compatible way.<BR>
On all DVD media, cdrskin is able to perform any recording job
which is possible with cdrecord.
Other than with cdrecord, option -multi is supported with many DVD types and
BD-R. Write mode -tao works with anything but quickly blanked DVD-RW and
DVD-R DL, which both support no -multi.
</DT>
<BR><BR>
<DT>Get an overview of drives and their addresses</DT>
<DD>#<KBD>&nbsp;cdrskin -scanbus</KBD></DD>
<DD>#<KBD>&nbsp;cdrskin dev=ATA -scanbus</KBD></DD>
<DD>#<KBD>&nbsp;cdrskin --devices</KBD></DD>
<DT>Being superuser avoids permission problems with /dev/srN and /dev/hdX .
</DT>
<DT>Ordinary users should then get granted access to the /dev files
as listed by option --devices. Linux, FreeBSD, and NetBSD demand rw-permission.
On Solaris it is r-permission and privileges "basic,sys_devices".</DT>
<DT>&nbsp;</DT>
<DT>Get info about a particular drive or loaded media:</DT>
<DD>$<KBD>&nbsp;cdrskin dev=0,1,0 -checkdrive</KBD></DD>
<DD>$<KBD>&nbsp;cdrskin dev=ATA:1,0,0 -v -atip</KBD></DD>
<DD>$<KBD>&nbsp;cdrskin dev=/dev/hdc -minfo</KBD></DD>
<DT>Prepare CD-RW or DVD-RW for re-use, DVD-RAM or BD-RE for first use:</DT>
<DD>$<KBD>&nbsp;cdrskin -v dev=/dev/sg1 blank=as_needed -eject</KBD></DD>
<DT>Format DVD-RW to avoid need for blanking before re-use:</DT>
<DD>$<KBD>&nbsp;cdrskin -v dev=/dev/sr0 blank=format_overwrite</KBD></DD>
<DT>De-format DVD-RW to make it capable of multi-session again:</DT>
<DD>$<KBD>&nbsp;cdrskin -v dev=/dev/sr0 blank=deformat_sequential</KBD></DD>
<DT>Write ISO-9660 filesystem image as only one to blank or formatted media:
</DT>
<DD>$<KBD>&nbsp;cdrskin -v dev=/dev/hdc speed=12 fs=8m \</KBD></DD>
<DD><KBD>&nbsp;&nbsp;blank=as_needed -eject padsize=300k my_image.iso</KBD></DD>
<DT>Write compressed afio archive on-the-fly
(not DVD-R DL or minimally blanked DVD-RW):</DT>
<DD>$<KBD>&nbsp;find . | afio -oZ - | \</KBD></DD>
<DD><KBD>&nbsp;&nbsp;cdrskin -v dev=0,1,0 fs=32m speed=8 \</KBD></DD>
<DD><KBD>&nbsp;&nbsp;blank=as_needed padsize=300k -</KBD></DD>
<DT>Write several sessions to the same CD, DVD-R[W] or DVD+R[/DL]:</DT>
<DD>$<KBD>&nbsp;cdrskin dev=/dev/hdc -v padsize=300k -multi 1.iso</KBD>
</DD>
<DD>$<KBD>&nbsp;cdrskin dev=/dev/hdc -v padsize=300k -multi 2.iso</KBD>
</DD>
<DD>$<KBD>&nbsp;cdrskin dev=/dev/hdc -v padsize=300k -multi 3.iso</KBD>
</DD>
<DD>$<KBD>&nbsp;cdrskin dev=/dev/hdc -v padsize=300k 4.iso</KBD></DD>
<DT>Get multi-session info for option -C of program mkisofs:</DT>
<DD>$<KBD>&nbsp;c_values=$(cdrskin dev=/dev/sr0 -msinfo 2>/dev/null)</KBD></DD>
<DD>$<KBD>&nbsp;mkisofs ... -C "$c_values" ...</KBD></DD>
<DT>Inquire free space on media for a -multi run:</DT>
<DD>$<KBD>&nbsp;x=$(cdrskin dev=/dev/sr0 -multi \</KBD></DD>
<DD><KBD>&nbsp;&nbsp;--tell_media_space 2>/dev/null)</KBD></DD>
<DD>$<KBD>&nbsp;echo "Available: $x blocks of 2048 data bytes"</KBD></DD>
<DT>Accelerate BD-RE writing to full nominal speed after the first 250 MB</DT>
<DD>$<KBD>&nbsp;cdrskin ... stream_recording=250m ...</KBD>
<DT>Write audio tracks to CD:</DT>
<DD>$<KBD>&nbsp;cdrskin -v dev=ATA:1,0,0 speed=48 -sao \</KBD></DD>
<DD><KBD>&nbsp;&nbsp;track1.wav track2.au -audio -swab track3.raw</KBD></DD>
<DT>Get overview of the cdrecord compatible options:</DT>
<DD>$<KBD>&nbsp;<A HREF="cdrskin_help">cdrskin -help</A></KBD></DD>
<DT>Get overview of the non-cdrecord options:</DT>
<DD>$<KBD>&nbsp;<A HREF="cdrskin__help">cdrskin --help</A></KBD></DD>
<DT>Read the detailed manual page:</DT>
<DD>$<KBD>&nbsp;<A HREF="man_1_cdrskin.html">man cdrskin</A></KBD></DD>
</DL>
<DL>
<DT>Read about the standard for which cdrskin is striving:</DT>
<DD>$<KBD>&nbsp;
<A HREF="http://cdrecord.berlios.de/old/private/man/cdrecord-2.0.html">
man cdrecord</A></KBD></DD>
<DD><B>Do not bother Joerg Schilling with any cdrskin problems.</B>
(Be cursed if you install cdrskin as "cdrecord" without clearly forwarding
this "don't bother Joerg" demand.)
</DD>
</DL>
<DL>
<DT>Learn to know a more versatile way to burn ISO 9660 formatted data</DT>
<DD>
Standalone ISO 9660 multi-session CD/DVD/BD tool
<A HREF="http://scdbackup.sourceforge.net/xorriso_eng.html">xorriso</A>.
</DD>
</DL>
</P>
<HR>
<A NAME="download"></A>
<P>
<DL>
<DT>Download as source code (see README):</DT>
<DD><A HREF="cdrskin-1.5.2.pl01.tar.gz">cdrskin-1.5.2.pl01.tar.gz</A>
(1060 KB).
</DD>
<DD><A HREF="cdrskin-1.5.2.pl01.tar.gz.sig">cdrskin-1.5.2.pl01.tar.gz.sig</A></DD>
<DD>
(detached GPG signature for verification by
<KBD>gpg --verify cdrskin-1.5.2.pl01.tar.gz.sig cdrskin-1.5.2.pl01.tar.gz</KBD>
<BR>
after <KBD>gpg --keyserver keys.gnupg.net --recv-keys ABC0A854</KBD>).
</DD>
<DD>
The cdrskin tarballs are source code identical with libburn releases
of the same version number.
They get produced via a different procedure, though.<BR>
cdrskin is part of libburn - full libburn is provided with cdrskin releases.
</DD>
<!-- This is not offered any more since spring 2008
<DD>&nbsp;</DD>
<DT>Download as single x86 binaries (untar and move to /usr/bin/cdrskin):</DT>
<DD><A HREF="cdrskin_0.4.2.pl00-x86-suse9_0.tar.gz">
cdrskin_0.4.2.pl00-x86-suse9_0.tar.gz</A>, (110 KB),
<DL>
<DD>runs on SuSE 9.0 (2.4.21) , RIP-14.4 (2.6.14) ,
Gentoo (2.6.15 x86_64 Athlon).</DD>
</DL>
<DD><A HREF="cdrskin_0.4.2.pl00-x86-suse9_0-static.tar.gz">
cdrskin_0.4.2.pl00-x86-suse9_0-static.tar.gz</A>, (310 KB), -static compiled,
<DL>
<DD>runs on SuSE 7.2 (2.4.4), and on the systems above.</DD>
</DL>
</DD>
-->
</DL>
<DL><DT>Documentation:</DT>
<DD><A HREF="README_cdrskin">README</A> an introduction</DD>
<DD><A HREF="cdrskin__help">cdrskin --help</A> non-cdrecord options</DD>
<DD><A HREF="cdrskin_help">cdrskin -help</A> cdrecord compatible options</DD>
<DD><A HREF="man_1_cdrskin.html">man cdrskin</A> the manual page</DD>
<DD>&nbsp;</DD>
</DL>
<DL><DT>Contact:</DT>
<DD>Thomas Schmitt, <A HREF="mailto:scdbackup@gmx.net">scdbackup@gmx.net</A></DD>
<DD>GNU xorriso mailing list, where cdrskin and libburn are on topic, too:
<A HREF="mailto:bug-xorriso@gnu.org">bug-xorriso@gnu.org</A></DD>
</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>
<DD>&nbsp;</DD>
</DL>
</P>
<HR>
<P>
Enhancements towards previous stable version cdrskin-1.5.0:
<UL>
<LI>New cdrskin option --list_features</LI>
<!--
<LI>none</LI>
-->
</UL>
Bug fixes towards cdrskin-1.5.0:
<UL>
<LI>
No lock was obtained for setting up a fifo object
</LI>
<LI>
TDK Corporation was not recognized as manufacturer of DVD-R "TTH02"
</LI>
<LI>
Stream recording was applied regardless whether the drive offers it.
This caused Xfburn failures with some MATSHITA laptop drives.
</LI>
</UL>
Bug fixes towards cdrskin-1.5.2 (without .pl01):
<UL>
<LI>
cdrskin multi-track burning was slow and stalled after track 1.
Regression introduced in version 1.5.0 by commit 84fad99, 2018.02.05
</LI>
</UL>
<!--
<LI>none</LI>
Bug fixes towards cdrskin-1.5.2 (without .pl01):
<UL>
</UL>
-->
<HR>
<P>
<DL>
<DT><H3>Development snapshot, version 1.5.3 :</H3></DT>
<DD>Enhancements towards current stable version 1.5.2:
<UL>
<LI>none yet</LI>
<!--
-->
</UL>
</DD>
<DD>Bug fixes towards cdrskin-1.5.2.pl01:
<UL>
<LI>none yet</LI>
<!--
<LI>none yet</LI>
-->
</UL>
</DD>
<DD>&nbsp;</DD>
<DD><A HREF="README_cdrskin_devel">README 1.5.3</A>
<DD><A HREF="cdrskin__help_devel">cdrskin-1.5.3 --help</A></DD>
<DD><A HREF="cdrskin_help_devel">cdrskin-1.5.3 -help</A></DD>
<DD><A HREF="man_1_cdrskin_devel.html">man cdrskin (as of 1.5.3)</A></DD>
<DD>&nbsp;</DD>
<DT>Maintainers of cdrskin unstable packages please use SVN 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>
</KBD></DD>
<DD>Build: <KBD><B>cd libburn ; ./bootstrap ; ./configure --prefix /usr ; make ; cdrskin/compile_cdrskin.sh</B>
</KBD></DD>
<DD>Build of SVN versions needs <A HREF="http://sources.redhat.com/autobook/">
autotools</A> of at least version 1.7 installed.
But after the run of <KBD>./bootstrap</KBD>, only
vanilla tools like make and gcc are needed.</DD>
</DD>
<DD>&nbsp;</DD>
<DT>The following download is intended for adventurous end users or
admins with full system sovereignty.</DT>
<DD>Source (./bootstrap is already applied, build tested, for more see
<A HREF="README_cdrskin_devel">upcoming README</A> ):
</DD>
<DD>
<A HREF="cdrskin-1.5.3.tar.gz">cdrskin-1.5.3.tar.gz</A>
(1060 KB).
</DD>
<!-- This is not offered any more since spring 2008
<DT>The following downloads are intended for adventurous end users or
admins with full system souvereignty.</DT>
<DD>Binary (untar and move to /usr/bin/cdrskin):</DD>
<DD><A HREF="cdrskin_0.4.3-x86-suse9_0.tar.gz">
cdrskin_0.4.3-x86-suse9_0.tar.gz</A>, (110 KB).
</DD>
<DD><A HREF="cdrskin_0.4.3-x86-suse9_0-static.tar.gz">
cdrskin_0.4.3-x86-suse9_0-static.tar.gz</A>, (310 KB)
</DD>
-->
</DL>
</P>
<HR>
<P>
Many thanks to Joerg Schilling for cdrecord,
<BR>
and to Derek Foreman and Ben Jansens for creating libburn.
<BR>
Historic versions based on Derek's and Ben's
<A HREF="http://icculus.org/burn">icculus.org/burn</A> :<BR>
<A HREF="cdrskin-0.1.2.0.2.ts.tar.gz">cdrskin-0.1.2.0.2.ts.tar.gz</A><BR>
<A HREF="cdrskin-0.1.3.0.2.ts.tar.gz">cdrskin-0.1.3.0.2.ts.tar.gz</A>
<BR>
Very special thanks to Andy Polyakov whose
<A HREF="http://fy.chalmers.se/~appro/linux/DVD+RW/tools">dvd+rw-tools</A>
provide libburn with invaluable examples on how to deal with DVD and BD media.
</P>
<HR>
<A NAME="examples">
<P>
<DL>
<DT>Example for a setup of device permissions.</DT>
<DT>
Newer Linux distros enable rw-access for the desktop user automatically.
So try as normal user whether all your drives are found.
CD devices which offer no rw-permission will stay invisible.
</DT>
<DD>$ <KBD><B>cdrskin --devices</B></KBD></DD>
<DT>If not all desired drives show up, become superuser and do again:</DT>
</DT>
<DD># <KBD><B>cdrskin --devices</B></KBD></DD>
<DD><KBD>...</KBD></DD>
<DD><KBD>0&nbsp; dev='/dev/sr0'&nbsp; rwr-r- :&nbsp; 'TEAC' 'CD-ROM CD-532S'</KBD></DD>
<DD><KBD>1&nbsp; dev='/dev/hdc'&nbsp; rwrw-- :&nbsp; 'LITE-ON' 'LTR-48125S'</KBD></DD>
<DT>Most simple and most insecure is this equivalent
of the usual cdrecord permissions u+s,a+x:</DT>
<DD># <KBD><B>chmod a+rw /dev/sr0 /dev/hdc</B></KBD></DD>
<DT>
More secure is to put the permitted users into a group like
"floppy", to assign /dev/sr0 /dev/hdc to this group,
and to allow rw-access only to group members.
</DT>
<DD># <KBD><B>vi /etc/group</B></KBD></DD>
<DD><KBD>...</KBD></DD>
<DD><KBD>floppy:x:19:thomas,scdbackup</KBD></DD>
<DD><KBD>...</KBD></DD>
<DD># <KBD><B>chgrp floppy /dev/sr0 /dev/hdc</B></KBD></DD>
<DD># <KBD><B>chmod g+rw /dev/sr0 /dev/hdc</B></KBD></DD>
</DL>
</P>
<HR>
<A NAME="k3b">
<P>
<A HREF="k3b_on_cdrskin.html">
Example how to setup K3b to use cdrskin for burning data CD projects.
<A><BR>
(<A HREF="http://www.k3b.org">K3b</A>
is a GUI frontend which uses cdrecord for CD burning.)
</P>
<!--
<HR>
<A NAME="scdbackup">
<P>
<DL>
<DT>Example for a test session with a cdrecord based scdbackup installation:</DT>
<DD>$ <KBD><B>cdrskin -scanbus</B></KBD></DD>
<DD><KBD>...</KBD></DD>
<DD><KBD>&nbsp;&nbsp;&nbsp; 2,0,0 &nbsp;&nbsp; 0)&nbsp; 'TEAC' 'CD-ROM CD-532S' '?' Removable CD-ROM</KBD></DD>
<DD>$ <KBD><B>cdrskin -scanbus dev=ATA</B></KBD></DD>
<DD><KBD>...</KBD></DD>
<DD><KBD>&nbsp;&nbsp;&nbsp; 1,0,0 &nbsp;&nbsp; 1)&nbsp; 'LITE-ON' 'LTR-48125S' '?' Removable CD-ROM</KBD></DD>
<DD>$ <KBD><B>export SCDBACKUP_SCSI_ADR="ATA:1,0,0"</B></KBD></DD>
<DD>$ <KBD><B>export SCDBACKUP_CDRECORD="cdrskin -v -v"</B></KBD></DD>
<DD>$ <KBD><B>scdbackup_home</B></KBD></DD>
</DL>
<DL>
<DT>Example for a permanent configuration of cdrskin based scdbackup</DT>
<DD>$ <KBD><B>cd scdbackup-0.8.6/inst</B></KBD></DD>
<DD>$ <KBD><B>export SCDBACKUP_USE_CDRSKIN=1</B></KBD></DD>
<DD>$ <KBD><B>./CONFIGURE_CD</B></KBD></DD>
<DD><KBD>...</KBD></DD>
<DD><KBD>cdrskin 0.3.8 : limited cdrecord compatibility wrapper for libburn</KBD></DD>
</DL>
If your system is stricken with some ill CD device then this can stall
and you will have to press <KBD>Ctrl+C</KBD> to abort.
In this case, you may execute
<KBD>export SCDBACKUP_NO_SCANBUS=1</KBD>
and try again.
<DL>
<DT></DT>
<DD><KBD> ------------------- SCSI devices. To be used like &nbsp;&nbsp; 0,0,0</KBD></DD>
<DD><KBD>&nbsp;&nbsp;&nbsp; 2,0,0 &nbsp;&nbsp; 0)&nbsp; 'TEAC' 'CD-ROM CD-532S' '?' Removable CD-ROM</KBD></DD>
<DD><KBD> ------------------- end of SCSI device list</KBD></DD>
<DD><KBD> ------------------- ATA devices. To be used like ATA:0,0,0
<DD><KBD>&nbsp;&nbsp;&nbsp; 1,0,0 &nbsp;&nbsp; 1)&nbsp; 'LITE-ON' 'LTR-48125S' '?' Removable CD-ROM</KBD></DD>
<DD><KBD>...</KBD></DD>
<DD><KBD>&nbsp;&nbsp;&nbsp; * Your cdrecord offers -driveropts=burnfree with your recorder.</KBD></DD>
<DD><KBD>...</KBD></DD>
<DD><KBD>scdbackup for CD 0.8.6 : First stage of installation done.</KBD></DD>
<DD><KBD>...</KBD></DD>
<DD><KBD>Now give it a try. Run : scdbackup_home</KBD></DD>
<DD>$ <KBD><B>unset SCDBACKUP_USE_CDRSKIN</B></KBD></DD>
</DL>
<DL>
<DT>To get back to using cdrecord :</DT>
<DD>$ <KBD><B>cd scdbackup-0.8.6/inst</B></KBD></DD>
<DD>$ <KBD><B>export SCDBACKUP_USE_CDRSKIN=0</B></KBD></DD>
<DD>$ <KBD><B>./CONFIGURE_CD</B></KBD></DD>
<DD><KBD>...</KBD></DD>
<DD>$ <KBD><B>unset SCDBACKUP_USE_CDRSKIN</B></KBD></DD>
</DL>
</P>
-->
<HR>
<A NAME="cdrecord">
<P>
<CENTER><H3>About the relationship of cdrecord and cdrskin</H3></CENTER>
First of all: this relationship is single sided, as cdrskin has to be aware of
cdrecord but not vice versa.
<BR>
<BR>
I was a long time user of cdrecord and it worked fine for me.
Especially i do appreciate its write mode -tao which can pipe arbitrary
data on CD and CD-RW via stdin. cdrecord is reliable, versatile and well
maintained. So for me - there would be no problem with using it for
burning CDs.
<BR>
But the author of cdrecord and the Linux kernel people foster a very hostile
relationship. Ok, that's their business, not mine (or ours if you are with me).
One has to be aware, though, that this relationship might lead to a situation
where cdrecord is no longer available for certain Linux kernels.
<BR>
To have my own project prepared for such a time, i began to implement its
cdrecord gestures on top of libburn.
From now on i invite other interested users of cdrecord to teach cdrskin
the gestures necessary for their cdrecord applications.
Contact me. Let's see what we can achieve.
<BR>
<BR>
libburn and cdrskin are now mature enough to substitute cdrecord in its
major use cases of CD and DVD burning. It is possible to foist cdrskin on
various software packages if it gets falsely named "cdrecord".
I do not encourage this approach, but of course such a replacement
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.
I owe him much. For cdrecord, for mkisofs, for star. Chapeau.
<BR>
</P>
<HR>
<CENTER><FONT SIZE=+0>
<!-- <A NAME="bottom" HREF="main_ger.html#bottom">deutsch (german)</A>
<BR><BR>
-->
<A HREF="http://en.wikipedia.org/wiki/D%C3%B6ner_kebab">
<IMG SRC="doener_150x200_tr.png" BORDER=0
ALT="cdrskin logo: Doener mit Scharf"></A>
<BR><BR>
<FONT SIZE=+0>Enjoying free Open Source hosting by <A HREF="http://www.webframe.org">www.webframe.org</A><BR>
<A HREF="http://www.webframe.org">
<IMG SRC="msfree.gif" ALT="100 % Microsoft free" BORDER=0></A><BR>
and by <A HREF="http://sourceforge.net">sourceforge.net</A><BR>
<A href="http://sourceforge.net">
<IMG src="sflogo-88-1.png" BORDER="0" ALT="SourceForge Logo"></A>
<!-- on sourceforge use : <IMG src="http://sourceforge.net/sflogo.php?group_id=16010" width="88" height="31" border="0" alt="SourceForge Logo"></A> -->
<!--
<P>
Enjoying a FreeBSD shell account with the opportunity to
build and install cdrskin at<BR>
<A HREF="http://www.en.free-shells.com.ar">free-shells.com.ar</A>
</P>
-->
</FONT></CENTER>
<HR>
<DL>
<DT>Links to my other published software projects :
<DD><A HREF="http://scdbackup.webframe.org/xorriso_eng.html">
xorriso, a standalone ISO 9660 multi-session CD/DVD/BD burn tool.
No mkisofs needed.
<DL>
<DD>
<A HREF="http://scdbackup.sourceforge.net/xorriso_eng.html">
(a second source of above)</A>
</DD>
</DL>
</DD>
<DD><A HREF=http://scdbackup.webframe.org/main_eng.html>
scdbackup, multi volume CD backup</A>
<DL><DD><A HREF=http://scdbackup.sourceforge.net/main_eng.html>
(a second source of above)</A></DD></DL></DD>
<DD><A HREF=http://stic.sourceforge.net>Some Tools for Image Collectors</A>
</DD>
<DD><A HREF=http://scdbackup.webframe.org/pppoem>
pppoem, a DSL throughput monitor (mainly for Linux kernel 2.4)</A>
</DD>
</DL>
<BR><BR>
Legal statement: This website does not serve any commercial purpose.<BR>
</FONT>
</BODY>
</HTML>

View File

@ -0,0 +1 @@
#define Cdrskin_timestamP "2019.11.25.094931"

14102
cdrskin/changelog.txt Normal file

File diff suppressed because it is too large Load Diff

216
cdrskin/cleanup.c Normal file
View File

@ -0,0 +1,216 @@
/*
cleanup.c , Copyright 2006 Thomas Schmitt <scdbackup@gmx.net>
A signal handler which cleans up an application and exits.
Provided under GPL license within GPL projects, BSD license elsewise.
*/
/*
cc -g -o cleanup -DCleanup_standalonE cleanup.c
*/
#include <sys/types.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <signal.h>
typedef void (*sighandler_t)(int);
#include "cleanup.h"
#ifndef Cleanup_has_no_libburn_os_H
#include "../libburn/os.h"
/* see os.h for name of particular os-*.h where this is defined */
static int signal_list[]= { BURN_OS_SIGNAL_MACRO_LIST , -1};
static char *signal_name_list[]= { BURN_OS_SIGNAL_NAME_LIST , "@"};
static int signal_list_count= BURN_OS_SIGNAL_COUNT;
static int non_signal_list[]= { BURN_OS_NON_SIGNAL_MACRO_LIST, -1};
static int non_signal_list_count= BURN_OS_NON_SIGNAL_COUNT;
#else /* ! Cleanup_has_no_libburn_os_H */
/* Outdated. Linux only. For backward compatibility with pre-libburn-0.2.3 */
/* Signals to be caught */
static int signal_list[]= {
SIGHUP, SIGINT, SIGQUIT, SIGILL, SIGABRT,
SIGFPE, SIGSEGV, SIGPIPE, SIGALRM, SIGTERM,
SIGUSR1, SIGUSR2, SIGXCPU, SIGTSTP, SIGTTIN,
SIGTTOU,
SIGBUS, SIGPOLL, SIGPROF, SIGSYS, SIGTRAP,
SIGVTALRM, SIGXCPU, SIGXFSZ, -1
};
static char *signal_name_list[]= {
"SIGHUP", "SIGINT", "SIGQUIT", "SIGILL", "SIGABRT",
"SIGFPE", "SIGSEGV", "SIGPIPE", "SIGALRM", "SIGTERM",
"SIGUSR1", "SIGUSR2", "SIGXCPU", "SIGTSTP", "SIGTTIN",
"SIGTTOU",
"SIGBUS", "SIGPOLL", "SIGPROF", "SIGSYS", "SIGTRAP",
"SIGVTALRM", "SIGXCPU", "SIGXFSZ", "@"
};
static int signal_list_count= 24;
/* Signals not to be caught */
static int non_signal_list[]= {
SIGKILL, SIGCHLD, SIGSTOP, SIGURG, SIGWINCH, -1
};
static int non_signal_list_count= 5;
#endif /* Cleanup_has_no_libburn_os_H */
/* run time dynamic part */
static char cleanup_msg[4096]= {""};
static int cleanup_exiting= 0;
static int cleanup_has_reported= -1234567890;
static void *cleanup_app_handle= NULL;
static Cleanup_app_handler_T cleanup_app_handler= NULL;
static int cleanup_perform_app_handler_first= 0;
static int Cleanup_handler_exit(int exit_value, int signum, int flag)
{
int ret;
if(cleanup_msg[0]!=0 && cleanup_has_reported!=signum) {
fprintf(stderr,"\n%s\n",cleanup_msg);
cleanup_has_reported= signum;
}
if(cleanup_perform_app_handler_first)
if(cleanup_app_handler!=NULL) {
ret= (*cleanup_app_handler)(cleanup_app_handle,signum,0);
if(ret==2 || ret==-2)
return(2);
}
if(cleanup_exiting) {
fprintf(stderr,"cleanup: ABORT : repeat by pid=%d, signum=%d\n",
getpid(),signum);
return(0);
}
cleanup_exiting= 1;
alarm(0);
if(!cleanup_perform_app_handler_first)
if(cleanup_app_handler!=NULL) {
ret= (*cleanup_app_handler)(cleanup_app_handle,signum,0);
if(ret==2 || ret==-2)
return(2);
}
exit(exit_value);
}
static void Cleanup_handler_generic(int signum)
{
int i;
sprintf(cleanup_msg,"UNIX-SIGNAL caught: %d errno= %d",signum,errno);
for(i= 0; i<signal_list_count; i++)
if(signum==signal_list[i]) {
sprintf(cleanup_msg,"UNIX-SIGNAL: %s errno= %d",
signal_name_list[i],errno);
break;
}
Cleanup_handler_exit(1,signum,0);
}
int Cleanup_set_handlers(void *handle, Cleanup_app_handler_T handler, int flag)
/*
bit0= set to default handlers
bit1= set to ignore
bit2= set cleanup_perform_app_handler_first
bit3= set SIGABRT to handler (makes sense with bits 0 or 1)
*/
{
int i,j,max_sig= -1,min_sig= 0x7fffffff;
sighandler_t sig_handler;
cleanup_msg[0]= 0;
cleanup_app_handle= handle;
cleanup_app_handler= handler;
/* <<< make cleanup_exiting thread safe to get rid of this */
if(flag&4)
cleanup_perform_app_handler_first= 1;
if(flag&1)
sig_handler= SIG_DFL;
else if(flag&2)
sig_handler= SIG_IGN;
else
sig_handler= Cleanup_handler_generic;
/* set all signal numbers between the lowest and highest in the list
except those in the non-signal list */
for(i= 0; i<signal_list_count; i++) {
if(signal_list[i]>max_sig)
max_sig= signal_list[i];
if(signal_list[i]<min_sig)
min_sig= signal_list[i];
}
for(i= min_sig; i<=max_sig; i++) {
for(j= 0; j<non_signal_list_count; j++)
if(i==non_signal_list[j])
break;
if(j>=non_signal_list_count) {
if(i==SIGABRT && (flag&8))
signal(i,Cleanup_handler_generic);
else
signal(i,sig_handler);
}
}
return(1);
}
#ifdef Cleanup_standalonE
struct Demo_apP {
char *msg;
};
int Demo_app_handler(struct Demo_apP *demoapp, int signum, int flag)
{
printf("Handling exit of demo application on signal %d. msg=\"%s\"\n",
signum,demoapp->msg);
return(1);
}
main()
{
struct Demo_apP demoapp;
demoapp.msg= "Good Bye";
Cleanup_set_handlers(&demoapp,(Cleanup_app_handler_T) Demo_app_handler,0);
if(1) { /* change to 0 in order to wait for external signals */
char *cpt= NULL, c= ' ';
printf("Intentionally provoking SIGSEGV ...\n");
c= *cpt;
printf("Strange: The system ignored a SIGSEGV: c= %u\n", (unsigned int) c);
} else {
printf("killme: %d\n",getpid());
sleep(3600);
}
Cleanup_set_handlers(NULL,NULL,1);
exit(0);
}
#endif /* Cleanup_standalonE */

34
cdrskin/cleanup.h Normal file
View File

@ -0,0 +1,34 @@
/*
cleanup.c , Copyright 2006 Thomas Schmitt <scdbackup@gmx.net>
A signal handler which cleans up an application and exits.
Provided under GPL license within GPL projects, BSD license elsewise.
*/
#ifndef Cleanup_includeD
#define Cleanup_includeD 1
/** Layout of an application provided cleanup function using an application
provided handle as first argument and the signal number as second
argument. The third argument is a flag bit field with no defined bits yet.
If the handler returns 2 or -2 then it has delegated exit() to some other
instance and the Cleanup handler shall return rather than exit.
*/
typedef int (*Cleanup_app_handler_T)(void *, int, int);
/** Establish exiting signal handlers on (hopefully) all signals that are
not ignored by default or non-catchable.
@param handle Opaque object which knows how to cleanup application
@param handler Function which uses handle to perform application cleanup
@param flag Control Bitfield
bit0= reset to default signal handling
*/
int Cleanup_set_handlers(void *handle, Cleanup_app_handler_T handler,
int flag);
#endif /* ! Cleanup_includeD */

245
cdrskin/compile_cdrskin.sh Executable file
View File

@ -0,0 +1,245 @@
#!/bin/sh
# compile_cdrskin.sh
# Copyright 2005 - 2019 Thomas Schmitt, scdbackup@gmx.net, GPL v2 or later
# to be executed within ./libburn-* or./cdrskin-*
debug_opts="-O2"
def_opts=
largefile_opts="-D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE=1"
fifo_opts=""
libvers="-DCdrskin_libburn_1_5_2"
# To be used if Makefile.am uses libburn_libburn_la_CFLAGS
# burn="libburn/libburn_libburn_la-"
burn="libburn/"
cleanup_src_or_obj="$burn"cleanup.o
libdax_msgs_o="$burn"libdax_msgs.o
libdax_audioxtr_o="$burn"libdax_audioxtr.o
do_strip=0
static_opts=
warn_opts="-Wall -Wextra -Wno-unused-parameter"
libcdio=
fifo_source="cdrskin/cdrfifo.c"
compile_cdrskin=1
compile_cdrfifo=0
compile_dewav=0
libcam=
os=$(uname -s)
case $os in
*FreeBSD)
libcam="-lcam"
esac
for i in "$@"
do
if test "$i" = "-compile_cdrfifo"
then
compile_cdrfifo=1
elif test "$i" = "-compile_dewav"
then
compile_dewav=1
elif test "$i" = "-libburn_1_5_2"
then
libvers="-DCdrskin_libburn_1_5_2"
libdax_audioxtr_o="$burn"libdax_audioxtr.o
libdax_msgs_o="$burn"libdax_msgs.o
cleanup_src_or_obj="$burn"cleanup.o
elif test "$i" = "-libburn_svn"
then
libvers="-DCdrskin_libburn_1_5_3"
libdax_audioxtr_o="$burn"libdax_audioxtr.o
libdax_msgs_o="$burn"libdax_msgs.o
cleanup_src_or_obj="$burn"cleanup.o
elif test "$i" = "-newapi" -o "$i" = "-experimental"
then
def_opts="$def_opts -DCdrskin_new_api_tesT"
elif test "$i" = "-no_largefile"
then
largefile_opts=
elif test "$i" = "-dvd_obs_64k"
then
def_opts="$def_opts -DCdrskin_dvd_obs_default_64K"
elif test "$i" = "-do_not_compile_cdrskin"
then
compile_cdrskin=0
elif test "$i" = "-do_diet"
then
fifo_source=
def_opts="$def_opts -DCdrskin_extra_leaN"
warn_opts=
elif test "$i" = "-do_strip"
then
do_strip=1
elif test "$i" = "-use_libburn_fifo"
then
fifo_opts="-DCdrskin_use_libburn_fifO"
elif test "$i" = "-use_no_libburn_fifo"
then
fifo_opts=""
elif test "$i" = "-use_no_cdrfifo"
then
fifo_source=
fifo_opts="-DCdrskin_use_libburn_fifO -DCdrskin_no_cdrfifO"
elif test "$i" = "-use_libburn_cleanup"
then
fifo_source=
fifo_opts="-DCdrskin_use_libburn_cleanuP -DCdrskin_use_libburn_fifO -DCdrskin_no_cdrfifO"
elif test "$i" = "-use_libcdio"
then
libcdio="-lcdio"
elif test "$i" = "-g"
then
debug_opts="-g"
elif test "$i" = "-help" -o "$i" = "--help" -o "$i" = "-h"
then
echo "cdrskin/compile_cdrskin.sh : to be executed within top level directory"
echo "Options:"
echo " -compile_cdrfifo compile program cdrskin/cdrfifo."
echo " -compile_dewav compile program test/dewav without libburn."
echo " -libburn_1_5_2 set macro to match libburn-1.5.2"
echo " -libburn_svn set macro to match current libburn-SVN."
echo " -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."
echo " -use_no_libburn_fifo use cdrfifo even for single track non-CD"
echo " -use_no_cdrfifo always use fifo of libburn and never cdrfifo"
echo " -experimental use newly introduced libburn features."
echo " -do_diet produce capability reduced lean version."
echo " -do_strip apply program strip to compiled programs."
echo " -g produce debuggable programm."
echo " -static compile with cc option -static."
exit 0
elif test "$i" = "-static"
then
static_opts="-static"
fi
done
timestamp="$(date -u '+%Y.%m.%d.%H%M%S')"
echo "Version timestamp : $(sed -e 's/#define Cdrskin_timestamP "//' -e 's/"$//' cdrskin/cdrskin_timestamp.h)"
echo "Build timestamp : $timestamp"
if test "$compile_cdrskin"
then
echo "compiling program cdrskin/cdrskin.c $fifo_source $static_opts $debug_opts $libvers $fifo_opts $def_opts $cleanup_src_or_obj $libcdio $libcam"
cc -I. \
$warn_opts \
$static_opts \
$debug_opts \
$libvers \
$largefile_opts \
$fifo_opts \
$def_opts \
\
-DCdrskin_build_timestamP='"'"$timestamp"'"' \
\
-o cdrskin/cdrskin \
\
cdrskin/cdrskin.c \
$fifo_source \
\
$cleanup_src_or_obj \
\
"$burn"async.o \
"$burn"cdtext.o \
"$burn"debug.o \
"$burn"drive.o \
"$burn"file.o \
"$burn"init.o \
"$burn"options.o \
"$burn"source.o \
"$burn"structure.o \
\
"$burn"sg.o \
"$burn"write.o \
"$burn"read.o \
$libdax_audioxtr_o \
$libdax_msgs_o \
\
"$burn"mmc.o \
"$burn"sbc.o \
"$burn"spc.o \
"$burn"util.o \
\
"$burn"sector.o \
"$burn"toc.o \
\
"$burn"crc.o \
"$burn"ecma130ab.o \
\
$libcdio \
$libcam \
-lpthread
ret=$?
if test "$ret" = 0
then
dummy=dummy
else
echo >&2
echo "+++ FATAL : Compilation of cdrskin failed" >&2
echo >&2
exit 1
fi
fi
if test "$compile_cdrfifo" = 1
then
echo "compiling program cdrskin/cdrfifo.c $static_opts $debug_opts"
cc $static_opts $debug_opts \
-DCdrfifo_standalonE \
-o cdrskin/cdrfifo \
cdrskin/cdrfifo.c
ret=$?
if test "$ret" = 0
then
dummy=dummy
else
echo >&2
echo "+++ FATAL : Compilation of cdrfifo failed" >&2
echo >&2
exit 2
fi
fi
if test "$compile_dewav" = 1
then
echo "compiling program test/dewav.c -DDewav_without_libburN $static_opts $debug_opts"
cc $static_opts $debug_opts \
-DDewav_without_libburN \
-o test/dewav \
test/dewav.c \
"$burn"libdax_audioxtr.o \
"$burn"libdax_msgs.o \
\
-lpthread
ret=$?
if test "$ret" = 0
then
dummy=dummy
else
echo >&2
echo "+++ FATAL : Compilation of test/dewav failed" >&2
echo >&2
exit 2
fi
fi
if test "$do_strip" = 1
then
echo "stripping result cdrskin/cdrskin"
strip cdrskin/cdrskin
if test "$compile_cdrfifo" = 1
then
echo "stripping result cdrskin/cdrfifo"
strip cdrskin/cdrfifo
fi
fi
echo 'done.'

82
cdrskin/convert_man_to_html.sh Executable file
View File

@ -0,0 +1,82 @@
#!/bin/sh
#
# convert_man_to_html.sh - ts A61214 , B50802
#
# Generates a HTML version of man page cdrskin.1
#
# To be executed within the libburn toplevel directory (like ./libburn-0.2.7)
#
# set -x
man_dir=$(pwd)"/cdrskin"
export MANPATH="$man_dir"
manpage="cdrskin"
raw_html=$(pwd)/"cdrskin/raw_man_1_cdrskin.html"
htmlpage=$(pwd)/"cdrskin/man_1_cdrskin.html"
if test -r "$man_dir"/"$manpage".1
then
dummy=dummy
else
echo "Cannot find readable man page source $1" >&2
exit 1
fi
if test -e "$man_dir"/man1
then
dummy=dummy
else
ln -s . "$man_dir"/man1
fi
if test "$1" = "-work_as_filter"
then
# set -x
sed \
-e 's/<meta name="generator" content="groff -Thtml, see www.gnu.org">/<meta name="generator" content="groff -Thtml, via man -H, via cdrskin\/convert_man_to_html.sh">/' \
-e 's/<meta name="Content-Style" content="text\/css">/<meta name="Content-Style" content="text\/css"><META NAME="description" CONTENT="man page of cdrskin"><META NAME="keywords" CONTENT="man cdrskin, manual, cdrskin, CD-RW, CD-R, DVD-R, DVD-RW, DVD+R, DVD+RW, BD-R, BD-RE, burning, cdrecord, compatible"><META NAME="robots" CONTENT="follow">/' \
-e 's/<title>CDRSKIN<\/title>/<title>man 1 cdrskin<\/title>/' \
-e 's/<h1 align=center>CDRSKIN<\/h1>/<h1 align=center>man 1 cdrskin<\/h1>/' \
-e 's/<body>/<body BGCOLOR="#F5DEB3" TEXT=#000000 LINK=#0000A0 VLINK=#800000>/' \
-e 's/<b>Overview of features:<\/b>/<b>Overview of features:<\/b><BR>/' \
-e 's/<b>General information paragraphs:<\/b>/<b>General information paragraphs:<\/b><BR>/' \
-e 's/<b>Track recording model:<\/b>/\&nbsp;<BR><b>Track recording model:<\/b><BR>/' \
-e 's/^In general there are two types of tracks: data and audio./\&nbsp;<BR>In general there are two types of tracks: data and audio./' \
-e 's/^While audio tracks just contain a given/\&nbsp;<BR>While audio tracks just contain a given/' \
-e 's/<b>Write mode selection:<\/b>/<b>Write mode selection:<\/b><BR>/' \
-e 's/<b>Recordable CD Media:<\/b>/<b>Recordable CD Media:<\/b><BR>/' \
-e 's/<b>Overwriteable DVD or BD Media:<\/b>/<b>Overwriteable DVD or BD Media:<\/b><BR>/' \
-e 's/<b>Sequentially Recordable DVD or BD Media:<\/b>/<b>Sequentially Recordable DVD or BD Media:<\/b><BR>/' \
-e 's/^The write modes for DVD+R/\&nbsp;<BR>The write modes for DVD+R/' \
-e 's/<b>Drive preparation and addressing:<\/b>/<b>Drive preparation and addressing:<\/b><BR>/' \
-e 's/^If you only got one CD capable drive/\&nbsp;<BR>If you only got one CD capable drive/' \
-e 's/<b>Emulated drives:<\/b>/<b>Emulated drives:<\/b><BR>/' \
-e 's/for normal use: <b><br>/for normal use: <b><br><BR>/' \
-e 's/original cdrecord by Joerg Schilling:<\/p>/original cdrecord by Joerg Schilling:<\/p><BR>/' \
-e 's/<\/body>/<BR><HR><FONT SIZE=-1><CENTER>(HTML generated from '"$manpage"'.1 on '"$(date)"' by '$(basename "$0")' )<\/CENTER><\/FONT><\/body>/' \
-e 's/See section FILES/See section <A HREF="#FILES">FILES<\/A>/' \
-e 's/See section EXAMPLES/See section <A HREF="#EXAMPLES">EXAMPLES<\/A>/' \
-e 's/&minus;/-/g' \
<"$2" >"$htmlpage"
set +x
chmod u+rw,go+r,go-w "$htmlpage"
echo "Emerged file:"
ls -lL "$htmlpage"
else
# export BROWSER='cp "%s" '"$raw_html"
export BROWSER=$(pwd)/'cdrskin/unite_html_b_line "%s" '"$raw_html"
man -H "$manpage"
# cp "$raw_html" /tmp/x.html
"$0" -work_as_filter "$raw_html"
rm "$raw_html"
rm "$man_dir"/man1
fi

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.2 KiB

9
cdrskin/make_timestamp.sh Executable file
View File

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

124
cdrskin/unite_html_b_line.c Normal file
View File

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

297
cdrskin/wiki_plain.txt Normal file
View File

@ -0,0 +1,297 @@
--------------------------------------------------------------------------
cdrskin Wiki - plain text copy
--------------------------------------------------------------------------
[[Image(source:/libburn/trunk/cdrskin/doener_150x200_tr.png)]] [http://en.wikipedia.org/wiki/D%C3%B6ner_kebab Doener]
'''cdrskin is the cdrecord compatibility middleware of libburn.'''
Its paragon, cdrecord, is a powerful GPL'ed burn program included in Joerg
Schilling's cdrtools. cdrskin strives to be a second source for the services
traditionally provided by cdrecord. Currently it does CD-R and CD-RW this way.
Overwriteable media DVD-RAM, DVD+RW, DVD-RW, and BD-RE are handled differently
than with cdrecord-ProDVD in order to offer TAO-like single track recording.
Sequential DVD-R[W], DVD+R, DVD+R DL, BD-R are handled like CD-R[W] with TAO
and multi-session. Additionally cdrskin offers cdrecord-ProDVD-like mode DAO
with DVD-R[W].
cdrskin does not contain any bytes copied from cdrecord's sources.
Many bytes have been copied from the message output of cdrecord
runs, though. The most comprehensive technical overview of cdrskin
can be found in [http://libburnia-project.org/browser/libburn/trunk/cdrskin/README?format=txt cdrskin/README].
About libburn API for burning CD, DVD, and BD: http://api.libburnia-project.org
--------------------------------------------------------------------------
About the command line options of cdrskin:
They are described in detail in [http://scdbackup.sourceforge.net/man_1_cdrskin_devel.html#OPTIONS section OPTIONS] of
[http://scdbackup.sourceforge.net/man_1_cdrskin_devel.html man cdrskin]
There are two families of options: cdrecord-compatible ones and options
which are specific to cdrskin. The latter are mostly used to configure
cdrskin for its task to emulate cdrecord. There are some, nevertheless,
which provide rather exotic unique features of cdrskin.
The cdrecord-compatible options are listed in the output of
{{{
cdrskin -help
}}}
where the option "help" has *one* dash. Online: [http://scdbackup.sourceforge.net/cdrskin_help_devel cdrskin -help]
For these options you may expect program behavior that is roughly the
same as described in original man cdrecord .
Online: http://cdrecord.berlios.de/old/private/man/cdrecord-2.0.html
The cdrskin-specific options are listed by
{{{
cdrskin --help
}}}
where the option "help" has *two* dashes. Online: [http://scdbackup.sourceforge.net/cdrskin__help_devel cdrskin --help]
Some are very experimental and should only be
used in coordination with the libburnia developer team.
Some are of general user interest, though:
--------------------------------------------------------------------------
--devices can be used by the sysadmin to scan the system for possible drives
and displays their detected properties.
The drives are listed one per line, with fields:
libburn-drive-number, sysadmin-device-file, permissions, vendor, type
{{{
0 dev='/dev/sr0' rwrw-- : 'HL-DT-ST' 'DVDRAM GSA-4082B'
}}}
This feature is valuable since cdrskin -scanbus will not give you
the device file name and its current permissions.
cdrskin will accept of course the proposed dev= option as address
for any usage of the drive.
Different from cdrecord, cdrskin is intended to be run without special
privileges, i.e. no superuser setuid. It is intended that the sysadmin
controls drive accessability by rw-permissions of the drive rather than
by x-permission of the burn binary. To be usable with cdrskin, the drive
has to offer both, r- and w-permission.
--------------------------------------------------------------------------
blank=as_needed applies the suitable blanking or formatting to make
any supported type of media ready for writing from scratch.
If this is not possible, e.g. because the media is written and not
re-usable, then the program run fails.
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 acquire MMC background information before making use of them.
--------------------------------------------------------------------------
cdrskin does not only read from and write to optical drives which comply
to the MMC standard but also does the same with regular files or block
devices other than optical drives.
Because the power to alter a disk file might be a bad surprise for a
traditional user of cdrecord, it is necessary to give option
--allow_emulated_drives before an emulated drive may be addressed.
Eventually one of the startup files would be a good place for it.
See man page, section FILES.
The addresses of emulated drives begin with the prefix "stdio:".
{{{
dev=stdio:/tmp/pseudo_drive
dev=stdio:/dev/usbstick
}}}
Regular files and block devices behave much like DVD-RAM.
Other file types may be valid targets for write-only operations.
This includes standard output, named pipes, character devices
{{{
dev=stdio:/dev/fd/1
dev=stdio:/tmp/named_pipe
dev=stdio:/dev/ptyxy
}}}
These files behave much like blank DVD-R.
All files used as pseudo-drives have to offer rw-permission.
--------------------------------------------------------------------------
The DVD capabilities of cdrskin differ from those of cdrecord-ProDVD. cdrskin
offers TAO-like multi-session with DVD-R[W], DVD+R[ DL] and TAO-like single
session with overwriteable DVD media. It also offers DAO on DVD-R[W] which is
probably the same as the traditional cdrecord-ProDVD write mode.
Non-cdrecord blank mode blank=format_overwrite brings a DVD-RW
disc from its initial profile "Sequential Recording" into profile state
"Restricted Overwrite".
{{{
cdrskin dev=/dev/sr0 -v blank=format_overwrite
}}}
DVD-RAM, DVD+RW, BD-RE and overwriteable DVD-RW appear to cdrskin as blank
media which are capable of taking only a single track. This track may be
positioned on a 32KiB aligned address, though.
{{{
cdrskin ... write_start_address=2412m ...
}}}
Non-cdrecord blank mode blank=deformat_sequential brings an overwriteable
DVD-RW back into state "Sequential Recording" with the capability of doing
multi-session, if the drive is capable of "Incremental Streaming"
(MMC feature 21h).
Used sequential DVD-RW media may be blanked by blank=fast or blank=all which
normally both do full blanking. Thus sequential DVD-RW behave much like large
CD-RW with possibly more than 99 tracks.
blank=deformat_sequential does minimal blanking of DVD-RW which usually yields
media incapable of "Incremental Streaming".
Option --prodvd_cli_compatible activates blank=fast and blank=all for
overwriteable DVD-RW which normally ignore those two options. It also makes
option -multi tolerable with media and write modes which are not suitable for
multi-session. (The default behavior of cdrskin deems me to be preferrable.)
Option --grow_overwriteable_iso gives cdrskin ISO pseudo-multi-session
capabilities on DVD-RAM, DVD+RW, BD-RE similar to growisofs.
Associated options blank=, -multi, -msinfo and -toc are available in this case.
They either pretend a blank media (if there is no ISO 9660 image) or appendable
media with a single session and track on it. blank= invalidates ISO images.
--------------------------------------------------------------------------
assert_write_lba=<lba> ensures that the start block address which
was used with the formatter program (e.g. mkisofs -C) matches the start block
address which will be used by the upcoming burn.
E.g. cdrskin aborts with an error message if
{{{
assert_write_lba=0
}}}
is given but an appendable media is to be burned which would start at
block 68432.
An ISO-9660 file system image must be prepared according to a particular
block address on media. If the prepared address and the real address on media
do not match then the filesystem will not be mountable or may even cause system
trouble.
A sequential archive format like afio or star will not necessarily need such
a coordination of addresses. It might nevertheless be confusing to a reader
if the archive does not start at block 0.
--------------------------------------------------------------------------
fifo_start_at=<num> is a throughput enhancer for unsteady data streams
like they are produced by a compressing archiver program when piping to
CD on-the-fly. It makes better use of the general property of a FIFO
buffer to transport surplus bandwidth into the future. Yep. A time machine.
One-way, i fear.
FIFO originally was introduced by cdrecord's author Joerg Schilling in order
to protect mediocre burner hardware from suffering buffer underruns
and thus producing misburns (at 1x speed on CD-R media at the price of a
DVD-RAM nowadays). This purpose would not justify a fifo any more -
given the limited life time of burners and the seamless underrun protection
of contemporary consumer drives.
With an unsteady data stream the task of the buffer is to soak up peak
performance and to release it steadily at the drive's maximum speed.
The larger the buffer the more reserves can be built up and the longer
input drought can be compensated.
Original cdrecord has the historical property, though, to first wait until
the buffer is completely filled. Best practice for fighting drive
underruns, of course.
With a very fat fs=# buffer (128 MB for 12x CD is not unrealistic) this
can cause a big delay until burning finally starts and takes its due time.
fifo_start_at=<num> makes cdrskin start burning after the given number of bytes
is read rather than waiting for the FIFO to be completely full or the data
stream to end. It risks a few drive buffer underruns at the beginning of burn
- but modern drives stand this.
Usage examples:
{{{
cdrskin ... fs=128m fifo_start_at=20m ...
cdrskin ... fifo_start_at=0 ...
}}}
Note: no FIFO can give you better average throughput than the average
throughput of the data source and the throughput of the burner.
It can be used, though, to bring the effective throughput very close
to the theoretical limit. Especially with high speed media.
--------------------------------------------------------------------------
--no_rc allows you to surely ban influence from systemwide or user specific
default settings of cdrskin. Possible locations for such settings:
/etc/default/cdrskin
/etc/opt/cdrskin/rc
/etc/cdrskin/cdrskin.conf
$HOME/.cdrskinrc
--------------------------------------------------------------------------
dev_translation=<sep><from><sep><to> may be needed to foist cdrskin to
frontend programs of cdrecord which do *not* ask cdrecord -scanbus but
which make own assumptions and guesses about cdrecord's device addresses.
Normally, cdrskin understands all addresses which are suitable for cdrecord
under Linux. See cdrskin/README, "Pseudo-SCSI Adresses".
This option is mainly for (yet unknown) exotic configurations or very
stubborn frontend programs.
If a frontend refuses to work with cdrskin, look into the error protocol
of that frontend, look at the output of a run of cdrskin --devices and give
cdrskin the necessary hint.
Example: Your frontend insists in using "0,0,0" and --devices reported
dev='/dev/hdc' resp. cdrskin dev=ATA -scanbus reported "1,0,0" then this
would be the appropriate translation:
{{{
dev_translation=+0,0,0+/dev/hdc
}}}
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
{{{
dev_translation=-"cd+dvd"-1,0,0
}}}
See http://scdbackup.sourceforge.net/k3b_on_cdrskin.html
for an illustrated example with K3b 0.10 .
--------------------------------------------------------------------------
Advanced multi-session use cases as of dvd+rw-tools:
A special feature of dvd+rw-tools is growing of ISO-9660 filesystems on
overwriteable media. This is not the same as multi-session writing of cdrskin
with CD media, but retrieves additional information from the existing ISO
image and finally manipulates the start sectors of this existing image.
So, inspired by growisofs, cdrskin can offer DVD multi-session not only with
sequential DVD-R[W] and with DVD+R [DL], but also with DVD-RAM, DVD+RW, BD-RE
and even regular disk files or block devices other than CD/DVD writers.
This is enabled by option --grow_overwriteable_iso.
The libburnia project provides an integrated ISO-9660 multi-session tool
named [wiki:Xorriso xorriso] which tries to go one step beyond
growisofs. It uses [wiki:Libburn libburn] , [wiki:Libisofs libisofs]
and [wiki:Libisoburn libisoburn].
See [http://scdbackup.sourceforge.net/man_1_xorriso.html man xorriso].
--------------------------------------------------------------------------

377
configure.ac Normal file
View File

@ -0,0 +1,377 @@
AC_INIT([libburn], [1.5.2], [http://libburnia-project.org])
AC_PREREQ([2.50])
dnl AC_CONFIG_HEADER([config.h])
AC_CANONICAL_HOST
AC_CANONICAL_TARGET
LIBBURNIA_SET_FLAGS
AM_INIT_AUTOMAKE([subdir-objects])
AC_CONFIG_MACRO_DIR([./])
dnl Notes about version numbers and .so numbers:
dnl
dnl Regrettably the meaning of the various version types was misunderstood
dnl before version 0.4.1.
dnl
dnl In the past MAJOR.MINOR.MICRO versions led to the following SONAME numbers:
dnl 0.2.2 = 2 , 0.2.3 = 3 , 0.2.6 = 6
dnl 0.3.0 = 0 , 0.3.2 = 2 , 0.3.4 = 4 . 0.3.6 = 6 , 0.3.8 = 4
dnl 0.4.0 = 0 (also released as SONAME 4)
dnl
dnl Meanwhile the following schemes are maintained in parallel:
dnl
dnl BURN_MAJOR_VERSION , BURN_MINOR_VERSION , BURN_MICRO_VERSION
dnl are three small non-negative integers which describe the evolution
dnl steps of the library.
dnl Older applications are able to use younger libraries over
dnl quite a long range of such steps. Some day, nevertheless,
dnl compatibility might get terminated, after due notice.
dnl
dnl SONAME (libburn.so.4)
dnl is a small positive integer which marks a family of compatible
dnl evolution steps. Libraries with a particular SONAME allow a binary
dnl with the same SONAME to start up. Any further compatibility check is to
dnl be done by own runtime means. Especially *_version() calls in the API
dnl which return BURN_MAJOR_VERSION, BURN_MINOR_VERSION, BURN_MICRO_VERSION.
dnl See below.
dnl
dnl CURRENT, AGE, REVISION
dnl are three integers used by libtool. CURRENT is positive, the others
dnl non-negative. The use at runtime is not known yet. But libtool computes
dnl at build time SONAME = CURRENT - AGE.
dnl So this is a superspace of the SONAME version space. To avoid
dnl ill SONAME, the value of CURRENT must be larger than AGE.
dnl See also http://www.gnu.org/software/libtool/manual.html#Interfaces
dnl
dnl On Linux the name of the dynamic library will be
dnl libburn.so.$SONAME.$AGE.$REV
dnl In the terminology of this file:
dnl CURRENT = LT_CURRENT
dnl AGE = LT_AGE
dnl REVISION= LT_REVISION
dnl
dnl Beginning with libburn-0.4.1 a rectified counting was introduced as
dnl CURRENT=10, REVISION=1, AGE=6
dnl This rectification declared that version to be binary compatible up
dnl from libburn-0.3.4.
dnl Real compatibility was given since libburn-0.3.2.
dnl Beware of libburn-0.2.6 which had SONAME=6 and is not binary compatible.
dnl Applications for libburn-0.2 to libburn-0.3.1 need recompilation but no
dnl source code changes.
dnl
dnl Neatly versioned stable releases meanwhile:
dnl 0.4.2 = libburn.so.4.7.0
dnl 0.4.4 = libburn.so.4.9.0
dnl 0.4.6 = libburn.so.4.11.0
dnl 0.4.8 = libburn.so.4.13.0
dnl 0.5.0 = libburn.so.4.15.0
dnl 0.5.2 = libburn.so.4.17.0
dnl 0.5.4 = libburn.so.4.19.0
dnl 0.5.6 = libburn.so.4.21.0
dnl 0.5.8 = libburn.so.4.23.0
dnl 0.6.0 = libburn.so.4.25.0
dnl 0.6.2 = libburn.so.4.27.0
dnl 0.6.4 = libburn.so.4.29.0
dnl 0.6.6 = libburn.so.4.31.0
dnl 0.6.8 = libburn.so.4.33.0
dnl 0.7.0 = libburn.so.4.35.0
dnl 0.7.2 = libburn.so.4.37.0
dnl 0.7.4 = libburn.so.4.39.0
dnl 0.7.6 = libburn.so.4.41.0
dnl 0.7.8 = libburn.so.4.43.0
dnl 0.8.0 = libburn.so.4.45.0
dnl 0.8.2 = libburn.so.4.47.0
dnl 0.8.4 = libburn.so.4.49.0
dnl 0.8.6 = libburn.so.4.51.0
dnl 0.8.8 = libburn.so.4.53.0
dnl 0.9.0 = libburn.so.4.55.0
dnl 1.0.0 = libburn.so.4.57.0
dnl 1.0.2 = libburn.so.4.59.0
dnl 1.0.4 = libburn.so.4.61.0
dnl 1.0.6 = libburn.so.4.63.0
dnl 1.1.0 = libburn.so.4.65.0
dnl 1.1.4 = libburn.so.4.67.0
dnl 1.1.6 = libburn.so.4.69.0
dnl 1.1.8 = libburn.so.4.71.0
dnl 1.2.0 = libburn.so.4.73.0
dnl 1.2.2 = libburn.so.4.75.0
dnl 1.2.4 = libburn.so.4.77.0
dnl 1.2.6 = libburn.so.4.79.0
dnl 1.2.8 = libburn.so.4.81.0
dnl 1.3.0 = libburn.so.4.83.0
dnl 1.3.2 = libburn.so.4.85.0
dnl 1.3.4 = libburn.so.4.87.0
dnl 1.3.6 = libburn.so.4.89.0
dnl 1.3.8 = libburn.so.4.91.0
dnl 1.4.0 = libburn.so.4.93.0
dnl 1.4.2 = libburn.so.4.95.0
dnl 1.4.4 = libburn.so.4.97.0
dnl 1.4.6 = libburn.so.4.99.0
dnl 1.4.8 = libburn.so.4.101.0
dnl 1.5.0 = libburn.so.4.103.0
dnl 1.5.2 = libburn.so.4.105.0
dnl
dnl So LT_CURRENT, LT_REVISION and LT_AGE get set directly here.
dnl SONAME of the emerging library is LT_CURRENT - LT_AGE.
dnl The linker will do no finer checks. Especially no age range check for
dnl the application binary. If SONAME matches, then the couple starts.
dnl
dnl Therefore at run time info is provided by libburn function burn_version().
dnl It returns the major, minor and micro revision of the library.
dnl Before using any API feature, a program should check for age.
dnl
dnl The variables BURN_*_VERSION are mere copies for informing libtool.
dnl The true values which get issued and should be compared are macros
dnl defined in libburn/libburn.h .
dnl
dnl Normally one can allow a program to run with a library which passed the
dnl linker SONAME test and which is not older than the library it was
dnl developed for. Library2 is younger than library1 if:
dnl major2>major1 || (major2==major1 &&
dnl (minor2>minor1 || (minor2==minor1 && micro2 > micro1)))
dnl
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=5
BURN_MICRO_VERSION=2
BURN_VERSION=$BURN_MAJOR_VERSION.$BURN_MINOR_VERSION.$BURN_MICRO_VERSION
AC_SUBST(BURN_MAJOR_VERSION)
AC_SUBST(BURN_MINOR_VERSION)
AC_SUBST(BURN_MICRO_VERSION)
AC_SUBST(BURN_VERSION)
dnl Libtool versioning
LT_RELEASE=$BURN_MAJOR_VERSION.$BURN_MINOR_VERSION.$BURN_MICRO_VERSION
dnl
dnl This is the release version libburn-1.5.2
dnl ### This is the development version after above release version
dnl LT_CURRENT++, LT_AGE++ has not yet happened.
dnl ### LT_CURRENT++, LT_AGE++ has happened meanwhile.
dnl
dnl SONAME = 109 - 105 = 4 . Linux library name = libburn.so.4.105.0
LT_CURRENT=109
LT_AGE=105
LT_REVISION=0
LT_CURRENT_MINUS_AGE=`expr $LT_CURRENT - $LT_AGE`
AC_SUBST(LT_RELEASE)
AC_SUBST(LT_CURRENT)
AC_SUBST(LT_REVISION)
AC_SUBST(LT_AGE)
AC_SUBST(LT_CURRENT_MINUS_AGE)
dnl ts A71207: This is done only not to break any old components
BURN_INTERFACE_AGE=$LT_REVISION
BURN_BINARY_AGE=`expr $LT_AGE + $BURN_INTERFACE_AGE`
AC_SUBST(BURN_INTERFACE_AGE)
AC_SUBST(BURN_BINARY_AGE)
AC_PREFIX_DEFAULT([/usr/local])
test "$prefix" = "NONE" && prefix=$ac_default_prefix
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
AC_FUNC_FSEEKO
AC_CHECK_FUNC([fseeko])
if test ! $ac_cv_func_fseeko; then
AC_ERROR([Libburn requires largefile support.])
fi
AC_PROG_LIBTOOL
AC_SUBST(LIBTOOL_DEPS)
# LIBTOOL="$LIBTOOL --silent"
AC_PROG_INSTALL
AC_CHECK_HEADERS()
THREAD_LIBS=-lpthread
AC_SUBST(THREAD_LIBS)
TARGET_SHIZZLE
AC_SUBST(ARCH)
AC_SUBST(LIBBURNIA_PKGCONFDIR)
AC_SUBST(LIBBURN_ARCH_LIBS)
dnl ts A90303
dnl Check the preconditions for using statvfs() in sg-dummy
dnl (sg-linux and sg-freebsd use statvfs() unconditionally)
STATVFS_DEF=-DLibburn_os_has_statvfS
AC_CHECK_HEADER(sys/statvfs.h, X=, STATVFS_DEF=)
AC_CHECK_FUNC([statvfs], X=, STATVFS_DEF=)
dnl If this would be done more specifically in Makefile.am
dnl via libburn_libburn_la_CFLAGS then undesired .o file names would emerge
CFLAGS="$STATVFS_DEF $CFLAGS"
dnl ts A91122
AC_ARG_ENABLE(track-src-odirect,
[ --enable-track-src-odirect 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"
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"
fi
dnl Avoid the need for libburn_libburn_la_CFLAGS in Makefile.am (ugly .o names)
dnl ### AC_SUBST(LIBBURN_O_DIRECT_DEF)
CFLAGS="$LIBBURN_O_DIRECT_DEF $CFLAGS"
dnl ts A91116
AC_ARG_ENABLE(dvd-obs-64k,
[ --enable-dvd-obs-64k 64 KB default size for DVD writing, default=no],
, enable_dvd_obs_64k=no)
if test x$enable_dvd_obs_64k = xyes; then
LIBBURN_DVD_OBS_64K="-DLibburn_dvd_obs_default_64K"
echo "enabled write size default 64 KB on DVD"
else
LIBBURN_DVD_OBS_64K=
echo "disabled write size default 64 KB on DVD"
fi
CFLAGS="$LIBBURN_DVD_OBS_64K $CFLAGS"
dnl ts B20413
AC_ARG_ENABLE(dvd-obs-pad,
[ --enable-dvd-obs-pad pad DVD DAO sessions to 32 or 64 KB, default=no],
, enable_dvd_obs_pad=no)
if test x$enable_dvd_obs_pad = xyes; then
LIBBURN_DVD_OBS_PAD="-DLibburn_dvd_always_obs_paD"
echo "enabled padding of DVD DAO sessions to 32 or 64 KB"
else
LIBBURN_DVD_OBS_64K=
echo "disabled padding of DVD DAO sessions to 32 or 64 KB"
fi
CFLAGS="$LIBBURN_DVD_OBS_PAD $CFLAGS"
dnl ts A91218 - B21002
case $host_os in
cygwin*|mingw*)
default_libcdio=yes
;;
*)
default_libcdio=no
;;
esac
# Check for proper library versions if this is desired.
# (It fails too often on too many systems.)
AC_ARG_ENABLE(pkg-check-modules,
[ --enable-pkg-check-modules Enable pkg-config check for libcdio , default=no],
, enable_pkg_check_modules=no)
AC_ARG_ENABLE(libcdio,
[ --enable-libcdio Enable use of libcdio as system adapter, default=no (except on MSWindows)],
, enable_libcdio=$default_libcdio)
PKG_PROG_PKG_CONFIG
if test x$enable_libcdio = xyes; then
dnl Check whether there is libcdio-devel and libcdio-runtime.
dnl If not, erase this macro
LIBCDIO_DEF="-DLibburn_use_libcdiO"
dnl The empty yes case obviously causes -lcdio to be linked
AC_CHECK_HEADER(cdio/cdio.h, AC_CHECK_LIB(cdio, mmc_last_cmd_sense, , LIBCDIO_DEF= ), LIBCDIO_DEF= )
else
LIBCDIO_DEF=
fi
if test x$LIBCDIO_DEF = x
then
if test x$enable_libcdio = xyes
then
echo "WARNING: could not enable use of libcdio as system adapter"
fi
else
echo "enabled use of libcdio as system adapter"
CFLAGS="$LIBCDIO_DEF $CFLAGS"
if test x$enable_pkg_check_modules = xyes; then
LIBCDIO_REQUIRED=0.83
PKG_CHECK_MODULES(LIBCDIO, libcdio >= $LIBCDIO_REQUIRED)
else
echo "checking for LIBCDIO... skipped, no --enable-pkg-check-modules"
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
# simple feature to declare function names "global:" or "local:". Only the
# global ones are visible to applications at library load time.
AC_ARG_ENABLE(versioned-libs,
[ --enable-versioned-libs Enable strict symbol encapsulation , default=yes],
, enable_versioned_libs=yes)
if test x$enable_versioned_libs = xyes; then
vers_libs_test=no
LIBBURN_ASSERT_VERS_LIBS
if test x$vers_libs_test = xno
then
echo "disabled strict symbol encapsulation (test failed)"
else
echo "enabled strict symbol encapsulation"
fi
else
echo "disabled strict symbol encapsulation"
fi
# 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)
if test x$ldconfig_at_install = xyes; then
dummy=dummy
else
LIBBURNIA_LDCONFIG_CMD="echo 'NOTE: ldconfig is disabled. If needed, configure manually for:'"
echo "disabled run of ldconfig during installation on GNU/Linux"
fi
AC_SUBST(LIBBURNIA_LDCONFIG_CMD)
dnl Add compiler-specific flags
dnl See if the user wants aggressive optimizations of the code
AC_ARG_ENABLE(debug,
[ --enable-debug Disable aggressive optimizations [default=yes]],
, enable_debug=yes)
if test x$enable_debug != xyes; then
if test x$GCC = xyes; then
CFLAGS="-O3 $CFLAGS"
CFLAGS="-fexpensive-optimizations $CFLAGS"
fi
CFLAGS="-DNDEBUG $CFLAGS"
else
if test x$GCC = xyes; then
CFLAGS="-g -pedantic -Wall -Wextra -Wno-unused-parameter -Wno-char-subscripts $CFLAGS"
fi
CFLAGS="-DDEBUG $CFLAGS"
fi
dnl Determine target directory for libburn-*.pc
dnl Important: Must be performed _after_ TARGET_SHIZZLE
dnl
LIBBURNIA_SET_PKGCONFIG
AC_CONFIG_FILES([
Makefile
doc/doxygen.conf
version.h
libburn-1.pc
])
AC_OUTPUT

4
doc/Makefile Normal file
View File

@ -0,0 +1,4 @@
all clean:
$(MAKE) -C .. -$(MAKEFLAGS) $@
.PHONY: all clean

736
doc/cdtext.txt Normal file
View File

@ -0,0 +1,736 @@
Description of CD-TEXT
Guided by Leon Merten Lohse via libcdio-devel@gnu.org
by reading mmc3r10g.pdf from http://www.t10.org/ftp/t10/drafts/mmc3/
by docs and results of cdtext.zip from http://www.sonydadc.com/file/
by reading http://digitalx.org/cue-sheet/syntax
by reading source of libcdio from http://www.gnu.org/s/libcdio
which quotes source of cdrecord from ftp://ftp.berlios.de/pub/cdrecord/alpha
by reading cdrecord.1 from ftp://ftp.berlios.de/pub/cdrecord/alpha
Language codes were learned from http://tech.ebu.ch/docs/tech/tech3264.pdf
Genre codes were learned from libcdio and confirmed by
http://helpdesk.audiofile-engineering.com/index.php?pg=kb.page&id=123
For libburnia-project.org by Thomas Schmitt <scdbackup@gmx.net>
Content:
- CD-TEXT from the view of the user
- Content specifications of particular pack types
- Format of a CD-TEXT packs array
- Overview of libburn API calls for CD-TEXT
- Sony Text File Format (Input Sheet Version 0.7T)
- CDRWIN cue sheet files
-------------------------------------------------------------------------------
CD-TEXT from the view of the user:
CD-TEXT records attributes of disc and tracks on audio CD.
The attributes are grouped into blocks which represent particular languages.
Up to 8 blocks are possible.
There are 13 defined attribute categories, which are called Pack Types and are
identified by a single-byte code:
0x80 = Title
0x81 = Names of Performers
0x82 = Names of Songwriters
0x83 = Names of Composers
0x84 = Names of Arrangers
0x85 = Messages
0x86 = text-and-binary: Disc Identification
0x87 = text-and-binary: Genre Identification
0x88 = binary: Table of Content information
0x89 = binary: Second Table of Content information
(0x8a to 0x8c are reserved.)
0x8d = Closed Information
0x8e = UPC/EAN code of the album and ISRC code of each track
0x8f = binary: Size Information of the Block
Some of these categories apply to the whole disc only:
0x86, 0x87, 0x88, 0x89, 0x8d
Some have to be additionally attributed to each track, if they are present for
the whole disc:
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x8e
One describes the overall content of a block and in part of all other blocks:
0x8f
The total size of a block's attribute set is restricted by the fact that it
has to be stored in at most 253 records with 12 bytes of payload. These records
are called Text Packs.
A shortcut for repeated identical track texts is provided, so that a text
that is identical to the one of the previous track occupies only 2 or 4 bytes.
-------------------------------------------------------------------------------
Content specification of particular pack types:
Pack types 0x80 to 0x85 and 0x8e contain 0-terminated cleartext. If double byte
characters are used, then two 0-bytes terminate the cleartext.
The meaning of 0x80 to 0x85 should be clear by above list. They are encoded
according to the Character Code of their block. Either as ISO-8859-1 single
byte characters, or as 7-bit ASCII single byte characters, or as MS-JIS double
byte characters.
More info to 0x8e is given below.
Pack type 0x86 (Disc Identification) is documented by Sony as "Catalog Number:
(use ASCII Code) Catalog Number of the album". So it is not really binary
but might be non-printable, and should contain only bytes with bit7 = 0.
Pack type 0x87 contains 2 binary bytes, followed by 0-terminated cleartext.
The two binary bytes form a big-endian index to the following list.
0x0000 = "Not Used" (Sony prescribes to use this if no genre applies)
0x0001 = "Not Defined"
0x0002 = "Adult Contemporary"
0x0003 = "Alternative Rock"
0x0004 = "Childrens Music"
0x0005 = "Classical"
0x0006 = "Contemporary Christian"
0x0007 = "Country"
0x0008 = "Dance"
0x0009 = "Easy Listening"
0x000a = "Erotic"
0x000b = "Folk"
0x000c = "Gospel"
0x000d = "Hip Hop"
0x000e = "Jazz"
0x000f = "Latin"
0x0010 = "Musical"
0x0011 = "New Age"
0x0012 = "Opera"
0x0013 = "Operetta"
0x0014 = "Pop Music"
0x0015 = "Rap"
0x0016 = "Reggae"
0x0017 = "Rock Music"
0x0018 = "Rhythm & Blues"
0x0019 = "Sound Effects"
0x001a = "Spoken Word"
0x001b = "World Music"
Sony documents the cleartext part as "Genre information that would supplement
the Genre Code, such as 'USA Rock music in the 60s'". Always ASCII encoded.
Pack type 0x88 records information from the CD's Table of Content, as of
READ PMA/TOC/ATIP Format 0010b (mmc3r10g.pdf, table 237 TOC Track Descriptor
Format, Q Sub-channel).
See below, Format of a CD-TEXT packs array, for more details about the content
of pack type 0x88.
Pack type 0x89 is yet quite unclear. It might be a representation of Playback
Skip Interval, Mode-5 Q sub-channel, POINT 01 to 40 (mmc3r10g.pdf 4.2.3.6.3).
If so, then this seems not to apply to write type SAO, because the CUE SHEET
format offers no way to express Mode-5 Q.
See below, Format of a CD-TEXT packs array, for an example of this pack type.
Pack type 0x8d is documented by Sony as "Closed Information: (use 8859-1 Code)
Any information can be recorded on disc as memorandum. Information in this
field will not be read by CD TEXT players available to the public."
Always ISO-8859-1 encoded.
Pack type 0x8e is documented by Sony as "UPC/EAN Code (POS Code) of the album.
This field typically consists of 13 characters." Always ASCII encoded.
It applies to tracks as "ISRC code [which] typically consists of 12 characters"
and is always ISO-8859-1 encoded.
MMC calls these information entities Media Catalog Number and ISRC.
The catalog number consists of 13 decimal digits.
ISRC consists of 12 characters: 2 country code [0-9A-Z], 3 owner code [0-9A-Z],
2 year digits (00 to 99), 5 serial number digits (00000 to 99999).
Pack type 0x8f summarizes the whole list of text packs of a block.
See below, Format of a CD-TEXT packs array, for details.
-------------------------------------------------------------------------------
Format of a CD-TEXT packs array:
The attributes are represented on CD as Text Packs in the sub-channel of
the Lead-in of the disc. See doc/cookbook.txt for a description how to write
the readily formatted CD-TEXT pack array to CD, and how to read CD-TEXT packs
from CD.
The format is explained in part in MMC-3 (mmc3r10g.pdf, Annex J) and in part by
the documentation in Sony's cdtext.zip :
Each pack consists of a 4-byte header, 12 bytes of payload, and 2 bytes of CRC.
The first byte of each pack tells the pack type. See above for a list of types.
The second byte tells the track number to which the first text piece in
a pack is associated. Number 0 means the whole album. Higher numbers are
valid for types 0x80 to 0x85, and 0x8e. With these types, there should be
one text for the disc and one for each track.
With types 0x88 and 0x89, the second byte bears a track number, too.
With type 0x8f, the second byte counts the record parts from 0 to 2.
The third byte is a sequential counter.
The fourth byte is the Block Number and Character Position Indicator.
It consists of three bit fields:
bit7 = Double Bytes Character Code (0= single byte characters)
bit4-6 = Block Number (groups text packs in language blocks)
bit0-3 = Character position. Either the number of characters which
the current text inherited from the previous pack, or
15 if the current text started before the previous pack.
The 12 payload bytes contain pieces of 0-terminated texts or binary data.
A text may span over several packs. Unused characters in a pack are used for
the next text of the same pack type. If no text of the same type follows,
then the remaining text bytes are set to 0.
The CRC algorithm uses divisor 0x11021. The resulting 16-bit residue of the
polynomial division gets inverted and written as big-endian number to bytes
16 and 17 of the pack.
The text packs are grouped in up to 8 blocks of at most 256 packs. Each block
is in charge for one language. Sequence numbers of each block are counted
separately. All packs of block 0 come before the packs of block 1.
The limitation of block number and sequence numbers imply that there are at
most 2048 text packs possible. (READ TOC/PMA/ATIP could retrieve 3640 packs,
as it is limited to 64 kB - 2.)
If a text of a track (pack types 0x80 to 0x85 and 0x8e) repeats identically
for the next track, then it may be represented by a TAB character (ASCII 9)
for single byte texts, and two TAB characters for double byte texts.
(This should be used because 256 * 12 bytes is few space for 99 tracks.)
The two binary bytes of pack type 0x87 are written to the first 0x87 pack of
a block. They may or may not be repeated at the start of the follow-up packs
of type 0x87.
The first pack of type 0x88 in a block records in its payload bytes:
0 : PMIN of POINT A1 = First Track Number
1 : PMIN of POINT A2 = Last Track Number
2 : unknown, 0 in Sony example
3 : PMIN of POINT A2 = Start position of Lead-Out
4 : PSEC of POINT A2 = Start position of Lead-Out
5 : PFRAME of POINT A2 = Start position of Lead-Out
6 to 11 : unknown, 0 in Sony example
The following packs record PMIN, PSEC, PFRAME of the POINTs between the
lowest track number (min 01h) and the highest track number (max 63h).
The payload of the last pack is padded by 0s.
The Sony .TOC example:
A0 01
A1 14
A2 63:02:18
01 00:02:00
02 04:11:25
03 08:02:50
04 11:47:62
...
13 53:24:25
14 57:03:25
yields
88 00 23 00 01 0e 00 3f 02 12 00 00 00 00 00 00 12 00
88 01 24 00 00 02 00 04 0b 19 08 02 32 0b 2f 3e 67 2d
...
88 0d 27 00 35 18 19 39 03 19 00 00 00 00 00 00 ea af
Pack type 0x89 is yet quite unclear. Especially what the information shall
mean to the user of the CD. The time points in the Sony example are in the
time range of the tracks numbers that are given before the time points:
01 02:41:48 01 02:52:58
06 23:14:25 06 23:29:60
07 28:30:39 07 28:42:30
13 55:13:26 13 55:31:50
yields
89 01 28 00 01 04 00 00 00 00 02 29 30 02 34 3a f3 0c
89 06 29 00 02 04 00 00 00 00 17 0e 19 17 1d 3c 73 92
89 07 2a 00 03 04 00 00 00 00 1c 1e 27 1c 2a 1e 72 20
89 0d 2b 00 04 04 00 00 00 00 37 0d 1a 37 1f 32 0b 62
The track numbers are stored in the track number byte of the packs. The two
time points are stored in byte 6 to 11 of the payload. Byte 0 of the payload
seems to be a sequential counter. Byte 1 always 4 ? Byte 2 to 5 always 0 ?
Pack type 0x8f summarizes the whole list of text packs of a block.
So there is one group of three 0x8f packs per block.
Nevertheless each 0x8f group tells the highest sequence number and the
language code of all blocks.
The payload bytes of three 0x8f packs form a 36 byte record. The track number
bytes of the three packs have the values 0, 1, 2.
Byte :
0 : Character code for pack types 0x80 to 0x85:
0x00 = ISO-8859-1
0x01 = 7 bit ASCII
0x80 = MS-JIS (japanese Kanji, double byte characters)
1 : Number of first track
2 : Number of last track
3 : libcdio source states: "cd-text information copyright byte"
Probably 3 means "copyrighted", 0 means "not copyrighted".
4 - 19 : Pack count of the various types 0x80 to 0x8f.
Byte number N tells the count of packs of type 0x80 + (N - 4).
I.e. the first byte in this field of 16 counts packs of type 0x80.
20 - 27 : Highest sequence byte number of blocks 0 to 7.
28 - 36 : Language code for blocks 0 to 7 (tech3264.pdf appendix 3)
Not all of these Codes have ever been seen with CD-TEXT, though.
0x00 = Unknown
0x01 = Albanian
0x02 = Breton
0x03 = Catalan
0x04 = Croatian
0x05 = Welsh
0x06 = Czech
0x07 = Danish
0x08 = German
0x09 = English
0x0a = Spanish
0x0b = Esperanto
0x0c = Estonian
0x0d = Basque
0x0e = Faroese
0x0f = French
0x10 = Frisian
0x11 = Irish
0x12 = Gaelic
0x13 = Galician
0x14 = Icelandic
0x15 = Italian
0x16 = Lappish
0x17 = Latin
0x18 = Latvian
0x19 = Luxembourgian
0x1a = Lithuanian
0x1b = Hungarian
0x1c = Maltese
0x1d = Dutch
0x1e = Norwegian
0x1f = Occitan
0x20 = Polish
0x21 = Portuguese
0x22 = Romanian
0x23 = Romansh
0x24 = Serbian
0x25 = Slovak
0x26 = Slovenian
0x27 = Finnish
0x28 = Swedish
0x29 = Turkish
0x2a = Flemish
0x2b = Wallon
0x45 = Zulu
0x46 = Vietnamese
0x47 = Uzbek
0x48 = Urdu
0x49 = Ukrainian
0x4a = Thai
0x4b = Telugu
0x4c = Tatar
0x4d = Tamil
0x4e = Tadzhik
0x4f = Swahili
0x50 = Sranan Tongo
0x51 = Somali
0x52 = Sinhalese
0x53 = Shona
0x54 = Serbo-croat
0x55 = Ruthenian
0x56 = Russian
0x57 = Quechua
0x58 = Pushtu
0x59 = Punjabi
0x5a = Persian
0x5b = Papamiento
0x5c = Oriya
0x5d = Nepali
0x5e = Ndebele
0x5f = Marathi
0x60 = Moldavian
0x61 = Malaysian
0x62 = Malagasay
0x63 = Macedonian
0x64 = Laotian
0x65 = Korean
0x66 = Khmer
0x67 = Kazakh
0x68 = Kannada
0x69 = Japanese
0x6a = Indonesian
0x6b = Hindi
0x6c = Hebrew
0x6d = Hausa
0x6e = Gurani
0x6f = Gujurati
0x70 = Greek
0x71 = Georgian
0x72 = Fulani
0x73 = Dari
0x74 = Churash
0x75 = Chinese
0x76 = Burmese
0x77 = Bulgarian
0x78 = Bengali
0x79 = Bielorussian
0x7a = Bambora
0x7b = Azerbaijani
0x7c = Assamese
0x7d = Armenian
0x7e = Arabic
0x7f = Amharic
E.g. these three packs
42 : 8f 00 2a 00 01 01 03 00 06 05 04 05 07 06 01 02 48 65
43 : 8f 01 2b 00 00 00 00 00 00 00 06 03 2c 00 00 00 c0 20
44 : 8f 02 2c 00 00 00 00 00 09 00 00 00 00 00 00 00 11 45
decode to
Byte :Value Meaning
0 : 01 = ASCII 7-bit
1 : 01 = first track is 1
2 : 03 = last track is 3
3 : 00 = copyright (0 = public domain, 3 = copyrighted ?)
4 : 06 = 6 packs of type 0x80
5 : 05 = 5 packs of type 0x81
6 : 04 = 4 packs of type 0x82
7 : 05 = 5 packs of type 0x83
8 : 07 = 7 packs of type 0x84
9 : 06 = 6 packs of type 0x85
10 : 01 = 1 pack of type 0x86
11 : 02 = 2 packs of type 0x87
12 : 00 = 0 packs of type 0x88
13 : 00 = 0 packs of type 0x89
14 : 00 00 00 00 = 0 packs of types 0x8a to 0x8d
18 : 06 = 6 packs of type 0x8e
19 : 03 = 3 packs of type 0x8f
20 : 2c = last sequence for block 0
This matches the sequence number of the last text pack (0x2c = 44)
21 : 00 00 00 00 00 00 00 = last sequence numbers for block 1..7 (none)
28 : 09 = language code for block 0: English
29 : 00 00 00 00 00 00 00 = language codes for block 1..7 (none)
-------------------------------------------------------------------------------
Overview of libburn API calls for CD-TEXT (see libburn/libburn.h for details):
libburn can retrieve the array of text packs from a CD:
int burn_disc_get_leadin_text(struct burn_drive *d,
unsigned char **text_packs, int *num_packs,
int flag);
It can write a text pack set with a CD SAO session.
This set may be attached as array of readily formatted text packs by:
int burn_write_opts_set_leadin_text(struct burn_write_opts *opts,
unsigned char *text_packs,
int num_packs, int flag);
The array of text packs may be read from a file by
int burn_cdtext_from_packfile(char *path, unsigned char **text_packs,
int *num_packs, int flag);
Alternatively the pack set may be defined by attaching CD-TEXT attributes
to burn_session and burn_track:
int burn_session_set_cdtext_par(struct burn_session *s,
int char_codes[8], int copyrights[8],
int languages[8], int flag);
int burn_session_set_cdtext(struct burn_session *s, int block,
int pack_type, char *pack_type_name,
unsigned char *payload, int length, int flag);
int burn_track_set_cdtext(struct burn_track *t, int block,
int pack_type, char *pack_type_name,
unsigned char *payload, int length, int flag);
Macros list the texts for genre and language codes:
BURN_CDTEXT_LANGUAGES_0X00
BURN_CDTEXT_FILLER
BURN_CDTEXT_LANGUAGES_0X45
BURN_CDTEXT_GENRE_LIST
BURN_CDTEXT_NUM_GENRES
There is a reader for Sony Input Sheet Version 0.7T:
int burn_session_input_sheet_v07t(struct burn_session *session,
char *path, int block, int flag);
and a writer which converts an array of text packs to such a Sony Input Sheet:
int burn_make_input_sheet_v07t(unsigned char *text_packs, int num_packs,
int start_tno, int track_count,
char **result, int *char_code, int flag);
CD-TEXT can be read from a CDRWIN cue sheet file which defines the tracks
of a session
int burn_session_by_cue_file(struct burn_session *session,
char *path, int fifo_size, struct burn_source **fifo,
unsigned char **text_packs, int *num_packs, int flag);
The session and track attributes can then be converted into an array of
text packs by:
int burn_cdtext_from_session(struct burn_session *s,
unsigned char **text_packs, int *num_packs,
int flag);
or they can be written as array of text packs to CD when burning begins and
no array of pre-formatted packs was attached to the write options by
burn_write_opts_set_leadin_text().
There are calls for inspecting the attached attributes:
int burn_session_get_cdtext_par(struct burn_session *s,
int char_codes[8], int copyrights[8],
int block_languages[8], int flag);
int burn_session_get_cdtext(struct burn_session *s, int block,
int pack_type, char *pack_type_name,
unsigned char **payload, int *length, int flag);
int burn_track_get_cdtext(struct burn_track *t, int block,
int pack_type, char *pack_type_name,
unsigned char **payload, int *length, int flag);
and for removing attached attributes:
int burn_session_dispose_cdtext(struct burn_session *s, int block);
int burn_track_dispose_cdtext(struct burn_track *t, int block);
UPC/EAN and ISRC not only affect CD-TEXT but also information that is written
along with the tracks in Q sub-channel. These can be influenced by
burn_session_input_sheet_v07t(), burn_session_by_cue_file() and by
void burn_write_opts_set_mediacatalog(struct burn_write_opts *opts,
unsigned char mediacatalog[13]);
void burn_write_opts_set_has_mediacatalog(struct burn_write_opts *opts,
int has_mediacatalog);
void burn_track_set_isrc(struct burn_track *t, char *country, char *owner,
unsigned char year, unsigned int serial);
int burn_track_set_isrc_string(struct burn_track *t, char isrc[13],
int flag);
-------------------------------------------------------------------------------
Sony Text File Format (Input Sheet Version 0.7T):
This text file format provides comprehensive means to define the text
attributes of session and tracks for a single block. More than one
such file has to be read to form an attribute set with multiple blocks.
The information is given by text lines of the following form:
purpose specifier [whitespace] = [whitespace] content text
[whitespace] is zero or more ASCII 32 (space) or ASCII 9 (tab) characters.
The purpose specifier tells the meaning of the content text.
Empty content text does not cause a CD-TEXT attribute to be attached.
The following purpose specifiers apply to the session as a whole:
Specifier = Meaning
-------------------------------------------------------------------------
Text Code = Character code for pack type 0x8f
"ASCII", "8859"
Language Code = One of the language names for pack type 0x8f
Album Title = Content of pack type 0x80
Artist Name = Content of pack type 0x81
Songwriter = Content of pack type 0x82
Composer = Content of pack type 0x83
Arranger = Content of pack type 0x84
Album Message = Content of pack type 0x85
Catalog Number = Content of pack type 0x86
Genre Code = One of the genre names for pack type 0x87
Genre Information = Cleartext part of pack type 0x87
Closed Information = Content of pack type 0x8d
UPC / EAN = Content of pack type 0x8e
Text Data Copy Protection = Copyright value for pack type 0x8f
"ON" = 0x03, "OFF" = 0x00
First Track Number = The lowest track number used in the file
Last Track Number = The highest track number used in the file
The following purpose specifiers apply to particular tracks:
Track NN Title = Content of pack type 0x80
Track NN Artist = Content of pack type 0x81
Track NN Songwriter = Content of pack type 0x82
Track NN Composer = Content of pack type 0x83
Track NN Arranger = Content of pack type 0x84
Track NN Message = Content of pack type 0x85
ISRC NN = Content of pack type 0x8e
The following purpose specifiers have no effect on CD-TEXT:
Remarks = Comments with no influence on CD-TEXT
Disc Information NN = Supplementary information for use by record companies.
ISO-8859-1 encoded. NN ranges from 01 to 04.
Input Sheet Version = "0.7T"
libburn peculiarties:
libburn may read files of the described format by
burn_session_input_sheet_v07t()
after the burn_session has been establiched and all burn_track objects have
been added. It can convert an array of CD-TEXT packs into this format by
burn_make_input_sheet_v07t()
The following purpose specifiers accept byte values of the form 0xXY.
Text Code , Language Code , Genre Code , Text Data Copy Protection
E.g. to indicate MS-JIS character code (of which the exact name is unknown):
Text Code = 0x80
Genre Code is settable by 0xXY or 0xXYZT or 0xXY 0xZT.
Genre Code = 0x001b
Purpose specifiers which have the meaning "Content of pack type 0xXY"
may be replaced by the pack type codes. E.g.:
0x80 = Session content of pack type 0x80
Track 02 0x80 = Track content of pack type 0x80 for track 2.
Applicable are pack types 0x80 to 0x86, 0x8d, 0x8e.
Text Code may be specified only once. It gets speficied to "ISO-8850-1"
automatically as soon as content is defined which depends on the text
encoding of the block. I.e with pack types 0x80 to 0x85.
If a track attribute is set, but the corresponding session attribute is not
defined or defined with empty text, then the session attribute gets attached
as empty test. (Normally empty content is ignored.)
Example cdrskin run with three tracks:
$ cdrskin dev=/dev/sr0 -v input_sheet_v07t=NIGHTCATS.TXT \
-audio -swab track_source_1 track_source_2 track_source_3
----------------------------------------------------------
Content of file NIGHTCATS.TXT :
----------------------------------------------------------
Input Sheet Version = 0.7T
Text Code = 8859
Language Code = English
Album Title = Joyful Nights
Artist Name = United Cat Orchestra
Songwriter = Various Songwriters
Composer = Various Composers
Arranger = Tom Cat
Album Message = For all our fans
Catalog Number = 1234567890
Genre Code = Classical
Genre Information = Feline classic music
Closed Information = This is not to be shown by CD players
UPC / EAN = 1234567890123
Text Data Copy Protection = OFF
First Track Number = 1
Last Track Number = 3
Track 01 Title = Song of Joy
Track 01 Artist = Felix and The Purrs
Track 01 Songwriter = Friedrich Schiller
Track 01 Composer = Ludwig van Beethoven
Track 01 Arranger = Tom Cat
Track 01 Message = Fritz and Louie once were punks
ISRC 01 = XYBLG1101234
Track 02 Title = Humpty Dumpty
Track 02 Artist = Catwalk Beauties
Track 02 Songwriter = Mother Goose
Track 02 Composer = unknown
Track 02 Arranger = Tom Cat
Track 02 Message = Pluck the goose
ISRC 02 = XYBLG1100005
Track 03 Title = Mee Owwww
Track 03 Artist = Mia Kitten
Track 03 Songwriter = Mia Kitten
Track 03 Composer = Mia Kitten
Track 03 Arranger = Mia Kitten
Track 03 Message =
ISRC 03 = XYBLG1100006
----------------------------------------------------------
-------------------------------------------------------------------------------
CDRWIN cue sheet files:
A CDRWIN cue sheet file defines the track data source (FILE), various text
attributes (CATALOG, TITLE, PERFORMER, SONGWRITER, ISRC), track block types
(TRACK), track start addresses (INDEX).
The rules for CDRWIN cue sheet files are described at
http://digitalx.org/cue-sheet/syntax/
There are three more text attributes mentioned in man cdrecord for defining
the corresponding CD-TEXT attributes: ARRANGER, COMPOSER, MESSAGE.
--------------------------------------------------------
Example of a CDRWIN cue sheet file named NIGHTCATS.CUE :
--------------------------------------------------------
CATALOG 1234567890123
FILE "audiodata.bin" BINARY
TITLE "Joyful Nights"
TRACK 01 AUDIO
FLAGS DCP
TITLE "Song of Joy"
PERFORMER "Felix and The Purrs"
SONGWRITER "Friedrich Schiller"
ISRC XYBLG1101234
INDEX 01 00:00:00
TRACK 02 AUDIO
FLAGS DCP
TITLE "Humpty Dumpty"
PERFORMER "Catwalk Beauties"
SONGWRITER "Mother Goose"
ISRC XYBLG1100005
INDEX 01 08:20:12
TRACK 03 AUDIO
FLAGS DCP
TITLE "Mee Owwww"
PERFORMER "Mia Kitten"
SONGWRITER "Mia Kitten"
ISRC XYBLG1100006
INDEX 01 13:20:33
By
$ cdrskin -v dev=/dev/sr0 -text cuefile=NIGHTCATS.CUE
this yields as text packs:
0 : 80 00 00 00 J o y f u l N i g h t f0 f7
1 : 80 00 01 0c s 00 S o n g o f J o 43 1c
2 : 80 01 02 0a y 00 H u m p t y D u m 43 f9
3 : 80 02 03 0a p t y 00 M e e O w w w 24 72
4 : 80 03 04 08 w 00 00 00 00 00 00 00 00 00 00 00 6e af
5 : 81 00 05 00 00 F e l i x a n d T 4d 51
6 : 81 01 06 0b h e P u r r s 00 C a t a7 40
7 : 81 02 07 03 w a l k B e a u t i e 59 80
8 : 81 02 08 0f s 00 M i a K i t t e n 30 c9
9 : 81 03 09 0a 00 00 00 00 00 00 00 00 00 00 00 00 ad 19
10 : 82 00 0a 00 00 F r i e d r i c h S 70 8f
11 : 82 01 0b 0b c h i l l e r 00 M o t h 33 43
12 : 82 02 0c 04 e r G o o s e 00 M i a d6 f5
13 : 82 03 0d 03 K i t t e n 00 00 00 00 00 f5 83
14 : 8e 00 0e 00 1 2 3 4 5 6 7 8 9 0 1 2 92 3e
15 : 8e 00 0f 0c 3 00 X Y B L G 1 1 0 1 2 c0 2b
16 : 8e 01 10 0a 3 4 00 X Y B L G 1 1 0 0 bb b3
17 : 8e 02 11 09 0 0 5 00 X Y B L G 1 1 0 f3 bf
18 : 8e 03 12 08 0 0 0 6 00 00 00 00 00 00 00 00 5b 5c
19 : 8f 00 13 00 00 01 03 00 05 05 04 00 00 00 00 00 9b fe
20 : 8f 01 14 00 00 00 00 00 00 00 05 03 15 00 00 00 11 0b
21 : 8f 02 15 00 00 00 00 00 09 00 00 00 00 00 00 00 da 77
--------------------------------------
Some restrictions apply in the libburn call burn_session_by_cue_file():
Only FILE types BINARY, MOTOROLA, WAVE are allowed.
Only TRACK datatypes AUDIO, MODE1/2048 are allowed. They may not be mixed in
the same session.
On the other hand, ARRANGER, COMPOSER, MESSAGE are supported unconditionally.
-------------------------------------------------------------------------------
This text is copyright 2011 - 2012 Thomas Schmitt <scdbackup@gmx.net>.
Permission is granted to copy, modify, and distribute it, as long as the
references to the original information sources are maintained.
There is NO WARRANTY, to the extent permitted by law.
-------------------------------------------------------------------------------

119
doc/comments Normal file
View File

@ -0,0 +1,119 @@
/**
@author Mario Danic, Thomas Schmitt
@mainpage Libburn Documentation Index
@section intro Introduction
Libburnia is an open-source project for reading, mastering and writing
optical discs. This page is about its capability to handle optical media.
For now this means CD-R, CD-RW, DVD-RAM, DVD+RW, DVD+R, DVD+R/DL, DVD-RW,
DVD-R, DVD-R/DL, BD-R, BD-RE.
Our scope is currently Linux 2.4 and 2.6, FreeBSD, OpenSolaris, or NetBSD.
For ports to other systems we would need : login on a development machine or
an OS that is installable on an AMD 64-bit PC, advise from a system person
about the equivalent of Linux sg or FreeBSD CAM, volunteers for testing of
realistic use cases.
libburn is the library by which preformatted data get onto optical media.
Its code is independent of cdrecord. Its DVD capabilities are learned from
studying the code of dvd+rw-tools and MMC-5 specs. No code but only the pure
SCSI knowledge has been taken from dvd+rw-tools, though.
cdrskin is a limited cdrecord compatibility wrapper for libburn.
cdrecord is a powerful GPL'ed burn program included in Joerg Schilling's
cdrtools. cdrskin strives to be a second source for the services traditionally
provided by cdrecord. Additionally it provides libburn's DVD/BD capabilities,
where only -sao is compatible with cdrecord.
cdrskin does not contain any bytes copied from cdrecord's sources.
Many bytes have been copied from the message output of cdrecord runs, though.
See cdrskin/README for more.
The burn API example of libburn is named test/libburner.c . The API for media
information inquiry is demonstrated in test/telltoc.c .
Explore these examples if you look for inspiration.
SONAME:
libburn.so.4 (since 0.3.4, March 2007),
@section using Using libburn
Our build system is based on autotools.
User experience tells us that you will need at least autotools version 1.7.
To build libburn and its companion applications go into its toplevel directory
and execute
- ./bootstrap (needed if you downloaded from SVN)
- ./configure
- make
To make the libraries accessible for running and developing applications
- make install
@section libburner Libburner
libburner is a minimal demo application for the library libburn
(see: libburn/libburn.h) as provided on http://libburnia-project.org .
It can list the available devices, can burn to recordable CD, DVD, or BD,
can blank a CD-RW or DVD-RW, and can format unformatted DVD-RW, BD-R, or BD-RE.
It's main purpose, nevertheless, is to show you how to use libburn and also
to serve the libburnia team as reference application. libburner does indeed
define the standard way how above gestures can be implemented and stay upward
compatible for a good while.
@subsection libburner-help Libburner --help
<pre>
Usage: test/libburner
[--drive address|driveno|"-"] [--audio]
[--blank_fast|--blank_full|--format] [--try_to_simulate]
[--multi] [one or more imagefiles|"-"]
Examples
A bus scan (needs rw-permissions to see a drive):
test/libburner --drive -
Burn a file to drive chosen by number, leave appendable:
test/libburner --drive 0 --multi my_image_file
Burn a file to drive chosen by persistent address, close:
test/libburner --drive /dev/hdc my_image_file
Blank a used CD-RW (is combinable with burning in one run):
test/libburner --drive /dev/hdc --blank_fast
Blank a used DVD-RW (is combinable with burning in one run):
test/libburner --drive /dev/hdc --blank_full
Format a DVD-RW, BD-RE or BD-R:
test/libburner --drive /dev/hdc --format
Burn two audio tracks (to CD only):
lame --decode -t /path/to/track1.mp3 track1.cd
test/dewav /path/to/track2.wav -o track2.cd
test/libburner --drive /dev/hdc --audio track1.cd track2.cd
Burn a compressed afio archive on-the-fly:
( cd my_directory ; find . -print | afio -oZ - ) | \
test/libburner --drive /dev/hdc -
To be read from *not mounted* media via: afio -tvZ /dev/hdc
</pre>
libburner has two companions, telltoc and dewav, which help to perform some
peripheral tasks of burning.
telltoc prints a table of content (sessions, tracks and leadouts), it tells
about type and state of media, and also is able to provide the necessary
multi-session information for program mkisofs option -C. Especially helpful
are its predictions with "Write multi" and "Write modes" where availability
of "TAO" indicates that tracks of unpredicted length can be written.
See: test/telltoc --help.
dewav extracts raw byte-swapped audio data from files of format .wav (MS WAVE)
or .au (SUN Audio). See example in libburner --help.
@subsection libburner-source Sourceode of libburner
Click on blue names of functions, structures, variables, etc in oder to
get to the according specs of libburn API or libburner sourcecode.
@include libburner.c
*/

1520
doc/cookbook.txt Normal file

File diff suppressed because it is too large Load Diff

388
doc/ddlp.txt Normal file
View File

@ -0,0 +1,388 @@
-------------------------------------------------------------------------------
Users of modern desktop Linux installations report misburns with CD/DVD
recording due to concurrency problems.
This text describes two locking protocols which have been developed by our
best possible effort. But finally they rather serve as repelling example of
what would be needed in user space to achieve an insufficient partial solution.
Ted Ts'o was so friendly to help as critic with his own use cases. It turned
out that we cannot imagine a way in user space how to cover reliably the needs
of callers of libblkid and the needs of our burn programs.
-------------------------------------------------------------------------------
Content:
The "Delicate Device Locking Protocol" shall demonstrate our sincere
consideration of the problem.
"What are the Stumble Stones ?" lists reasons why the effort finally failed.
-----------------------------------------------------------------------------
Delicate Device Locking Protocol
(a joint sub project of cdrkit and libburnia)
(contact: scdbackup@gmx.net )
Our projects provide programs which allow recording of data on CD or DVD.
We encounter an increasing number of bug reports about spoiled burn runs and
wasted media which obviously have one common cause: interference by other
programs which access the drive's device files.
There is some riddling about which gestures exactly are dangerous for
ongoing recordings or can cause weirdly misformatted drive replies to MMC
commands.
We do know, nevertheless, that these effects do not occur if no other program
accesses a device file of the drive while our programs use it.
DDLP shall help to avoid collisions between programs in the process of
recording to a CD or DVD drive and other programs which access that drive.
The protocol intends to provide advisory locking. So any good-willing program
has to take some extra precautions to participate.
If a program does not feel vulnerable to disturbance, then the precautions
impose much less effort than if the program feels the need for protection.
Two locking strategies are specified:
DDLP-A operates on device files only. It is very Linux specific.
DDLP-B adds proxy lock files, inspired by FHS /var/lock standard.
DDLP-A
This protocol relies on the hardly documented feature open(O_EXCL | O_RDWR)
with Linux device files and on POSIX compliant fcntl(F_SETLK).
Other than the original meaning of O_EXCL with creating regular files, the
effect on device files is mutual exclusion of access. I.e. if one
filedescriptor is open on that combination of major-minor device number, then
no other open(O_EXCL) will succeed. But open() without O_EXCL would succeed.
So this is advisory and exclusive locking.
With kernel 2.6 it seems to work on all device drivers which might get used
to access a CD/DVD drive.
The vulnerable programs shall not start their operation before they occupied a
wide collection of drive representations.
Non-vulnerable programs shall take care to detect the occupation of _one_ such
representation.
So for Friendly Programs
A program which does not feel vulnerable to disturbance is urged to access
CD/DVD drives by opening a file descriptor which will uphold the lock
as long as it does not get closed. There are two alternative ways to achieve
this.
Very reliable is
open( some_path , O_EXCL | ...)
But O_EXCL imposes restrictions and interferences:
- O_EXCL | O_RDONLY does not succeed with /dev/sg* !
- O_EXCL cannot provide shared locks for programs which only want to lock
against burn programs but not against their own peers.
- O_EXCL keeps from obtaining information by harmless activities.
- O_EXCL already has a meaning with devices which are mounted as filesystems.
This priority meaning is more liberal than the one needed for CD/DV recording
protection.
So it may be necessary to use a cautious open() without O_EXCL and to aquire
a POSIX lock via fcntl(). "Cautious" means to add O_NDELAY to the flags of
open(), because this is declared to avoid side effects within open().
With this gesture it is important to use the paths expected by our burn
programs: /dev/sr[0..255] /dev/scd[0..255] /dev/sg[0..255] /dev/hd[a..z]
because fcntl(F_SETLK) does not lock the device but only a device-inode.
std_path = one of the standard device files:
/dev/sr[0..255] /dev/scd[0..255] /dev/sg[0..255] /dev/hd[a..z]
or a symbolic link pointing to one of them.
open( std_path , ... | O_NDELAY)
fcntl(F_SETLK) and close() on failure
... eventually disable O_NDELAY by fcntl(F_SETFL) ...
There is a pitfall mentioned in man 2 fcntl :
"locks are automatically released [...] if it closes any file descriptor
referring to a file on which locks are held. This is bad [...]"
So you may have to re-lock after some temporary fd got closed.
Vulnerable Programs
For programs which do feel vulnerable, O_EXCL would suffice for the /dev/hd*
device file family and their driver. But USB and SATA recorders appear with
at least two different major-minor combinations simultaneously.
One as /dev/sr* alias /dev/scd*, the other as /dev/sg*.
The same is true for ide-scsi or recorders attached to SCSI controllers.
So, in order to lock any access to the recorder, one has to open(O_EXCL)
not only the device file that is intended for accessing the recorder but also
a device file of any other major-minor representation of the recorder.
This is done via the SCSI address parameter vector (Host,Channel,Id,Lun)
and a search on standard device file paths /dev/sr* /dev/scd* /dev/sg*.
In this text the alternative device representations are called "siblings".
For finding them, it is necessary to apply open() to many device files which
might be occupied by delicate operations. On the other hand it is very
important to occupy all reasonable representations of the drive.
So the reading of the (Host,Channel,Id,Lun) parameters demands an
open(O_RDONLY | O_NDELAY) _without_ fcntl() in order to find the outmost
number of representations among the standard device files. Only ioctls
SCSI_IOCTL_GET_IDLUN and SCSI_IOCTL_GET_BUS_NUMBER are applied.
Hopefully this gesture is unable to cause harmful side effects on kernel 2.6.
At least one file of each class sr, scd and sg should be found to regard
the occupation as satisfying. Thus corresponding sr-scd-sg triplets should have
matching ownerships and access permissions.
One will have to help the sysadmins to find those triplets.
A spicy detail is that sr and scd may be distinct device files for the same
major-minor combination. In this case fcntl() locks on both are needed
but O_EXCL can only be applied to one of them.
An open and free implementation ddlpa.[ch] is provided as
http://libburnia.pykix.org/browser/libburn/trunk/libburn/ddlpa.h?format=txt
http://libburnia.pykix.org/browser/libburn/trunk/libburn/ddlpa.c?format=txt
The current version of this text is
http://libburnia.pykix.org/browser/libburn/trunk/doc/ddlp.txt?format=txt
Put ddlpa.h and ddlpa.c into the same directory and compile as test program by
cc -g -Wall -DDDLPA_C_STANDALONE -o ddlpa ddlpa.c
Use it to occupy a drive's representations for a given number of seconds
./ddlpa /dev/sr0 300
It should do no harm to any of your running activities.
If it does: Please, please alert us.
Your own programs should not be able to circumvent the occupation if they
obey above rules for Friendly Programs.
Of course ./ddlpa should be unable to circumvent itself.
A successfull occupation looks like
DDLPA_DEBUG: ddlpa_std_by_rdev("/dev/scd0") = "/dev/sr0"
DDLPA_DEBUG: ddlpa_collect_siblings() found "/dev/sr0"
DDLPA_DEBUG: ddlpa_collect_siblings() found "/dev/scd0"
DDLPA_DEBUG: ddlpa_collect_siblings() found "/dev/sg0"
DDLPA_DEBUG: ddlpa_occupy() : '/dev/scd0'
DDLPA_DEBUG: ddlpa_occupy() O_EXCL : '/dev/sg0'
DDLPA_DEBUG: ddlpa_occupy() O_EXCL : '/dev/sr0'
---------------------------------------------- Lock gained
ddlpa: opened /dev/sr0
ddlpa: opened siblings: /dev/scd0 /dev/sg0
slept 1 seconds of 300
Now an attempt via device file alias /dev/NEC must fail:
DDLPA_DEBUG: ddlpa_std_by_rdev("/dev/NEC") = "/dev/sg0"
DDLPA_DEBUG: ddlpa_collect_siblings() found "/dev/sr0"
DDLPA_DEBUG: ddlpa_collect_siblings() found "/dev/scd0"
DDLPA_DEBUG: ddlpa_collect_siblings() found "/dev/sg0"
Cannot exclusively open '/dev/sg0'
Reason given : Failed to open O_RDWR | O_NDELAY | O_EXCL : '/dev/sr0'
Error condition : 16 'Device or resource busy'
With hdc, of course, things are trivial
DDLPA_DEBUG: ddlpa_std_by_rdev("/dev/hdc") = "/dev/hdc"
DDLPA_DEBUG: ddlpa_occupy() O_EXCL : '/dev/hdc'
---------------------------------------------- Lock gained
ddlpa: opened /dev/hdc
slept 1 seconds of 1
Ted Ts'o provided program open-cd-excl which allows to explore open(2) on
device files with combinations of read-write, O_EXCL, and fcntl().
(This does not mean that Ted endorsed our project yet. He helps exploring.)
Friendly in the sense of DDLP-A would be any run which uses at least one of
the options -e (i.e. O_EXCL) or -f (i.e. F_SETLK, applied to a file
descriptor which was obtained from a standard device file path).
The code is available under GPL at
http://libburnia.pykix.org/browser/libburn/trunk/test/open-cd-excl.c?format=txt
To be compiled by
cc -g -Wall -o open-cd-excl open-cd-excl.c
Options:
-e : open O_EXCL
-f : aquire lock by fcntl(F_SETLK) after sucessful open
-i : do not wait in case of success but exit 0 immediately
-r : open O_RDONLY , with -f use F_RDLCK
-w : open O_RDWR , with -f use F_WRLCK
plus the path of the devce file to open.
Friendly Programs would use gestures like:
./open-cd-excl -e -r /dev/sr0
./open-cd-excl -e -w /dev/sg1
./open-cd-excl -e -w /dev/black-drive
./open-cd-excl -f -r /dev/sg1
./open-cd-excl -e -f -w /dev/sr0
Ignorant programs would use and cause potential trouble by:
./open-cd-excl -r /dev/sr0
./open-cd-excl -w /dev/sg1
./open-cd-excl -f -w /dev/black-drive
where "/dev/black-drive" is _not_ a symbolic link to
any of /dev/sr* /dev/scd* /dev/sg* /dev/hd*, but has an own inode.
Prone to failure without further reason is:
./open-cd-excl -e -r /dev/sg1
----------------------------------------------------------------------------
DDLP-B
This protocol relies on proxy lock files in some filesystem directory. It can
be embedded into DDLP-A or it can be used be used standalone, outside DDLP-A.
DDLP-A shall be kept by DDLP-B from trying to access any device file which
might already be in use. There is a problematic gesture in DDLP-A when SCSI
address parameters are to be retrieved. For now this gesture seems to be
harmless. But one never knows.
Vice versa DDLP-B may get from DDLP-A the service to search for SCSI device
file siblings. So they are best as a couple.
But they are not perfect. Not even as couple. fcntl() locking is flawed.
There is a proxy file locking protocol described in FHS:
http://www.pathname.com/fhs/pub/fhs-2.3.html#VARLOCKLOCKFILES
But it has shortcommings (see below). Decisive obstacle for its usage are the
possibility for stale locks and the lack of shared locks.
DDLP-B rather defines a "path prefix" which is advised to be
/tmp/ddlpb-lock-
This prefix will get appended "device specific suffixes" and then form the path
of a "lockfile".
Not the existence of a lockfile but its occupation by an fcntl(F_SETLK) will
constitute a lock. Lockfiles may get prepared by the sysadmin in directories
where normal users are not allowed to create new files. Their rw-permissions
then act as additional access restriction to the device files.
The use of fcntl(F_SETLK) will prevent any stale locks after the process ended.
It will also allow to obtain shared locks as well as exclusive locks.
There are two classes of device specific suffixes:
- Device file path suffix. Absolute paths only. "/" gets replaced by "_-".
Eventual "_-" in path gets replaced by "_-_-". The leading group of "_-"
is always interpreted as a group of "/", though. E.g.:
/dev/sr0 <-> "_-dev_-sr0"
/mydevs/burner/nec <-> "_-mydevs_-burners_-nec"
/dev/rare_-name <-> "_-dev_-rare_-_-name"
///strange/dev/x <-> "_-_-_-strange_-dev_-x"
- st_rdev suffix. A hex representation of struct stat.st_rdev. Capital letters.
The number of characters is pare with at most one leading 0. I.e. bytewise
printf("%2.2X") beginning with the highest order byte that is not zero.
E.g. : "0B01", "2200", "01000000000004001"
If a lockfile does not exist and cannot be created then this shall not keep
a program from working on a device. But if a lockfile exists and if permissions
or locking state do not allow to obtain a lock of the appropirate type, then
this shall prevent any opening of device file in question and shall cause
immediate close(2) of an already opened device file.
The vulnerable programs shall not start their operation before they locked a
wide collection of drive representations.
Non-vulnerable programs shall take care to lock the suffix resulting from the
path they will be using and the suffix from the st_rdev from that path.
The latter is to be obtained by call stat(2).
Locks get upheld as long as their file descriptor is not closed or no other
incident as described in man 2 fcntl releases the lock.
So with shared locks there are no imandatory further activities after they
have been obtained.
In case of exclusive locks, the file has to have been opened for writing and
must be truncated to 0 bytes length immediately after obtaining the lock.
When releasing an exclusive lock it is a nice gesture to
already do this truncation.
Then a /var/lock/ compatible first line has to be written.
E.g. by: printf("%10u\n",(unsigned) getpid()) yielding " 1230\n".
Any further lines are optional. They shall have the form Name=Value and must
be printable cleartext. If such further lines exist, then the last one must
have the name "endmark".
Defined Names are:
hostid =hostname of the machine where the process number of line 1 is valid
start =start time of lock in seconds since 1970. E.g: 1177147634.592410
program =self chosen name of the program which obtained the lock
argv0 =argv[0] of that program
mainpath =device file path which will be used for operations by that program
path =device file path which lead to the lock
st_rdev =st_rdev suffix which is associated with path
scsi_hcil=eventual SCSI parameters Host,Channel,Id,Lun
scsi_bus =eventual SCSI parameter Bus
endmark =declares the info as complete.
Any undefined name or a line without "=" shall be handled as comment.
"=" in the value is allowed. Any line beginning with an "=" character is an
extension of the previous value.
If programs encounter an exclusive lock, they are invited to read the content
of the lockfile anyway. But they should be aware that the info might be in the
progress of emerging. There is a race condition possible in the short time
between obtaining the exclusive lock and erasing the file content.
If it is not crucial to obtain most accurate info then one may take the newline
of the first line as indicator of a valid process number and the "endmark"
name as indicator that the preceding lines are valid.
Very cautious readers should obtain the info twice with a decent waiting period
inbetween. Only if both results are identical they should be considered valid.
There is no implementation of DDLP-B yet.
----------------------------------------------------------------------------
What are the Stumble Stones ?
----------------------------------------------------------------------------
Any of the considered locking mechanisms has decisive shortcommings
which keeps it from being the solution to all known legitimate use cases.
The attempt has failed to compose a waterproof locking mechanism from means of
POSIX, FHS and from hardly documented Linux open(O_EXCL) on device files.
The resulting mechanisms would need about 1000 lines of code and still do
not close all gaps and cover the well motivated use cases.
This attempt you see above: DDLP-A and DDLP-B.
Summary of the reasons why the established locking mechanisms do not suffice:
None of the mechanisms can take care of the double device driver identity
sr versus sg. To deduce the one device file from the other involves the need
to open many other (possibly unrelated) device files with the risk to disturb
them.
This hard to solve problem is aggravated by the following facts.
Shortcommings of Linux specific open(O_EXCL) :
- O_EXCL | O_RDONLY does not succeed with /dev/sg*
- O_EXCL cannot provide shared locks for programs which only want to lock
against burn programs but not against their own peers.
- O_EXCL keeps from obtaining information by harmless activities.
- O_EXCL already has a meaning with devices which are mounted as filesystems.
This priority meaning is more liberal than the one needed for CD/DV recording
protection.
Shortcommings of POSIX fcntl(F_SETLK) :
- fcntl() demands an open file descriptor. open(2) might have side effects.
- fcntl() locks can be released inadvertedly by submodules which just open and
close the same file (inode ?) without refering to fcntl locks in any way.
See man 2 fcntl "This is bad:".
Stacking of software modules is a widely used design pattern. But fcntl()
cannot cope with that.
Shortcommings of FHS /var/lock/ :
- Stale locks are possible.
- It is necessary to create a file (using the _old_ meaning of O_EXCL flag ?)
but /var/lock/ might not be available early during system start and it often
has restrictive permission settings.
- There is no way to indicate a difference between exclusive and shared locks.
- The FHS prescription relies entirely on the basename of the device file path.

1884
doc/doxygen.conf.in Normal file

File diff suppressed because it is too large Load Diff

1216
doc/mediainfo.txt Normal file

File diff suppressed because it is too large Load Diff

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.

12
libburn-1.pc.in Normal file
View File

@ -0,0 +1,12 @@
prefix=@prefix@
exec_prefix=@exec_prefix@
libdir=@libdir@
includedir=@includedir@
Name: libburn
Description: Library to read/write optical discs
Version: @VERSION@
Requires:
Libs: -L${libdir} -lburn
Libs.private: @THREAD_LIBS@ @LIBBURN_ARCH_LIBS@
Cflags: -I${includedir}/libburn

4
libburn/Makefile Normal file
View File

@ -0,0 +1,4 @@
all clean:
$(MAKE) -C .. -$(MAKEFLAGS) $@
.PHONY: all clean

65
libburn/Makefile.am Normal file
View File

@ -0,0 +1,65 @@
pkgconfigdir=$(libdir)/pkgconfig
libincludedir=$(includedir)/libburn
lib_LTLIBRARIES = libburn.la
libburn_la_SOURCES = \
async.c \
async.h \
crc.c \
crc.h \
debug.c \
debug.h \
drive.c \
drive.h \
file.c \
file.h \
init.c \
init.h \
lec.c \
lec.h \
message.c \
message.h \
mmc.c \
mmc.h \
null.c \
null.h \
options.c \
options.h \
read.c \
read.h \
sbc.c \
sbc.h \
sector.c \
sector.h \
sg.c \
sg.h \
spc.c \
spc.h \
source.h \
source.c \
structure.c \
structure.h \
toc.c \
toc.h \
transport.h \
util.c \
util.h \
write.c \
write.h
libinclude_HEADERS = libburn.h
## ========================================================================= ##
indent_files = $(libburn_la_SOURCES)
indent: $(indent_files)
indent -bad -bap -nbbb -nbbo -nbc -bli0 -br -bls \
-cdw -ce -cli0 -ncs -nbfda -i8 -l79 -lc79 \
-lp -saf -sai -nprs -npsl -saw -sob -ss -ut \
-sbi0 -nsc -ts8 -npcs -ncdb -fca \
$^
.PHONY: indent
## ========================================================================= ##

792
libburn/asserts.txt Normal file
View File

@ -0,0 +1,792 @@
List of assert() calls in libburn. 6 Oct 2006.
Format:
------------------------------------------------------------------------------
Number) grep'ed line
(++ before number means: is fully done, + means is done so far )
function():
Description of abort condition.
Possible callers and their relation to the abort condition.
: Error Evaluation
=> Consequences
Eventual implementation timestamp
------------------------------------------------------------------------------
++ 1) libburn/async.c: assert(a != NULL); /* wasn't found.. this should not be possible */
static remove_worker():
A thread describing structure (struct w_list) could not be found in
order to be released.
Called by API burn_drive_scan()
Called by static erase_worker_func() , thread under API burn_disc_erase()
Called by static write_disc_worker_func(), thread under API burn_disc_write()
All three want to clean up after they are done.
: Severe Libburn Error
=> issue LIBDAX_MSGS_SEV_WARNING
ts A61006
------------------------------------------------------------------------------
++ 2) libburn/async.c: assert(!(workers && workers->drive));
API burn_drive_scan():
Before spawning a thread, the function refuses work because another
drive activity is going on.
: Severe Application Error
=> return -1; redefine @return in API , issue LIBDAX_MSGS_SEV_SORRY
ts A61006
------------------------------------------------------------------------------
+ 3) libburn/async.c: assert(workers == NULL);
API burn_drive_scan():
After thread is done and remover_worker() succeeded, there is still a
worker registered. Shall probably detect roguely appeared burn or
erase runs. (I consider to install a mutex shielded function for that.)
: Severe Libburn Error
=> Same as 1)
ts A61006
------------------------------------------------------------------------------
++ 4) libburn/async.c: assert(drive);
libburn/async.c: assert(!SCAN_GOING());
libburn/async.c: assert(!find_worker(drive));
API burn_disc_erase():
Wants to see a drive (assumes NULL == 0), wants to see no scan and
wants to see no other worker on that drive. I.e. this would tolerate
a parallel activity on another drive.
: Severe Application Error
=> (no return value), issue LIBDAX_MSGS_SEV_SORRY
ts A61006
------------------------------------------------------------------------------
++ 5) libburn/async.c: assert(!SCAN_GOING());
libburn/async.c: assert(!find_worker(opts->drive));
API burn_disc_write():
Same as 4)
: Severe Application Error
=> Same as 4)
ts A61006
---------------------------------------------------------------------
++ 6) libburn/drive.c: assert(d->busy == BURN_DRIVE_IDLE);
API burn_drive_release():
A drive is not idle on release.
: Severe Application Error
=> Same as 4)
ts A61007
------------------------------------------------------------------------------
++ 7) libburn/drive.c: assert(d->released);
burn_wait_all()
A drive is found grabbed.
Called by burn_drive_scan_sync(), thread under API burn_drive_scan()
Called by API burn_finish
: Severe Application Error
=> rename and redefine burn_wait_all() : now burn_drives_are_clear()
=> change all use of burn_wait_all()
=> Move tests up to burn_drive_scan()
=> There: return -1; issue LIBDAX_MSGS_SEV_SORRY
ts A61007
------------------------------------------------------------------------------
++ 8) libburn/drive.c: assert(!d->released);
API burn_disc_get_status()
Attempt to read status of non-grabbed drive.
: Severe Application Error
=> extend enum burn_disc_status by BURN_DISC_UNGRABBED
=> return BURN_DISC_UNGRABBED, issue LIBDAX_MSGS_SEV_SORRY
ts A61007
------------------------------------------------------------------------------
++ 9) libburn/drive.c: assert( /* (write_type >= BURN_WRITE_PACKET) && */
burn_drive_get_block_types():
Will not work on BURN_WRITE below BURN_WRITE_RAW.
Called by -nobody- ?
: Severe Application Error
=> inactivate unused function
ts A61007
------------------------------------------------------------------------------
++ 10) libburn/drive.c: assert(d->idata);
libburn/drive.c: assert(d->mdata);
static drive_getcaps():
sg.c:enumerate_common() did not succeed in creating a proper struct burn_drive
Called by burn_drive_scan_sync()
: Severe System Error
=> This could possibly really stay an abort() because the reason is
a plain failure of the system's memory management.
=> Detect this failure already in enumerate_common(),
issue LIBDAX_MSGS_SEV_FATAL, return
ts A61007
------------------------------------------------------------------------------
++ 11) libburn/drive.c: assert(burn_running);
burn_drive_scan_sync():
The library was not initialized.
Called as thread by API burn_drive_scan()
: Severe Application Error
=> Move this test up to burn_drive_scan()
=> There: return -1; redefine @return in API , issue LIBDAX_MSGS_SEV_FATAL
ts A61007
------------------------------------------------------------------------------
++ 12) libburn/drive.c: assert(d->released == 1);
burn_drive_scan_sync():
Inactivated
: (Severe Application Error)
=> throw out inactivated code
ts A61007
------------------------------------------------------------------------------
++ 13) libburn/drive.c: assert(strlen(d->devname) < BURN_DRIVE_ADR_LEN);
burn_drive_raw_get_adr():
An enumerated device address is longer than the API's maximum length
Called by API burn_drive_get_adr()
Called by API burn_drive_obtain_scsi_adr()
: Severe Libburn Error
=> return -1; in all three functions, enhance burn_drive_get_adr @return docs
=> issue LIBDAX_MSGS_SEV_SORRY
ts A61007
------------------------------------------------------------------------------
++ 14) libburn/drive.c: assert(drive_info->drive!=NULL);
API burn_drive_get_adr():
Drive info has no drive attached.
: Severe Libburn Error (unlikely, will eventually SIGSEGV on NULL)
=> delete assert
ts A61007
------------------------------------------------------------------------------
++ 15) libburn/init.c: assert(burn_running);
API burn_finish():
The library is not initialized
: Severe Application Error
=> return (assume no msg system)
ts A61007
------------------------------------------------------------------------------
++ 16) libburn/init.c: assert(burn_running);
API burn_preset_device_open():
The library is not initialized
: Severe Application Error
=> return (assume no msg system)
ts A61007
------------------------------------------------------------------------------
++ 17) libburn/mmc.c: assert(o->drive == d);
mmc_close_disc():
alias: struct burn_drive.close_disc()
Parameters struct burn_drive and struct burn_write_opts do not match
Called by -nobody- ?
( => Disable unused function ? )
=> removed redundant parameter struct burn_drive
ts A61009
------------------------------------------------------------------------------
++ 18) libburn/mmc.c: assert(o->drive == d);
mmc_close_session():
Same as 17)
alias: struct burn_drive.close_session()
Called by -nobody- ?
( => Disable unused function ? )
=> removed redundant parameter struct burn_drive
ts A61009
------------------------------------------------------------------------------
++ 19) libburn/mmc.c: assert(buf->bytes >= buf->sectors); /* can be == at 0... */
mmc_write_12():
- Unclear what .bytes and .sectors mean in struct buffer -
Called by -nobody- ?
=> problems with filling the write buffer have to be handled by callers
=> delete assert
ts A61009
------------------------------------------------------------------------------
++ 20) libburn/mmc.c: assert(buf->bytes >= buf->sectors); /* can be == at 0... */
mmc_write():
- Unclear what .bytes and .sectors mean in struct buffer -
libburn/mmc.c: c.page->sectors = errorblock - start + 1;
mmc_read_sectors() by toc_find_modes() by mmc_read_toc() alias drive.read_toc()
by burn_drive_grab()
This seems to be unrelated to mmc_write().
libburn/sector.c: out->sectors++;
get_sector()
Seems to hand out sector start pointer in opts->drive->buffer
and to count reservation transactions as well as reserved bytes.
Ensures out->bytes >= out->sectors
libburn/mmc.c: c.page->bytes = s->count * 8;
mmc_send_cue_sheet()
Does not use mmc_write() but directly (sg_)issue_command()
libburn/sector.c: out->bytes += seclen;
get_sector()
See above
Ensures out->bytes >= out->sectors
libburn/spc.c: c.page->bytes = 8 + 2 + d->mdata->retry_page_length;
spc_select_error_params()
Does not use mmc_write() but directly (sg_)issue_command()
libburn/spc.c: c.page->bytes = 8 + 2 + d->mdata->write_page_length;
spc_select_error_params()
Does not use mmc_write() but directly (sg_)issue_command()
libburn/spc.c: c.page->bytes = 8 + 2 + 0x32;
spc_probe_write_modes()
Does not use mmc_write() but directly (sg_)issue_command()
alias struct burn_drive.write()
Called by static get_sector, by many
Called by burn_write_flush
Called by burn_write_track
=> problems with filling the write buffer have to be handled by callers
=> delete assert
ts A61009
------------------------------------------------------------------------------
++ 21) libburn/mmc.c: assert(((dlen - 2) % 11) == 0);
mmc_read_toc():
- Is defunct -
=> :)
ts A61009
------------------------------------------------------------------------------
++ 22) libburn/mmc.c: assert(len >= 0);
mmc_read_sectors():
Catches a bad parameter
alias: struct burn_drive.read_sectors()
Called by API burn_disc_read() , - is defunct -, one could catch the problem
Called by toc_find_modes(), problem cannot occur: mem.sectors = 1;
: Severe Libburn Error
(=> in burn_disc_read() check page.sectors before d->read_sectors() )
=> :)
ts A61009
------------------------------------------------------------------------------
++ 23) libburn/mmc.c: assert(d->busy);
mmc_read_sectors():
Catches use of a drive that is not marked as busy
alias: struct burn_drive.read_sectors()
Called by API burn_disc_read() , - is defunct -, busy = BURN_DRIVE_READING;
Called by toc_find_modes(), does the same assert. To be solved there.
: Severe Libburn Error
=> :)
ts A61009
------------------------------------------------------------------------------
++ 24) libburn/options.c: assert(0);
API burn_write_opts_set_write_type():
Detects unsuitable enum burn_write_types write_type and int block_type.
API promises return 0 on failure
: Severe Application Error
=> issue LIBDAX_MSGS_SEV_SORRY
=> should also detect problem of 26) : wrong write_type,block_type combination
by calling sector_get_outmode() and checking for -1
=> should also detect problem of 41) : unknown block_type
by spc_block_type() and checking for -1
=> delete assert(0)
ts A61007
------------------------------------------------------------------------------
++ 25) libburn/read.c: assert((o->version & 0xfffff000) == (OPTIONS_VERSION & 0xfffff000));
libburn/read.c: assert(!d->busy);
libburn/read.c: assert(d->toc->valid);
libburn/read.c: assert(o->datafd != -1);
API burn_disc_read():
- ? -
burn_disc_read() is defunct
OPTIONS_VERSION does not occur outside this line
( => one would return )
( 22) => catch page.sectors<0 before d->read_sectors() )
( 37) => catch ! d->mdata->valid )
=> :)
ts A61007
------------------------------------------------------------------------------
++ 26) libburn/sector.c: assert(0); /* return BURN_MODE_UNIMPLEMENTED :) */
static get_outmode():
burn_write_opts is wrongly programmed with .write_type and .block_type
: Severe Application Error
=> This gets handled by burn_write_opts_set_write_type()
ts A61007 by new semi-public sector_get_outmode()
=> delete assert()
ts A61007
------------------------------------------------------------------------------
++ 27) libburn/sector.c: assert(outlen >= inlen);
libburn/sector.c: assert(outmode & BURN_MODE_RAW);
libburn/sector.c: assert(offset != -1);
static convert_data():
Several unacceptable settings within struct burn_write_opts
Called by sector_toc() sector_pregap() sector_postgap() sector_lout()
sector_data()
: Severe Application Error
=> change return type of convert_data()
=> all callers interpret return value and eventually return failure
ts A61007
------------------------------------------------------------------------------
++ 28) libburn/sector.c: assert(0);
static char_to_isrc():
Called by subcode_user() with data set by API burn_track_set_isrc()
Some character conversion fails on wrong input
: Severe Application Error
=> burn_track_set_isrc() has to make sure that only good data are set
=> char_to_isrc() returns 0 as default
=> delete assert()
ts A61008
------------------------------------------------------------------------------
++ 29) libburn/sector.c: assert(qmode == 1 || qmode == 2 || qmode == 3);
subcode_user():
- can not happen -
: Unknown reason of assert()
=> remove assert()
ts A61010
------------------------------------------------------------------------------
++ 30) libburn/sector.c: assert(modebyte == 1);
sector_headers():
Does only accept modes BURN_AUDIO, BURN_MODE1 or write_type BURN_WRITE_SAO
Called by sector_toc() sector_pregap() sector_postgap() sector_lout()
sector_data()
: Severe Libburn Error
=> new functions sector_headers_is_ok(), burn_disc_write_is_ok()
help to catch problem in API burn_disc_write()
=> issue LIBDAX_MSGS_SEV_FATAL
ts A61009
------------------------------------------------------------------------------
++ 31) libburn/sector.c: assert(0);
process_q()
- defunct -
=> :)
ts A61009
------------------------------------------------------------------------------
++ 32) libburn/sg.c: assert("drive busy" == "non fatal");
sg_handle_busy_device():
Intentional abort preset by the app
=> change to abort()
ts A61007
------------------------------------------------------------------------------
++ 33) libburn/sg.c: assert(fd != -1337);
sg_grab():
The drive device file could not be opened
:Severe External Problem
=> obsolete by normal drive open failure handling
ts A61007
------------------------------------------------------------------------------
++ 34) libburn/sg.c: assert(!c->page);
sg_issue_command():
An SCSI command of direction NO_TRANSFER may not have a .page != NULL.
Since it is about exposing a libburn detail towards the sg driver, i believe
it is sufficient to just not use it.
: Libburn Error
=> enhance internal logics of sg_issue_command()
ts A61007
------------------------------------------------------------------------------
++ 35) libburn/sg.c: assert(c->page->bytes > 0);
sg_issue_command():
An SCSI command of direction TO_DRIVE wants to transfer 0 bytes.
: Severe Libburn Error
=> set command.error = 1 and return 0
ts A61010
------------------------------------------------------------------------------
++ 36) libburn/sg.c: assert(err != -1);
sg_issue_command():
The transfer of the command via ioctl() failed
: Severe Transport Level Problem
=> close drive fd, set idle and released
=> set command.error = 1 and return -1
ts A61010
------------------------------------------------------------------------------
++ 37) libburn/spc.c: assert(d->mdata->valid);
spc_select_error_params():
Drive was not properly programmed
alias struct burn_drive.send_parameters()
Called by burn_disc_read, - defunct -
: Severe Application Error
=> moved up as mangled assert to burn_disc_read()
ts A61007
------------------------------------------------------------------------------
++ 38) libburn/spc.c: assert(d->mdata->cdr_write || d->mdata->cdrw_write ||
spc_sense_write_params():
Drive does not offer write of any known media type
alias struct burn_drive.read_disc_info()
Called by API burn_drive_grab (assert test made there in soft)
: Severe Command Level Problem
=> remove assert()
ts A61007
------------------------------------------------------------------------------
++ 39) libburn/spc.c: assert(o->drive == d);
spc_select_write_params():
Drive does not match struct burn_write_opts
alias struct burn_drive.send_write_parameters()
Called by mmc_close_disc() (-defunct- ?), mmc_close_session() (-defunct- ?),
burn_write_track() (d = o->drive;),
burn_disc_write_sync() d = (o->drive;)
: Severe Libburn Error
=> remove assert()
ts A61007
------------------------------------------------------------------------------
++ 40) libburn/spc.c: assert(d->mdata->valid);
spc_select_write_params():
Drive was not properly programmed
Called by (see 39)
burn_write_track() by burn_write_session() by burn_disc_write_sync()
burn_disc_write_sync() indirectly by API burn_disc_write()
: Severe Libburn Error
=> caught in burn_disc_write() now
ts A61007
------------------------------------------------------------------------------
++ 41) libburn/spc.c: assert(0);
spc_block_type():
Unknown value with enum burn_block_types
Called by spc_select_write_params, uses burn_write_opts.block_type,
set by API burn_write_opts_set_write_type()
: Severe Application Error
=> catch in API burn_write_opts_set_write_type
by calling spc_block_type()
=> delete assert
ts A61007
------------------------------------------------------------------------------
++ 42) libburn/structure.c: assert(!(pos > BURN_POS_END));\
macro RESIZE
An illegal list index is given by the app.
( TO->NEW##s obviusly means to append "s" to cpp result of TO->NEW )
Used by API burn_session_add_track() and API burn_disc_add_session()
: Severe Application Error
=> replace assert by if-and-return-0
ts A61008
------------------------------------------------------------------------------
++ 43) libburn/structure.c: assert(s->track != NULL);
API burn_session_remove_track()
An application supplied pointer is NULL
: Severe Application Error
=> replace by if-and-return-0
ts A61008
------------------------------------------------------------------------------
++ 44) libburn/structure.c: assert((country[i] >= '0' || country[i] < '9') &&
libburn/structure.c: assert((owner[i] >= '0' || owner[i] < '9') &&
libburn/structure.c: assert(year <= 99);
libburn/structure.c: assert(serial <= 99999);
API burn_track_set_isrc():
Illegal texts supplied by application.
The logical expression is always true !
: Severe Application Error
=> issue LIBDAX_MSGS_SEV_SORRY and return
=> delete assert
=> delete assert 28) in char_to_isrc()
ts A61008
------------------------------------------------------------------------------
++ 45) libburn/toc.c: assert(0); /* unhandled! find out ccd's
static write_clonecd2():
- defunct -, - unused -
=> mangle assert
ts A61008
------------------------------------------------------------------------------
++ 46) libburn/toc.c: assert(d->busy);
toc_find_modes():
The drive to work on is not marked busy
Called by mmc_read_toc() alias read_toc() by ... burn_drive_grab()
: Severe Libburn Error
=> to be prevented on the higher levels
=> delete assert
ts A61008
------------------------------------------------------------------------------
++ 47) libburn/util.c: assert(s);
burn_strdup()
Abort on NULL string which would elsewise cause a SIGSEGV
Used once in enumerate_common() with a string that worked with open(2) before
: Severe Libburn Error
=> delete assert
ts A61008
------------------------------------------------------------------------------
++ 48) libburn/util.c: assert(s);
burn_strndup(): - unused -
Same as 47
: Severe Libburn Error
=> return NULL
=> delete assert
ts A61008
------------------------------------------------------------------------------
++ 49) libburn/util.c: assert(n > 0);
burn_strndup(): - unused -
Prevent problems by negative copy length
: Severe Libburn Error
=> return NULL
=> delete assert
ts A61008
------------------------------------------------------------------------------
++ 50) libburn/write.c: assert(0);
static type_to_ctrl():
Unsuitable mode to be converted into "ctrl"
Called by static type_to_form() finally burn_create_toc_entries()
: Severe Application Error
=> to be caught in burn_track_define_data by calling for test type_to_form()
=> return -1;
ts A61008
------------------------------------------------------------------------------
++ 51) libburn/write.c: assert(0);
libburn/write.c: assert(0); /* XXX someone's gonna want this sometime */
static type_to_form():
Does not like BURN_MODE0 or BURN_MODE2 but tolerates unknown modes
Called by static burn_create_toc_entries() by burn_disc_write_sync()
: Undocumented Libburn Restriction
=> set *form = -1 , *ctladr = 0xff , return
=> make function non-static
=> call for test in API burn_track_define_data()
ts A61009
------------------------------------------------------------------------------
++ 52) libburn/write.c: assert(ptr);
static add_cue():
realloc() failed
Called by burn_create_toc_entries() by burn_disc_write_sync()
(burn_create_toc_entries is ignorant towards own potential memory problems)
(This could possibly really stay an abort() because the reason is
a plain failure of the system's memory management.)
: Severe System Error
=> change return type of add_cue to int
=> react on return -1 in burn_create_toc_entries, return NULL on failure
=> abort burn_disc_write_sync() on NULL return
ts A61009
------------------------------------------------------------------------------
++ 53) libburn/write.c: assert(d->toc_entry == NULL);
burn_create_toc_entries():
Multiple usage of struct burn_drive.toc_entry
Called by burn_disc_write_sync()
This will probably trigger an abort with disc->sessions > 1
(disc->sessions is incremented in macro RESIZE() as "NEW##s")
: Design Problem
( => ? disallow multiple sessions ? )
=> replace assert by soft means and wait what happens
ts A61009
------------------------------------------------------------------------------
++ 54) libburn/write.c: assert(0);
burn_sector_length():
Only BURN_AUDIO, BURN_MODE_RAW, BURN_MODE1 are allowed
Called by get_sector(), convert_data(), ...
=> call burn_sector_length() for test in API burn_track_define_data()
=> replace assert by -1
ts A61009
------------------------------------------------------------------------------

830
libburn/async.c Normal file
View File

@ -0,0 +1,830 @@
/* -*- 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.
*/
/* ts A71019 */
/* Standard measure should be: Threads are created detached.
According to the man pages they should then care for disposing themselves.
>>> ??? It is yet unclear why the threads vanish from the process list
even if joinable and even if never joined.
To be activated after release of libburn-0.4.0
*/
#define Libburn_create_detached_threadS 1
/* Alternative : Threads are created joinable.
Threads get detached in remove_worker() and thus should dispose themselves.
#define Libburn_detach_done_workeR 1
*/
#ifdef HAVE_CONFIG_H
#include "../config.h"
#endif
#include "libburn.h"
#include "transport.h"
#include "drive.h"
#include "write.h"
#include "options.h"
#include "file.h"
#include "async.h"
#include "init.h"
#include "back_hacks.h"
#include <pthread.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <signal.h>
/*
#include <a ssert.h>
*/
#include "libdax_msgs.h"
extern struct libdax_msgs *libdax_messenger;
/* ts A80714 : introduced type codes for the worker list */
#define Burnworker_type_scaN 0
#define Burnworker_type_erasE 1
#define Burnworker_type_formaT 2
#define Burnworker_type_writE 3
#define Burnworker_type_fifO 4
#define SCAN_GOING() (workers != NULL && \
workers->w_type == Burnworker_type_scaN)
typedef void *(*WorkerFunc) (void *);
struct scan_opts
{
struct burn_drive_info **drives;
unsigned int *n_drives;
int done;
};
struct erase_opts
{
struct burn_drive *drive;
int fast;
};
/* ts A61230 */
struct format_opts
{
struct burn_drive *drive;
off_t size;
int flag;
};
struct write_opts
{
struct burn_drive *drive;
struct burn_write_opts *opts;
struct burn_disc *disc;
};
struct fifo_opts
{
struct burn_source *source;
int flag;
};
union w_list_data
{
struct scan_opts scan;
struct erase_opts erase;
struct format_opts format;
struct write_opts write;
struct fifo_opts fifo;
};
struct w_list
{
/* ts A80714 */
int w_type; /* see above define Burnworker_type_* */
struct burn_drive *drive;
pthread_t thread;
struct w_list *next;
union w_list_data u;
};
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)
{
struct w_list *a;
for (a = workers; a; a = a->next)
if (a->drive == d)
return a;
return NULL;
}
static void add_worker(int w_type, struct burn_drive *d,
WorkerFunc f, union w_list_data *data)
{
struct w_list *a;
struct w_list *tmp;
pthread_attr_t *attr_pt = NULL;
#ifdef Libburn_create_detached_threadS
pthread_attr_t attr;
#endif
a = calloc(1, sizeof(struct w_list));
a->w_type = w_type;
a->drive = d;
a->u = *data;
burn_async_manage_lock(BURN_ASYNC_LOCK_INIT);
/* insert at front of the list */
a->next = workers;
tmp = workers;
workers = a;
if (d != NULL)
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().
*/
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
attr_pt= &attr;
#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);
workers = tmp;
return;
}
}
static void remove_worker(pthread_t th)
{
struct w_list *a, *l = NULL;
for (a = workers; a; l = a, a = a->next)
if (a->thread == th) {
if (l)
l->next = a->next;
else
workers = a->next;
#ifdef Libburn_detach_done_workeR
/* ts A71019 : burry dead puppy before forgetting it */
/* Alternative : threads get detached and thus should
dispose themselves.
*/
pthread_detach(th);
/*
int ret;
char msg[80];
ret = pthread_detach(th);
sprintf(msg,
"remove_workers(): pid= %lu pthread_detach(%lu)= %d",
(unsigned long) getpid(), (unsigned long) th, ret);
libdax_msgs_submit(libdax_messenger, -1, 0x00020158,
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_LOW,
msg, 0, 0);
*/
#endif /* Libburn_detach_done_workeR */
free(a);
break;
}
/* ts A61006 */
/* a ssert(a != NULL);/ * wasn't found.. this should not be possible */
if (a == NULL)
libdax_msgs_submit(libdax_messenger, -1, 0x00020101,
LIBDAX_MSGS_SEV_WARNING, LIBDAX_MSGS_PRIO_HIGH,
"remove_worker() cannot find given worker item", 0, 0);
}
static void *scan_worker_func(struct w_list *w)
{
int ret;
ret = burn_drive_scan_sync(w->u.scan.drives, w->u.scan.n_drives, 1);
if (ret <= 0)
w->u.scan.done = -1;
else
w->u.scan.done = 1;
return NULL;
}
static void reset_progress(struct burn_drive *d, int sessions, int tracks,
int indices, int sectors, int flag)
{
/* reset the progress indicator */
d->progress.session = 0;
d->progress.sessions = sessions;
d->progress.track = 0;
d->progress.tracks = tracks;
d->progress.index = 0;
d->progress.indices = indices;
d->progress.start_sector = 0;
d->progress.sectors = sectors;
d->progress.sector = 0;
}
int burn_drive_scan(struct burn_drive_info *drives[], unsigned int *n_drives)
{
union w_list_data o;
int ret = 0;
/* ts A61006 : moved up from burn_drive_scan_sync , former Assert */
if (!burn_running) {
libdax_msgs_submit(libdax_messenger, -1, 0x00020109,
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
"Library not running (on attempt to scan)", 0, 0);
*drives = NULL;
*n_drives = 0;
return -1;
}
/* cannot be anything working! */
/* ts A61006 */
/* a ssert(!(workers && workers->drive)); */
if (workers != NULL && workers->drive != NULL) {
drive_is_active:;
libdax_msgs_submit(libdax_messenger, -1, 0x00020102,
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
"A drive operation is still going on (want to scan)",
0, 0);
*drives = NULL;
*n_drives = 0;
return -1;
}
if (workers == NULL) {
/* start it */
/* ts A61007 : test moved up from burn_drive_scan_sync()
was burn_wait_all() */
/* ts A70907 : now demanding freed drives, not only released */
if (!burn_drives_are_clear(1))
goto drive_is_active;
*drives = NULL;
*n_drives = 0;
o.scan.drives = drives;
o.scan.n_drives = n_drives;
o.scan.done = 0;
add_worker(Burnworker_type_scaN, NULL,
(WorkerFunc) scan_worker_func, &o);
} else if (workers->u.scan.done) {
/* its done */
ret = workers->u.scan.done;
remove_worker(workers->thread);
/* ts A61006 */
/* a ssert(workers == NULL); */
if (workers != NULL) {
libdax_msgs_submit(libdax_messenger, -1, 0x00020101,
LIBDAX_MSGS_SEV_WARNING, LIBDAX_MSGS_PRIO_HIGH,
"After scan a drive operation is still going on",
0, 0);
return -1;
}
} else {
/* still going */
}
return ret;
}
static void *erase_worker_func(struct w_list *w)
{
#define Libburn_protect_erase_threaD 1
#ifdef Libburn_protect_erase_threaD
sigset_t sigset, oldset;
/* Protect blank thread from being interrupted by external signals */
sigfillset(&sigset);
sigdelset(&sigset, SIGSEGV);
sigdelset(&sigset, SIGILL);
pthread_sigmask(SIG_SETMASK, &sigset, &oldset);
#endif /* Libburn_protect_erase_threaD */
burn_disc_erase_sync(w->u.erase.drive, w->u.erase.fast);
remove_worker(pthread_self());
#ifdef Libburn_protect_erase_threaD
/* (just in case it would not end with all signals blocked) */
pthread_sigmask(SIG_SETMASK, &oldset, NULL);
#endif /* Libburn_protect_erase_threaD */
return NULL;
}
void burn_disc_erase(struct burn_drive *drive, int fast)
{
union w_list_data o;
/* ts A61006 */
/* a ssert(drive); */
/* a ssert(!SCAN_GOING()); */
/* a ssert(!find_worker(drive)); */
if(drive == NULL) {
libdax_msgs_submit(libdax_messenger, -1,
0x00020104,
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
"NULL pointer caught in burn_disc_erase", 0, 0);
return;
}
if ((SCAN_GOING()) || find_worker(drive) != NULL) {
libdax_msgs_submit(libdax_messenger, drive->global_index,
0x00020102,
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
"A drive operation is still going on (want to erase)",
0, 0);
return;
}
reset_progress(drive, 1, 1, 1, 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 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
inappropriate. One would rather need a -force option
Note: keep this in sync with mmc_read_disc_info() */
/* ts B10321 : Allowed role 5 to be blanked */
if ((drive->drive_role == 1 &&
drive->current_profile != 0x0a &&
drive->current_profile != 0x13 &&
drive->current_profile != 0x14 &&
drive->status != BURN_DISC_FULL)
||
(drive->status != BURN_DISC_FULL &&
drive->status != BURN_DISC_APPENDABLE &&
drive->status != BURN_DISC_BLANK)
||
(drive->drive_role != 1 && drive->drive_role != 5)
) {
char msg[160];
sprintf(msg, "Drive and media state unsuitable for blanking. (role= %d , profile= 0x%x , status= %d)",
drive->drive_role,
(unsigned int) drive->current_profile,
drive->status);
libdax_msgs_submit(libdax_messenger, drive->global_index,
0x00020130,
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
msg, 0, 0);
return;
}
o.erase.drive = drive;
o.erase.fast = fast;
add_worker(Burnworker_type_erasE, drive,
(WorkerFunc) erase_worker_func, &o);
}
/* ts A61230 */
static void *format_worker_func(struct w_list *w)
{
#define Libburn_protect_format_threaD 1
#ifdef Libburn_protect_format_threaD
sigset_t sigset, oldset;
/* Protect format thread from being interrupted by external signals */
sigfillset(&sigset);
sigdelset(&sigset, SIGSEGV);
sigdelset(&sigset, SIGILL);
pthread_sigmask(SIG_SETMASK, &sigset, &oldset);
#endif /* Libburn_protect_format_threaD */
burn_disc_format_sync(w->u.format.drive, w->u.format.size,
w->u.format.flag);
remove_worker(pthread_self());
#ifdef Libburn_protect_format_threaD
/* (just in case it would not end with all signals blocked) */
pthread_sigmask(SIG_SETMASK, &oldset, NULL);
#endif /* Libburn_protect_format_threaD */
return NULL;
}
/* ts A61230 */
void burn_disc_format(struct burn_drive *drive, off_t size, int flag)
{
union w_list_data o;
int ok = 0, ret;
char msg[40];
reset_progress(drive, 1, 1, 1, 0x10000, 0);
if ((SCAN_GOING()) || find_worker(drive) != NULL) {
libdax_msgs_submit(libdax_messenger, drive->global_index,
0x00020102,
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
"A drive operation is still going on (want to format)",
0, 0);
return;
}
if (drive->drive_role != 1) {
libdax_msgs_submit(libdax_messenger, drive->global_index,
0x00020146,
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
"Drive is a virtual placeholder", 0, 0);
drive->cancel = 1;
return;
}
if (flag & 128) /* application prescribed format type */
flag |= 16; /* enforce re-format */
if (drive->current_profile == 0x14)
ok = 1; /* DVD-RW sequential */
else if (drive->current_profile == 0x13 && (flag & 16))
ok = 1; /* DVD-RW Restricted Overwrite with force bit */
else if (drive->current_profile == 0x1a) {
ok = 1; /* DVD+RW */
size = 0;
flag &= ~(2|8); /* no insisting in size 0, no expansion */
flag |= 4; /* format up to maximum size */
} else if (drive->current_profile == 0x12) {
ok = 1; /* DVD-RAM */
} else if (drive->current_profile == 0x41) {
/* BD-R SRM */
ok= 1;
ret = drive->read_format_capacities(drive, 0x00);
if (ret > 0 &&
drive->format_descr_type == BURN_FORMAT_IS_FORMATTED)
ok = 0;
if (drive->status != BURN_DISC_BLANK)
ok = 0;
if (!ok) {
libdax_msgs_submit(libdax_messenger,
drive->global_index, 0x00020162,
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
"BD-R not unformatted blank any more. Cannot format.",
0, 0);
drive->cancel = 1;
return;
}
if (flag & 32) {
libdax_msgs_submit(libdax_messenger,
drive->global_index, 0x00020163,
LIBDAX_MSGS_SEV_NOTE, LIBDAX_MSGS_PRIO_HIGH,
"Blank BD-R left unformatted for zero spare capacity.",
0, 0);
return;
}
} else if (drive->current_profile == 0x43) {
ok = 1; /* BD-RE */
if ((flag & 32) && !(drive->current_feat23h_byte4 & 8)) {
libdax_msgs_submit(libdax_messenger,
drive->global_index, 0x00020164,
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
"Drive does not format BD-RE without spares.",
0, 0);
drive->cancel = 1;
return;
}
}
if (!ok) {
sprintf(msg,"Will not format media type %4.4Xh",
drive->current_profile);
libdax_msgs_submit(libdax_messenger, drive->global_index,
0x00020129,
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
msg, 0, 0);
drive->cancel = 1;
return;
}
o.format.drive = drive;
o.format.size = size;
o.format.flag = flag;
add_worker(Burnworker_type_formaT, drive,
(WorkerFunc) format_worker_func, &o);
}
static void *write_disc_worker_func(struct w_list *w)
{
struct burn_drive *d = w->u.write.drive;
char msg[80];
#define Libburn_protect_write_threaD 1
#ifdef Libburn_protect_write_threaD
sigset_t sigset, oldset;
/* Protect write thread from being interrupted by external signals */
sigfillset(&sigset);
sigdelset(&sigset, SIGSEGV);
sigdelset(&sigset, SIGILL);
pthread_sigmask(SIG_SETMASK, &sigset, &oldset);
#endif /* Libburn_protect_write_threaD */
d->thread_pid = getpid();
d->thread_tid = pthread_self();
d->thread_pid_valid= 1;
burn_disc_write_sync(w->u.write.opts, w->u.write.disc);
d->thread_pid_valid= 0;
d->thread_pid = 0;
/* the options are refcounted, free out ref count which we added below
*/
burn_write_opts_free(w->u.write.opts);
sprintf(msg, "Write thread on drive %d ended", d->global_index);
libdax_msgs_submit(libdax_messenger, d->global_index, 0x00020178,
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH,
msg, 0, 0);
remove_worker(pthread_self());
d->busy = BURN_DRIVE_IDLE;
#ifdef Libburn_protect_write_threaD
/* (just in case it would not end with all signals blocked) */
pthread_sigmask(SIG_SETMASK, &oldset, NULL);
#endif /* Libburn_protect_write_threaD */
return NULL;
}
void burn_disc_write(struct burn_write_opts *opts, struct burn_disc *disc)
{
union w_list_data o;
char *reasons= NULL;
struct burn_drive *d;
int mvalid;
d = opts->drive;
/* ts A61006 */
/* a ssert(!SCAN_GOING()); */
/* a ssert(!find_worker(opts->drive)); */
if ((SCAN_GOING()) || find_worker(opts->drive) != NULL) {
libdax_msgs_submit(libdax_messenger, d->global_index,
0x00020102,
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
"A drive operation is still going on (want to write)",
0, 0);
return;
}
reset_progress(d, disc->sessions, disc->session[0]->tracks,
disc->session[0]->track[0]->indices, 0, 0);
/* For the next lines any return indicates failure */
d->cancel = 1;
/* ts A70203 : people have been warned in API specs */
if (opts->write_type == BURN_WRITE_NONE) {
libdax_msgs_submit(libdax_messenger, d->global_index,
0x0002017c,
LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH,
"No valid write type selected", 0, 0);
return;
}
if (d->drive_role == 0) {
libdax_msgs_submit(libdax_messenger, d->global_index,
0x00020146,
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
"Drive is a virtual placeholder (null-drive)", 0, 0);
return;
}
if (d->drive_role == 4) {
libdax_msgs_submit(libdax_messenger, d->global_index,
0x00020181,
LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH,
"Pseudo-drive is a read-only file. Cannot write.",
0, 0);
return;
}
/* ts A61007 : obsolete Assert in spc_select_write_params() */
if (d->drive_role == 1) {
mvalid = 0;
if (d->mdata != NULL)
mvalid = 1;
if (!mvalid) {
libdax_msgs_submit(libdax_messenger,
d->global_index, 0x00020113,
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
"Drive capabilities not inquired yet", 0, 0);
return;
}
}
/* ts A70219 : intended to replace all further tests here and many
tests in burn_*_write_sync()
*/
BURN_ALLOC_MEM_VOID(reasons, char, BURN_REASONS_LEN + 80);
strcpy(reasons, "Write job parameters are unsuitable:\n");
if (burn_precheck_write(opts, disc, reasons + strlen(reasons), 1)
<= 0) {
libdax_msgs_submit(libdax_messenger,
d->global_index, 0x00020139,
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
reasons, 0, 0);
goto ex;
}
BURN_FREE_MEM(reasons); reasons= NULL;
/* ts A90106 : early catching of unformatted BD-RE */
if (d->current_profile == 0x43)
if (d->read_format_capacities(d, 0x00) > 0 &&
d->format_descr_type != BURN_FORMAT_IS_FORMATTED) {
libdax_msgs_submit(libdax_messenger,
d->global_index, 0x00020168,
LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH,
"Media not properly formatted. Cannot write.",
0, 0);
return;
}
d->cancel = 0; /* End of the return = failure area */
o.write.drive = d;
o.write.opts = opts;
o.write.disc = disc;
opts->refcount++;
add_worker(Burnworker_type_writE, d,
(WorkerFunc) write_disc_worker_func, &o);
ex:;
BURN_FREE_MEM(reasons);
}
static void *fifo_worker_func(struct w_list *w)
{
#define Libburn_protect_fifo_threaD 1
#ifdef Libburn_protect_fifo_threaD
sigset_t sigset, oldset;
/* Protect fifo thread from being interrupted by external signals */
sigfillset(&sigset);
sigdelset(&sigset, SIGSEGV);
sigdelset(&sigset, SIGILL);
pthread_sigmask(SIG_SETMASK, &sigset, &oldset);
#endif /* Libburn_protect_fifo_threaD */
burn_fifo_source_shoveller(w->u.fifo.source, w->u.fifo.flag);
remove_worker(pthread_self());
#ifdef Libburn_protect_fifo_threaD
/* (just in case it would not end with all signals blocked) */
pthread_sigmask(SIG_SETMASK, &oldset, NULL);
#endif /* Libburn_protect_fifo_threaD */
return NULL;
}
int burn_fifo_start(struct burn_source *source, int flag)
{
union w_list_data o;
struct burn_source_fifo *fs = source->data;
fs->is_started = -1;
/* create and set up ring buffer */;
fs->buf = burn_os_alloc_buffer(
((size_t) fs->chunksize) * (size_t) fs->chunks, 0);
if (fs->buf == NULL) {
/* >>> could not start ring buffer */;
return -1;
}
o.fifo.source = source;
o.fifo.flag = flag;
add_worker(Burnworker_type_fifO, NULL,
(WorkerFunc) fifo_worker_func, &o);
fs->is_started = 1;
return 1;
}
int burn_fifo_abort(struct burn_source_fifo *fs, int flag)
{
int ret;
pthread_t pt;
burn_async_manage_lock(BURN_ASYNC_LOCK_OBTAIN);
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);
return (ret == 0);
}
#ifdef Libburn_has_burn_async_join_alL
/* ts A71019 : never used */
void burn_async_join_all(void)
{
void *ret;
while (workers)
pthread_join(workers->thread, &ret);
}
#endif /* Libburn_has_burn_async_join_alL */

28
libburn/async.h Normal file
View File

@ -0,0 +1,28 @@
/* -*- 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
void burn_async_join_all(void);
struct burn_write_opts;
/* ts A70930 */
/* To be called when the first read() call comes to a fifo */
int burn_fifo_start(struct burn_source *source, int flag);
/* ts A81108 */
/* 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 */

56
libburn/back_hacks.h Normal file
View File

@ -0,0 +1,56 @@
/**
Copyright (c) 2006 Thomas Schmitt <scdbackup@gmx.net>
Provided under GPL version 2 or later.
This file bundles variables which disable changes in libburn which are
not yet completely accepted.
The use of these variables is *strongly discouraged* unless you have sincere
reason and are willing to share your gained knowledge with the libburn
developers.
Do *not silently rely* on these variables with your application. Tell us
that you needed one or more of them. They are subject to removal as soon
as consense has been found about correctness of the change they revoke.
Value 0 means that the new behavior is enabled. Any other value enables
the described old time behavior.
If you doubt one of the changes here broke your application, then do
*in your application*, *not here* :
- #include "libburn/back_hacks.h" like you include "libburn/libburn.h"
- Set the libburn_back_hack_* variable of your choice to 1.
In your app. Not here.
- Then start and use libburn as usual. Watch out for results.
- If you believe to have detected a flaw in our change, come forward
and report it to the libburn developers. Thanks in advance. :)
*/
/** Do not define this macro in your application. Only libburn/init.c is
entitled to set it.
*/
#ifdef BURN_BACK_HACKS_INIT
/** Corresponds to http://libburn.pykix.org/ticket/42
Reinstates the old ban not to blank appendable CD-RW. We see no reason
for this ban yet. It appears unusual. But maybe it patches a bug.
*/
int libburn_back_hack_42= 0;
#else /* BURN_BACK_HACKS_INIT */
/* Note: no application programmer info beyond this point */
extern int libburn_back_hack_42;
#endif /* ! BURN_BACK_HACKS_INIT */

1737
libburn/cdtext.c Executable file

File diff suppressed because it is too large Load Diff

242
libburn/cleanup.c Normal file
View File

@ -0,0 +1,242 @@
/*
cleanup.c , Copyright 2006 - 2011 Thomas Schmitt <scdbackup@gmx.net>
A signal handler which cleans up an application and exits.
Provided under GPLv2+ license within GPL projects, BSD license elsewise.
*/
/*
cc -g -o cleanup -DCleanup_standalonE cleanup.c
*/
#ifdef HAVE_CONFIG_H
#include "../config.h"
#endif
#include <sys/types.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <signal.h>
typedef void (*sighandler_t)(int);
#include "cleanup.h"
#ifndef Cleanup_has_no_libburn_os_H
#include "../libburn/os.h"
/* see os.h for name of particular os-*.h where this is defined */
static int signal_list[]= { BURN_OS_SIGNAL_MACRO_LIST , -1};
static char *signal_name_list[]= { BURN_OS_SIGNAL_NAME_LIST , "@"};
static int signal_list_count= BURN_OS_SIGNAL_COUNT;
static int non_signal_list[]= { BURN_OS_NON_SIGNAL_MACRO_LIST, -1};
static int non_signal_list_count= BURN_OS_NON_SIGNAL_COUNT;
#else /* ! Cleanup_has_no_libburn_os_H */
/* Outdated. GNU/Linux only.
For backward compatibility with pre-libburn-0.2.3 */
/* Signals to be caught */
static int signal_list[]= {
SIGHUP, SIGINT, SIGQUIT, SIGILL, SIGABRT,
SIGFPE, SIGSEGV, SIGPIPE, SIGALRM, SIGTERM,
SIGUSR1, SIGUSR2, SIGXCPU, SIGTSTP, SIGTTIN,
SIGTTOU,
SIGBUS, SIGPOLL, SIGPROF, SIGSYS, SIGTRAP,
SIGVTALRM, SIGXCPU, SIGXFSZ, -1
};
static char *signal_name_list[]= {
"SIGHUP", "SIGINT", "SIGQUIT", "SIGILL", "SIGABRT",
"SIGFPE", "SIGSEGV", "SIGPIPE", "SIGALRM", "SIGTERM",
"SIGUSR1", "SIGUSR2", "SIGXCPU", "SIGTSTP", "SIGTTIN",
"SIGTTOU",
"SIGBUS", "SIGPOLL", "SIGPROF", "SIGSYS", "SIGTRAP",
"SIGVTALRM", "SIGXCPU", "SIGXFSZ", "@"
};
static int signal_list_count= 24;
/* Signals not to be caught */
static int non_signal_list[]= {
SIGKILL, SIGCHLD, SIGSTOP, SIGURG, SIGWINCH, -1
};
static int non_signal_list_count= 5;
#endif /* Cleanup_has_no_libburn_os_H */
/* run time dynamic part */
static char cleanup_msg[4096]= {""};
static int cleanup_exiting= 0;
static int cleanup_has_reported= -1234567890;
static void *cleanup_app_handle= NULL;
static Cleanup_app_handler_T cleanup_app_handler= NULL;
static int cleanup_perform_app_handler_first= 0;
static int Cleanup_handler_exit(int exit_value, int signum, int flag)
{
int ret;
if(cleanup_msg[0]!=0 && cleanup_has_reported!=signum) {
fprintf(stderr,"\n%s\n",cleanup_msg);
cleanup_has_reported= signum;
}
if(cleanup_perform_app_handler_first)
if(cleanup_app_handler!=NULL) {
ret= (*cleanup_app_handler)(cleanup_app_handle,signum,0);
if(ret==2 || ret==-2)
return(2);
}
if(cleanup_exiting) {
fprintf(stderr,"cleanup: ABORT : repeat by pid=%.f, signum=%d\n",
(double) getpid(), signum);
return(0);
}
cleanup_exiting= 1;
alarm(0);
if(!cleanup_perform_app_handler_first)
if(cleanup_app_handler!=NULL) {
ret= (*cleanup_app_handler)(cleanup_app_handle,signum,0);
if(ret==2 || ret==-2)
return(2);
}
exit(exit_value);
}
static void Cleanup_handler_generic(int signum)
{
int i;
sprintf(cleanup_msg,"UNIX-SIGNAL caught: %d errno= %d",signum,errno);
for(i= 0; i<signal_list_count; i++)
if(signum==signal_list[i]) {
sprintf(cleanup_msg,"UNIX-SIGNAL: %s errno= %d",
signal_name_list[i],errno);
break;
}
Cleanup_handler_exit(1,signum,0);
}
static char *Cleanup_signo_to_name(int signo)
{
int i;
for(i= 0; i < signal_list_count; i++)
if(signal_list[i] == signo)
return(signal_name_list[i]);
return("");
}
int Cleanup_set_handlers(void *handle, Cleanup_app_handler_T handler, int flag)
/*
bit0= set to default handlers
bit1= set to ignore
bit2= set cleanup_perform_app_handler_first
bit3= set SIGABRT to handler (makes sense with bits 0 or 1)
bit8= set SIGPIPE to SIGIGN
*/
{
int i,j,max_sig= -1,min_sig= 0x7fffffff;
char *sig_name;
sighandler_t sig_handler;
cleanup_msg[0]= 0;
cleanup_app_handle= handle;
cleanup_app_handler= handler;
/* <<< make cleanup_exiting thread safe to get rid of this */
if(flag&4)
cleanup_perform_app_handler_first= 1;
if(flag&1)
sig_handler= SIG_DFL;
else if(flag&2)
sig_handler= SIG_IGN;
else
sig_handler= Cleanup_handler_generic;
/* set all signal numbers between the lowest and highest in the list
except those in the non-signal list */
for(i= 0; i<signal_list_count; i++) {
if(signal_list[i]>max_sig)
max_sig= signal_list[i];
if(signal_list[i]<min_sig)
min_sig= signal_list[i];
}
for(i= min_sig; i<=max_sig; i++) {
for(j= 0; j<non_signal_list_count; j++)
if(i==non_signal_list[j])
break;
if(j>=non_signal_list_count) {
/* Avoid to use particular SIG macros which might not be defined.
If they are defined, then their names are in the name list.
*/
if(flag & (8 | 256))
sig_name= Cleanup_signo_to_name(i);
else
sig_name= "";
if((flag & 8) && strcmp(sig_name, "SIGABRT") == 0)
signal(i,Cleanup_handler_generic);
else if((flag & 256) && strcmp(sig_name, "SIGPIPE") == 0)
signal(i, SIG_IGN);
else
signal(i,sig_handler);
}
}
return(1);
}
#ifdef Cleanup_standalonE
struct Demo_apP {
char *msg;
};
int Demo_app_handler(struct Demo_apP *demoapp, int signum, int flag)
{
printf("Handling exit of demo application on signal %d. msg=\"%s\"\n",
signum,demoapp->msg);
return(1);
}
main()
{
struct Demo_apP demoapp;
demoapp.msg= "Good Bye";
Cleanup_set_handlers(&demoapp,(Cleanup_app_handler_T) Demo_app_handler,0);
if(1) { /* change to 0 in order to wait for external signals */
char *cpt= NULL, c= ' ';
printf("Intentionally provoking SIGSEGV ...\n");
c= *cpt;
printf("Strange: The system ignored a SIGSEGV: c= %u\n", (unsigned int) c);
} else {
printf("killme: %d\n",getpid());
sleep(3600);
}
Cleanup_set_handlers(NULL,NULL,1);
exit(0);
}
#endif /* Cleanup_standalonE */

34
libburn/cleanup.h Normal file
View File

@ -0,0 +1,34 @@
/*
cleanup.c , Copyright 2006 Thomas Schmitt <scdbackup@gmx.net>
A signal handler which cleans up an application and exits.
Provided under GPLv2+ within GPL projects, BSD license elsewise.
*/
#ifndef Cleanup_includeD
#define Cleanup_includeD 1
/** Layout of an application provided cleanup function using an application
provided handle as first argument and the signal number as second
argument. The third argument is a flag bit field with no defined bits yet.
If the handler returns 2 or -2 then it has delegated exit() to some other
instance and the Cleanup handler shall return rather than exit.
*/
typedef int (*Cleanup_app_handler_T)(void *, int, int);
/** Establish exiting signal handlers on (hopefully) all signals that are
not ignored by default or non-catchable.
@param handle Opaque object which knows how to cleanup application
@param handler Function which uses handle to perform application cleanup
@param flag Control Bitfield
bit0= reset to default signal handling
*/
int Cleanup_set_handlers(void *handle, Cleanup_app_handler_T handler,
int flag);
#endif /* ! Cleanup_includeD */

642
libburn/crc.c Normal file
View File

@ -0,0 +1,642 @@
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
/* Copyright (c) 2012 Thomas Schmitt <scdbackup@gmx.net>
Provided under GPL version 2 or later.
Containing disabled code pieces from other GPL programs.
They are just quotes for reference.
The activated code uses plain polynomial division and other primitve
algorithms to build tables of pre-computed CRC values. It then computes
the CRCs by algorithms which are derived from mathematical considerations
and from analysing the mathematical meaning of the disabled code pieces.
The comments here are quite detailed in order to prove my own understanding
of the topic.
*/
#ifdef HAVE_CONFIG_H
#include "../config.h"
#endif
#include "crc.h"
/* Exploration ts B00214 :
ECMA-130, 22.3.6 "CRC field"
"This field contains the inverted parity bits. The CRC code word must be
divisible by the check polynomial. [...]
The generating polynomial shall be
G(x) = x^16 + x^12 + x^5 + 1
"
Also known as CRC-16-CCITT, CRC-CCITT
Used in libburn for raw write modes in sector.c.
There is also disabled code in read.c which would use it.
ts B11222:
The same algorithm is prescribed for CD-TEXT in MMC-3 Annex J.
"CRC Field consists of 2 bytes. Initiator system may use these bytes
to check errors in the Pack. The polynomial is x^16 + x^12 + x^5 + 1.
All bits shall be inverted."
libburn/cdtext.c uses a simple bit shifting function : crc_11021()
ts B20211:
Discussion why both are equivalent in respect to their result:
Both map the bits of the given bytes to a polynomial over the finite field
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
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
corresponds to bitwise exclusive or. Addition and subtraction are identical.
Multiplication with polynomials of only one single non-zero coefficient
corresponds to leftward bit shifting by the exponent of that coefficient.
The same rules apply as with elementary school arithmetics on integer
numbers, but with surprising results due to the finite nature of the
coefficient number space.
Note that multiplication is _not_ an iteration of addition here.
Function crc_11021() performs a division with residue by the euclidian
algorithm. I.e. it splits polynomial d into quotient q(d) and residue r(d)
in respect to the polynomial p = x exp 16 + x exp 12 + x exp 5 + x exp 0
d = p * q(d) + r(d)
where r(d) is of a polynomial degree lower than p, i.e. only x exp 15
or lower have non-zero coefficients.
The checksum crc(D) is derived by reverse mapping (r(d) * (x exp 16)).
I.e. by mapping the coefficient of (x exp n) to bit n of the 16 bit word
crc(D).
The function result is the bit-wise complement of crc(D).
Function crc_ccitt uses a table ccitt_table of r(d) values for the
polynomials d which represent the single byte values 0x00 to 0xff.
It computes r(d) by computing the residues of an iteratively expanded
polynomial. The expansion of the processed byte string A by the next byte B
from the input byte string happens by shifting the string 8 bits to the
left, and by oring B onto bits 0 to 7.
In the space of polynomials, the already processed polynomial "a" (image of
byte string A) gets expanded by polynomial b (the image of byte B) like this
a * X + b
where X is (x exp 8), i.e. the single coefficient polynomial of degree 8.
The following argumentation uses algebra with commutative, associative
and distributive laws.
Valid especially with polynomials is this rule:
(1): r(a + b) = r(a) + r(b)
because r(a) and r(b) are of degree lower than degree(p) and
degree(a + b) <= max(degree(a), degree(b))
Further valid are:
(2): r(a) = r(r(a))
(3): r(p * a) = 0
The residue of this expanded polynomial can be expressed by means of the
residue r(a) which is known from the previous iteration step, and the
residue r(b) which may be looked up in ccitt_table.
r(a * X + b)
= r(p * q(a) * X + r(a) * X + p * q(b) + r(b))
Applying rule (1):
= r(p * q(a) * X) + r(r(a) * X) + r(p * q(b)) + r(r(b))
Rule (3) and rule (2):
= r(r(a) * X) + r(b)
Be h(a) and l(a) chosen so that: r(a) = h(a) * X + l(a),
and l(a) has zero coefficients above (x exp 7), and h(a) * X has zero
coefficients below (x exp 8). (They correspond to the high and low byte
of the 16 bit word crc(A).)
So the previous statement can be written as:
= r(h(a) * X * X) + r(l(a) * X) + r(b)
Since the degree of l(a) is lower than 8, the degree of l(a) * X is lower
than 16. Thus it cannot be divisible by p which has degree 16.
So: r(l(a) * X) = l(a) * X
This yields
= l(a) * X + r(h(a) * X * X + b)
h(a) * X * X is the polynomial representation of the high byte of 16 bit
word crc(A).
So in the world of bit patterns the iteration step is:
crc(byte string A expanded by byte B)
= (low_byte(crc(A)) << 8) ^ crc(high_byte(crc(A)) ^ B)
And this is what function crc_ccitt() does, modulo swapping the exor
operants and the final bit inversion which is prescribed by ECMA-130
and MMC-3 Annex J.
The start value of the table driven byte shifting algorithm may be
different from the start value of an equivalent bit shifting algorithm.
This is because the final flushing by zero bits is already pre-computed
in the table. So the start value of the table driven algorithm must be
the CRC of the 0-polynomial under the start value of the bit shifting
algorithm.
This fact is not of much importance here, because the start value of
the bit shifter is 0x0000 which leads to CRC 0x0000 and thus to start
value 0x0000 with the table driven byte shifter.
*/
/* Plain implementation of polynomial division on a Galois field, where
addition and subtraction both are binary exor. Euclidian algorithm.
Divisor is x^16 + x^12 + x^5 + 1 = 0x11021.
This is about ten times slower than the table driven algorithm.
*/
static int crc_11021(unsigned char *data, int count, int flag)
{
int acc = 0, i;
for (i = 0; i < count * 8 + 16; i++) {
acc = (acc << 1);
if (i < count * 8)
acc |= ((data[i / 8] >> (7 - (i % 8))) & 1);
if (acc & 0x10000)
acc ^= 0x11021;
}
return acc;
}
/* This is my own table driven implementation for which i claim copyright.
Copyright (c) 2012 Thomas Schmitt <scdbackup@gmx.net>
*/
unsigned short crc_ccitt(unsigned char *data, int count)
{
static unsigned short crc_tab[256], tab_initialized = 0;
unsigned short acc = 0;
unsigned char b[1];
int i;
if (!tab_initialized) {
/* Create table of byte residues */
for (i = 0; i < 256; i++) {
b[0] = i;
crc_tab[i] = crc_11021(b, 1, 0);
}
tab_initialized = 1;
}
/* There seems to be a speed advantage on amd64 if (acc << 8) is the
second operant of exor, and *(data++) seems faster than data[i].
*/
for (i = 0; i < count; i++)
acc = crc_tab[(acc >> 8) ^ *(data++)] ^ (acc << 8);
/* ECMA-130 22.3.6 and MMC-3 Annex J (CD-TEXT) want the result with
inverted bits
*/
return ~acc;
}
/*
This was the function inherited with libburn-0.2.
static unsigned short ccitt_table[256] = {
0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7,
0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF,
0x1231, 0x0210, 0x3273, 0x2252, 0x52B5, 0x4294, 0x72F7, 0x62D6,
0x9339, 0x8318, 0xB37B, 0xA35A, 0xD3BD, 0xC39C, 0xF3FF, 0xE3DE,
0x2462, 0x3443, 0x0420, 0x1401, 0x64E6, 0x74C7, 0x44A4, 0x5485,
0xA56A, 0xB54B, 0x8528, 0x9509, 0xE5EE, 0xF5CF, 0xC5AC, 0xD58D,
0x3653, 0x2672, 0x1611, 0x0630, 0x76D7, 0x66F6, 0x5695, 0x46B4,
0xB75B, 0xA77A, 0x9719, 0x8738, 0xF7DF, 0xE7FE, 0xD79D, 0xC7BC,
0x48C4, 0x58E5, 0x6886, 0x78A7, 0x0840, 0x1861, 0x2802, 0x3823,
0xC9CC, 0xD9ED, 0xE98E, 0xF9AF, 0x8948, 0x9969, 0xA90A, 0xB92B,
0x5AF5, 0x4AD4, 0x7AB7, 0x6A96, 0x1A71, 0x0A50, 0x3A33, 0x2A12,
0xDBFD, 0xCBDC, 0xFBBF, 0xEB9E, 0x9B79, 0x8B58, 0xBB3B, 0xAB1A,
0x6CA6, 0x7C87, 0x4CE4, 0x5CC5, 0x2C22, 0x3C03, 0x0C60, 0x1C41,
0xEDAE, 0xFD8F, 0xCDEC, 0xDDCD, 0xAD2A, 0xBD0B, 0x8D68, 0x9D49,
0x7E97, 0x6EB6, 0x5ED5, 0x4EF4, 0x3E13, 0x2E32, 0x1E51, 0x0E70,
0xFF9F, 0xEFBE, 0xDFDD, 0xCFFC, 0xBF1B, 0xAF3A, 0x9F59, 0x8F78,
0x9188, 0x81A9, 0xB1CA, 0xA1EB, 0xD10C, 0xC12D, 0xF14E, 0xE16F,
0x1080, 0x00A1, 0x30C2, 0x20E3, 0x5004, 0x4025, 0x7046, 0x6067,
0x83B9, 0x9398, 0xA3FB, 0xB3DA, 0xC33D, 0xD31C, 0xE37F, 0xF35E,
0x02B1, 0x1290, 0x22F3, 0x32D2, 0x4235, 0x5214, 0x6277, 0x7256,
0xB5EA, 0xA5CB, 0x95A8, 0x8589, 0xF56E, 0xE54F, 0xD52C, 0xC50D,
0x34E2, 0x24C3, 0x14A0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
0xA7DB, 0xB7FA, 0x8799, 0x97B8, 0xE75F, 0xF77E, 0xC71D, 0xD73C,
0x26D3, 0x36F2, 0x0691, 0x16B0, 0x6657, 0x7676, 0x4615, 0x5634,
0xD94C, 0xC96D, 0xF90E, 0xE92F, 0x99C8, 0x89E9, 0xB98A, 0xA9AB,
0x5844, 0x4865, 0x7806, 0x6827, 0x18C0, 0x08E1, 0x3882, 0x28A3,
0xCB7D, 0xDB5C, 0xEB3F, 0xFB1E, 0x8BF9, 0x9BD8, 0xABBB, 0xBB9A,
0x4A75, 0x5A54, 0x6A37, 0x7A16, 0x0AF1, 0x1AD0, 0x2AB3, 0x3A92,
0xFD2E, 0xED0F, 0xDD6C, 0xCD4D, 0xBDAA, 0xAD8B, 0x9DE8, 0x8DC9,
0x7C26, 0x6C07, 0x5C64, 0x4C45, 0x3CA2, 0x2C83, 0x1CE0, 0x0CC1,
0xEF1F, 0xFF3E, 0xCF5D, 0xDF7C, 0xAF9B, 0xBFBA, 0x8FD9, 0x9FF8,
0x6E17, 0x7E36, 0x4E55, 0x5E74, 0x2E93, 0x3EB2, 0x0ED1, 0x1EF0
};
unsigned short crc_ccitt(unsigned char *q, int len)
{
unsigned short crc = 0;
while (len-- > 0)
crc = ccitt_table[(crc >> 8 ^ *q++) & 0xff] ^ (crc << 8);
return ~crc;
}
*/
/* Exploration ts B00214 :
ECMA-130, 14.3 "EDC field"
"The EDC field shall consist of 4 bytes recorded in positions 2064 to 2067.
The error detection code shall be a 32-bit CRC applied on bytes 0 to 2063.
The least significant bit of a data byte is used first. The EDC codeword
must be divisible by the check polynomial:
P(x) = (x^16 + x^15 + x^2 + 1) . (x^16 + x^2 + x + 1)
The least significant parity bit (x^0) is stored in the most significant
bit position of byte 2067.
"
Used for raw writing in sector.c
ts B20211:
Discussion why function crc_32() implements above prescription of ECMA-130.
See end of this file for the ofunction inherited with libburn-0.2.
The mentioned polynomial product
(x^16 + x^15 + x^2 + 1) . (x^16 + x^2 + x + 1)
yields this sum of x exponents
32 31 18 16
18 17 4 2
17 16 3 1
16 15 2 0
======================================
32 31 16 15 4 3 1 0
(The number of x^18 and x^17 is divisible by two and thus 0 in GF(2).)
This yields as 33 bit number:
0x18001801b
If above prescription gets implemented straight forward by function
crc_18001801b(), then its results match the ones of crc_32() with all test
strings which i could invent.
The function consists of a conventional polynomial division with reverse
input order of bits per byte.
Further it swaps the bits in the resulting 32 bit word. That is because
sector.c:sector_headers writes the 4 bytes of crc_32() as little endian.
The ECMA-130 prescription rather demands big endianness and bit swapping
towards the normal bit order in bytes:
"The EDC field shall consist of 4 bytes recorded in positions 2064 to 2067.
[...]
The least significant parity bit (x^0) is stored in the most
significant bit position of byte 2067."
-----------------------------------------------------------------------
*/
/* Overall bit mirroring of a 32 bit word */
unsigned int rfl32(unsigned int acc)
{
unsigned int inv_acc;
int i;
inv_acc = 0;
for (i = 0; i < 32; i++)
if (acc & (1 << i))
inv_acc |= 1 << (31 - i);
return inv_acc;
}
/* Plain implementation of polynomial division on a Galois field, where
addition and subtraction both are binary exor. Euclidian algorithm.
Divisor is (x^16 + x^15 + x^2 + 1) * (x^16 + x^2 + x + 1).
This is about ten times slower than the table driven algorithm.
@param flag bit0= do not mirror bits in input bytes and result word
(Useful for building the byte indexed CRC table)
*/
static unsigned int crc_18001801b(unsigned char *data, int count, int flag)
{
unsigned int acc = 0, top;
long int i;
unsigned int inv_acc;
for (i = 0; i < count * 8 + 32; i++) {
top = acc & 0x80000000;
acc = (acc << 1);
if (i < count * 8) {
if (flag & 1)
/* Normal bit sequence of input bytes */
acc |= ((data[i / 8] >> (7 - (i % 8))) & 1);
else
/* Bit sequence of input bytes mirrored */
acc |= ((data[i / 8] >> (i % 8)) & 1);
}
if (top)
acc ^= 0x8001801b;
}
if (flag & 1)
return (unsigned int) (acc & 0xffffffff);
/* The bits of the whole 32 bit result are mirrored for ECMA-130
output compliance and for sector.c habit to store CRC little endian
although ECMA-130 prescribes it big endian.
*/
inv_acc = rfl32((unsigned int) acc);
return inv_acc;
}
/*
-----------------------------------------------------------------------
Above discussion why crc_ccitt() and crc_11021() yield identical results
can be changed from 16 bit to 32 bit by chosing h(a) and l(a) so that:
r(a) = h(a) * X * X * X + l(a)
h(a) corresponds to the highest byte of crc(A), whereas l(a) corresponds
to the lower three bytes of crc(A).
This yields
r(a * X + b)
= l(a) * X + r(h(a) * X * X * X * X + b)
h(a) * X * X * X * X is the polynomial representation of the high byte of
32 bit word crc(A).
So in the world of bit patterns we have:
crc(byte string A expanded by byte B)
= (lowest_three_bytes(crc(A)) << 8) ^ crc(high_byte(crc(A)) ^ B)
Regrettably this does not yet account for the byte-internal mirroring of
bits during the conversion from bit pattern to polynomial, and during
conversion from polynomial residue to bit pattern.
Be rfl8(D) the result of byte-internal mirroring of bit pattern D,
and mirr8(d) its corresponding polynom.
Be now h(a) and l(a) chosen so that: r(mirr8(a)) = h(a) * X * X * X + l(a)
This corresponds to highest byte and lower three bytes of crc(A).
r(mirr8(a) * X + mirr8(b))
= r(h(a) * X * X * X * X) + r(l(a) * X) + r(mirr8(b))
= l(a)) * X + r(h(a) * X * X * X * X + mirr8(b))
The corresponding bit pattern operation is
crc(mirrored byte string A expanded by mirrored byte B)
= (lowest_three_bytes(crc(A)) << 8) ^ crc(high_byte(crc(A)) ^ rfl8(B))
This demands a final result mirroring to meet the ECMA-130 prescription.
rfl8() can be implemented as lookup table.
The start value of the bit shifting iteration is 0x00000000, which leads
to the same start value for the table driven byte shifting.
The following function crc32_by_tab() yields the same results as functions
crc_18001801b() and crc_32():
-----------------------------------------------------------------------
*/
/* Byte-internal bit mirroring function.
*/
unsigned int rfl8(unsigned int acc)
{
unsigned int inv_acc;
int i, j;
inv_acc = 0;
for (j = 0; j < 4; j++)
for (i = 0; i < 8; i++)
if (acc & (1 << (i + 8 * j)))
inv_acc |= 1 << ((7 - i) + 8 * j);
return inv_acc;
}
#ifdef Libburn_with_crc_illustratioN
/* Not needed for libburn. The new implementation of function crc_32() is the
one that is used.
*/
unsigned int crc32_by_tab(unsigned char *data, int count, int flag)
{
static unsigned int crc_tab[256], tab_initialized = 0;
static unsigned char mirr_tab[256];
unsigned int acc, inv_acc;
unsigned char b[1];
int i;
if (!tab_initialized) {
for (i = 0; i < 256; i++) {
b[0] = i;
/* Create table of non-mirrored 0x18001801b residues */
crc_tab[i] = crc_18001801b(b, 1, 1);
/* Create table of mirrored byte values */
mirr_tab[i] = rfl8(i);
}
tab_initialized = 1;
}
acc = 0;
for (i = 0; i < count; i++)
acc = (acc << 8) ^ crc_tab[(acc >> 24) ^ mirr_tab[data[i]]];
/* The bits of the whole 32 bit result are mirrored for ECMA-130
output compliance and for sector.c habit to store CRC little endian
although ECMA-130 prescribes it big endian.
*/
inv_acc = rfl32((unsigned int) acc);
return inv_acc;
}
#endif /* Libburn_with_crc_illustratioN */
/*
-----------------------------------------------------------------------
Above function yields sufficient performance, nevertheless the old function
crc_32() (see below) is faster by avoiding the additional mirror table
lookup.
A test with 10 times 650 MB on 3000 MHz amd64:
crc_18001801b : 187 s
crc32_by_tab : 27 s
crc_32 : 16 s
So how does crc_32() avoid the application of bit mirroring to B ?.
Inherited crc_32() performs
crc = crc32_table[(crc ^ *data++) & 0xffL] ^ (crc >> 8);
Above function crc32_by_tab() would be
crc = crc_tab[(crc >> 24) ^ mirr_tab[*data++]] ^ (crc << 8);
The shortcut does not change the polynomial representation of the algorithm
or the mapping from and to bit patterns. It only mirrors the bit direction
in the bytes and in the 32-bit words which are involved in the bit pattern
computation. This affects input (which is desired), intermediate state
(which is as good as unmirrored), and final output (which would be slightly
undesirable if libburn could not use the mirrored result anyway).
Instead of the high byte (crc >> 24), the abbreviated algorithm uses
the low byte of the mirrored intermediate checksum (crc & 0xffL).
Instead of shifting the other three intermediate bytes to the left
(crc << 8), the abbreviated algorithm shifts them to the right (crc >> 8).
In both cases they overwrite the single byte that was used for computing
the table index.
The byte indexed table of CRC values needs to hold mirrored 32 bit values.
The byte index [(crc ^ *data++) & 0xffL] would need to be mirrored, which
would eat up the gain of not mirroring the input bytes. But this mirroring
can be pre-computed into the table by exchanging each value with the value
of its mirrored index.
So this relation exists between the CRC table crc_tab[] of crc32_by_tab()
and the table crc32_table[] of the abbreviated algorithm crc_32():
crc_tab[i] == rfl32(crc32_table[rfl8(i)])
for i={0..255}.
I compared the generated table in crc32_by_tab() by this test
for (i = 0; i < 256; i++) {
if (rfl32(crc_tab[rfl8(i)]) != crc32_table[i] ||
crc_tab[i] != rfl32(crc32_table[rfl8(i)])) {
printf("DEVIATION : i = %d\n", i);
exit(1);
}
}
No screaming abort happened.
-----------------------------------------------------------------------
*/
/* This is my own mirrored table implementation for which i claim copyright.
With gcc -O2 it shows the same efficiency as the inherited implementation
below. With -O3, -O1, or -O0 it is only slightly slower.
Copyright (c) 2012 Thomas Schmitt <scdbackup@gmx.net>
*/
unsigned int crc_32(unsigned char *data, int count)
{
static unsigned int crc_tab[256], tab_initialized = 0;
unsigned int acc = 0;
unsigned char b[1];
int i;
if (!tab_initialized) {
/* Create table of mirrored 0x18001801b residues in
bit-mirrored index positions.
*/
for (i = 0; i < 256; i++) {
b[0] = i;
crc_tab[rfl8(i)] = rfl32(crc_18001801b(b, 1, 1));
}
tab_initialized = 1;
}
for (i = 0; i < count; i++)
acc = (acc >> 8) ^ crc_tab[(acc & 0xff) ^ data[i]];
/* The bits of the whole 32 bit result stay mirrored for ECMA-130
output 8-bit mirroring and for sector.c habit to store the CRC
little endian although ECMA-130 prescribes it big endian.
*/
return acc;
}
/*
-----------------------------------------------------------------------
This was the function inherited with libburn-0.2 which implements the
abbreviated algorithm. Its obscure existence led me to above insights.
My compliments to the (unknown) people who invented this.
unsigned long crc32_table[256] = {
0x00000000L, 0x90910101L, 0x91210201L, 0x01B00300L,
0x92410401L, 0x02D00500L, 0x03600600L, 0x93F10701L,
0x94810801L, 0x04100900L, 0x05A00A00L, 0x95310B01L,
0x06C00C00L, 0x96510D01L, 0x97E10E01L, 0x07700F00L,
0x99011001L, 0x09901100L, 0x08201200L, 0x98B11301L,
0x0B401400L, 0x9BD11501L, 0x9A611601L, 0x0AF01700L,
0x0D801800L, 0x9D111901L, 0x9CA11A01L, 0x0C301B00L,
0x9FC11C01L, 0x0F501D00L, 0x0EE01E00L, 0x9E711F01L,
0x82012001L, 0x12902100L, 0x13202200L, 0x83B12301L,
0x10402400L, 0x80D12501L, 0x81612601L, 0x11F02700L,
0x16802800L, 0x86112901L, 0x87A12A01L, 0x17302B00L,
0x84C12C01L, 0x14502D00L, 0x15E02E00L, 0x85712F01L,
0x1B003000L, 0x8B913101L, 0x8A213201L, 0x1AB03300L,
0x89413401L, 0x19D03500L, 0x18603600L, 0x88F13701L,
0x8F813801L, 0x1F103900L, 0x1EA03A00L, 0x8E313B01L,
0x1DC03C00L, 0x8D513D01L, 0x8CE13E01L, 0x1C703F00L,
0xB4014001L, 0x24904100L, 0x25204200L, 0xB5B14301L,
0x26404400L, 0xB6D14501L, 0xB7614601L, 0x27F04700L,
0x20804800L, 0xB0114901L, 0xB1A14A01L, 0x21304B00L,
0xB2C14C01L, 0x22504D00L, 0x23E04E00L, 0xB3714F01L,
0x2D005000L, 0xBD915101L, 0xBC215201L, 0x2CB05300L,
0xBF415401L, 0x2FD05500L, 0x2E605600L, 0xBEF15701L,
0xB9815801L, 0x29105900L, 0x28A05A00L, 0xB8315B01L,
0x2BC05C00L, 0xBB515D01L, 0xBAE15E01L, 0x2A705F00L,
0x36006000L, 0xA6916101L, 0xA7216201L, 0x37B06300L,
0xA4416401L, 0x34D06500L, 0x35606600L, 0xA5F16701L,
0xA2816801L, 0x32106900L, 0x33A06A00L, 0xA3316B01L,
0x30C06C00L, 0xA0516D01L, 0xA1E16E01L, 0x31706F00L,
0xAF017001L, 0x3F907100L, 0x3E207200L, 0xAEB17301L,
0x3D407400L, 0xADD17501L, 0xAC617601L, 0x3CF07700L,
0x3B807800L, 0xAB117901L, 0xAAA17A01L, 0x3A307B00L,
0xA9C17C01L, 0x39507D00L, 0x38E07E00L, 0xA8717F01L,
0xD8018001L, 0x48908100L, 0x49208200L, 0xD9B18301L,
0x4A408400L, 0xDAD18501L, 0xDB618601L, 0x4BF08700L,
0x4C808800L, 0xDC118901L, 0xDDA18A01L, 0x4D308B00L,
0xDEC18C01L, 0x4E508D00L, 0x4FE08E00L, 0xDF718F01L,
0x41009000L, 0xD1919101L, 0xD0219201L, 0x40B09300L,
0xD3419401L, 0x43D09500L, 0x42609600L, 0xD2F19701L,
0xD5819801L, 0x45109900L, 0x44A09A00L, 0xD4319B01L,
0x47C09C00L, 0xD7519D01L, 0xD6E19E01L, 0x46709F00L,
0x5A00A000L, 0xCA91A101L, 0xCB21A201L, 0x5BB0A300L,
0xC841A401L, 0x58D0A500L, 0x5960A600L, 0xC9F1A701L,
0xCE81A801L, 0x5E10A900L, 0x5FA0AA00L, 0xCF31AB01L,
0x5CC0AC00L, 0xCC51AD01L, 0xCDE1AE01L, 0x5D70AF00L,
0xC301B001L, 0x5390B100L, 0x5220B200L, 0xC2B1B301L,
0x5140B400L, 0xC1D1B501L, 0xC061B601L, 0x50F0B700L,
0x5780B800L, 0xC711B901L, 0xC6A1BA01L, 0x5630BB00L,
0xC5C1BC01L, 0x5550BD00L, 0x54E0BE00L, 0xC471BF01L,
0x6C00C000L, 0xFC91C101L, 0xFD21C201L, 0x6DB0C300L,
0xFE41C401L, 0x6ED0C500L, 0x6F60C600L, 0xFFF1C701L,
0xF881C801L, 0x6810C900L, 0x69A0CA00L, 0xF931CB01L,
0x6AC0CC00L, 0xFA51CD01L, 0xFBE1CE01L, 0x6B70CF00L,
0xF501D001L, 0x6590D100L, 0x6420D200L, 0xF4B1D301L,
0x6740D400L, 0xF7D1D501L, 0xF661D601L, 0x66F0D700L,
0x6180D800L, 0xF111D901L, 0xF0A1DA01L, 0x6030DB00L,
0xF3C1DC01L, 0x6350DD00L, 0x62E0DE00L, 0xF271DF01L,
0xEE01E001L, 0x7E90E100L, 0x7F20E200L, 0xEFB1E301L,
0x7C40E400L, 0xECD1E501L, 0xED61E601L, 0x7DF0E700L,
0x7A80E800L, 0xEA11E901L, 0xEBA1EA01L, 0x7B30EB00L,
0xE8C1EC01L, 0x7850ED00L, 0x79E0EE00L, 0xE971EF01L,
0x7700F000L, 0xE791F101L, 0xE621F201L, 0x76B0F300L,
0xE541F401L, 0x75D0F500L, 0x7460F600L, 0xE4F1F701L,
0xE381F801L, 0x7310F900L, 0x72A0FA00L, 0xE231FB01L,
0x71C0FC00L, 0xE151FD01L, 0xE0E1FE01L, 0x7070FF00L
};
unsigned int crc_32(unsigned char *data, int len)
{
unsigned int crc = 0;
while (len-- > 0)
crc = crc32_table[(crc ^ *data++) & 0xffL] ^ (crc >> 8);
return crc;
}
*/

33
libburn/crc.h Normal file
View File

@ -0,0 +1,33 @@
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
Copyright (c) 2012 Thomas Schmitt <scdbackup@gmx.net>
Provided under GPL version 2 or later.
*/
#ifndef BURN__CRC_H
#define BURN__CRC_H
#ifdef Xorriso_standalonE
/* Source module crc.c of yet unclear ancestry is excluded from GNU xorriso */
/* ts B20219 : The functions have been re-implemented from scratch after
studying texts about CRC computation and understanding the
meaning of the underlying ECMA-130 specs.
Nevertheless, there is no need to include them into xorriso
because it does neither CD-TEXT nor raw CD writing.
*/
#ifndef Libburn_no_crc_C
#define Libburn_no_crc_C 1
#endif
#endif
#ifndef Libburn_no_crc_C
unsigned short crc_ccitt(unsigned char *, int len);
unsigned int crc_32(unsigned char *, int len);
#endif /* Libburn_no_crc_C */
#endif /* BURN__CRC_H */

621
libburn/ddlpa.c Normal file
View File

@ -0,0 +1,621 @@
/* ddlpa
Implementation of Delicate Device Locking Protocol level A.
Copyright (C) 2007 Thomas Schmitt <scdbackup@gmx.net>
Provided under any of the following licenses: GPL, LGPL, BSD. Choose one.
Compile as test program:
cc -g -Wall \
-D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE=1 -D_LARGEFILE64_SOURCE \
-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
our devices can offer more than 2 GB of addressable data.
Run test program:
./ddlpa /dev/sr0 15
./ddlpa 0,0,0 15
*/
#ifdef HAVE_CONFIG_H
#include "../config.h"
#endif
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <scsi/scsi.h>
/* All callers of ddlpa must do this */
#include "ddlpa.h"
/* 1 = Enable progress message on stderr, 0 = normal silent operation */
static int ddlpa_debug_mode = 1;
/* #define _GNU_SOURCE or _LARGEFILE64_SOURCE to get real O_LARGEFILE */
#ifndef O_LARGEFILE
#define O_LARGEFILE 0
#endif
#ifndef O_BINARY
#define O_BINARY 0
#endif
/* ----------------------- private -------------------- */
static int ddlpa_new(struct ddlpa_lock **lck, int o_flags, int ddlpa_flags)
{
int i;
struct ddlpa_lock *o;
o = *lck = (struct ddlpa_lock *) malloc(sizeof(struct ddlpa_lock));
if (o == NULL)
return ENOMEM;
for (i = 0; i < sizeof(struct ddlpa_lock); i++)
((char *) o)[i] = 0;
o->path = NULL;
o->fd = -1;
for (i = 0; i < DDLPA_MAX_SIBLINGS; i++)
o->sibling_fds[i] = -1;
o->errmsg = NULL;
o->o_flags = o_flags;
o->ddlpa_flags = ddlpa_flags;
return 0;
}
static int ddlpa_enumerate(struct ddlpa_lock *o, int *idx,
char path[DDLPA_MAX_STD_LEN + 1])
{
if (*idx < 0)
*idx = 0;
if (*idx < 26)
sprintf(path, "/dev/hd%c", 'a' + *idx);
else if (*idx < 256 + 26)
sprintf(path, "/dev/sr%d", *idx - 26);
else if (*idx < 2 * 256 + 26)
sprintf(path, "/dev/scd%d", *idx - 256 - 26);
else if (*idx < 3 * 256 + 26)
sprintf(path, "/dev/sg%d", *idx - 2 * 256 - 26);
else
return 1;
(*idx)++;
return 0;
}
static int ddlpa_std_by_rdev(struct ddlpa_lock *o)
{
int idx = 0;
char try_path[DDLPA_MAX_STD_LEN+1];
struct stat path_stbuf, try_stbuf;
if (!o->path_is_valid)
return EFAULT;
if (stat(o->path, &path_stbuf) == -1)
return errno;
while (ddlpa_enumerate(o, &idx, try_path) == 0) {
if (stat(try_path, &try_stbuf) == -1)
continue;
if (path_stbuf.st_rdev != try_stbuf.st_rdev)
continue;
strcpy(o->std_path, try_path);
if (ddlpa_debug_mode)
fprintf(stderr,
"DDLPA_DEBUG: ddlpa_std_by_rdev(\"%s\") = \"%s\"\n",
o->path, o->std_path);
return 0;
}
return ENOENT;
}
/* Caution : these tests are valid only with standard paths */
static int ddlpa_is_scsi(struct ddlpa_lock *o, char *path)
{
return (strncmp(path, "/dev/s", 6) == 0);
}
static int ddlpa_is_sg(struct ddlpa_lock *o, char *path)
{
return (strncmp(path, "/dev/sg", 7) == 0);
}
static int ddlpa_is_sr(struct ddlpa_lock *o, char *path)
{
return (strncmp(path, "/dev/sr", 7) == 0);
}
static int ddlpa_is_scd(struct ddlpa_lock *o, char *path)
{
return (strncmp(path, "/dev/scd", 8) == 0);
}
static int ddlpa_fcntl_lock(struct ddlpa_lock *o, int fd, int l_type)
{
struct flock lockthing;
int ret;
memset(&lockthing, 0, sizeof(lockthing));
lockthing.l_type = l_type;
lockthing.l_whence = SEEK_SET;
lockthing.l_start = 0;
lockthing.l_len = 0;
ret = fcntl(fd, F_SETLK, &lockthing);
if (ret == -1)
return EBUSY;
return 0;
}
static int ddlpa_occupy(struct ddlpa_lock *o, char *path, int *fd,
int no_o_excl)
{
int ret, o_flags, o_rw, l_type;
char *o_rwtext;
o_flags = o->o_flags | O_NDELAY | O_BINARY;
if(!no_o_excl)
o_flags |= O_EXCL;
o_rw = (o_flags) & (O_RDONLY | O_WRONLY | O_RDWR);
o_rwtext = (o_rw == O_RDONLY ? "O_RDONLY" :
(o_rw == O_WRONLY ? "O_WRONLY" :
(o_rw == O_RDWR ? "O_RDWR " : "O_?rw-mode?")));
*fd = open(path, o_flags);
if (*fd == -1) {
o->errmsg = malloc(strlen(path)+160);
if (o->errmsg)
sprintf(o->errmsg,
"Failed to open %s | O_NDELAY %s: '%s'",
o_rwtext,
(o_flags & O_EXCL ? "| O_EXCL " : ""), path);
return (errno ? errno : EBUSY);
}
if (o_rw == O_RDWR || o_rw == O_WRONLY)
l_type = F_WRLCK;
else
l_type = F_RDLCK;
ret = ddlpa_fcntl_lock(o, *fd, l_type);
if (ret) {
o->errmsg = malloc(strlen(path)+160);
if (o->errmsg)
sprintf(o->errmsg,
"Failed to lock fcntl(F_WRLCK) : '%s'",path);
close(*fd);
*fd = -1;
return ret;
}
if (ddlpa_debug_mode)
fprintf(stderr, "DDLPA_DEBUG: ddlpa_occupy() %s %s: '%s'\n",
o_rwtext,
(no_o_excl ? " " : "O_EXCL "), path);
return 0;
}
static int ddlpa_obtain_scsi_adr(struct ddlpa_lock *o, char *path,
int *bus, int *host, int *channel, int *id, int *lun)
{
int fd, ret, open_mode = O_RDONLY | O_NDELAY | O_BINARY;
struct my_scsi_idlun {
int x;
int host_unique_id;
};
struct my_scsi_idlun idlun;
fd = open(path, open_mode);
if (fd == -1)
return (errno ? errno : EBUSY);
if (ioctl(fd, SCSI_IOCTL_GET_BUS_NUMBER, bus) == -1)
*bus = -1;
ret = ioctl(fd, SCSI_IOCTL_GET_IDLUN, &idlun);
close(fd);
if (ret == -1)
return (errno ? errno : EIO);
*host = (idlun.x >> 24) & 255;
*channel = (idlun.x >> 16) & 255;
*id = (idlun.x) & 255;
*lun = (idlun.x >> 8 ) & 255;
return 0;
}
static int ddlpa_collect_siblings(struct ddlpa_lock *o)
{
int idx = 0, ret, have_sg = 0, have_sr = 0, have_scd = 0;
dev_t path_dev;
ino_t path_inode;
struct stat stbuf;
char *path, try_path[DDLPA_MAX_STD_LEN+1];
int t_bus, t_host, t_channel, t_id, t_lun;
if (o->ddlpa_flags & DDLPA_OPEN_GIVEN_PATH)
path = o->path;
else
path = o->std_path;
if (path[0] == 0 || o->num_siblings != 0)
return EFAULT;
if (!ddlpa_is_scsi(o, o->std_path))
return EFAULT;
if (stat(path, &stbuf) == -1)
return errno;
path_inode = stbuf.st_ino;
path_dev = stbuf.st_dev;
o->rdev = stbuf.st_rdev;
o->dev = stbuf.st_dev;
o->ino = stbuf.st_ino;
ret = ddlpa_obtain_scsi_adr(o, path,
&(o->bus), &(o->host), &(o->channel),
&(o->id), &(o->lun));
if (ret) {
o->errmsg = strdup(
"Cannot obtain SCSI parameters host,channel,id,lun");
return ret;
}
o->hcilb_is_valid = 1;
while (ddlpa_enumerate(o, &idx, try_path) == 0) {
if (!ddlpa_is_scsi(o, try_path))
continue;
if (stat(try_path, &stbuf) == -1)
continue;
ret = ddlpa_obtain_scsi_adr(o, try_path,
&t_bus, &t_host, &t_channel, &t_id, &t_lun);
if (ret) {
/* >>> interpret error, memorize busy, no permission */
continue;
}
if (t_host != o->host || t_channel != o->channel ||
t_id != o->id || t_lun != o->lun)
continue;
if (o->num_siblings >= DDLPA_MAX_SIBLINGS) {
o->errmsg =
strdup("Too many matching device files found");
return ERANGE;
}
if (ddlpa_is_sg(o, try_path))
have_sg = 1;
else if (ddlpa_is_sr(o, try_path))
have_sr = 1;
else if (ddlpa_is_scd(o, try_path))
have_scd = 1;
strcpy(o->sibling_paths[o->num_siblings], try_path);
o->sibling_rdevs[o->num_siblings] = stbuf.st_rdev;
o->sibling_devs[o->num_siblings] = stbuf.st_dev;
o->sibling_inodes[o->num_siblings] = stbuf.st_ino;
if (ddlpa_debug_mode)
fprintf(stderr,
"DDLPA_DEBUG: ddlpa_collect_siblings() found \"%s\"\n",
try_path);
(o->num_siblings)++;
}
if (have_sg && have_sr && have_scd)
return 0;
if (o->ddlpa_flags & DDLPA_ALLOW_MISSING_SGRCD)
return 0;
o->errmsg = strdup("Did not find enough siblings");
/* >>> add more info about busy and forbidden paths */
return EBUSY;
}
static int ddlpa_std_by_btl(struct ddlpa_lock *o)
{
int idx = 0, ret;
char try_path[DDLPA_MAX_STD_LEN+1];
int t_bus, t_host, t_channel, t_id, t_lun;
if (!o->inbtl_is_valid)
return EFAULT;
while (ddlpa_enumerate(o, &idx, try_path) == 0) {
if (!ddlpa_is_sr(o, try_path))
continue;
ret = ddlpa_obtain_scsi_adr(o, try_path,
&t_bus, &t_host, &t_channel, &t_id, &t_lun);
if (ret) {
/* >>> interpret error, memorize busy, no permission */
continue;
}
if (t_bus != o->in_bus || t_id != o->in_target ||
t_lun != o->in_lun)
continue;
strcpy(o->std_path, try_path);
if (ddlpa_debug_mode)
fprintf(stderr,
"DDLPA_DEBUG: ddlpa_std_by_btl(%d,%d,%d) = \"%s\"\n",
t_bus, t_id, t_lun, o->std_path);
return 0;
}
/* >>> add more info about busy and forbidden paths */
return ENOENT;
}
static int ddlpa_open_all(struct ddlpa_lock *o)
{
int i, j, ret, no_o_excl;
if (ddlpa_is_scsi(o, o->std_path)) {
ret = ddlpa_collect_siblings(o);
if (ret)
return ret;
for (i = 0; i < o->num_siblings; i++) {
/* Watch out for the main personality of the drive. */
/* No need to occupy identical path or softlink path */
if (o->sibling_devs[i] == o->dev &&
o->sibling_inodes[i] == o->ino)
continue;
/* There may be the same rdev but different inode. */
no_o_excl = (o->sibling_rdevs[i] == o->rdev);
/* Look for multiply registered device drivers with
distinct inodes. */
for (j = 0; j < i; j++) {
if (o->sibling_devs[j] == o->sibling_devs[i] &&
o->sibling_inodes[j] == o->sibling_inodes[i])
break;
if (o->sibling_rdevs[j] == o->sibling_rdevs[i])
no_o_excl = 1;
}
if (j < i)
continue; /* inode is already occupied */
ret = ddlpa_occupy(o, o->sibling_paths[i],
&(o->sibling_fds[i]), no_o_excl);
if (ret)
return ret;
}
}
if (o->ddlpa_flags & DDLPA_OPEN_GIVEN_PATH)
ret = ddlpa_occupy(o, o->path, &(o->fd), 0);
else
ret = ddlpa_occupy(o, o->std_path, &(o->fd), 0);
if (ret)
return ret;
/* >>> use fcntl() to adjust O_NONBLOCK */;
return 0;
}
/* ----------------------- public -------------------- */
int ddlpa_destroy(struct ddlpa_lock **lockbundle)
{
struct ddlpa_lock *o;
int i;
o= *lockbundle;
if (o == NULL)
return 0;
for (i = 0; i < o->num_siblings; i++)
if (o->sibling_fds[i] != -1)
close(o->sibling_fds[i]);
if(o->fd != -1)
close(o->fd);
if (o->path != NULL)
free(o->path);
if (o->errmsg != NULL)
free(o->errmsg);
free((char *) o);
*lockbundle = NULL;
return 0;
}
int ddlpa_lock_path(char *path, int o_flags, int ddlpa_flags,
struct ddlpa_lock **lockbundle, char **errmsg)
{
struct ddlpa_lock *o;
int ret;
*errmsg = NULL;
if (ddlpa_new(&o, o_flags, ddlpa_flags))
return ENOMEM;
*lockbundle = o;
o->path = strdup(path);
if (o->path == NULL)
return ENOMEM;
o->path_is_valid = 1;
ret = ddlpa_std_by_rdev(o);
if (ret) {
*errmsg = strdup(
"Cannot find equivalent of given path among standard paths");
return ret;
}
ret = ddlpa_open_all(o);
if (ret) {
*errmsg = o->errmsg;
o->errmsg = NULL;
ddlpa_destroy(&o);
}
return ret;
}
int ddlpa_lock_btl(int bus, int target, int lun,
int o_flags, int ddlpa_flags,
struct ddlpa_lock **lockbundle, char **errmsg)
{
struct ddlpa_lock *o;
int ret;
*errmsg = NULL;
ddlpa_flags &= ~DDLPA_OPEN_GIVEN_PATH;
if (ddlpa_new(&o, o_flags, ddlpa_flags))
return ENOMEM;
*lockbundle = o;
o->in_bus = bus;
o->in_target = target;
o->in_lun = lun;
o->inbtl_is_valid = 1;
ret = ddlpa_std_by_btl(o);
if (ret) {
*errmsg = strdup(
"Cannot find /dev/sr* with given Bus,Target,Lun");
return ret;
}
ret = ddlpa_open_all(o);
if (ret) {
*errmsg = o->errmsg;
o->errmsg = NULL;
ddlpa_destroy(&o);
return ret;
}
return 0;
}
#ifdef DDLPA_C_STANDALONE
/* ----------------------------- Test / Demo -------------------------- */
int main(int argc, char **argv)
{
struct ddlpa_lock *lck = NULL;
char *errmsg = NULL, *opened_path = NULL, *my_path = NULL;
int i, ret, fd = -1, duration = -1, bus = -1, target = -1, lun = -1;
if (argc < 3) {
usage:;
fprintf(stderr, "usage: %s device_path duration\n", argv[0]);
exit(1);
}
my_path = argv[1];
sscanf(argv[2], "%d", &duration);
if (duration < 0)
goto usage;
/* For our purpose, only O_RDWR is a suitable access mode.
But in order to allow experiments, o_flags are freely adjustable.
Warning: Do _not_ set an own O_EXCL flag with the following calls !
(This freedom to fail may get removed in a final version.)
*/
if (my_path[0] != '/' && my_path[0] != '.' &&
strchr(my_path, ',') != NULL) {
/*
cdrecord style dev=Bus,Target,Lun
*/
sscanf(my_path, "%d,%d,%d", &bus, &target, &lun);
ret = ddlpa_lock_btl(bus, target, lun, O_RDWR | O_LARGEFILE,
0, &lck, &errmsg);
} else {
/*
This substitutes for:
fd = open(my_path,
O_RDWR | O_EXCL | O_LARGEFILE | O_BINARY);
*/
ret = ddlpa_lock_path(my_path, O_RDWR | O_LARGEFILE,
0, &lck, &errmsg);
}
if (ret) {
fprintf(stderr, "Cannot exclusively open '%s'\n", my_path);
if (errmsg != NULL)
fprintf(stderr, "Reason given : %s\n",
errmsg);
free(errmsg);
fprintf(stderr, "Error condition : %d '%s'\n",
ret, strerror(ret));
exit(2);
}
fd = lck->fd;
printf("---------------------------------------------- Lock gained\n");
/* Use fd for the usual operations on the device depicted by my_path.
*/
/* This prints an overview of the impact of the lock */
if (lck->ddlpa_flags & DDLPA_OPEN_GIVEN_PATH)
opened_path = lck->path;
else
opened_path = lck->std_path;
printf("ddlpa: opened %s", opened_path);
if (strcmp(opened_path, lck->std_path) != 0)
printf(" (an alias of '%s')", lck->std_path);
printf("\n");
if (lck->num_siblings > 0) {
printf("ddlpa: opened siblings:");
for (i = 0; i < lck->num_siblings; i++)
if (lck->sibling_fds[i] != -1)
printf(" %s", lck->sibling_paths[i]);
printf("\n");
}
/* This example waits a while. So other lock candidates can collide. */
for (i = 0; i < duration; i++) {
sleep(1);
fprintf(stderr, "\rslept %d seconds of %d", i + 1, duration);
}
fprintf(stderr, "\n");
/* When finally done with the drive, this substitutes for:
close(fd);
*/
if (ddlpa_destroy(&lck)) {
/* Well, man 2 close says it can fail. */
exit(3);
}
exit(0);
}
#endif /* DDLPA_C_STANDALONE */

107
libburn/ddlpa.h Normal file
View File

@ -0,0 +1,107 @@
/* ddlpa
Implementation of Delicate Device Locking Protocol level A.
Copyright (C) 2007 Thomas Schmitt <scdbackup@gmx.net>
Provided under any of the following licenses: GPL, LGPL, BSD. Choose one.
See ../doc/ddlp.txt for a description of the protocol.
*/
#ifndef DDLPA_H_INCLUDED
#define DDLPA_H_INCLUDED 1
/* An upper limit for the length of standard paths and sibling paths */
#define DDLPA_MAX_STD_LEN 15
/* An upper limit for the number of siblings */
#define DDLPA_MAX_SIBLINGS 5
struct ddlpa_lock {
/* Recorded input parameters of locking call */
char *path;
int path_is_valid;
int in_bus, in_target, in_lun;
int inbtl_is_valid;
int ddlpa_flags;
int o_flags;
/* Result of locking call */
char std_path[DDLPA_MAX_STD_LEN + 1];
int fd;
dev_t rdev;
dev_t dev;
ino_t ino;
int host, channel, id, lun, bus;
int hcilb_is_valid;
int num_siblings;
char sibling_paths[DDLPA_MAX_SIBLINGS][DDLPA_MAX_STD_LEN + 1];
int sibling_fds[DDLPA_MAX_SIBLINGS];
dev_t sibling_rdevs[DDLPA_MAX_SIBLINGS];
dev_t sibling_devs[DDLPA_MAX_SIBLINGS];
ino_t sibling_inodes[DDLPA_MAX_SIBLINGS];
/* Is NULL if all goes well. Else it may contain a text message. */
char *errmsg;
};
/** Lock a recorder by naming a device file path. Allocate a new container.
@param path Gives the file system path of the recorder
as known to the calling program.
@param o_flags flags for open(2). Do not use O_EXCL here because this
is done automatically whenever appropriate.
Advised is O_RDWR | O_LARGEFILE, eventually | O_NDELAY.
@param ddlpa_flags 0 = default behavior: the standard path will be opened
and treated by fcntl(F_SETLK)
DDLPA_OPEN_GIVEN_PATH causes the input parameter "path"
to be used with open(2) and fcntl(2).
DDLPA_ALLOW_MISSING_SGRCD allows to grant a lock
although not all three, a sg, a sr and a scd device
file have been found during sibling search. Normally
this is counted as failure due to EBUSY.
@param lockbundle gets allocated and then represents the locking state
@param errmsg if *errmsg is not NULL after the call, it contains an
error message. Then to be released by free(3).
It is NULL in case of success or lack of memory.
@return 0=success , else an errno compatible error number
*/
int ddlpa_lock_path(char *path, int o_flags, int ddlpa_flags,
struct ddlpa_lock **lockbundle, char **errmsg);
/** Lock a recorder by naming a Bus,Target,Lun number triple.
Allocate a new container.
@param bus parameter to match ioctl(SCSI_IOCTL_GET_BUS_NUMBER)
@param target parameter to match ioctl(SCSI_IOCTL_GET_IDLUN) &0xff
@param lun parameter to match ioctl(SCSI_IOCTL_GET_IDLUN) &0xff00
@param o_flags see ddlpa_lock_path().
@param ddlpa_flags see ddlpa_lock_path(). Flag DDLPA_OPEN_GIVEN_PATH
will be ignored.
@param lockbundle see ddlpa_lock_path().
@param errmsg see ddlpa_lock_path().
@return 0=success , else an errno compatible error number
*/
int ddlpa_lock_btl(int bus, int target, int lun,
int o_flags, int ddlpa_flags,
struct ddlpa_lock **lockbundle, char **errmsg);
/** Release the lock by closing all filedescriptors and freeing memory.
@param lockbundle the lock which is to be released.
*lockbundle will be set to NULL by this call.
@return 0=success , 1=failure
*/
int ddlpa_destroy(struct ddlpa_lock **lockbundle);
/** Definitions of macros used in above functions */
#define DDLPA_OPEN_GIVEN_PATH 1
#define DDLPA_ALLOW_MISSING_SGRCD 2
#endif /* DDLPA_H_INCLUDED */

28
libburn/debug.c Normal file
View File

@ -0,0 +1,28 @@
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
Provided under GPL version 2 or later.
*/
#ifdef HAVE_CONFIG_H
#include "../config.h"
#endif
#ifdef WIN32
#include <windows.h>
#endif
#include <stdarg.h>
#include <stdio.h>
#include "libburn.h"
#include "debug.h"
static int burn_verbosity = 0;
void burn_set_verbosity(int v)
{
burn_verbosity = v;
}

8
libburn/debug.h Normal file
View File

@ -0,0 +1,8 @@
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
#ifndef BURN__DEBUG_H
#define BURN__DEBUG_H
void burn_print(int level, const char *a, ...);
#endif /* BURN__DEBUG_H */

3739
libburn/drive.c Normal file

File diff suppressed because it is too large Load Diff

173
libburn/drive.h Normal file
View File

@ -0,0 +1,173 @@
/* -*- 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>
Provided under GPL version 2 or later.
*/
#ifndef __DRIVE
#define __DRIVE
#include "libburn.h"
#include "toc.h"
#include "structure.h"
#include <pthread.h>
struct burn_drive;
struct command;
struct mempage;
struct scsi_mode_data;
struct burn_speed_descriptor;
struct burn_feature_descr;
#define LEAD_IN 1
#define GAP 2
#define USER_DATA 3
#define LEAD_OUT 4
#define SYNC 5
#define SESSION_LEADOUT_ENTRY(d,s) (d)->toc->session[(s)].leadout_entry
#define CURRENT_SESSION_START(d) \
burn_msf_to_lba(d->toc->session[d->currsession].start_m, \
d->toc->session[d->currsession].start_s, \
d->toc->session[d->currsession].start_f)
#define SESSION_END(d,s) \
TOC_ENTRY_PLBA((d)->toc, SESSION_LEADOUT_ENTRY((d), (s)))
#define PREVIOUS_SESSION_END(d) \
TOC_ENTRY_PLBA((d)->toc, SESSION_LEADOUT_ENTRY((d), (d)->currsession-1))
#define LAST_SESSION_END(d) \
TOC_ENTRY_PLBA((d)->toc, \
SESSION_LEADOUT_ENTRY((d), (d)->toc->sessions-1))
struct burn_drive *burn_drive_register(struct burn_drive *);
int burn_drive_unregister(struct burn_drive *d);
unsigned int burn_drive_count(void);
/* ts A61007 */
/* void burn_wait_all(void); */
/* @param flag bit0= demand freed drives (else released drives) */
int burn_drives_are_clear(int flag);
int burn_sector_length_write(struct burn_drive *d);
int burn_track_control(struct burn_drive *d, int);
void burn_write_empty_sector(int fd);
void burn_write_empty_subcode(int fd);
void burn_drive_free(struct burn_drive *d);
void burn_drive_free_all(void);
/* @param flag bit0= reset global drive list */
int burn_drive_scan_sync(struct burn_drive_info *drives[],
unsigned int *n_drives, int flag);
void burn_disc_erase_sync(struct burn_drive *d, int fast);
int burn_drive_get_block_types(struct burn_drive *d,
enum burn_write_types write_type);
int burn_drive_is_open(struct burn_drive *d);
int burn_drive_is_occupied(struct burn_drive *d);
int burn_drive_forget(struct burn_drive *d, int force);
int burn_drive_convert_fs_adr_sub(char *path, char adr[], int *rec_count);
/* ts A61021 : the unspecific part of sg.c:enumerate_common()
*/
int burn_setup_drive(struct burn_drive *d, char *fname);
/* ts A61021 : after-setup activities from sg.c:enumerate_common()
*/
struct burn_drive *burn_drive_finish_enum(struct burn_drive *d);
/* ts A61125 : media status aspects of burn_drive_grab() */
int burn_drive_inquire_media(struct burn_drive *d);
/* ts A61125 : model aspects of burn_drive_release */
int burn_drive_mark_unready(struct burn_drive *d, int flag);
/* ts A61226 */
int burn_speed_descriptor_new(struct burn_speed_descriptor **s,
struct burn_speed_descriptor *prev,
struct burn_speed_descriptor *next, int flag);
/* ts A61226 */
/* @param flag bit0= destroy whole next-chain of descriptors */
int burn_speed_descriptor_destroy(struct burn_speed_descriptor **s, int flag);
/* ts A61226 : free dynamically allocated sub data of struct scsi_mode_data */
int burn_mdata_free_subs(struct scsi_mode_data *m);
/* ts A61230 */
void burn_disc_format_sync(struct burn_drive *d, off_t size, int flag);
/* ts A70207 : evaluate write mode related peculiarities of a disc */
struct burn_disc_mode_demands {
int multi_session;
int multi_track;
int unknown_track_size; /* 0=known, 1=unknown, 2=unknown+defaulted */
int mixed_mode;
int audio;
int exotic_track;
int block_types;
int will_append; /* because of media state or multi session disc */
};
int burn_disc_get_write_mode_demands(struct burn_disc *disc,
struct burn_write_opts *opts,
struct burn_disc_mode_demands *result, int flag);
/* ts A70924 : convert a special stdio address into fd number.
@return >0 is a valid fd , -1 indicates unsuitable address string.
*/
int burn_drive__fd_from_special_adr(char *adr);
/* ts A70929 : Find the drive which is being worked on by pid , tid */
int burn_drive_find_by_thread_pid(struct burn_drive **d, pid_t pid,
pthread_t tid);
/* ts A51221 - A80731 : Whitelist inquiry functions */
int burn_drive_is_banned(char *device_address);
int burn_drive_whitelist_count(void);
char *burn_drive_whitelist_item(int idx, int flag);
/* ts A80801 */
int burn_drive_is_listed(char *path, struct burn_drive **found, int flag);
/* ts B00226 : Outsourced backend of burn_abort()
@param elapsed to be subtracted from start time
@param flag bit0= do not shutdown the library
*/
int burn_abort_5(int patience,
int (*pacifier_func)(void *handle, int patience, int elapsed),
void *handle, int elapsed, int flag);
/* ts B10730 */
/* Send a default mode page 05 to CD and DVD-R-oids */
int burn_drive_send_default_page_05(struct burn_drive *d, int flag);
/* ts B40106 */
int burn_feature_descr_new(struct burn_feature_descr **new,
unsigned char *descr, int descr_len, int flag);
/* ts B40106 */
int burn_feature_descr_free(struct burn_feature_descr **new, int flag);
/* ts B40107 */
int burn_drive_has_feature(struct burn_drive *d, int feature_code,
struct burn_feature_descr **descr, int flag);
int burn_drive_grab_stdio(struct burn_drive *d, int flag);
#endif /* __DRIVE */

855
libburn/ecma130ab.c Normal file
View File

@ -0,0 +1,855 @@
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
#ifdef HAVE_CONFIG_H
#include "../config.h"
#endif
/* ts A91016 : libburn/ecma130ab.c is the replacement for old libburn/lec.c
Copyright 2009, Thomas Schmitt <scdbackup@gmx.net>, libburnia-project.org
Provided under GPL version 2 or later.
This code module implements the production of RSPC parity bytes (P- and Q-
parity) and the scrambling of raw CD-ROM sectors as specified in ECMA-130:
http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-130.pdf
The following statements about Galois Fields have been learned mostly from
http://www.cs.utk.edu/~plank/plank/papers/CS-96-332.pdf
by James S. Plank after an e-mail exchange with Norbert Preining.
The output has been compared with the output of the old code of libburn
which was labeled "borrowed HEAVILY from cdrdao" and claimed by Joerg
Schilling to stem from code by Heiko Eissfeldt.
-------------------------------------------------------------------------
Note: In this text, "^" denotes exponentiation and not the binary exor
operation. Confusingly in the C code "^" is said exor.
Note: This is not C1, C2 which is rather mentioned in ECMA-130 Annex C and
always performed inside the drive.
-------------------------------------------------------------------------
RSPC , P- and Q-Parity
ECMA-130 Annex A prescribes to compute the parity bytes for P-columns and
Q-diagonals by RSPC based on a Galois Field GF(2^8) with enumerating
polynomials x^8+x^4+x^3+x^2+1 (i.e. 0x11d) and x^1 (i.e. 0x02).
Bytes 12 to 2075 of a audio-sized sector get ordered in two byte words
as 24 rows and 43 columns. Then this matrix is split into a LSB matrix
and a MSB matrix of the same layout. Parity bytes are to be computed
from these 8-bit values.
2 P-bytes cover each column of 24 bytes. They get appended to the matrix
as rows 24 and 25.
2 Q-bytes cover each the 26 diagonals of the extended matrix.
Both parity byte pairs have to be computed so that extended rows or
diagonals match this linear equation:
H x V = (0,0)
H is a 2-row matrix of size n matching the length of the V ectors
[ 1 1 ... 1 1 ]
[ x^(n-1) x^(n-2) x^1 1 ]
Vp represents a P-row. It is a byte vector consisting of row bytes at
position 0 to 23 and the two parity bytes which shall be determined
at position 24 and 25. So Hp has 26 columns.
Vq represents a Q-diagonal. It is a byte vector consisting of diagonal
bytes at position 0 to 42 and the two parity bytes at position 43 and 44.
So Hq has 45 columns. The Q-diagonals cover P-parity bytes.
By applying some high school algebra one gets the parity bytes b0, b1 of
vector V = (n_payload_bytes, b0 , b1) as
b0 = ( H[n] * SUM(n_payload_bytes) - H[0..(n-1)] x n_payload_bytes )
/ (H[n+1] - H[n])
b1 = - SUM(n_payload_bytes) - b0
H[i] is the i-the element of the second row of matrix H. E.g. H[0] = x^(n-1)
The result has to be computed by Galois field arithmetics. See below.
The P-parity bytes of each column get reunited as LSB and MSB of two words.
word1 gets written to positions 1032 to 1074, word0 to 1075 to 1117.
The Q-parity bytes of each diagonal get reunited too. word1 goes to 1118
to 1143, word0 to 1144 to 1169.
>>> I do not read this swap of word1 and word0 from ECMA-130 Annex A.
>>> But the new output matches the old output only if it is done that way.
>>> See correctness reservation below.
Algebra on Galois fields is the same as on Rational Numbers.
But arithmetics is defined by operations on polynomials rather than the
usual integer arithmetics on binary numbers.
Addition and subtraction are identical with the binary exor operator.
Multiplication and division would demand polynomial division, e.g. by the
euclidian algorithm. The computing path over logarithms and powers follows
algebra and 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
(not by exor) and their polynomial power depends on their value modulo 255.
Needed are a logarithm table and a power table (or inverse logarithm table)
for Galois Field GF(2^8) which will serve to perform the peculiar
multiplication and division operation of Galois fields.
The power table is simply an enumeration of x^n accorting to
GF-multiplication. It also serves as second line of matrix H for the parity
equations:
Hp[i] = gfpow[25-i] , i out of {0,..,25}
Hq[i] = gfpow[44-i] , i out of {0,..,44}
The logarithm table is the inverse permutation of the power table.
Some simplifications apply to the implementation:
In the world of Galois fields there is no difference between - and +.
The term (H[n+1] - H[n]) is constant: 3.
-------------------------------------------------------------------------
Scrambling
ECMA-130 Annex B prescribes to exor the byte stream of an audio-sized sector
with a sequence of pseudo random bytes. It mentions polynomial x^15+x+1 and
a 15-bit register.
It shows a diagram of a Feedback Shift Register with 16 bit boxes, though.
Comparing this with explanations in
http://www.newwaveinstruments.com/resources/articles/m_sequence_linear_feedback_shift_register_lfsr.htm
one can recognize the diagram as a Fibonacci Implementation. But there seems
really to be one bit box too many.
The difference of both lengths is expressed in function next_bit() by
the constants 0x3fff,0x4000 for 15 bit versus 0x7fff,0x8000 for 16 bits.
Comparing the output of both alternatives with the old scrambler output
lets 15 bit win for now.
So the prescription is to start with 15 bit value 1, to use the lowest bit
as output, to shift the bits down by one, to exor the output bit with the
next lowest bit, and to put that exor result into bit 14 of the register.
-------------------------------------------------------------------------
Correctness Reservation
In both cases, parity and scrambling, the goal for now is to replicate the
output of the dismissed old lec.c by output which is based on published
specs and own implementation code. Whether they comply to ECMA-130 is a
different question which can only be answered by real test cases for
raw CD recording.
Of course this implementation will be corrected so that it really complies
to ECMA-130 as soon as evidence emerges that it does not yet.
*/
/* ------------------------------------------------------------------------- */
/* Power and logarithm tables for GF(2^8), parity matrices for ECMA-130.
Generated by burn_rspc_setup_tables() and burn_rspc_print_tables().
The highest possible sum of gflog[] values is is 508. So the table gfpow[]
with period 255 was manually unrolled to 509 elements to avoid one modulo
255 operation in burn_rspc_mult().
Proposed by D. Hugh Redelmeier.
*/
static unsigned char gfpow[509] = {
1, 2, 4, 8, 16, 32, 64, 128, 29, 58,
116, 232, 205, 135, 19, 38, 76, 152, 45, 90,
180, 117, 234, 201, 143, 3, 6, 12, 24, 48,
96, 192, 157, 39, 78, 156, 37, 74, 148, 53,
106, 212, 181, 119, 238, 193, 159, 35, 70, 140,
5, 10, 20, 40, 80, 160, 93, 186, 105, 210,
185, 111, 222, 161, 95, 190, 97, 194, 153, 47,
94, 188, 101, 202, 137, 15, 30, 60, 120, 240,
253, 231, 211, 187, 107, 214, 177, 127, 254, 225,
223, 163, 91, 182, 113, 226, 217, 175, 67, 134,
17, 34, 68, 136, 13, 26, 52, 104, 208, 189,
103, 206, 129, 31, 62, 124, 248, 237, 199, 147,
59, 118, 236, 197, 151, 51, 102, 204, 133, 23,
46, 92, 184, 109, 218, 169, 79, 158, 33, 66,
132, 21, 42, 84, 168, 77, 154, 41, 82, 164,
85, 170, 73, 146, 57, 114, 228, 213, 183, 115,
230, 209, 191, 99, 198, 145, 63, 126, 252, 229,
215, 179, 123, 246, 241, 255, 227, 219, 171, 75,
150, 49, 98, 196, 149, 55, 110, 220, 165, 87,
174, 65, 130, 25, 50, 100, 200, 141, 7, 14,
28, 56, 112, 224, 221, 167, 83, 166, 81, 162,
89, 178, 121, 242, 249, 239, 195, 155, 43, 86,
172, 69, 138, 9, 18, 36, 72, 144, 61, 122,
244, 245, 247, 243, 251, 235, 203, 139, 11, 22,
44, 88, 176, 125, 250, 233, 207, 131, 27, 54,
108, 216, 173, 71, 142,
1, 2, 4, 8, 16, 32, 64, 128, 29, 58,
116, 232, 205, 135, 19, 38, 76, 152, 45, 90,
180, 117, 234, 201, 143, 3, 6, 12, 24, 48,
96, 192, 157, 39, 78, 156, 37, 74, 148, 53,
106, 212, 181, 119, 238, 193, 159, 35, 70, 140,
5, 10, 20, 40, 80, 160, 93, 186, 105, 210,
185, 111, 222, 161, 95, 190, 97, 194, 153, 47,
94, 188, 101, 202, 137, 15, 30, 60, 120, 240,
253, 231, 211, 187, 107, 214, 177, 127, 254, 225,
223, 163, 91, 182, 113, 226, 217, 175, 67, 134,
17, 34, 68, 136, 13, 26, 52, 104, 208, 189,
103, 206, 129, 31, 62, 124, 248, 237, 199, 147,
59, 118, 236, 197, 151, 51, 102, 204, 133, 23,
46, 92, 184, 109, 218, 169, 79, 158, 33, 66,
132, 21, 42, 84, 168, 77, 154, 41, 82, 164,
85, 170, 73, 146, 57, 114, 228, 213, 183, 115,
230, 209, 191, 99, 198, 145, 63, 126, 252, 229,
215, 179, 123, 246, 241, 255, 227, 219, 171, 75,
150, 49, 98, 196, 149, 55, 110, 220, 165, 87,
174, 65, 130, 25, 50, 100, 200, 141, 7, 14,
28, 56, 112, 224, 221, 167, 83, 166, 81, 162,
89, 178, 121, 242, 249, 239, 195, 155, 43, 86,
172, 69, 138, 9, 18, 36, 72, 144, 61, 122,
244, 245, 247, 243, 251, 235, 203, 139, 11, 22,
44, 88, 176, 125, 250, 233, 207, 131, 27, 54,
108, 216, 173, 71,
};
static unsigned char gflog[256] = {
0, 0, 1, 25, 2, 50, 26, 198, 3, 223,
51, 238, 27, 104, 199, 75, 4, 100, 224, 14,
52, 141, 239, 129, 28, 193, 105, 248, 200, 8,
76, 113, 5, 138, 101, 47, 225, 36, 15, 33,
53, 147, 142, 218, 240, 18, 130, 69, 29, 181,
194, 125, 106, 39, 249, 185, 201, 154, 9, 120,
77, 228, 114, 166, 6, 191, 139, 98, 102, 221,
48, 253, 226, 152, 37, 179, 16, 145, 34, 136,
54, 208, 148, 206, 143, 150, 219, 189, 241, 210,
19, 92, 131, 56, 70, 64, 30, 66, 182, 163,
195, 72, 126, 110, 107, 58, 40, 84, 250, 133,
186, 61, 202, 94, 155, 159, 10, 21, 121, 43,
78, 212, 229, 172, 115, 243, 167, 87, 7, 112,
192, 247, 140, 128, 99, 13, 103, 74, 222, 237,
49, 197, 254, 24, 227, 165, 153, 119, 38, 184,
180, 124, 17, 68, 146, 217, 35, 32, 137, 46,
55, 63, 209, 91, 149, 188, 207, 205, 144, 135,
151, 178, 220, 252, 190, 97, 242, 86, 211, 171,
20, 42, 93, 158, 132, 60, 57, 83, 71, 109,
65, 162, 31, 45, 67, 216, 183, 123, 164, 118,
196, 23, 73, 236, 127, 12, 111, 246, 108, 161,
59, 82, 41, 157, 85, 170, 251, 96, 134, 177,
187, 204, 62, 90, 203, 89, 95, 176, 156, 169,
160, 81, 11, 245, 22, 235, 122, 117, 44, 215,
79, 174, 213, 233, 230, 231, 173, 232, 116, 214,
244, 234, 168, 80, 88, 175
};
#define Libburn_use_h_matriceS 1
#ifdef Libburn_use_h_matriceS
/* On my AMD 2x64 bit 3000 MHz processor h[i] costs about 7 % more time
than using gfpow[25-i] and gfpow[44-1]. I blame this on the more
condensed data representation which slightly increases the rate of cache
hits.
Nevertheless this effect is very likely depending on the exact cache
size and architecture. In general, using h[] saves more than 8000
subtractions per sector.
*/
/* Parity matrices H as prescribed by ECMA-130 Annex A.
Actually just reverted order start pieces of gfpow[].
*/
static unsigned char h26[26] = {
3, 143, 201, 234, 117, 180, 90, 45, 152, 76,
38, 19, 135, 205, 232, 116, 58, 29, 128, 64,
32, 16, 8, 4, 2, 1,
};
static unsigned char h45[45] = {
238, 119, 181, 212, 106, 53, 148, 74, 37, 156,
78, 39, 157, 192, 96, 48, 24, 12, 6, 3,
143, 201, 234, 117, 180, 90, 45, 152, 76, 38,
19, 135, 205, 232, 116, 58, 29, 128, 64, 32,
16, 8, 4, 2, 1,
};
#endif /* Libburn_use_h_matriceS */
/* Pseudo-random bytes which of course are exactly the same as with the
previously used code.
Generated by function print_ecma_130_scrambler().
*/
static unsigned char ecma_130_annex_b[2340] = {
1, 128, 0, 96, 0, 40, 0, 30, 128, 8,
96, 6, 168, 2, 254, 129, 128, 96, 96, 40,
40, 30, 158, 136, 104, 102, 174, 170, 252, 127,
1, 224, 0, 72, 0, 54, 128, 22, 224, 14,
200, 4, 86, 131, 126, 225, 224, 72, 72, 54,
182, 150, 246, 238, 198, 204, 82, 213, 253, 159,
1, 168, 0, 126, 128, 32, 96, 24, 40, 10,
158, 135, 40, 98, 158, 169, 168, 126, 254, 160,
64, 120, 48, 34, 148, 25, 175, 74, 252, 55,
1, 214, 128, 94, 224, 56, 72, 18, 182, 141,
182, 229, 182, 203, 54, 215, 86, 222, 190, 216,
112, 90, 164, 59, 59, 83, 83, 125, 253, 225,
129, 136, 96, 102, 168, 42, 254, 159, 0, 104,
0, 46, 128, 28, 96, 9, 232, 6, 206, 130,
212, 97, 159, 104, 104, 46, 174, 156, 124, 105,
225, 238, 200, 76, 86, 181, 254, 247, 0, 70,
128, 50, 224, 21, 136, 15, 38, 132, 26, 227,
75, 9, 247, 70, 198, 178, 210, 245, 157, 135,
41, 162, 158, 249, 168, 66, 254, 177, 128, 116,
96, 39, 104, 26, 174, 139, 60, 103, 81, 234,
188, 79, 49, 244, 20, 71, 79, 114, 180, 37,
183, 91, 54, 187, 86, 243, 126, 197, 224, 83,
8, 61, 198, 145, 146, 236, 109, 141, 237, 165,
141, 187, 37, 179, 91, 53, 251, 87, 3, 126,
129, 224, 96, 72, 40, 54, 158, 150, 232, 110,
206, 172, 84, 125, 255, 97, 128, 40, 96, 30,
168, 8, 126, 134, 160, 98, 248, 41, 130, 158,
225, 168, 72, 126, 182, 160, 118, 248, 38, 194,
154, 209, 171, 28, 127, 73, 224, 54, 200, 22,
214, 142, 222, 228, 88, 75, 122, 183, 99, 54,
169, 214, 254, 222, 192, 88, 80, 58, 188, 19,
49, 205, 212, 85, 159, 127, 40, 32, 30, 152,
8, 106, 134, 175, 34, 252, 25, 129, 202, 224,
87, 8, 62, 134, 144, 98, 236, 41, 141, 222,
229, 152, 75, 42, 183, 95, 54, 184, 22, 242,
142, 197, 164, 83, 59, 125, 211, 97, 157, 232,
105, 142, 174, 228, 124, 75, 97, 247, 104, 70,
174, 178, 252, 117, 129, 231, 32, 74, 152, 55,
42, 150, 159, 46, 232, 28, 78, 137, 244, 102,
199, 106, 210, 175, 29, 188, 9, 177, 198, 244,
82, 199, 125, 146, 161, 173, 184, 125, 178, 161,
181, 184, 119, 50, 166, 149, 186, 239, 51, 12,
21, 197, 207, 19, 20, 13, 207, 69, 148, 51,
47, 85, 220, 63, 25, 208, 10, 220, 7, 25,
194, 138, 209, 167, 28, 122, 137, 227, 38, 201,
218, 214, 219, 30, 219, 72, 91, 118, 187, 102,
243, 106, 197, 239, 19, 12, 13, 197, 197, 147,
19, 45, 205, 221, 149, 153, 175, 42, 252, 31,
1, 200, 0, 86, 128, 62, 224, 16, 72, 12,
54, 133, 214, 227, 30, 201, 200, 86, 214, 190,
222, 240, 88, 68, 58, 179, 83, 53, 253, 215,
1, 158, 128, 104, 96, 46, 168, 28, 126, 137,
224, 102, 200, 42, 214, 159, 30, 232, 8, 78,
134, 180, 98, 247, 105, 134, 174, 226, 252, 73,
129, 246, 224, 70, 200, 50, 214, 149, 158, 239,
40, 76, 30, 181, 200, 119, 22, 166, 142, 250,
228, 67, 11, 113, 199, 100, 82, 171, 125, 191,
97, 176, 40, 116, 30, 167, 72, 122, 182, 163,
54, 249, 214, 194, 222, 209, 152, 92, 106, 185,
239, 50, 204, 21, 149, 207, 47, 20, 28, 15,
73, 196, 54, 211, 86, 221, 254, 217, 128, 90,
224, 59, 8, 19, 70, 141, 242, 229, 133, 139,
35, 39, 89, 218, 186, 219, 51, 27, 85, 203,
127, 23, 96, 14, 168, 4, 126, 131, 96, 97,
232, 40, 78, 158, 180, 104, 119, 110, 166, 172,
122, 253, 227, 1, 137, 192, 102, 208, 42, 220,
31, 25, 200, 10, 214, 135, 30, 226, 136, 73,
166, 182, 250, 246, 195, 6, 209, 194, 220, 81,
153, 252, 106, 193, 239, 16, 76, 12, 53, 197,
215, 19, 30, 141, 200, 101, 150, 171, 46, 255,
92, 64, 57, 240, 18, 196, 13, 147, 69, 173,
243, 61, 133, 209, 163, 28, 121, 201, 226, 214,
201, 158, 214, 232, 94, 206, 184, 84, 114, 191,
101, 176, 43, 52, 31, 87, 72, 62, 182, 144,
118, 236, 38, 205, 218, 213, 155, 31, 43, 72,
31, 118, 136, 38, 230, 154, 202, 235, 23, 15,
78, 132, 52, 99, 87, 105, 254, 174, 192, 124,
80, 33, 252, 24, 65, 202, 176, 87, 52, 62,
151, 80, 110, 188, 44, 113, 221, 228, 89, 139,
122, 231, 99, 10, 169, 199, 62, 210, 144, 93,
172, 57, 189, 210, 241, 157, 132, 105, 163, 110,
249, 236, 66, 205, 241, 149, 132, 111, 35, 108,
25, 237, 202, 205, 151, 21, 174, 143, 60, 100,
17, 235, 76, 79, 117, 244, 39, 7, 90, 130,
187, 33, 179, 88, 117, 250, 167, 3, 58, 129,
211, 32, 93, 216, 57, 154, 146, 235, 45, 143,
93, 164, 57, 187, 82, 243, 125, 133, 225, 163,
8, 121, 198, 162, 210, 249, 157, 130, 233, 161,
142, 248, 100, 66, 171, 113, 191, 100, 112, 43,
100, 31, 107, 72, 47, 118, 156, 38, 233, 218,
206, 219, 20, 91, 79, 123, 116, 35, 103, 89,
234, 186, 207, 51, 20, 21, 207, 79, 20, 52,
15, 87, 68, 62, 179, 80, 117, 252, 39, 1,
218, 128, 91, 32, 59, 88, 19, 122, 141, 227,
37, 137, 219, 38, 219, 90, 219, 123, 27, 99,
75, 105, 247, 110, 198, 172, 82, 253, 253, 129,
129, 160, 96, 120, 40, 34, 158, 153, 168, 106,
254, 175, 0, 124, 0, 33, 192, 24, 80, 10,
188, 7, 49, 194, 148, 81, 175, 124, 124, 33,
225, 216, 72, 90, 182, 187, 54, 243, 86, 197,
254, 211, 0, 93, 192, 57, 144, 18, 236, 13,
141, 197, 165, 147, 59, 45, 211, 93, 157, 249,
169, 130, 254, 225, 128, 72, 96, 54, 168, 22,
254, 142, 192, 100, 80, 43, 124, 31, 97, 200,
40, 86, 158, 190, 232, 112, 78, 164, 52, 123,
87, 99, 126, 169, 224, 126, 200, 32, 86, 152,
62, 234, 144, 79, 44, 52, 29, 215, 73, 158,
182, 232, 118, 206, 166, 212, 122, 223, 99, 24,
41, 202, 158, 215, 40, 94, 158, 184, 104, 114,
174, 165, 188, 123, 49, 227, 84, 73, 255, 118,
192, 38, 208, 26, 220, 11, 25, 199, 74, 210,
183, 29, 182, 137, 182, 230, 246, 202, 198, 215,
18, 222, 141, 152, 101, 170, 171, 63, 63, 80,
16, 60, 12, 17, 197, 204, 83, 21, 253, 207,
1, 148, 0, 111, 64, 44, 48, 29, 212, 9,
159, 70, 232, 50, 206, 149, 148, 111, 47, 108,
28, 45, 201, 221, 150, 217, 174, 218, 252, 91,
1, 251, 64, 67, 112, 49, 228, 20, 75, 79,
119, 116, 38, 167, 90, 250, 187, 3, 51, 65,
213, 240, 95, 4, 56, 3, 82, 129, 253, 160,
65, 184, 48, 114, 148, 37, 175, 91, 60, 59,
81, 211, 124, 93, 225, 249, 136, 66, 230, 177,
138, 244, 103, 7, 106, 130, 175, 33, 188, 24,
113, 202, 164, 87, 59, 126, 147, 96, 109, 232,
45, 142, 157, 164, 105, 187, 110, 243, 108, 69,
237, 243, 13, 133, 197, 163, 19, 57, 205, 210,
213, 157, 159, 41, 168, 30, 254, 136, 64, 102,
176, 42, 244, 31, 7, 72, 2, 182, 129, 182,
224, 118, 200, 38, 214, 154, 222, 235, 24, 79,
74, 180, 55, 55, 86, 150, 190, 238, 240, 76,
68, 53, 243, 87, 5, 254, 131, 0, 97, 192,
40, 80, 30, 188, 8, 113, 198, 164, 82, 251,
125, 131, 97, 161, 232, 120, 78, 162, 180, 121,
183, 98, 246, 169, 134, 254, 226, 192, 73, 144,
54, 236, 22, 205, 206, 213, 148, 95, 47, 120,
28, 34, 137, 217, 166, 218, 250, 219, 3, 27,
65, 203, 112, 87, 100, 62, 171, 80, 127, 124,
32, 33, 216, 24, 90, 138, 187, 39, 51, 90,
149, 251, 47, 3, 92, 1, 249, 192, 66, 208,
49, 156, 20, 105, 207, 110, 212, 44, 95, 93,
248, 57, 130, 146, 225, 173, 136, 125, 166, 161,
186, 248, 115, 2, 165, 193, 187, 16, 115, 76,
37, 245, 219, 7, 27, 66, 139, 113, 167, 100,
122, 171, 99, 63, 105, 208, 46, 220, 28, 89,
201, 250, 214, 195, 30, 209, 200, 92, 86, 185,
254, 242, 192, 69, 144, 51, 44, 21, 221, 207,
25, 148, 10, 239, 71, 12, 50, 133, 213, 163,
31, 57, 200, 18, 214, 141, 158, 229, 168, 75,
62, 183, 80, 118, 188, 38, 241, 218, 196, 91,
19, 123, 77, 227, 117, 137, 231, 38, 202, 154,
215, 43, 30, 159, 72, 104, 54, 174, 150, 252,
110, 193, 236, 80, 77, 252, 53, 129, 215, 32,
94, 152, 56, 106, 146, 175, 45, 188, 29, 177,
201, 180, 86, 247, 126, 198, 160, 82, 248, 61,
130, 145, 161, 172, 120, 125, 226, 161, 137, 184,
102, 242, 170, 197, 191, 19, 48, 13, 212, 5,
159, 67, 40, 49, 222, 148, 88, 111, 122, 172,
35, 61, 217, 209, 154, 220, 107, 25, 239, 74,
204, 55, 21, 214, 143, 30, 228, 8, 75, 70,
183, 114, 246, 165, 134, 251, 34, 195, 89, 145,
250, 236, 67, 13, 241, 197, 132, 83, 35, 125,
217, 225, 154, 200, 107, 22, 175, 78, 252, 52,
65, 215, 112, 94, 164, 56, 123, 82, 163, 125,
185, 225, 178, 200, 117, 150, 167, 46, 250, 156,
67, 41, 241, 222, 196, 88, 83, 122, 189, 227,
49, 137, 212, 102, 223, 106, 216, 47, 26, 156,
11, 41, 199, 94, 210, 184, 93, 178, 185, 181,
178, 247, 53, 134, 151, 34, 238, 153, 140, 106,
229, 239, 11, 12, 7, 69, 194, 179, 17, 181,
204, 119, 21, 230, 143, 10, 228, 7, 11, 66,
135, 113, 162, 164, 121, 187, 98, 243, 105, 133,
238, 227, 12, 73, 197, 246, 211, 6, 221, 194,
217, 145, 154, 236, 107, 13, 239, 69, 140, 51,
37, 213, 219, 31, 27, 72, 11, 118, 135, 102,
226, 170, 201, 191, 22, 240, 14, 196, 4, 83,
67, 125, 241, 225, 132, 72, 99, 118, 169, 230,
254, 202, 192, 87, 16, 62, 140, 16, 101, 204,
43, 21, 223, 79, 24, 52, 10, 151, 71, 46,
178, 156, 117, 169, 231, 62, 202, 144, 87, 44,
62, 157, 208, 105, 156, 46, 233, 220, 78, 217,
244, 90, 199, 123, 18, 163, 77, 185, 245, 178,
199, 53, 146, 151, 45, 174, 157, 188, 105, 177,
238, 244, 76, 71, 117, 242, 167, 5, 186, 131,
51, 33, 213, 216, 95, 26, 184, 11, 50, 135,
85, 162, 191, 57, 176, 18, 244, 13, 135, 69,
162, 179, 57, 181, 210, 247, 29, 134, 137, 162,
230, 249, 138, 194, 231, 17, 138, 140, 103, 37,
234, 155, 15, 43, 68, 31, 115, 72, 37, 246,
155, 6, 235, 66, 207, 113, 148, 36, 111, 91,
108, 59, 109, 211, 109, 157, 237, 169, 141, 190,
229, 176, 75, 52, 55, 87, 86, 190, 190, 240,
112, 68, 36, 51, 91, 85, 251, 127, 3, 96,
1, 232, 0, 78, 128, 52, 96, 23, 104, 14,
174, 132, 124, 99, 97, 233, 232, 78, 206, 180,
84, 119, 127, 102, 160, 42, 248, 31, 2, 136,
1, 166, 128, 122, 224, 35, 8, 25, 198, 138,
210, 231, 29, 138, 137, 167, 38, 250, 154, 195,
43, 17, 223, 76, 88, 53, 250, 151, 3, 46,
129, 220, 96, 89, 232, 58, 206, 147, 20, 109,
207, 109, 148, 45, 175, 93, 188, 57, 177, 210,
244, 93, 135, 121, 162, 162, 249, 185, 130, 242,
225, 133, 136, 99, 38, 169, 218, 254, 219, 0,
91, 64, 59, 112, 19, 100, 13, 235, 69, 143,
115, 36, 37, 219, 91, 27, 123, 75, 99, 119,
105, 230, 174, 202, 252, 87, 1, 254, 128, 64,
96, 48, 40, 20, 30, 143, 72, 100, 54, 171,
86, 255, 126, 192, 32, 80, 24, 60, 10, 145,
199, 44, 82, 157, 253, 169, 129, 190, 224, 112,
72, 36, 54, 155, 86, 235, 126, 207, 96, 84,
40, 63, 94, 144, 56, 108, 18, 173, 205, 189,
149, 177, 175, 52, 124, 23, 97, 206, 168, 84,
126, 191, 96, 112, 40, 36, 30, 155, 72, 107,
118, 175, 102, 252, 42, 193, 223, 16, 88, 12,
58, 133, 211, 35, 29, 217, 201, 154, 214, 235,
30, 207, 72, 84, 54, 191, 86, 240, 62, 196,
16, 83, 76, 61, 245, 209, 135, 28, 98, 137,
233, 166, 206, 250, 212, 67, 31, 113, 200, 36,
86, 155, 126, 235, 96, 79, 104, 52, 46, 151,
92, 110, 185, 236, 114, 205, 229, 149, 139, 47,
39, 92, 26, 185, 203, 50, 215, 85, 158, 191,
40, 112, 30, 164, 8, 123, 70, 163, 114, 249,
229, 130, 203, 33, 151, 88, 110, 186, 172, 115,
61, 229, 209, 139, 28, 103, 73, 234, 182, 207,
54, 212, 22, 223, 78, 216, 52, 90, 151, 123,
46, 163, 92, 121, 249, 226, 194, 201, 145, 150,
236, 110, 205, 236, 85, 141, 255, 37, 128, 27,
32, 11, 88, 7, 122, 130, 163, 33, 185, 216,
114, 218, 165, 155, 59, 43, 83, 95, 125, 248,
33, 130, 152, 97, 170, 168, 127, 62, 160, 16,
120, 12, 34, 133, 217, 163, 26, 249, 203, 2,
215, 65, 158, 176, 104, 116, 46, 167, 92, 122,
185, 227, 50, 201, 213, 150, 223, 46, 216, 28,
90, 137, 251, 38, 195, 90, 209, 251, 28, 67,
73, 241, 246, 196, 70, 211, 114, 221, 229, 153
};
/* ------------------------------------------------------------------------- */
/* This is the new implementation of P- and Q-parity generation.
It needs about the same computing time as the old implementation (both
with gcc -O2 on AMD 64 bit). Measurements indicate that about 280 MIPS
are needed for 48x CD speed (7.1 MB/s).
*/
static unsigned char burn_rspc_mult(unsigned char a, unsigned char b)
{
if (a == 0 || b == 0)
return 0;
/* Optimization of (a == 0 || b == 0) by D. Hugh Redelmeier
if((((int)a - 1) | ((int)b - 1)) < 0)
return 0;
*/
return gfpow[gflog[a] + gflog[b]];
/* % 255 not necessary because gfpow is unrolled up to index 510 */
}
/* Divide by polynomial 0x03. Derived from burn_rspc_div() and using the
unrolled size of the gfpow[] array.
*/
static unsigned char burn_rspc_div_3(unsigned char a)
{
if (a == 0)
return 0;
return gfpow[230 + gflog[a]];
}
static void burn_rspc_p0p1(unsigned char *sector, int col,
unsigned char *p0_lsb, unsigned char *p0_msb,
unsigned char *p1_lsb, unsigned char *p1_msb)
{
unsigned char *start, b;
unsigned int i, sum_v_lsb = 0, sum_v_msb = 0;
unsigned int hxv_lsb = 0, hxv_msb = 0;
start = sector + 12 + 2 * col;
for(i = 0; i < 24; i++) {
b = *start;
sum_v_lsb ^= b;
#ifdef Libburn_use_h_matriceS
hxv_lsb ^= burn_rspc_mult(b, h26[i]);
#else
hxv_lsb ^= burn_rspc_mult(b, gfpow[25 - i]);
#endif
b = *(start + 1);
sum_v_msb ^= b;
#ifdef Libburn_use_h_matriceS
hxv_msb ^= burn_rspc_mult(b, h26[i]);
#else
hxv_msb ^= burn_rspc_mult(b, gfpow[25 - i]);
#endif
start += 86;
}
/* 3 = gfpow[1] ^ gfpow[0] , 2 = gfpow[1] */
*p0_lsb = burn_rspc_div_3(burn_rspc_mult(2, sum_v_lsb) ^ hxv_lsb);
*p0_msb = burn_rspc_div_3(burn_rspc_mult(2, sum_v_msb) ^ hxv_msb);
*p1_lsb = sum_v_lsb ^ *p0_lsb;
*p1_msb = sum_v_msb ^ *p0_msb;
}
void burn_rspc_parity_p(unsigned char *sector)
{
int i;
unsigned char p0_lsb, p0_msb, p1_lsb, p1_msb;
/* Loop over P columns */
for(i = 0; i < 43; i++) {
burn_rspc_p0p1(sector, i, &p0_lsb, &p0_msb, &p1_lsb, &p1_msb);
sector[2162 + 2 * i] = p0_lsb;
sector[2162 + 2 * i + 1] = p0_msb;
sector[2076 + 2 * i] = p1_lsb;
sector[2076 + 2 * i + 1] = p1_msb;
#ifdef Libburn_with_lec_generatoR
if(verbous) {
printf("p %2d : %2.2X %2.2X ", i,
(unsigned int) p0_lsb, (unsigned int) p0_msb);
printf("%2.2X %2.2X ",
(unsigned int) p1_lsb, (unsigned int) p1_msb);
printf("-> %d,%d\n", 2162 + 2 * i, 2076 + 2 * i);
}
#endif /* Libburn_with_lec_generatoR */
}
}
static void burn_rspc_q0q1(unsigned char *sector, int diag,
unsigned char *q0_lsb, unsigned char *q0_msb,
unsigned char *q1_lsb, unsigned char *q1_msb)
{
unsigned char *start, b;
unsigned int i, idx, sum_v_lsb = 0, sum_v_msb = 0;
unsigned int hxv_lsb = 0, hxv_msb = 0;
start = sector + 12;
idx = 2 * 43 * diag;
for(i = 0; i < 43; i++) {
if (idx >= 2236)
idx -= 2236;
b = start[idx];
sum_v_lsb ^= b;
#ifdef Libburn_use_h_matriceS
hxv_lsb ^= burn_rspc_mult(b, h45[i]);
#else
hxv_lsb ^= burn_rspc_mult(b, gfpow[44 - i]);
#endif
b = start[idx + 1];
sum_v_msb ^= b;
#ifdef Libburn_use_h_matriceS
hxv_msb ^= burn_rspc_mult(b, h45[i]);
#else
hxv_msb ^= burn_rspc_mult(b, gfpow[44 - i]);
#endif
idx += 88;
}
/* 3 = gfpow[1] ^ gfpow[0] , 2 = gfpow[1] */
*q0_lsb = burn_rspc_div_3(burn_rspc_mult(2, sum_v_lsb) ^ hxv_lsb);
*q0_msb = burn_rspc_div_3(burn_rspc_mult(2, sum_v_msb) ^ hxv_msb);
*q1_lsb = sum_v_lsb ^ *q0_lsb;
*q1_msb = sum_v_msb ^ *q0_msb;
}
void burn_rspc_parity_q(unsigned char *sector)
{
int i;
unsigned char q0_lsb, q0_msb, q1_lsb, q1_msb;
/* Loop over Q diagonals */
for(i = 0; i < 26; i++) {
burn_rspc_q0q1(sector, i, &q0_lsb, &q0_msb, &q1_lsb, &q1_msb);
sector[2300 + 2 * i] = q0_lsb;
sector[2300 + 2 * i + 1] = q0_msb;
sector[2248 + 2 * i] = q1_lsb;
sector[2248 + 2 * i + 1] = q1_msb;
#ifdef Libburn_with_lec_generatoR
if(verbous) {
printf("q %2d : %2.2X %2.2X ", i,
(unsigned int) q0_lsb, (unsigned int) q0_msb);
printf("%2.2X %2.2X ",
(unsigned int) q1_lsb, (unsigned int) q1_msb);
printf("-> %d,%d\n", 2300 + 2 * i, 2248 + 2 * i);
}
#endif /* Libburn_with_lec_generatoR */
}
}
/* ------------------------------------------------------------------------- */
/* The new implementation of the ECMA-130 Annex B scrambler.
It is totally unoptimized. One should make use of larger word operations.
Measurements indicate that about 50 MIPS are needed for 48x CD speed.
*/
void burn_ecma130_scramble(unsigned char *sector)
{
int i;
unsigned char *s;
s = sector + 12;
for (i = 0; i < 2340; i++)
s[i] ^= ecma_130_annex_b[i];
}
/* ------------------------------------------------------------------------- */
/* The following code is not needed for libburn but rather documents the
origin of the tables above. In libburn it will not be compiled.
*/
#ifdef Libburn_with_lec_generatoR
/* This function produced the content of gflog[] and gfpow[]
*/
static int burn_rspc_setup_tables(void)
{
unsigned int b, l;
memset(gflog, 0, sizeof(gflog));
memset(gfpow, 0, sizeof(gfpow));
b = 1;
for (l = 0; l < 255; l++) {
gfpow[l] = (unsigned char) b;
gflog[b] = (unsigned char) l;
b = b << 1;
if (b & 256)
b = b ^ 0x11d;
}
return 0;
}
/* This function printed the content of gflog[] and gfpow[] as C code
and compared the content with the tables of the old implementation.
h26[] and h45[] are reverted order copies of gfpow[]
*/
static int burn_rspc_print_tables(void)
{
int i;
printf("static unsigned char gfpow[255] = {");
printf("\n\t");
for(i= 0; i < 255; i++) {
printf("%3u, ", gfpow[i]);
#ifdef Libburn_with_old_lec_comparisoN
if(gfpow[i] != gf8_ilog[i])
fprintf(stderr, "*** ILOG %d : %d != %d ***\n", i, gfpow[i], gf8_ilog[i]);
#endif
if((i % 10) == 9)
printf("\n\t");
}
printf("\n};\n\n");
printf("static unsigned char gflog[256] = {");
printf("\n\t");
for(i= 0; i < 256; i++) {
printf(" %3u,", gflog[i]);
#ifdef Libburn_with_old_lec_comparisoN
if(gflog[i] != gf8_log[i])
fprintf(stderr, "*** LOG %d : %d != %d ***\n", i, gflog[i], gf8_log[i]);
#endif
if((i % 10) == 9)
printf("\n\t");
}
printf("\n};\n\n");
printf("static unsigned char h26[26] = {");
printf("\n\t");
for(i= 0; i < 26; i++) {
printf(" %3u,", gfpow[25 - i]);
if((i % 10) == 9)
printf("\n\t");
}
printf("\n};\n\n");
printf("static unsigned char h45[45] = {");
printf("\n\t");
for(i= 0; i < 45; i++) {
printf(" %3u,",gfpow[44 - i]);
if((i % 10) == 9)
printf("\n\t");
}
printf("\n};\n\n");
return 0;
}
/* This code was used to generate the content of array ecma_130_annex_b[].
*/
static unsigned short ecma_130_fsr = 1;
static int next_bit(void)
{
int ret;
ret = ecma_130_fsr & 1;
ecma_130_fsr = (ecma_130_fsr >> 1) & 0x3fff;
if (ret ^ (ecma_130_fsr & 1))
ecma_130_fsr |= 0x4000;
return ret;
}
static int print_ecma_130_scrambler(void)
{
int i, j, b;
ecma_130_fsr = 1;
printf("static unsigned char ecma_130_annex_b[2340] = {");
printf("\n\t");
for (i = 0; i < 2340; i++) {
b = 0;
for (j = 0; j < 8; j++)
b |= next_bit() << j;
printf("%3u, ", b);
if ((i % 10) == 9)
printf("\n\t");
}
printf("\n};\n");
return 1;
}
#ifdef Libburn_with_general_rspc_diV
/* This is a general polynomial division function.
burn_rspc_div_3() has been derived from this by setting b to constant 3.
*/
static unsigned char burn_rspc_div(unsigned char a, unsigned char b)
{
int d;
if (a == 0)
return 0;
if (b == 0)
return -1;
d = gflog[a] - gflog[b];
if (d < 0)
d += 255;
return gfpow[d];
}
#endif /* Libburn_with_general_rspc_diV */
#endif /* Libburn_with_lec_generatoR */

24
libburn/ecma130ab.h Normal file
View File

@ -0,0 +1,24 @@
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
/* ts A91016 : libburn/ecma130ab.h is the replacement for old libburn/lec.h
Copyright 2009, Thomas Schmitt <scdbackup@gmx.net>, libburnia-project.org
Provided under GPL version 2 or later.
This code module implements the computations prescribed in ECMA-130 Annex A
and B. For explanations of the underlying mathematics see ecma130ab.c .
*/
#ifndef Libburn_ecma130ab_includeD
#define Libburn_ecma130ab_includeD 1
void burn_rspc_parity_p(unsigned char *sector);
void burn_rspc_parity_q(unsigned char *sector);
void burn_ecma130_scramble(unsigned char *sector);
#endif /* ! Libburn_ecma130ab_includeD */

8
libburn/error.h Normal file
View File

@ -0,0 +1,8 @@
/* -*- indent-tabs-mode; t; tab-width: 8; c-basic-offset: 8; -*- */
#ifndef __ERROR_H
#define __ERROR_H
#define BE_CANCELLED 1
#endif /* __ERROR_H */

1124
libburn/file.c Normal file

File diff suppressed because it is too large Load Diff

102
libburn/file.h Normal file
View File

@ -0,0 +1,102 @@
/* -*- 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__FILE_H
#define BURN__FILE_H
struct burn_source_file
{
char magic[4];
int datafd;
int subfd;
off_t fixed_size;
};
/* ts A70126 : burn_source_file obsoleted burn_source_fd */
/* ts A70930 */
struct burn_source_fifo {
char magic[4];
/* 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_shoveller()
which shovels data and finally destroys the resources.
This late start is to stay modest in case of multiple tracks
in one disc.
*/
int is_started;
void *thread_handle; /* actually a pointer to a thread_t */
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;
/* <<< up to now it was only a pipe. This is on its way out. */
int outlet[2];
/* The ring buffer mechanism */
int chunksize;
int chunks;
char *buf;
volatile int buf_writepos;
volatile int buf_readpos;
volatile int end_of_input;
volatile int input_error;
volatile int end_of_consumption;
off_t in_counter;
off_t out_counter;
int total_min_fill;
int interval_min_fill;
int put_counter;
int get_counter;
int empty_counter;
int full_counter;
};
/** The worker behind the fifo thread.
Gets started from burn_fifo_start() in async.c
*/
int burn_fifo_source_shoveller(struct burn_source *source, int flag);
/* ts B00922 */
struct burn_source_offst {
/* See burn_offst_source_new() */
struct burn_source *inp;
struct burn_source *prev;
off_t start;
off_t size;
int size_adjustable;
/* for set_size/get_size */
int nominal_size;
/* To help offst_free() */
struct burn_source *next;
/* The current reading position */
int running;
off_t pos;
};
#endif /* LIBBURN__FILE_H */

664
libburn/init.c Normal file
View File

@ -0,0 +1,664 @@
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
Copyright (c) 2006 - 2013 Thomas Schmitt <scdbackup@gmx.net>
Provided under GPL version 2 or later.
*/
#ifdef HAVE_CONFIG_H
#include "../config.h"
#endif
#include <unistd.h>
/* ts A61007 */
/* #include <a ssert.h> */
#include <stdio.h>
#include <signal.h>
#include <string.h>
#include <stdlib.h>
#include <pthread.h>
/* ts A70928 : init.h is for others, not for init .c
#include "init.h"
*/
#include "sg.h"
#include "error.h"
#include "libburn.h"
#include "drive.h"
#include "transport.h"
#include "util.h"
/* ts A60825 : The storage location for back_hacks.h variables. */
#define BURN_BACK_HACKS_INIT 1
#include "back_hacks.h"
/* ts A60924 : a new message handling facility */
#include "libdax_msgs.h"
struct libdax_msgs *libdax_messenger= NULL;
int burn_running = 0;
double lib_start_time;
/* ts A60813 : GNU/Linux: whether to use O_EXCL on open() of device files
ts B00212 : FreeBSD: whether to use flock(LOCK_EX) after open()
*/
int burn_sg_open_o_excl = 1;
/* ts A70403 : GNU/Linux: wether to use fcntl(,F_SETLK,)
after open() of device files */
int burn_sg_fcntl_f_setlk = 1;
/* ts A70314 : GNU/Linux: what device family to use :
0= default family
1= sr
2= scd
(3= st)
4= sg
*/
int burn_sg_use_family = 0;
/* O_NONBLOCK was hardcoded in enumerate_ata() which i hardly use.
For enumerate_sg() it seems ok.
So it should stay default mode until enumerate_ata() without O_NONBLOCK
has been thoroughly tested. */
int burn_sg_open_o_nonblock = 1;
/* wether 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;
/* The message returned from sg_id_string() and/or sg_initialize()
*/
static char sg_initialize_msg[1024] = {""};
/* ts A61002 */
#include "cleanup.h"
/* Parameters for builtin abort handler */
static char abort_message_prefix[81] = {"libburn : "};
static pid_t abort_control_pid= 0;
static pthread_t abort_control_thread;
volatile int burn_global_abort_level= 0;
int burn_global_abort_signum= 0;
void *burn_global_signal_handle = NULL;
burn_abort_handler_t burn_global_signal_handler = NULL;
int burn_builtin_signal_action = 0; /* burn_set_signal_handling() */
volatile int burn_builtin_triggered_action = 0; /* burn_is_aborting() */
/* ts A70223 : wether implemented untested profiles are supported */
int burn_support_untested_profiles = 0;
/* ts A91111 :
whether to log SCSI commands (to be implemented in sg-*.c)
bit0= log in /tmp/libburn_sg_command_log
bit1= log to stderr
bit2= flush every line
*/
int burn_sg_log_scsi = 0;
/* ts B10312 :
Whether to map random-access readonly files to drive role 4.
Else it is role 2 overwriteable drive
*/
int burn_drive_role_4_allowed = 0;
/* ts A60925 : ticket 74 */
/** Create the messenger object for libburn. */
int burn_msgs_initialize(void)
{
int ret;
if(libdax_messenger == NULL) {
ret = libdax_msgs_new(&libdax_messenger,0);
if (ret <= 0)
return 0;
}
libdax_msgs_set_severities(libdax_messenger, LIBDAX_MSGS_SEV_NEVER,
LIBDAX_MSGS_SEV_FATAL, "libburn: ", 0);
return 1;
}
/* ts A60924 : ticket 74 : Added use of global libdax_messenger */
int burn_initialize(void)
{
int ret;
if (burn_running)
return 1;
lib_start_time = burn_get_time(0);
burn_support_untested_profiles = 0;
ret = burn_msgs_initialize();
if (ret <= 0)
return 0;
ret = sg_initialize(sg_initialize_msg, 0);
if (ret <= 0) {
libdax_msgs_submit(libdax_messenger, -1,
0x00020175,
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
sg_initialize_msg, 0, 0);
return 0;
}
burn_running = 1;
return 1;
}
void burn_finish(void)
{
/* ts A61007 : assume no messageing system */
/* a ssert(burn_running); */
if (!burn_running)
return;
/* ts A61007 */
/* burn_wait_all(); */
if (!burn_drives_are_clear(0)) {
libdax_msgs_submit(libdax_messenger, -1, 0x00020107,
LIBDAX_MSGS_SEV_WARNING, LIBDAX_MSGS_PRIO_HIGH,
"A drive is still busy on shutdown of library", 0, 0);
usleep(1000001);
burn_abort(4440, burn_abort_pacifier, abort_message_prefix);
}
/* ts A60904 : ticket 62, contribution by elmom : name addon "_all" */
burn_drive_free_all();
/* ts A60924 : ticket 74 */
libdax_msgs_destroy(&libdax_messenger,0);
sg_shutdown(0);
burn_drive_clear_whitelist();
burn_running = 0;
}
/* ts A91226 */
/** API function. See libburn.h */
char *burn_scsi_transport_id(int flag)
{
if (!burn_running)
sg_id_string(sg_initialize_msg, 0);
return sg_initialize_msg;
}
/* ts A60813 */
/** API function. See libburn.h */
void burn_preset_device_open(int exclusive, int blocking, int abort_on_busy)
{
/* ts A61007 */
/* a ssert(burn_running); */
if (!burn_running)
return;
burn_sg_open_o_excl = exclusive & 3;
burn_sg_fcntl_f_setlk = !!(exclusive & 32);
burn_sg_use_family = (exclusive >> 2) & 7;
burn_sg_open_o_nonblock = !blocking;
burn_sg_open_abort_busy = !!abort_on_busy;
}
/* ts A60924 : ticket 74 */
/** Control queueing and stderr printing of messages from libburn.
Severity may be one of "NEVER", "FATAL", "SORRY", "WARNING", "HINT",
"NOTE", "UPDATE", "DEBUG", "ALL".
@param queue_severity Gives the minimum limit for messages to be queued.
Default: "NEVER". If you queue messages then you
must consume them by burn_msgs_obtain().
@param print_severity Does the same for messages to be printed directly
to stderr.
@param print_id A text prefix to be printed before the message.
@return >0 for success, <=0 for error
*/
int burn_msgs_set_severities(char *queue_severity,
char *print_severity, char *print_id)
{
int ret, queue_sevno, print_sevno;
ret = libdax_msgs__text_to_sev(queue_severity, &queue_sevno, 0);
if (ret <= 0)
return 0;
ret = libdax_msgs__text_to_sev(print_severity, &print_sevno, 0);
if (ret <= 0)
return 0;
ret = libdax_msgs_set_severities(libdax_messenger, queue_sevno,
print_sevno, print_id, 0);
if (ret <= 0)
return 0;
return 1;
}
/* ts A60924 : ticket 74 */
#define BURM_MSGS_MESSAGE_LEN 4096
/** Obtain the oldest pending libburn message from the queue which has at
least the given minimum_severity. This message and any older message of
lower severity will get discarded from the queue and is then lost forever.
Severity may be one of "NEVER", "FATAL", "SORRY", "WARNING", "HINT",
"NOTE", "UPDATE", "DEBUG", "ALL". To call with minimum_severity "NEVER"
will discard the whole queue.
@param error_code Will become a unique error code as liste in
libburn/libdax_msgs.h
@param msg_text Must provide at least BURM_MSGS_MESSAGE_LEN bytes.
@param os_errno Will become the eventual errno related to the message
@param severity Will become the severity related to the message and
should provide at least 80 bytes.
@return 1 if a matching item was found, 0 if not, <0 for severe errors
*/
int burn_msgs_obtain(char *minimum_severity,
int *error_code, char msg_text[], int *os_errno,
char severity[])
{
int ret, minimum_sevno, sevno, priority;
char *textpt, *sev_name;
struct libdax_msgs_item *item = NULL;
ret = libdax_msgs__text_to_sev(minimum_severity, &minimum_sevno, 0);
if (ret <= 0)
return 0;
if (libdax_messenger == NULL)
return 0;
ret = libdax_msgs_obtain(libdax_messenger, &item, minimum_sevno,
LIBDAX_MSGS_PRIO_ZERO, 0);
if (ret <= 0)
goto ex;
ret = libdax_msgs_item_get_msg(item, error_code, &textpt, os_errno, 0);
if (ret <= 0)
goto ex;
strncpy(msg_text, textpt, BURM_MSGS_MESSAGE_LEN-1);
if(strlen(textpt) >= BURM_MSGS_MESSAGE_LEN)
msg_text[BURM_MSGS_MESSAGE_LEN-1] = 0;
severity[0]= 0;
ret = libdax_msgs_item_get_rank(item, &sevno, &priority, 0);
if(ret <= 0)
goto ex;
ret = libdax_msgs__sev_to_text(sevno, &sev_name, 0);
if(ret <= 0)
goto ex;
strcpy(severity,sev_name);
ret = 1;
ex:
libdax_msgs_destroy_item(libdax_messenger, &item, 0);
return ret;
}
/* ts A70922 : API */
int burn_msgs_submit(int error_code, char msg_text[], int os_errno,
char severity[], struct burn_drive *d)
{
int ret, sevno, global_index = -1;
ret = libdax_msgs__text_to_sev(severity, &sevno, 0);
if (ret <= 0)
sevno = LIBDAX_MSGS_SEV_ALL;
if (error_code <= 0) {
switch(sevno) {
case LIBDAX_MSGS_SEV_ABORT: error_code = 0x00040000;
break; case LIBDAX_MSGS_SEV_FATAL: error_code = 0x00040001;
break; case LIBDAX_MSGS_SEV_SORRY: error_code = 0x00040002;
break; case LIBDAX_MSGS_SEV_WARNING: error_code = 0x00040003;
break; case LIBDAX_MSGS_SEV_HINT: error_code = 0x00040004;
break; case LIBDAX_MSGS_SEV_NOTE: error_code = 0x00040005;
break; case LIBDAX_MSGS_SEV_UPDATE: error_code = 0x00040006;
break; case LIBDAX_MSGS_SEV_DEBUG: error_code = 0x00040007;
break; default: error_code = 0x00040008;
}
}
if (d != NULL)
global_index = d->global_index;
ret = libdax_msgs_submit(libdax_messenger, global_index, error_code,
sevno, LIBDAX_MSGS_PRIO_HIGH, msg_text, os_errno, 0);
return ret;
}
/* ts A71016 API */
int burn_text_to_sev(char *severity_name, int *sevno, int flag)
{
int ret;
ret = libdax_msgs__text_to_sev(severity_name, sevno, 0);
return ret;
}
/* ts A80202 API */
int burn_sev_to_text(int severity_number, char **severity_name, int flag)
{
int ret;
ret = libdax_msgs__sev_to_text(severity_number, severity_name, 0);
return ret;
}
/* ts B21214 API */
char *burn_list_sev_texts(int flag)
{
char *sev_list;
libdax_msgs__sev_to_text(0, &sev_list, 1);
return sev_list;
}
/* ts B00224 */
char *burn_util_thread_id(pid_t pid, pthread_t tid, char text[80])
{
int i, l;
sprintf(text, "[%lu,", (unsigned long int) getpid());
l= strlen(text);
for(i= 0; i < ((int) sizeof(pthread_t)) && 2 * i < 80 - l - 3; i++)
sprintf(text + l + 2 * i,
"%2.2X", ((unsigned char *) &tid)[i]);
sprintf(text + l + 2 * i, "]");
return text;
}
/* ts B20122 */
/* @param value 0=return rather than exit(value)
*/
int burn_abort_exit(int value)
{
burn_abort(4440, burn_abort_pacifier, abort_message_prefix);
fprintf(stderr,
"\n%sABORT : Program done. Even if you do not see a shell prompt.\n\n",
abort_message_prefix);
if (value)
exit(value);
burn_global_abort_level = -2;
return(1);
}
int burn_builtin_abort_handler(void *handle, int signum, int flag)
{
#define Libburn_new_thread_signal_handleR 1
/*
#define Libburn_signal_handler_verbouS 1
*/
int ret;
struct burn_drive *d;
#ifdef Libburn_signal_handler_verbouS
char text[80];
fprintf(stderr, "libburn_ABORT: in = %s\n",
burn_util_thread_id(getpid(), pthread_self(), text));
fprintf(stderr, "libburn_ABORT: ctrl = %s\n",
burn_util_thread_id(abort_control_pid, abort_control_thread,
text));
if (burn_global_signal_handler == burn_builtin_abort_handler)
fprintf(stderr, "libburn_ABORT: signal action = %d\n",
burn_builtin_signal_action);
/* >>> find writing drives and report their tid
fprintf(stderr, "libburn_ABORT: wrt = %s\n",
burn_util_thread_id(0, burn_write_thread_id, text));
fprintf(stderr, "libburn_ABORT: sig= %d\n", signum);
*/
#endif
burn_builtin_triggered_action = burn_builtin_signal_action;
burn_global_abort_level = -1;
if (burn_builtin_signal_action > 1) {
Cleanup_set_handlers(NULL, NULL, 2);
if (burn_builtin_signal_action == 4)
return -2;
fprintf(stderr,"%sABORT : Trying to shut down busy drives\n",
abort_message_prefix);
fprintf(stderr,
"%sABORT : Wait the normal burning time before any kill -9\n",
abort_message_prefix);
burn_abort_5(0, burn_abort_pacifier, abort_message_prefix,
0, 1);
libdax_msgs_submit(libdax_messenger, -1, 0x00020177,
LIBDAX_MSGS_SEV_ABORT, LIBDAX_MSGS_PRIO_HIGH,
"Urged drive worker threads to do emergency halt",
0, 0);
return -2;
}
/* ---- old deprecated stuck-in-abort-handler loop ---- */
/* ts A70928:
Must be quick. Allowed to coincide with other thread and to share
the increment with that one. It must not decrease, though, and
yield at least 1 if any thread calls this function.
*/
burn_global_abort_level++;
burn_global_abort_signum= signum;
if(getpid() != abort_control_pid) {
#ifdef Libburn_new_thread_signal_handleR
ret = burn_drive_find_by_thread_pid(&d, getpid(),
pthread_self());
if (ret > 0 && d->busy == BURN_DRIVE_WRITING) {
/* This is an active writer thread */
#ifdef Libburn_signal_handler_verbouS
fprintf(stderr, "libburn_ABORT: pid %d found drive busy with writing, (level= %d)\n", (int) getpid(), burn_global_abort_level);
#endif
d->sync_cache(d);
/* >>> perform a more qualified end of burn process */;
d->busy = BURN_DRIVE_IDLE;
if (burn_global_abort_level > 0) {
/* control process did not show up yet */
#ifdef Libburn_signal_handler_verbouS
fprintf(stderr, "libburn_ABORT: pid %d sending signum %d to pid %d\n", (int) getpid(), (int) signum, (int) abort_control_pid);
#endif
kill(abort_control_pid, signum);
}
#ifdef Libburn_signal_handler_verbouS
fprintf(stderr, "libburn_ABORT: pid %d signum %d returning -2\n", (int) getpid(), (int) signum);
#endif
return -2;
} else {
usleep(1000000); /* calm down */
return -2;
}
#else
usleep(1000000); /* calm down */
return -2;
#endif /* ! Libburn_new_thread_signal_handleR */
}
burn_global_abort_level = -1;
Cleanup_set_handlers(NULL, NULL, 2);
fprintf(stderr,"%sABORT : Trying to shut down drive and library\n",
abort_message_prefix);
fprintf(stderr,
"%sABORT : Wait the normal burning time before any kill -9\n",
abort_message_prefix);
close(0); /* somehow stdin as input blocks abort until EOF */
burn_abort_exit(0);
return (1);
}
/* ts A61002 : API */
void burn_set_signal_handling(void *handle, burn_abort_handler_t handler,
int mode)
{
/*
fprintf(stderr, "libburn_experimental: burn_set_signal_handling, handler==%lx mode=%d\n", (unsigned long) handler, mode);
*/
if(handler == NULL) {
handler = burn_builtin_abort_handler;
/*
if ((mode & ~4) == 0)
fprintf(stderr, "libburn_experimental: activated burn_builtin_abort_handler() with handle '%s'\n",(handle==NULL ? "libburn : " : (char *) handle));
*/
}
strcpy(abort_message_prefix, "libburn : ");
abort_message_prefix[0] = 0;
if(handle != NULL && handler == burn_builtin_abort_handler)
strncpy(abort_message_prefix, (char *) handle,
sizeof(abort_message_prefix)-1);
abort_message_prefix[sizeof(abort_message_prefix)-1] = 0;
abort_control_pid = getpid();
abort_control_thread = pthread_self();
burn_builtin_signal_action = (mode >> 4) & 15;
if((mode & 11) != 0)
burn_builtin_signal_action = 0;
if(burn_builtin_signal_action > 1)
burn_builtin_triggered_action = 0;
if(burn_builtin_signal_action == 0)
burn_builtin_signal_action = 1;
Cleanup_set_handlers(handle, (Cleanup_app_handler_T) handler,
(mode & 15) | 4 | (mode & 256));
burn_global_signal_handle = handle;
burn_global_signal_handler = handler;
}
/* ts B00304 : API */
int burn_is_aborting(int flag)
{
return burn_builtin_triggered_action;
}
/* ts B00225 */
/* @return 0= no abort action 2 pending , 1= not control thread
*/
int burn_init_catch_on_abort(int flag)
{
if (burn_builtin_triggered_action != 2)
return 0;
if (abort_control_pid != getpid() ||
abort_control_thread != pthread_self())
return 1;
burn_abort(4440, burn_abort_pacifier, abort_message_prefix);
fprintf(stderr,
"\n%sABORT : Program done. Even if you do not see a shell prompt.\n\n",
abort_message_prefix);
exit(1);
}
/* B20122 */
/* Temporarily disable builtin actions 0,1,2 to avoid that burn_abort()
waits for its own thread to end grabbing.
*/
int burn_grab_prepare_sig_action(int *signal_action_mem, int flag)
{
*signal_action_mem = -1;
if (burn_global_signal_handler == burn_builtin_abort_handler &&
burn_builtin_signal_action >= 0 &&
burn_builtin_signal_action <= 2) {
*signal_action_mem = burn_builtin_signal_action;
burn_builtin_signal_action = 3;
}
return 1;
}
/* B20122 */
/* Re-enable builtin actions 0,1,2 and perform delayed signal reactions
*/
int burn_grab_restore_sig_action(int signal_action_mem, int flag)
{
if (signal_action_mem >= 0)
burn_builtin_signal_action = signal_action_mem;
if (burn_is_aborting(0) && signal_action_mem >= 0) {
if (signal_action_mem == 0 || signal_action_mem == 1) {
burn_abort_exit(1); /* Never comes back */
} else if (signal_action_mem == 2) {
burn_builtin_triggered_action = signal_action_mem;
}
}
return 1;
}
/* ts A70223 : API */
void burn_allow_untested_profiles(int yes)
{
burn_support_untested_profiles = !!yes;
}
/* ts A70915 : API */
int burn_set_messenger(void *messenger)
{
struct libdax_msgs *pt;
if (libdax_msgs_refer(&pt, messenger, 0) <= 0)
return 0;
libdax_msgs_destroy(&libdax_messenger, 0);
libdax_messenger = (struct libdax_msgs *) pt;
return 1;
}
/* ts A91111 API */
void burn_set_scsi_logging(int flag)
{
burn_sg_log_scsi = flag & 7;
}
/* ts B10312 API */
void burn_allow_drive_role_4(int allowed)
{
burn_drive_role_4_allowed = (allowed & 0xf);
}
/* ts B10606 */
void *burn_alloc_mem(size_t size, size_t count, int flag)
{
void *pt;
pt = calloc(count, size);
if(pt == NULL)
libdax_msgs_submit(libdax_messenger, -1, 0x00000003,
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
"Out of virtual memory", 0, 0);
return pt;
}

63
libburn/init.h Normal file
View File

@ -0,0 +1,63 @@
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
Copyright (c) 2006 - 2013 Thomas Schmitt <scdbackup@gmx.net>
Provided under GPL version 2 or later.
*/
#ifndef BURN__INIT_H
#define BURN__INIT_H
extern int burn_running;
extern double lib_start_time;
/** Indicator for burn_drive_get_status() wether a signal hit parts of the
thread team.
0= all works well ,
1 to 5 = waiting for eventual signal on control thread
> 5 = do abort now
-1 = control thread has been informed
*/
extern volatile int burn_global_abort_level;
extern int burn_global_abort_signum;
extern void *burn_global_signal_handle;
extern burn_abort_handler_t burn_global_signal_handler;
extern int burn_builtin_signal_action; /* burn_set_signal_handling() */
extern volatile int burn_builtin_triggered_action; /* burn_is_aborting() */
/* ts B00225 */
/* @return 0= no abort pending , 1= not control thread ,
-1= surprisingly burn_abort returned
*/
int burn_init_catch_on_abort(int flag);
/* ts B10606 */
void *burn_alloc_mem(size_t size, size_t count, int flag);
#define BURN_ALLOC_MEM(pt, typ, count) { \
pt= (typ *) burn_alloc_mem(sizeof(typ), (size_t) (count), 0); \
if(pt == NULL) { \
ret= -1; goto ex; \
} }
#define BURN_ALLOC_MEM_VOID(pt, typ, count) { \
pt= (typ *) burn_alloc_mem(sizeof(typ), (size_t) (count), 0); \
if(pt == NULL) { \
goto ex; \
} }
#define BURN_FREE_MEM(pt) { \
if(pt != NULL) \
free((char *) pt); \
}
/* B20122 */
int burn_grab_prepare_sig_action(int *signal_action_mem, int flag);
int burn_grab_restore_sig_action(int signal_action_mem, int flag);
#endif /* BURN__INIT_H */

4446
libburn/libburn.h Normal file

File diff suppressed because it is too large Load Diff

212
libburn/libburn.ver Normal file
View File

@ -0,0 +1,212 @@
LIBBURN4 {
global:
burn_abort;
burn_abort_pacifier;
burn_allow_drive_role_4;
burn_allow_untested_profiles;
burn_cdtext_from_session;
burn_cdtext_from_packfile;
burn_disc_add_session;
burn_disc_available_space;
burn_disc_close_damaged;
burn_disc_create;
burn_disc_erasable;
burn_disc_erase;
burn_disc_format;
burn_disc_free;
burn_disc_free_multi_caps;
burn_disc_get_bd_spare_info;
burn_disc_get_cd_info;
burn_disc_get_format_descr;
burn_disc_get_formats;
burn_disc_get_incomplete_sessions;
burn_disc_get_leadin_text;
burn_disc_get_media_id;
burn_disc_get_msc1;
burn_disc_get_multi_caps;
burn_disc_get_phys_format_info;
burn_disc_get_profile;
burn_disc_get_sectors;
burn_disc_get_sessions;
burn_disc_get_status;
burn_disc_next_track_is_damaged;
burn_disc_pretend_blank;
burn_disc_pretend_full;
burn_disc_pretend_full_uncond;
burn_disc_read;
burn_disc_read_atip;
burn_disc_remove_session;
burn_disc_track_lba_nwa;
burn_disc_write;
burn_drive_add_whitelist;
burn_drive_cancel;
burn_drive_clear_whitelist;
burn_drive_convert_fs_adr;
burn_drive_convert_scsi_adr;
burn_drive_d_get_adr;
burn_drive_equals_adr;
burn_drive_extract_audio;
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;
burn_drive_get_serial_no;
burn_drive_get_speedlist;
burn_drive_get_start_end_lba;
burn_drive_get_status;
burn_drive_get_write_speed;
burn_drive_grab;
burn_drive_info_forget;
burn_drive_info_free;
burn_drive_is_enumerable_adr;
burn_drive_leave_locked;
burn_drive_obtain_scsi_adr;
burn_drive_probe_cd_write_modes;
burn_drive_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_stream_recording;
burn_drive_snooze;
burn_drive_was_feat21_failure;
burn_drive_wrote_well;
burn_fd_source_new;
burn_fifo_fill;
burn_fifo_get_statistics;
burn_fifo_inquire_status;
burn_fifo_next_interval;
burn_fifo_peek_data;
burn_fifo_source_new;
burn_file_source_new;
burn_finish;
burn_get_read_capacity;
burn_guess_cd_manufacturer;
burn_guess_manufacturer;
burn_initialize;
burn_is_aborting;
burn_lba_to_msf;
burn_list_sev_texts;
burn_lookup_device_link;
burn_make_input_sheet_v07t;
burn_msf_to_lba;
burn_msf_to_sectors;
burn_msgs_obtain;
burn_msgs_set_severities;
burn_msgs_submit;
burn_obtain_profile_name;
burn_offst_source_new;
burn_os_alloc_buffer;
burn_os_free_buffer;
burn_os_open_track_src;
burn_precheck_write;
burn_preset_device_open;
burn_random_access_write;
burn_read_audio;
burn_read_data;
burn_read_opts_free;
burn_read_opts_new;
burn_read_opts_read_subcodes_audio;
burn_read_opts_read_subcodes_data;
burn_read_opts_report_recovered_errors;
burn_read_opts_set_c2errors;
burn_read_opts_set_hardware_error_recovery;
burn_read_opts_set_hardware_error_retries;
burn_read_opts_set_raw;
burn_read_opts_transfer_damaged_blocks;
burn_scsi_transport_id;
burn_sectors_to_msf;
burn_session_add_track;
burn_session_by_cue_file;
burn_session_create;
burn_session_dispose_cdtext;
burn_session_free;
burn_session_get_cdtext;
burn_session_get_cdtext_par;
burn_session_get_hidefirst;
burn_session_get_leadout_entry;
burn_session_get_sectors;
burn_session_get_start_tno;
burn_session_get_tracks;
burn_session_hide_first_track;
burn_session_input_sheet_v07t;
burn_session_remove_track;
burn_session_set_cdtext;
burn_session_set_cdtext_par;
burn_session_set_start_tno;
burn_set_messenger;
burn_set_scsi_logging;
burn_set_signal_handling;
burn_set_verbosity;
burn_sev_to_text;
burn_source_free;
burn_structure_print_disc;
burn_structure_print_session;
burn_structure_print_track;
burn_text_to_sev;
burn_track_clear_indice;
burn_track_clear_isrc;
burn_track_create;
burn_track_define_data;
burn_track_dispose_cdtext;
burn_track_free;
burn_track_get_cdtext;
burn_track_get_counters;
burn_track_get_entry;
burn_track_get_mode;
burn_track_get_sectors;
burn_track_set_byte_swap;
burn_track_set_cdxa_conv;
burn_track_set_cdtext;
burn_track_set_default_size;
burn_track_set_index;
burn_track_set_isrc;
burn_track_set_isrc_string;
burn_track_set_postgap_size;
burn_track_set_pregap_size;
burn_track_set_size;
burn_track_set_source;
burn_version;
burn_write_opts_auto_write_type;
burn_write_opts_free;
burn_write_opts_get_drive;
burn_write_opts_new;
burn_write_opts_set_dvd_obs;
burn_write_opts_set_fail21h_sev;
burn_write_opts_set_fillup;
burn_write_opts_set_force;
burn_write_opts_set_format;
burn_write_opts_set_has_mediacatalog;
burn_write_opts_set_leadin_text;
burn_write_opts_set_mediacatalog;
burn_write_opts_set_multi;
burn_write_opts_set_obs_pad;
burn_write_opts_set_perform_opc;
burn_write_opts_set_simulate;
burn_write_opts_set_start_byte;
burn_write_opts_set_stdio_fsync;
burn_write_opts_set_stream_recording;
burn_write_opts_set_toc_entries;
burn_write_opts_set_underrun_proof;
burn_write_opts_set_write_type;
libdax_audioxtr_destroy;
libdax_audioxtr_detach_fd;
libdax_audioxtr_get_id;
libdax_audioxtr_get_size;
libdax_audioxtr_new;
libdax_audioxtr_read;
local: *;
};

408
libburn/libdax_audioxtr.c Normal file
View File

@ -0,0 +1,408 @@
/* libdax_audioxtr
Audio track data extraction facility of libdax and libburn.
Copyright (C) 2006 Thomas Schmitt <scdbackup@gmx.net>, provided under GPLv2+
*/
#ifdef HAVE_CONFIG_H
#include "../config.h"
#endif
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
/* ts B41126 : O_BINARY is needed for Cygwin but undefined elsewhere */
#ifndef O_BINARY
#define O_BINARY 0
#endif
#include "libdax_msgs.h"
extern struct libdax_msgs *libdax_messenger;
/* Only this single source module is entitled to do this */
#define LIBDAX_AUDIOXTR_H_INTERNAL 1
/* All clients of the extraction facility must do this or include libburn.h */
#define LIBDAX_AUDIOXTR_H_PUBLIC 1
#include "libdax_audioxtr.h"
int libdax_audioxtr_new(struct libdax_audioxtr **xtr, char *path, int flag)
{
int ret= -1;
struct libdax_audioxtr *o;
o= *xtr= (struct libdax_audioxtr *) calloc(1, sizeof(struct libdax_audioxtr));
if(o==NULL)
return(-1);
strncpy(o->path,path,LIBDAX_AUDIOXTR_STRLEN-1);
o->path[LIBDAX_AUDIOXTR_STRLEN-1]= 0;
o->fd= -1;
strcpy(o->fmt,"unidentified");
o->fmt_info[0]= 0;
o->data_size= 0;
o->extract_count= 0;
o->num_channels= 0;
o->sample_rate= 0;
o->bits_per_sample= 0;
o->msb_first= 0;
o->wav_data_location= 44;
o->wav_subchunk2_size= 0;
o->au_data_location= 0;
o->au_data_size= 0xffffffff;
ret= libdax_audioxtr_open(o,0);
if(ret<=0)
{ret= -2*(ret<0); goto failure;}
return(1);
failure:
libdax_audioxtr_destroy(xtr,0);
return(ret);
}
int libdax_audioxtr_destroy(struct libdax_audioxtr **xtr, int flag)
{
struct libdax_audioxtr *o;
o= *xtr;
if(o==NULL)
return(0);
if(o->fd>=0 && strcmp(o->path,"-")!=0)
close(o->fd);
free((char *) o);
*xtr= NULL;
return(1);
}
static int libdax_audioxtr_open(struct libdax_audioxtr *o, int flag)
{
int ret;
char msg[LIBDAX_AUDIOXTR_STRLEN+80];
if(strcmp(o->path,"-")==0)
o->fd= 0;
else
o->fd= open(o->path, O_RDONLY | O_BINARY);
if(o->fd<0) {
sprintf(msg,"Cannot open audio source file : %s",o->path);
libdax_msgs_submit(libdax_messenger,-1,0x00020200,
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
msg, errno, 0);
return(-1);
}
ret= libdax_audioxtr_identify(o,0);
if(ret<=0) {
sprintf(msg,"Audio source file has unsuitable format : %s",o->path);
libdax_msgs_submit(libdax_messenger,-1,0x00020201,
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
msg, 0, 0);
return(0);
}
ret= libdax_audioxtr_init_reading(o,0);
if(ret<=0) {
sprintf(msg,"Failed to prepare reading of audio data : %s",o->path);
libdax_msgs_submit(libdax_messenger,-1,0x00020202,
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
msg, 0, 0);
return(0);
}
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, 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/
https://en.wikipedia.org/wiki/WAV
see summary in: doc/waveformat.txt
*/
ubuf= (unsigned char *) buf;
/* 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);
}
/* Read RIFF Format header */
ret= read(o->fd, buf, 4);
if(ret < 4)
return(0);
old_pos+= 4;
if(strncmp(buf, "WAVE", 4) != 0) /* Format */
return(0);
riff_end= pos;
/* 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);
}
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 */
/* info used: http://ccrma.stanford.edu/courses/422/projects/WaveFormat/ */
if(o->fd!=0) {
ret= lseek(o->fd,0,SEEK_SET);
if(ret==-1)
return(0);
}
ret= read(o->fd, buf, 24);
if(ret<24)
return(0);
if(strncmp(buf,".snd",4)!=0)
return(0);
strcpy(o->fmt,".au");
o->msb_first= 1;
o->au_data_location= libdax_audioxtr_to_int(o,(unsigned char *)buf+4,4,1);
o->au_data_size= libdax_audioxtr_to_int(o,(unsigned char *)buf+8,4,1);
encoding= libdax_audioxtr_to_int(o,(unsigned char *)buf+12,4,1);
if(encoding==2)
o->bits_per_sample= 8;
else if(encoding==3)
o->bits_per_sample= 16;
else if(encoding==4)
o->bits_per_sample= 24;
else if(encoding==5)
o->bits_per_sample= 32;
else
o->bits_per_sample= -encoding;
o->sample_rate= libdax_audioxtr_to_int(o,(unsigned char *)buf+16,4,1);
o->num_channels= libdax_audioxtr_to_int(o,(unsigned char *)buf+20,4,1);
if(o->au_data_size!=0xffffffff)
o->data_size= o->au_data_size;
else
o->data_size= 0;
sprintf(o->fmt_info,
".au , num_channels=%d , sample_rate=%d , bits_per_sample=%d",
o->num_channels,o->sample_rate,o->bits_per_sample);
return(o->bits_per_sample>0); /* Audio format must be linear PCM */
}
static int libdax_audioxtr_identify(struct libdax_audioxtr *o, int flag)
{
int ret;
ret= libdax_audioxtr_identify_wav(o, 0);
if(ret!=0)
return(ret);
if(o->fd==0) /* cannot rewind stdin */
return(0);
ret= libdax_audioxtr_identify_au(o, 0);
if(ret!=0)
return(ret);
return(0);
}
/* @param flag bit0=msb_first */
static unsigned libdax_audioxtr_to_int(struct libdax_audioxtr *o,
unsigned char *bytes, int len, int flag)
{
unsigned int ret= 0;
int i;
if(flag&1)
for(i= 0; i<len; i++)
ret= ret*256+bytes[i];
else
for(i= len-1; i>=0; i--)
ret= ret*256+bytes[i];
return(ret);
}
static int libdax_audioxtr_init_reading(struct libdax_audioxtr *o, int flag)
{
int ret;
/* currently this only works for MS WAVE files .wav and Sun .au*/;
if(o->fd==0) /* stdin: hope no read came after libdax_audioxtr_identify() */
return(1);
o->extract_count= 0;
if(strcmp(o->fmt,".wav")==0)
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
ret= -1;
if(ret==-1)
return(0);
return(1);
}
int libdax_audioxtr_get_id(struct libdax_audioxtr *o,
char **fmt, char **fmt_info,
int *num_channels, int *sample_rate, int *bits_per_sample,
int *msb_first, int flag)
{
*fmt= o->fmt;
*fmt_info= o->fmt_info;
*num_channels= o->num_channels;
*sample_rate= o->sample_rate;
*bits_per_sample= o->bits_per_sample;
*msb_first= o->msb_first;
return(1);
}
int libdax_audioxtr_get_size(struct libdax_audioxtr *o, off_t *size, int flag)
{
*size= o->data_size;
return(1);
}
int libdax_audioxtr_read(struct libdax_audioxtr *o,
char buffer[], int buffer_size, int flag)
{
int ret;
if(buffer_size<=0 || o->fd<0)
return(-2);
if(o->data_size>0 && !(flag&1))
if(buffer_size > o->data_size - o->extract_count)
buffer_size= o->data_size - o->extract_count;
if(buffer_size<=0)
return(0);
ret= read(o->fd,buffer,buffer_size);
if(ret>0)
o->extract_count+= ret;
return(ret);
}
int libdax_audioxtr_detach_fd(struct libdax_audioxtr *o, int *fd, int flag)
{
if(o->fd<0)
return(-1);
if(strcmp(o->fmt,".wav")!=0 && strcmp(o->fmt,".au")!=0)
return(0);
if(flag&1) {
*fd= o->fd;
} else {
*fd= dup(o->fd);
if(*fd>=0 && strcmp(o->path,"-")!=0)
close(o->fd);
}
if(*fd>=0) {
o->fd= -1;
return(1);
}
return(-1);
}

240
libburn/libdax_audioxtr.h Normal file
View File

@ -0,0 +1,240 @@
/* libdax_audioxtr
Audio track data extraction facility of libdax and libburn.
Copyright (C) 2006 Thomas Schmitt <scdbackup@gmx.net>, provided under GPLv2+
*/
#ifndef LIBDAX_AUDIOXTR_H_INCLUDED
#define LIBDAX_AUDIOXTR_H_INCLUDED 1
/* Normally this public API is defined in <libburn/libburn.h>
Macro LIBDAX_AUDIOXTR_H_PUBLIC enables the definition for programs
which only include this file.
*/
#ifdef LIBDAX_AUDIOXTR_H_PUBLIC
/* Public Macros */
/* Maximum size for address paths and fmt_info strings */
#define LIBDAX_AUDIOXTR_STRLEN 4096
/* Public Opaque Handles */
/** Extractor object encapsulating intermediate states of extraction.
The clients of libdax_audioxtr shall only allocate pointers to this
struct and get a storage object via libdax_audioxtr_new().
Appropriate initial value for the pointer is NULL.
*/
struct libdax_audioxtr;
/* Public Functions */
/* Calls initiated from inside libdax/libburn */
/* Calls from applications (to be forwarded by libdax/libburn) */
/** Open an audio file, check wether 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).
@param flag Bitfield for control purposes (unused yet, submit 0)
@return >0 success
0 unsuitable format
-1 severe error
-2 path not found
*/
int libdax_audioxtr_new(struct libdax_audioxtr **xtr, char *path, int flag);
/** Obtain identification parameters of opened audio source.
@param xtr Opaque handle to extractor
@param fmt Gets pointed to the audio file format id text: ".wav" , ".au"
@param fmt_info Gets pointed to a format info text telling parameters
@param num_channels e.g. 1=mono, 2=stereo, etc
@param sample_rate e.g. 11025, 44100
@param bits_per_sample e.g. 8= 8 bits per sample, 16= 16 bits ...
@param msb_first Byte order of samples: 0=Intel 1=Motorola
@param flag Bitfield for control purposes (unused yet, submit 0)
@return >0 success, <=0 failure
*/
int libdax_audioxtr_get_id(struct libdax_audioxtr *xtr,
char **fmt, char **fmt_info,
int *num_channels, int *sample_rate,
int *bits_per_sample, int *msb_first, int flag);
/** Obtain a prediction about the extracted size based on internal information
of the formatted file.
@param xtr 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
*/
int libdax_audioxtr_get_size(struct libdax_audioxtr *o, off_t *size, int flag);
/** Obtain next buffer full of extracted data in desired format (only raw audio
for now).
@param xtr Opaque handle to extractor
@param buffer Gets filled with extracted data
@param buffer_size Maximum number of bytes to be filled into buffer
@param flag Bitfield for control purposes
bit0= do not stop at predicted end of data
@return >0 number of valid buffer bytes,
0 End of file
-1 operating system reports error
-2 usage error by application
*/
int libdax_audioxtr_read(struct libdax_audioxtr *xtr,
char buffer[], int buffer_size, int flag);
/** Try to obtain a file descriptor which will deliver extracted data
to normal calls of read(2). This may fail because the format is
unsuitable for that, but ".wav" is ok. If this call succeeds the xtr
object will have forgotten its file descriptor and libdax_audioxtr_read()
will return a usage error. One may use *fd after libdax_audioxtr_destroy()
and will have to close it via close(2) when done with it.
@param xtr Opaque handle to extractor
@param fd Eventually 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
*/
int libdax_audioxtr_detach_fd(struct libdax_audioxtr *o, int *fd, int flag);
/** Clean up after extraction and destroy extractor object.
@param xtr Opaque handle to extractor, *xtr is allowed to be NULL,
*xtr is set to NULL by this function
@param flag Bitfield for control purposes (unused yet, submit 0)
@return 1 = destroyed object, 0 = was already destroyed
*/
int libdax_audioxtr_destroy(struct libdax_audioxtr **xtr, int flag);
#endif /* LIBDAX_AUDIOXTR_H_PUBLIC */
#ifdef LIBDAX_AUDIOXTR________________
-- place documentation text here ---
#endif /* LIBDAX_AUDIOXTR_________________ */
/*
*Never* set this macro outside libdax_audioxtr.c !
The entrails of this facility are not to be seen by
the other library components or the applications.
*/
#ifdef LIBDAX_AUDIOXTR_H_INTERNAL
/* Internal Structures */
/** Extractor object encapsulating intermediate states of extraction */
struct libdax_audioxtr {
/* Source of the encoded audio data */
char path[LIBDAX_AUDIOXTR_STRLEN];
/* File descriptor to path. Anything else than 0 must be lseek-able */
int fd;
/* Format identifier. E.g. ".wav" */
char fmt[80];
/* Format parameter info text */
char fmt_info[LIBDAX_AUDIOXTR_STRLEN];
/* 1= mono, 2= stereo, etc. */
int num_channels;
/* 8000, 44100, etc. */
int sample_rate;
/* 8 bits = 8, 16 bits = 16, etc. */
int bits_per_sample;
/* Byte order of samples: 0=Intel 1=Motorola */
int msb_first;
/* Number of bytes to extract (0= unknown/unlimited) */
off_t data_size;
/* Number of extracted data bytes */
off_t extract_count;
/* Format dependent parameters */
/* MS WAVE Format */
/* 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. */
unsigned wav_subchunk2_size;
/* Sun Audio, .au */
/* info used: http://www.opengroup.org/public/pubs/external/auformat.html */
/* Number of bytes in non-payload header part */
unsigned au_data_location;
/* Number of payload bytes or 0xffffffff */
unsigned au_data_size;
};
/* Internal Functions */
/** Open the audio source pointed to by .path and evaluate suitability.
@return -1 failure to open, 0 unsuitable format, 1 success
*/
static int libdax_audioxtr_open(struct libdax_audioxtr *o, int flag);
/** Identify format and evaluate suitability.
@return 0 unsuitable format, 1 format is suitable
*/
static int libdax_audioxtr_identify(struct libdax_audioxtr *o, int flag);
/** Specialized identifier for .wav */
static int libdax_audioxtr_identify_wav(struct libdax_audioxtr *o, int flag);
/** Specialized identifier for .au */
static int libdax_audioxtr_identify_au(struct libdax_audioxtr *o, int flag);
/** Convert a byte string into a number (currently only little endian)
@param flag Bitfield for control purposes
bit0=msb_first
@return The resulting number
*/
static unsigned libdax_audioxtr_to_int(struct libdax_audioxtr *o,
unsigned char *bytes, int len, int flag);
/** Prepare for reading of first buffer.
@return 0 error, 1 success
*/
static int libdax_audioxtr_init_reading(struct libdax_audioxtr *o, int flag);
#endif /* LIBDAX_AUDIOXTR_H_INTERNAL */
#endif /* ! LIBDAX_AUDIOXTR_H_INCLUDED */

449
libburn/libdax_msgs.c Normal file
View File

@ -0,0 +1,449 @@
/* libdax_msgs
Message handling facility of libdax.
Copyright (C) 2006 - 2016 Thomas Schmitt <scdbackup@gmx.net>,
provided under GPL version 2 or later.
*/
#ifdef HAVE_CONFIG_H
#include "../config.h"
#endif
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/time.h>
#include <pthread.h>
/* Only this single source module is entitled to do this */
#define LIBDAX_MSGS_H_INTERNAL 1
/* All participants in the messaging system must do this */
#include "libdax_msgs.h"
/* ----------------------------- libdax_msgs_item ------------------------- */
static int libdax_msgs_item_new(struct libdax_msgs_item **item,
struct libdax_msgs_item *link, int flag)
{
int ret;
struct libdax_msgs_item *o;
struct timeval tv;
(*item)= o=
(struct libdax_msgs_item *) calloc(1, sizeof(struct libdax_msgs_item));
if(o==NULL)
return(-1);
o->timestamp= 0.0;
ret= gettimeofday(&tv, NULL);
if(ret==0)
o->timestamp= tv.tv_sec+0.000001*tv.tv_usec;
o->process_id= getpid();
o->origin= -1;
o->severity= LIBDAX_MSGS_SEV_ALL;
o->priority= LIBDAX_MSGS_PRIO_ZERO;
o->error_code= 0;
o->msg_text= NULL;
o->os_errno= 0;
o->prev= link;
o->next= NULL;
if(link!=NULL) {
if(link->next!=NULL) {
link->next->prev= o;
o->next= link->next;
}
link->next= o;
}
return(1);
}
/** Detaches item from its queue and eventually readjusts start, end pointers
of the queue */
int libdax_msgs_item_unlink(struct libdax_msgs_item *o,
struct libdax_msgs_item **chain_start,
struct libdax_msgs_item **chain_end, int flag)
{
if(o->prev!=NULL)
o->prev->next= o->next;
if(o->next!=NULL)
o->next->prev= o->prev;
if(chain_start!=NULL)
if(*chain_start == o)
*chain_start= o->next;
if(chain_end!=NULL)
if(*chain_end == o)
*chain_end= o->prev;
o->next= o->prev= NULL;
return(1);
}
int libdax_msgs_item_destroy(struct libdax_msgs_item **item,
int flag)
{
struct libdax_msgs_item *o;
o= *item;
if(o==NULL)
return(0);
libdax_msgs_item_unlink(o,NULL,NULL,0);
if(o->msg_text!=NULL)
free((char *) o->msg_text);
free((char *) o);
*item= NULL;
return(1);
}
int libdax_msgs_item_get_msg(struct libdax_msgs_item *item,
int *error_code, char **msg_text, int *os_errno,
int flag)
{
*error_code= item->error_code;
*msg_text= item->msg_text;
*os_errno= item->os_errno;
return(1);
}
int libdax_msgs_item_get_origin(struct libdax_msgs_item *item,
double *timestamp, pid_t *process_id, int *origin,
int flag)
{
*timestamp= item->timestamp;
*process_id= item->process_id;
*origin= item->origin;
return(1);
}
int libdax_msgs_item_get_rank(struct libdax_msgs_item *item,
int *severity, int *priority, int flag)
{
*severity= item->severity;
*priority= item->priority;
return(1);
}
/* ------------------------------- libdax_msgs ---------------------------- */
int libdax_msgs_new(struct libdax_msgs **m, int flag)
{
struct libdax_msgs *o;
(*m)= o= (struct libdax_msgs *) calloc(1, sizeof(struct libdax_msgs));
if(o==NULL)
return(-1);
o->refcount= 1;
o->oldest= NULL;
o->youngest= NULL;
o->count= 0;
o->queue_severity= LIBDAX_MSGS_SEV_ALL;
o->print_severity= LIBDAX_MSGS_SEV_NEVER;
strcpy(o->print_id,"libdax: ");
#ifndef LIBDAX_MSGS_SINGLE_THREADED
pthread_mutex_init(&(o->lock_mutex),NULL);
#endif
return(1);
}
static int libdax_msgs_lock(struct libdax_msgs *m, int flag)
{
#ifndef LIBDAX_MSGS_SINGLE_THREADED
int ret;
ret= pthread_mutex_lock(&(m->lock_mutex));
if(ret!=0)
return(0);
#endif
return(1);
}
static int libdax_msgs_unlock(struct libdax_msgs *m, int flag)
{
#ifndef LIBDAX_MSGS_SINGLE_THREADED
int ret;
ret= pthread_mutex_unlock(&(m->lock_mutex));
if(ret!=0)
return(0);
#endif
return(1);
}
int libdax_msgs_destroy(struct libdax_msgs **m, int flag)
{
struct libdax_msgs *o;
struct libdax_msgs_item *item, *next_item;
o= *m;
if(o==NULL)
return(0);
if(o->refcount > 1) {
if(libdax_msgs_lock(*m,0)<=0)
return(-1);
o->refcount--;
libdax_msgs_unlock(*m,0);
*m= NULL;
return(1);
}
#ifndef LIBDAX_MSGS_SINGLE_THREADED
if(pthread_mutex_destroy(&(o->lock_mutex))!=0) {
pthread_mutex_unlock(&(o->lock_mutex));
pthread_mutex_destroy(&(o->lock_mutex));
}
#endif
for(item= o->oldest; item!=NULL; item= next_item) {
next_item= item->next;
libdax_msgs_item_destroy(&item,0);
}
free((char *) o);
*m= NULL;
return(1);
}
int libdax_msgs_refer(struct libdax_msgs **pt, struct libdax_msgs *m, int flag)
{
if(libdax_msgs_lock(m,0)<=0)
return(0);
m->refcount++;
*pt= m;
libdax_msgs_unlock(m,0);
return(1);
}
int libdax_msgs_set_severities(struct libdax_msgs *m, int queue_severity,
int print_severity, char *print_id, int flag)
{
if(libdax_msgs_lock(m,0)<=0)
return(0);
m->queue_severity= queue_severity;
m->print_severity= print_severity;
strncpy(m->print_id,print_id,80);
m->print_id[80]= 0;
libdax_msgs_unlock(m,0);
return(1);
}
int libdax_msgs__text_to_sev(char *severity_name, int *severity,
int flag)
{
if(strncmp(severity_name,"NEVER",5)==0)
*severity= LIBDAX_MSGS_SEV_NEVER;
else if(strncmp(severity_name,"ABORT",5)==0)
*severity= LIBDAX_MSGS_SEV_ABORT;
else if(strncmp(severity_name,"FATAL",5)==0)
*severity= LIBDAX_MSGS_SEV_FATAL;
else if(strncmp(severity_name,"FAILURE",7)==0)
*severity= LIBDAX_MSGS_SEV_FAILURE;
else if(strncmp(severity_name,"MISHAP",6)==0)
*severity= LIBDAX_MSGS_SEV_MISHAP;
else if(strncmp(severity_name,"SORRY",5)==0)
*severity= LIBDAX_MSGS_SEV_SORRY;
else if(strncmp(severity_name,"WARNING",7)==0)
*severity= LIBDAX_MSGS_SEV_WARNING;
else if(strncmp(severity_name,"HINT",4)==0)
*severity= LIBDAX_MSGS_SEV_HINT;
else if(strncmp(severity_name,"NOTE",4)==0)
*severity= LIBDAX_MSGS_SEV_NOTE;
else if(strncmp(severity_name,"UPDATE",6)==0)
*severity= LIBDAX_MSGS_SEV_UPDATE;
else if(strncmp(severity_name,"DEBUG",5)==0)
*severity= LIBDAX_MSGS_SEV_DEBUG;
else if(strncmp(severity_name,"ERRFILE",7)==0)
*severity= LIBDAX_MSGS_SEV_ERRFILE;
else if(strncmp(severity_name,"ALL",3)==0)
*severity= LIBDAX_MSGS_SEV_ALL;
else {
*severity= LIBDAX_MSGS_SEV_ALL;
return(0);
}
return(1);
}
int libdax_msgs__sev_to_text(int severity, char **severity_name,
int flag)
{
if(flag&1) {
*severity_name= "ALL ERRFILE DEBUG UPDATE NOTE HINT WARNING SORRY MISHAP FAILURE FATAL ABORT NEVER";
return(1);
}
*severity_name= "";
if(severity>=LIBDAX_MSGS_SEV_NEVER)
*severity_name= "NEVER";
else if(severity>=LIBDAX_MSGS_SEV_ABORT)
*severity_name= "ABORT";
else if(severity>=LIBDAX_MSGS_SEV_FATAL)
*severity_name= "FATAL";
else if(severity>=LIBDAX_MSGS_SEV_FAILURE)
*severity_name= "FAILURE";
else if(severity>=LIBDAX_MSGS_SEV_MISHAP)
*severity_name= "MISHAP";
else if(severity>=LIBDAX_MSGS_SEV_SORRY)
*severity_name= "SORRY";
else if(severity>=LIBDAX_MSGS_SEV_WARNING)
*severity_name= "WARNING";
else if(severity>=LIBDAX_MSGS_SEV_HINT)
*severity_name= "HINT";
else if(severity>=LIBDAX_MSGS_SEV_NOTE)
*severity_name= "NOTE";
else if(severity>=LIBDAX_MSGS_SEV_UPDATE)
*severity_name= "UPDATE";
else if(severity>=LIBDAX_MSGS_SEV_DEBUG)
*severity_name= "DEBUG";
else if(severity>=LIBDAX_MSGS_SEV_ERRFILE)
*severity_name= "ERRFILE";
else if(severity>=LIBDAX_MSGS_SEV_ALL)
*severity_name= "ALL";
else {
*severity_name= "";
return(0);
}
return(1);
}
/*
@param flag Bitfield for control purposes
bit0= If direct output to stderr:
CarriageReturn rather than LineFeed
*/
int libdax_msgs_submit(struct libdax_msgs *m, int origin, int error_code,
int severity, int priority, char *msg_text,
int os_errno, int flag)
{
int ret;
char *textpt,*sev_name,sev_text[81];
struct libdax_msgs_item *item= NULL;
if(severity >= m->print_severity) {
if(msg_text==NULL)
textpt= "";
else
textpt= msg_text;
sev_text[0]= 0;
ret= libdax_msgs__sev_to_text(severity,&sev_name,0);
if(ret>0)
sprintf(sev_text,"%s : ",sev_name);
fprintf(stderr, "%s%s%s%c", m->print_id, sev_text, textpt,
(flag & 1) ? '\r' : '\n');
if(os_errno!=0) {
ret= libdax_msgs_lock(m,0);
if(ret<=0)
return(-1);
fprintf(stderr,"%s( Most recent system error: %d '%s' )\n",
m->print_id,os_errno,strerror(os_errno));
libdax_msgs_unlock(m,0);
}
}
if(severity < m->queue_severity)
return(0);
ret= libdax_msgs_lock(m,0);
if(ret<=0)
return(-1);
ret= libdax_msgs_item_new(&item,m->youngest,0);
if(ret<=0)
goto failed;
item->origin= origin;
item->error_code= error_code;
item->severity= severity;
item->priority= priority;
if(msg_text!=NULL) {
item->msg_text= calloc(1, strlen(msg_text)+1);
if(item->msg_text==NULL)
goto failed;
strcpy(item->msg_text,msg_text);
}
item->os_errno= os_errno;
if(m->oldest==NULL)
m->oldest= item;
m->youngest= item;
m->count++;
libdax_msgs_unlock(m,0);
/*
fprintf(stderr,"libdax_experimental: message submitted to queue (now %d)\n",
m->count);
*/
return(1);
failed:;
libdax_msgs_item_destroy(&item,0);
libdax_msgs_unlock(m,0);
return(-1);
}
int libdax_msgs_obtain(struct libdax_msgs *m, struct libdax_msgs_item **item,
int severity, int priority, int flag)
{
int ret;
struct libdax_msgs_item *im, *next_im= NULL;
*item= NULL;
ret= libdax_msgs_lock(m,0);
if(ret<=0)
return(-1);
for(im= m->oldest; im!=NULL; im= next_im) {
for(; im!=NULL; im= next_im) {
next_im= im->next;
if(im->severity>=severity)
break;
libdax_msgs_item_unlink(im,&(m->oldest),&(m->youngest),0);
libdax_msgs_item_destroy(&im,0); /* severity too low: delete */
}
if(im==NULL)
break;
if(im->priority>=priority)
break;
}
if(im==NULL)
{ret= 0; goto ex;}
libdax_msgs_item_unlink(im,&(m->oldest),&(m->youngest),0);
*item= im;
ret= 1;
ex:;
libdax_msgs_unlock(m,0);
return(ret);
}
int libdax_msgs_destroy_item(struct libdax_msgs *m,
struct libdax_msgs_item **item, int flag)
{
int ret;
ret= libdax_msgs_lock(m,0);
if(ret<=0)
return(-1);
ret= libdax_msgs_item_destroy(item,0);
libdax_msgs_unlock(m,0);
return(ret);
}

775
libburn/libdax_msgs.h Normal file
View File

@ -0,0 +1,775 @@
/* libdax_msgs
Message handling facility of libburn and libisofs.
Copyright (C) 2006-2016 Thomas Schmitt <scdbackup@gmx.net>,
provided under GPL version 2 or later.
*/
/*
*Never* set this macro outside libdax_msgs.c !
The entrails of the message handling facility are not to be seen by
the other library components or the applications.
*/
#ifdef LIBDAX_MSGS_H_INTERNAL
#ifndef LIBDAX_MSGS_SINGLE_THREADED
#include <pthread.h>
#endif
struct libdax_msgs_item {
double timestamp;
pid_t process_id;
int origin;
int severity;
int priority;
/* Apply for your developer's error code range at
libburn-hackers@pykix.org
Report introduced codes in the list below. */
int error_code;
char *msg_text;
int os_errno;
struct libdax_msgs_item *prev,*next;
};
struct libdax_msgs {
int refcount;
struct libdax_msgs_item *oldest;
struct libdax_msgs_item *youngest;
int count;
int queue_severity;
int print_severity;
char print_id[81];
#ifndef LIBDAX_MSGS_SINGLE_THREADED
pthread_mutex_t lock_mutex;
#endif
};
#endif /* LIBDAX_MSGS_H_INTERNAL */
#ifndef LIBDAX_MSGS_H_INCLUDED
#define LIBDAX_MSGS_H_INCLUDED 1
#ifndef LIBDAX_MSGS_H_INTERNAL
/* Architectural aspects */
/*
libdax_msgs is designed to serve in libraries which want to offer their
applications a way to control the output of library messages. It shall be
incorporated by an owner, i.e. a software entity which encloses the code
of the .c file.
Owner of libdax_msgs is libburn. A fully compatible variant named libiso_msgs
is owned by libisofs and can get generated by a script of the libburn
project: libburn/libdax_msgs_to_xyz_msgs.sh .
Reason: One cannot link two owners of the same variant together because
both would offer the same functions to the linker. For that situation one
has to create a compatible variant as it is done for libisofs.
Compatible variants may get plugged together by call combinations like
burn_set_messenger(iso_get_messenger());
A new variant would demand a _set_messenger() function if it has to work
with libisofs. If only libburn is planned as link partner then a simple
_get_messenger() does suffice.
Take care to shutdown libburn before its provider of the *_msgs object
gets shut down.
*/
/* Public Opaque Handles */
/** A pointer to this is a opaque handle to a message handling facility */
struct libdax_msgs;
/** A pointer to this is a opaque handle to a single message item */
struct libdax_msgs_item;
#endif /* ! LIBDAX_MSGS_H_INTERNAL */
/* Public Macros */
/* Registered Severities */
/* It is well advisable to let applications select severities via strings and
forwarded functions libdax_msgs__text_to_sev(), libdax_msgs__sev_to_text().
These macros are for use by the owner of libdax_msgs.
*/
/** Use this to get messages of any severity. Do not use for submitting.
*/
#define LIBDAX_MSGS_SEV_ALL 0x00000000
/** Messages of this severity shall transport plain disk file paths
whenever an event of severity SORRY or above is related with an
individual disk file.
No message text shall be added to the file path. The ERRFILE message
shall be issued before the human readable message which carries the
true event severity. That message should contain the file path so it
can be found by strstr(message, path)!=NULL.
The error code shall be the same as with the human readable message.
*/
#define LIBDAX_MSGS_SEV_ERRFILE 0x08000000
/** Debugging messages not to be visible to normal users by default
*/
#define LIBDAX_MSGS_SEV_DEBUG 0x10000000
/** Update of a progress report about long running actions
*/
#define LIBDAX_MSGS_SEV_UPDATE 0x20000000
/** Not so usual events which were gracefully handled
*/
#define LIBDAX_MSGS_SEV_NOTE 0x30000000
/** Possibilities to achieve a better result
*/
#define LIBDAX_MSGS_SEV_HINT 0x40000000
/** Warnings about problems which could not be handled optimally
*/
#define LIBDAX_MSGS_SEV_WARNING 0x50000000
/** Non-fatal error messages indicating that parts of an action failed but
processing may go on if one accepts deviations from the desired result.
SORRY may also be the severity for incidents which are severe enough
for FAILURE but happen within already started irrevocable actions,
like ISO image generation. A precondition for such a severity ease is
that the action can be continued after the incident.
See below MISHAP for what xorriso would need instead of this kind of SORRY
and generates for itself in case of libisofs image generation.
E.g.: A pattern yields no result.
A speed setting cannot be made.
A libisofs input file is inaccessible during image generation.
After SORRY a function should try to go on if that makes any sense
and if no threshold prescribes abort on SORRY. The function should
nevertheless indicate some failure in its return value.
It should - but it does not have to.
*/
#define LIBDAX_MSGS_SEV_SORRY 0x60000000
/** A FAILURE (see below) which can be tolerated during long lasting
operations just because they cannot simply be stopped or revoked.
xorriso converts libisofs SORRY messages issued during image generation
into MISHAP messages in order to allow its evaluators to distinguish
image generation problems from minor image composition problems.
E.g.:
A libisofs input file is inaccessible during image generation.
After a MISHAP a function should behave like after SORRY.
*/
#define LIBDAX_MSGS_SEV_MISHAP 0x64000000
/** Non-fatal error indicating that an important part of an action failed and
that only a new setup of preconditions will give hope for sufficient
success.
E.g.: No media is inserted in the output drive.
No write mode can be found for inserted media.
A libisofs input file is inaccessible during grafting.
After FAILURE a function should end with a return value indicating failure.
It is at the discretion of the function whether it ends immediately in any
case or whether it tries to go on if the eventual threshold allows.
*/
#define LIBDAX_MSGS_SEV_FAILURE 0x68000000
/** An error message which puts the whole operation of the program in question
E.g.: Not enough memory for essential temporary objects.
Irregular errors from resources.
Programming errors (soft assert).
After FATAL a function should end very soon with a return value
indicating severe failure.
*/
#define LIBDAX_MSGS_SEV_FATAL 0x70000000
/** A message from an abort handler which will finally finish libburn
*/
#define LIBDAX_MSGS_SEV_ABORT 0x71000000
/** A severity to exclude resp. discard any possible message.
Do not use this severity for submitting.
*/
#define LIBDAX_MSGS_SEV_NEVER 0x7fffffff
/* Registered Priorities */
/* Priorities are to be selected by the programmers and not by the user. */
#define LIBDAX_MSGS_PRIO_ZERO 0x00000000
#define LIBDAX_MSGS_PRIO_LOW 0x10000000
#define LIBDAX_MSGS_PRIO_MEDIUM 0x20000000
#define LIBDAX_MSGS_PRIO_HIGH 0x30000000
#define LIBDAX_MSGS_PRIO_TOP 0x7ffffffe
/* Do not use this priority for submitting */
#define LIBDAX_MSGS_PRIO_NEVER 0x7fffffff
/* Origin numbers of libburn drives may range from 0 to 1048575 */
#define LIBDAX_MSGS_ORIGIN_DRIVE_BASE 0
#define LIBDAX_MSGS_ORIGIN_DRIVE_TOP 0xfffff
/* Origin numbers of libisofs images may range from 1048575 to 2097152 */
#define LIBDAX_MSGS_ORIGIN_IMAGE_BASE 0x100000
#define LIBDAX_MSGS_ORIGIN_IMAGE_TOP 0x1fffff
/* Public Functions */
/* Calls initiated from inside the direct owner (e.g. from libburn) */
/** Create new empty message handling facility with queue and issue a first
official reference to it.
@param flag Bitfield for control purposes (unused yet, submit 0)
@return >0 success, <=0 failure
*/
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 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)
@return 1 for success, 0 for pointer to NULL, -1 for fatal error
*/
int libdax_msgs_destroy(struct libdax_msgs **m, int flag);
/** Create an official reference to an existing libdax_msgs object. The
references keep the object alive at least until it is released by
a matching number of destroy calls. So each reference MUST be revoked
by exactly one call to libdax_msgs_destroy().
@param pt The pointer to be set and registered
@param m A pointer to the existing object
@param flag Bitfield for control purposes (unused yet, submit 0)
@return 1 for success, 0 for failure
*/
int libdax_msgs_refer(struct libdax_msgs **pt, struct libdax_msgs *o, int flag);
/** Submit a message to a message handling facility.
@param origin program specific identification number of the originator of
a message. E.g. drive number. Programs should have an own
range of origin numbers. See above LIBDAX_MSGS_ORIGIN_*_BASE
Use -1 if no number is known.
@param error_code Unique error code. Use only registered codes. See below.
The same unique error_code may be issued at different
occasions but those should be equivalent out of the view
of a libdax_msgs application. (E.g. "cannot open ATA drive"
versus "cannot open SCSI drive" would be equivalent.)
@param severity The LIBDAX_MSGS_SEV_* of the event.
@param priority The LIBDAX_MSGS_PRIO_* number of the event.
@param msg_text Printable and human readable message text.
@param os_errno Eventual error code from operating system (0 if none)
@param flag Bitfield for control purposes
bit0= If direct output to stderr:
CarriageReturn rather than LineFeed
@return 1 on success, 0 on rejection, <0 for severe errors
*/
int libdax_msgs_submit(struct libdax_msgs *m, int origin, int error_code,
int severity, int priority, char *msg_text,
int os_errno, int flag);
/* Calls from applications (to be forwarded by direct owner) */
/** Convert a registered severity number into a severity name
@param flag Bitfield for control purposes:
bit0= list all severity names in a blank separated string
@return >0 success, <=0 failure
*/
int libdax_msgs__sev_to_text(int severity, char **severity_name,
int flag);
/** Convert a severity name into a severity number,
@param flag Bitfield for control purposes (unused yet, submit 0)
@return >0 success, <=0 failure
*/
int libdax_msgs__text_to_sev(char *severity_name, int *severity,
int flag);
/** Set minimum severity for messages to be queued (default
LIBDAX_MSGS_SEV_ALL) and for messages to be printed directly to stderr
(default LIBDAX_MSGS_SEV_NEVER).
@param print_id A text of at most 80 characters to be printed before
any eventually printed message (default is "libdax: ").
@param flag Bitfield for control purposes (unused yet, submit 0)
@return always 1 for now
*/
int libdax_msgs_set_severities(struct libdax_msgs *m, int queue_severity,
int print_severity, char *print_id, int flag);
/** Obtain a message item that has at least the given severity and priority.
Usually all older messages of lower severity are discarded then. If no
item of sufficient severity was found, all others are discarded from the
queue.
@param flag Bitfield for control purposes (unused yet, submit 0)
@return 1 if a matching item was found, 0 if not, <0 for severe errors
*/
int libdax_msgs_obtain(struct libdax_msgs *m, struct libdax_msgs_item **item,
int severity, int priority, int flag);
/** Destroy a message item obtained by libdax_msgs_obtain(). The submitted
pointer gets set to NULL.
Caution: Copy eventually obtained msg_text before destroying the item,
if you want to use it further.
@param flag Bitfield for control purposes (unused yet, submit 0)
@return 1 for success, 0 for pointer to NULL, <0 for severe errors
*/
int libdax_msgs_destroy_item(struct libdax_msgs *m,
struct libdax_msgs_item **item, int flag);
/** Obtain from a message item the three application oriented components as
submitted with the originating call of libdax_msgs_submit().
Caution: msg_text becomes a pointer into item, not a copy.
@param flag Bitfield for control purposes (unused yet, submit 0)
@return 1 on success, 0 on invalid item, <0 for servere errors
*/
int libdax_msgs_item_get_msg(struct libdax_msgs_item *item,
int *error_code, char **msg_text, int *os_errno,
int flag);
/** Obtain from a message item the submitter identification submitted
with the originating call of libdax_msgs_submit().
@param flag Bitfield for control purposes (unused yet, submit 0)
@return 1 on success, 0 on invalid item, <0 for servere errors
*/
int libdax_msgs_item_get_origin(struct libdax_msgs_item *item,
double *timestamp, pid_t *process_id, int *origin,
int flag);
/** Obtain from a message item severity and priority as submitted
with the originating call of libdax_msgs_submit().
@param flag Bitfield for control purposes (unused yet, submit 0)
@return 1 on success, 0 on invalid item, <0 for servere errors
*/
int libdax_msgs_item_get_rank(struct libdax_msgs_item *item,
int *severity, int *priority, int flag);
#ifdef LIBDAX_MSGS_________________
/* Registered Error Codes */
Format: error_code (LIBDAX_MSGS_SEV_*,LIBDAX_MSGS_PRIO_*) = explanation
If no severity or priority are fixely associated, use "(,)".
------------------------------------------------------------------------------
Range "libdax_msgs" : 0x00000000 to 0x0000ffff
0x00000000 (ALL,ZERO) = Initial setting in new libdax_msgs_item
0x00000001 (DEBUG,ZERO) = Test error message
0x00000002 (DEBUG,ZERO) = Debugging message
0x00000003 (FATAL,HIGH) = Out of virtual memory
0x00000004 (FATAL,HIGH) = Generic fatal error
------------------------------------------------------------------------------
Range "elmom" : 0x00010000 to 0x0001ffff
------------------------------------------------------------------------------
Range "scdbackup" : 0x00020000 to 0x0002ffff
Acessing and defending drives:
0x00020001 (SORRY,LOW) = Cannot open busy device
0x00020002 (SORRY,HIGH) = Encountered error when closing drive
0x00020003 (SORRY,HIGH) = Could not grab drive
0x00020004 (NOTE,HIGH) = Opened O_EXCL scsi sibling
0x00020005 (SORRY,HIGH) = Failed to open device
0x00020006 (FATAL,HIGH) = Too many scsi siblings
0x00020007 (NOTE,HIGH) = Closed O_EXCL scsi siblings
0x00020008 (SORRY,HIGH) = Device busy. Failed to fcntl-lock
0x00020009 (SORRY,HIGH) = Neither stdio-path nor its directory exist
0x0002000a (FAILURE,HIGH) = Cannot accept '...' as SG_IO CDROM drive
0x0002000b (FAILURE,HIGH) = File object '...' not found
0x0002000c (FAILURE,HIGH) = Cannot start device file enumeration
0x0002000d (FAILURE,HIGH) = Cannot enumerate next device
0x0002000e (NOTE,HIGH) = Failed to open device during
General library operations:
0x00020101 (WARNING,HIGH) = Cannot find given worker item
0x00020102 (SORRY,HIGH) = A drive operation is still going on
0x00020103 (WARNING,HIGH) = After scan a drive operation is still going on
0x00020104 (SORRY,HIGH) = NULL pointer caught
0x00020105 (SORRY,HIGH) = Drive is already released
0x00020106 (SORRY,HIGH) = Drive is busy on attempt to close
0x00020107 (WARNING,HIGH) = A drive is still busy on shutdown of library
0x00020108 (SORRY,HIGH) = Drive is not grabbed on disc status inquiry
0x00020108 (FATAL,HIGH) = Could not allocate new drive object
0x00020109 (FATAL,HIGH) = Library not running
0x0002010a (FATAL,HIGH) = Unsuitable track mode
0x0002010b (FATAL,HIGH) = Burn run failed
0x0002010c (FATAL,HIGH) = Failed to transfer command to drive
0x0002010d (DEBUG,HIGH) = Could not inquire TOC
0x0002010e (FATAL,HIGH) = Attempt to read ATIP from ungrabbed drive
0x0002010f (DEBUG,HIGH) = SCSI error condition on command
0x00020110 (FATAL,HIGH) = Persistent drive address too long
0x00020111 (FATAL,HIGH) = Could not allocate new auxiliary object
0x00020112 (SORRY,HIGH) = Bad combination of write_type and block_type
0x00020113 (FATAL,HIGH) = Drive capabilities not inquired yet
0x00020114 (SORRY,HIGH) = Attempt to set ISRC with bad data
0x00020115 (SORRY,HIGH) = Attempt to set track mode to unusable value
0x00020116 (FATAL,HIGH) = Track mode has unusable value
0x00020117 (FATAL,HIGH) = toc_entry of drive is already in use
0x00020118 (DEBUG,HIGH) = Closing track
0x00020119 (DEBUG,HIGH) = Closing session
0x0002011a (NOTE,HIGH) = Padding up track to minimum size
0x0002011b (FATAL,HIGH) = Attempt to read track info from ungrabbed drive
0x0002011c (FATAL,HIGH) = Attempt to read track info from busy drive
0x0002011d (FATAL,HIGH) = SCSI error on write
0x0002011e (SORRY,HIGH) = Unsuitable media detected
0x0002011f (SORRY,HIGH) = Burning is restricted to a single track
0x00020120 (NOTE,HIGH) = FORMAT UNIT ignored
0x00020121 (FATAL,HIGH) = Write preparation setup failed
0x00020122 (FAILURE,HIGH) = SCSI error on format_unit
0x00020123 (SORRY,HIGH) = DVD Media are unsuitable for desired track type
0x00020124 (SORRY,HIGH) = SCSI error on set_streaming
0x00020125 (SORRY,HIGH) = Write start address not supported
0x00020126 (SORRY,HIGH) = Write start address not properly aligned
0x00020127 (NOTE,HIGH) = Write start address is ...
0x00020128 (FATAL,HIGH) = Unsupported inquiry_type with mmc_get_performance
0x00020129 (SORRY,HIGH) = Will not format media type
0x0002012a (FATAL,HIGH) = Cannot inquire write mode capabilities
0x0002012b (FATAL,HIGH) = Drive offers no suitable write mode with this job
0x0002012c (SORRY,HIGH) = Too many logical tracks recorded
0x0002012d (FATAL,HIGH) = Exceeding range of permissible write addresses
0x0002012e (NOTE,HIGH) = Activated track default size
0x0002012f (SORRY,HIGH) = SAO is restricted to single fixed size session
0x00020130 (SORRY,HIGH) = Drive and media state unsuitable for blanking
0x00020131 (SORRY,HIGH) = No suitable formatting type offered by drive
0x00020132 (SORRY,HIGH) = Selected format is not suitable for libburn
0x00020133 (SORRY,HIGH) = Cannot mix data and audio in SAO mode
0x00020134 (NOTE,HIGH) = Defaulted TAO to DAO
0x00020135 (SORRY,HIGH) = Cannot perform TAO, job unsuitable for DAO
0x00020136 (SORRY,HIGH) = DAO burning restricted to single fixed size track
0x00020137 (HINT,HIGH) = TAO would be possible
0x00020138 (FATAL,HIGH) = Cannot reserve track
0x00020139 (SORRY,HIGH) = Write job parameters are unsuitable
0x0002013a (FATAL,HIGH) = No suitable media detected
0x0002013b (DEBUG,HIGH) = SCSI command indicates host or driver error
0x0002013c (SORRY,HIGH) = Malformed capabilities page 2Ah received
0x0002013d (DEBUG,LOW) = Waiting for free buffer space takes long time
0x0002013e (SORRY,HIGH) = Timeout with waiting for free buffer. Now disabled
0x0002013f (DEBUG,LOW) = Reporting total time spent with waiting for buffer
0x00020140 (FATAL,HIGH) = Drive is busy on attempt to write random access
0x00020141 (SORRY,HIGH) = Write data count not properly aligned
0x00020142 (FATAL,HIGH) = Drive is not grabbed on random access write
0x00020143 (SORRY,HIGH) = Read start address not properly aligned
0x00020144 (SORRY,HIGH) = SCSI error on read
0x00020145 (FATAL,HIGH) = Drive is busy on attempt to read data
0x00020146 (FATAL,HIGH) = Drive is a virtual placeholder
0x00020147 (SORRY,HIGH) = Cannot address start byte
0x00020148 (SORRY,HIGH) = Cannot write desired amount of data
0x00020149 (SORRY,HIGH) = Unsuitable filetype for pseudo-drive
0x0002014a (SORRY,HIGH) = Cannot read desired amount of data
0x0002014b (SORRY,HIGH) = Drive is already registered resp. scanned
0x0002014c (FATAL,HIGH) = Emulated drive caught in SCSI function
0x0002014d (SORRY,HIGH) = Asynchronous SCSI error
0x0002014f (SORRY,HIGH) = Timeout with asynchronous SCSI command
0x00020150 (DEBUG,LOW) = Reporting asynchronous waiting time
0x00020151 (FAILURE,HIGH) = Read attempt on write-only drive
0x00020152 (FATAL,HIGH) = Cannot start fifo thread
0x00020153 (SORRY,HIGH) = Read error on fifo input
0x00020154 (NOTE,HIGH) = Forwarded input error ends output
0x00020155 (SORRY,HIGH) = Desired fifo buffer too large
0x00020156 (SORRY,HIGH) = Desired fifo buffer too small
0x00020157 (FATAL,HIGH) = burn_source is not a fifo object
0x00020158 (DEBUG,LOW) = Reporting thread disposal precautions
0x00020159 (DEBUG,HIGH) = TOC Format 0 returns inconsistent data
0x0002015a (NOTE,HIGH) = Could not examine busy device
0x0002015b (HINT,HIGH) = Busy '...' seems to be a hard disk, as '...1' exists
0x0002015c (FAILURE,HIGH) = Fifo size too small for desired peek buffer
0x0002015d (FAILURE,HIGH) = Fifo input ended short of desired peek buffer size
0x0002015e (FATAL,HIGH) = Fifo is already under consumption when peeking
0x0002015f (MISHAP,HIGH) = Damaged CD table-of-content detected and truncated
0x00020160 (WARNING,HIGH) = Session without leadout encountered
0x00020161 (WARNING,HIGH) = Empty session deleted
0x00020162 (SORRY,HIGH) = BD-R not unformatted blank any more. Cannot format
0x00020163 (NOTE,HIGH) = Blank BD-R left unformatted for zero spare capacity
0x00020164 (SORRY,HIGH) = Drive does not format BD-RE without spares
0x00020165 (WARNING,HIGH) = Drive does not support fast formatting
0x00020166 (WARNING,HIGH) = Drive does not support full formatting
0x00020167 (SORRY,HIGH) = Drive does not support non-default formatting
0x00020168 (FAILURE,HIGH) = Media not properly formatted. Cannot write.
0x00020169 (WARNING,HIGH) = Last session on media is still open
0x0002016a (FAILURE,HIGH) = No MMC transport adapter is present
0x0002016b (WARNING,HIGH) = No MMC transport adapter is present
0x0002016c (DEBUG,HIGH) = No MMC transport adapter is present
0x0002016e (DEBUG,HIGH) = MODE SENSE page 2A too short
0x0002016f (DEBUG,HIGH) = Unable to grab scanned drive
0x00020170 (NOTE,HIGH) = Closing open session before writing new one
0x00020171 (NOTE,HIGH) = Closing BD-R with accidentaly open session
0x00020172 (SORRY,HIGH) = Read start address larger than number of readable blocks
0x00020173 (FAILURE,HIGH) = Drive tells NWA smaller than last written address
0x00020174 (SORRY,HIGH) = Fifo alignment does not allow desired read size
0x00020175 (FATAL,HIGH) = Supporting library is too old
0x00020176 (NOTE,HIGH) = Stream recording disabled because of small OS buffer
0x00020177 (ABORT,HIGH) = Urged drive worker threads to do emergency halt
0x00020178 (DEBUG,HIGH) = Write thread ended
0x00020179 (FAILURE,HIGH) = Offset source start address is before end of previous source
0x0002017a (FAILURE,HIGH) = Expected offset source object as parameter
0x0002017b (WARNING,HIGH) = Sequential BD-R media likely to soon fail writing
0x0002017c (FAILURE,HIGH) = No valid write type selected
0x0002017d (FATAL,HIGH) = Invalid file descriptor with stdio pseudo-drive
0x0002017e (FAILURE,HIGH) = Failed to close track, session, or disc
0x0002017f (FAILURE,HIGH) = Failed to synchronize drive cache
0x00020180 (FAILURE,HIGH) = Premature end of input encountered
0x00020181 (FAILURE,HIGH) = Pseudo-drive is a read-only file. Cannot write.
0x00020182 (FAILURE,HIGH) = Cannot truncate disk file for pseudo blanking
0x00020183 (WARNING,HIGH) = Failed to open device (a pseudo-drive) for reading
0x00020184 (WARNING,HIGH) = No Next-Writable-Address
0x00020185 (WARNING,HIGH) = Track damaged, not closed and not writable
0x00020186 (WARNING,HIGH) = Track damaged and not closed
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.
0x0002018b (FAILURE,HIGH) = Too many CD-TEXT packs
0x0002018c (FAILURE,HIGH) = CD-TEXT pack type out of range
0x0002018d (FAILURE,HIGH) = CD-TEXT block number out of range
0x0002018e (FAILURE,HIGH) = Too many CD-TEXT packs in block
0x0002018f (FAILURE,HIGH) = CD-TEXT pack CRC mismatch
0x00020190 (WARNING,HIGH) = CD-TEXT pack CRC mismatch had to be corrected
0x00020191 (FAILURE,HIGH) = Unknown parameter in text input file
0x00020192 (FAILURE,HIGH) = Text input file sequence error
0x00020193 (FAILURE,HIGH) = Text input file readability problem
0x00020194 (FAILURE,HIGH) = Text input file syntax error or specs violation
0x00020195 (WARNING,HIGH) = Text input file warning
0x00020196 (FAILURE,HIGH) = Session has already defined tracks
0x00020197 (FAILURE,HIGH) = Unsupported text input file feature
0x00020198 (FAILURE,HIGH) = CD-TEXT pack file readability problem
0x00020199 (SORRY,HIGH) = Text input file reading aborted
0x0002019a (SORRY,HIGH) = Bad track index number
0x0002019b (SORRY,HIGH) = CD track number exceeds range of 1 to 99
0x0002019c (SORRY,HIGH) = Session has no defined tracks
0x0002019d (SORRY,HIGH) = Audio read size not properly aligned
0x0002019e (NOTE,HIGH) = Drive does not support media certification
0x0002019f (FAILURE,HIGH) = CD-TEXT binary pack array faulty
0x000201a0 (WARNING,HIGH) = Maximum number of CD-TEXT blocks exceeded
0x000201a1 (FAILURE,HIGH) = Cannot open disk file for writing
0x000201a2 (FAILURE,HIGH) = Error while writing to disk file
0x000201a3 (UPDATE,HIGH) = Progress message of burn_drive_extract_audio()
0x000201a4 (FAILURE,HIGH) = Failure to read audio sectors
0x000201a5 (FAILURE,HIGH) = Asynchronous SCSI error
0x000201a6 (FATAL,HIGH) = Lost connection to drive
0x000201a7 (FAILURE,HIGH) = SCSI command yielded host problem
0x000201a8 (FAILURE,HIGH) = SCSI command yielded driver problem
0x000201a9 (FAILURE,HIGH) = Implausible length from GET CONFIGURATION
0x000201aa (FAILURE,HIGH) = No CD-TEXT packs in file
0x000201ab (WARN,HIGH) = Leaving burn_source_fifo object undisposed
0x000201ac (NOTE,HIGH) = Drive currently does not offer Stream Recording
0x000201ad (NOTE,HIGH) = WRITE commands have been repeated
libdax_audioxtr:
0x00020200 (SORRY,HIGH) = Cannot open audio source file
0x00020201 (SORRY,HIGH) = Audio source file has unsuitable format
0x00020202 (SORRY,HIGH) = Failed to prepare reading of audio data
------------------------------------------------------------------------------
Range "vreixo" : 0x00030000 to 0x0003ffff
0x0003ffff (FAILURE,HIGH) = Operation canceled
0x0003fffe (FATAL,HIGH) = Unknown or unexpected fatal error
0x0003fffd (FAILURE,HIGH) = Unknown or unexpected error
0x0003fffc (FATAL,HIGH) = Internal programming error
0x0003fffb (FAILURE,HIGH) = NULL pointer where NULL not allowed
0x0003fffa (FATAL,HIGH) = Memory allocation error
0x0003fff9 (FATAL,HIGH) = Interrupted by a signal
0x0003fff8 (FAILURE,HIGH) = Invalid parameter value
0x0003fff7 (FATAL,HIGH) = Cannot create a needed thread
0x0003fff6 (FAILURE,HIGH) = Write error
0x0003fff5 (FAILURE,HIGH) = Buffer read error
0x0003ffc0 (FAILURE,HIGH) = Trying to add a node already added to another dir
0x0003ffbf (FAILURE,HIGH) = Node with same name already exist
0x0003ffbe (FAILURE,HIGH) = Trying to remove a node that was not added to dir
0x0003ffbd (FAILURE,HIGH) = A requested node does not exist
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
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
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
0x0003ff77 (FAILURE,HIGH) = Not symlink used where a symlink is expected
0x0003ff76 (FAILURE,HIGH) = Cannot seek to specified location
0x0003ff75 (HINT,MEDIUM) = File not supported in ECMA-119 tree and ignored
0x0003ff74 (HINT,MEDIUM) = File bigger than supported by used standard
0x0003ff73 (MISHAP,HIGH) = File read error during image creation
0x0003ff72 (HINT,MEDIUM) = Cannot convert filename to requested charset
0x0003ff71 (SORRY,HIGH) = File cannot be added to the tree
0x0003ff70 (HINT,MEDIUM) = File path breaks specification constraints
0x0003ff00 (FAILURE,HIGH) = Charset conversion error
0x0003feff (FAILURE,HIGH) = Too much files to mangle
0x0003fec0 (FAILURE,HIGH) = Wrong or damaged Primary Volume Descriptor
0x0003febf (SORRY,HIGH) = Wrong or damaged RR entry
0x0003febe (SORRY,HIGH) = Unsupported RR feature
0x0003febd (FAILURE,HIGH) = Wrong or damaged ECMA-119
0x0003febc (FAILURE,HIGH) = Unsupported ECMA-119 feature
0x0003febb (SORRY,HIGH) = Wrong or damaged El-Torito catalog
0x0003feba (SORRY,HIGH) = Unsupported El-Torito feature
0x0003feb9 (SORRY,HIGH) = Cannot patch isolinux boot image
0x0003feb8 (SORRY,HIGH) = Unsupported SUSP feature
0x0003feb7 (WARNING,HIGH) = Error on a RR entry that can be ignored
0x0003feb6 (HINT,MEDIUM) = Error on a RR entry that can be ignored
0x0003feb5 (WARNING,HIGH) = Multiple ER SUSP entries found
0x0003feb4 (HINT,MEDIUM) = Unsupported volume descriptor found
0x0003feb3 (WARNING,HIGH) = El-Torito related warning
0x0003feb2 (MISHAP,HIGH) = Image write cancelled
0x0003feb1 (WARNING,HIGH) = El-Torito image is hidden
Outdated codes which may not be re-used for other purposes than
re-instating them, if ever:
X 0x00031001 (SORRY,HIGH) = Cannot read file (ignored)
X 0x00031002 (FATAL,HIGH) = Cannot read file (operation canceled)
X 0x00031000 (FATAL,HIGH) = Unsupported ISO-9660 image
X 0x00031001 (HINT,MEDIUM) = Unsupported Vol Desc that will be ignored
X 0x00031002 (FATAL,HIGH) = Damaged ISO-9660 image
X 0x00031003 (SORRY,HIGH) = Cannot read previous image file
X 0x00030101 (HINT,MEDIUM) = Unsupported SUSP entry that will be ignored
X 0x00030102 (SORRY,HIGH) = Wrong/damaged SUSP entry
X 0x00030103 (WARNING,MEDIUM)= Multiple SUSP ER entries where found
X 0x00030111 (SORRY,HIGH) = Unsupported RR feature
X 0x00030112 (SORRY,HIGH) = Error in a Rock Ridge entry
X 0x00030201 (HINT,MEDIUM) = Unsupported Boot Vol Desc that will be ignored
X 0x00030202 (SORRY,HIGH) = Wrong El-Torito catalog
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 0x00030301 (NOTE,MEDIUM) = Unsupported file type for Joliet tree
------------------------------------------------------------------------------
Range "application" : 0x00040000 to 0x0004ffff
0x00040000 (ABORT,HIGH) : Application supplied message
0x00040001 (FATAL,HIGH) : Application supplied message
0x00040002 (SORRY,HIGH) : Application supplied message
0x00040003 (WARNING,HIGH) : Application supplied message
0x00040004 (HINT,HIGH) : Application supplied message
0x00040005 (NOTE,HIGH) : Application supplied message
0x00040006 (UPDATE,HIGH) : Application supplied message
0x00040007 (DEBUG,HIGH) : Application supplied message
0x00040008 (*,HIGH) : Application supplied message
------------------------------------------------------------------------------
Range "libisofs-xorriso" : 0x00050000 to 0x0005ffff
This is an alternative representation of libisofs.so.6 error codes in xorriso.
If values returned by iso_error_get_code() do not fit into 0x30000 to 0x3ffff
then they get truncated to 16 bit and mapped into this range.
(This should never need to happen, of course.)
------------------------------------------------------------------------------
Range "libisoburn" : 0x00060000 to 0x00006ffff
0x00060000 (*,*) : Message which shall be attributed to libisoburn
>>> the messages of libisoburn need to be registered individually
------------------------------------------------------------------------------
#endif /* LIBDAX_MSGS_________________ */
#ifdef LIBDAX_MSGS_H_INTERNAL
/* Internal Functions */
/** Lock before doing side effect operations on m */
static int libdax_msgs_lock(struct libdax_msgs *m, int flag);
/** Unlock after effect operations on m are done */
static int libdax_msgs_unlock(struct libdax_msgs *m, int flag);
/** Create new empty message item.
@param link Previous item in queue
@param flag Bitfield for control purposes (unused yet, submit 0)
@return >0 success, <=0 failure
*/
static int libdax_msgs_item_new(struct libdax_msgs_item **item,
struct libdax_msgs_item *link, int flag);
/** Destroy a message item obtained by libdax_msgs_obtain(). The submitted
pointer gets set to NULL.
@param flag Bitfield for control purposes (unused yet, submit 0)
@return 1 for success, 0 for pointer to NULL
*/
static int libdax_msgs_item_destroy(struct libdax_msgs_item **item, int flag);
#endif /* LIBDAX_MSGS_H_INTERNAL */
#endif /* ! LIBDAX_MSGS_H_INCLUDED */

View File

@ -0,0 +1,37 @@
#!/bin/sh
# libdax_msgs_to_iso_msgs.sh
# generates ${xyz}_msgs.[ch] from libdax_msgs.[ch]
# To be executed within ./libburn-* resp ./cdrskin-*
# The module name for the generated sourcecode in several
# uppercase-lowercase forms
xyz="libiso"
Xyz="Libiso"
XYZ="LIBISO"
# The project name for which the generated code shall serve
project="libisofs"
for i in libburn/libdax_msgs.[ch]
do
target_adr=$(echo "$i" | sed -e "s/libdax_/${xyz}_/")
echo "$target_adr"
sed \
-e "s/^\/\* libdax_msgs/\/* ${xyz}_msgs (generated from XYZ_msgs : $(date))/" \
-e "s/Message handling facility of libdax/Message handling facility of ${project}/" \
-e "s/libdax_/${xyz}_/g" \
-e "s/libdax:/${xyz}:/g" \
-e "s/Libdax_/${Xyz}_/g" \
-e "s/LIBDAX_/${XYZ}_/g" \
-e "s/generated from XYZ_msgs/generated from libdax_msgs/" \
-e "s/${xyz}_msgs is designed to serve in libraries/libdax_msgs is designed to serve in libraries/" \
-e "s/Owner of ${xyz}_msgs is libburn/Owner of libdax_msgs is libburn/" \
\
<"$i" >"$target_adr"
done

5931
libburn/mmc.c Normal file

File diff suppressed because it is too large Load Diff

147
libburn/mmc.h Normal file
View File

@ -0,0 +1,147 @@
/* -*- 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>
Provided under GPL version 2 or later.
*/
#ifndef __MMC
#define __MMC
struct burn_drive;
struct burn_write_opts;
struct command;
struct buffer;
struct cue_sheet;
/* MMC commands */
void mmc_read(struct burn_drive *);
/* ts A61009 : removed redundant parameter d in favor of o->drive */
/* void mmc_close_session(struct burn_drive *, struct burn_write_opts *); */
/* void mmc_close_disc(struct burn_drive *, struct burn_write_opts *); */
void mmc_close_session(struct burn_write_opts *o);
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);
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 *);
void mmc_eject(struct burn_drive *);
void mmc_erase(struct burn_drive *, int);
void mmc_read_toc(struct burn_drive *);
void mmc_read_disc_info(struct burn_drive *);
void mmc_read_atip(struct burn_drive *);
int mmc_read_cd(struct burn_drive *d, int start, int len,
int sec_type, int main_ch,
const struct burn_read_opts *o, struct buffer *buf, int flag);
void mmc_set_speed(struct burn_drive *, int, int);
void mmc_read_lead_in(struct burn_drive *, struct buffer *);
void mmc_perform_opc(struct burn_drive *);
void mmc_get_configuration(struct burn_drive *);
/* ts A61110 : added parameters trackno, lba, nwa. Redefined return value.
@return 1=nwa is valid , 0=nwa is not valid , -1=error */
int mmc_get_nwa(struct burn_drive *d, int trackno, int *lba, int *nwa);
/* ts B11228 : changed from void to int */
int mmc_send_cue_sheet(struct burn_drive *, struct cue_sheet *);
/* ts A61023 : get size and free space of drive buffer */
int mmc_read_buffer_capacity(struct burn_drive *d);
/* ts A61021 : the mmc specific part of sg.c:enumerate_common()
*/
int mmc_setup_drive(struct burn_drive *d);
/* ts A61219 : learned much from dvd+rw-tools-7.0: plus_rw_format()
and mmc5r03c.pdf, 6.5 FORMAT UNIT */
int mmc_format_unit(struct burn_drive *d, off_t size, int flag);
/* ts A61225 : obtain write speed descriptors via ACh GET PERFORMANCE */
int mmc_get_write_performance(struct burn_drive *d);
/* ts A61229 : outsourced from spc_select_write_params() */
/* Note: Page data is not zeroed here to allow preset defaults. Thus
memset(pd, 0, 2 + d->mdata->write_page_length);
is the eventual duty of the caller.
*/
int mmc_compose_mode_page_5(struct burn_drive *d,
struct burn_session *s, int tno,
const struct burn_write_opts *o,
unsigned char *pd);
/* ts A70201 */
int mmc_four_char_to_int(unsigned char *data);
/* ts A70201 :
Common track info fetcher for mmc_get_nwa() and mmc_fake_toc()
*/
int mmc_read_track_info(struct burn_drive *d, int trackno, struct buffer *buf,
int alloc_len);
/* ts A70812 : return 0 = ok , return BE_CANCELLED = error occurred */
int mmc_read_10(struct burn_drive *d, int start, int amount,
struct buffer *buf);
/* ts A81210 : Determine the upper limit of readable data size */
int mmc_read_capacity(struct burn_drive *d);
/* ts A61201 */
char *mmc_obtain_profile_name(int profile_number);
/* mmc5r03c.pdf 4.3.4.4.1 d) "The maximum number of RZones is 2 302." */
#define BURN_MMC_FAKE_TOC_MAX_SIZE 2302
/* ts A90903 */
/* MMC backend of API call burn_get_media_product_id()
*/
int mmc_get_media_product_id(struct burn_drive *d,
char **product_id, char **media_code1, char **media_code2,
char **book_type, int flag);
/* ts A60910 (estimated) */
int mmc_function_spy(struct burn_drive *d, char * text);
/* ts A91118 */
int mmc_start_if_needed(struct burn_drive *d, int flag);
/* ts B00924 */
int mmc_get_bd_spare_info(struct burn_drive *d,
int *alloc_blocks, int *free_blocks, int flag);
/* ts B10801 */
int mmc_get_phys_format_info(struct burn_drive *d, int *disk_category,
char **book_name, int *part_version, int *num_layers,
int *num_blocks, int flag);
/* ts B11201 */
int mmc_get_leadin_text(struct burn_drive *d,
unsigned char **text_packs, int *num_packs, int flag);
/* ts B40107 */
int mmc_get_performance(struct burn_drive *d, int descr_type, int flag);
/* ts B90414 */
int burn_make_feature_text(struct burn_drive *d, unsigned int feature_code,
unsigned char flags,
unsigned char additional_length,
unsigned char *feature_data,
char **text, int flag);
#ifdef Libburn_develop_quality_scaN
/* B21108 ts */
int mmc_nec_optiarc_f3(struct burn_drive *d, int sub_op,
int start_lba, int rate_period,
int *eba, int *error_rate1, int *error_rate2);
#endif
#endif /*__MMC*/

40
libburn/null.c Normal file
View File

@ -0,0 +1,40 @@
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
Provided under GPL version 2 or later.
*/
#ifdef HAVE_CONFIG_H
#include "../config.h"
#endif
#include "null.h"
#include "libburn.h"
#include <stdlib.h>
#include <string.h>
int null_read(struct burn_source *source, unsigned char *buffer, int size)
{
memset(buffer, 0, size);
return size;
}
struct burn_source *burn_null_source_new(void)
{
struct burn_source *src;
src = calloc(1, sizeof(struct burn_source));
src->refcount = 1;
src->read = null_read;
src->read_sub = NULL;
src->get_size = 0;
/* ts A70126 */
src->set_size = NULL;
src->free_data = NULL;
src->data = NULL;
return src;
}

10
libburn/null.h Normal file
View File

@ -0,0 +1,10 @@
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
#ifndef BURN__NULL_H
#define BURN__NULL_H
struct burn_source;
int null_read(struct burn_source *source, unsigned char *buffer, int size);
struct burn_source *burn_null_source_new(void);
#endif /* LIBBURN__NULL_H */

605
libburn/options.c Normal file
View File

@ -0,0 +1,605 @@
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
Copyright (c) 2006 - 2017 Thomas Schmitt <scdbackup@gmx.net>
Provided under GPL version 2 or later.
*/
#ifdef HAVE_CONFIG_H
#include "../config.h"
#endif
#include "libburn.h"
#include "options.h"
#include "drive.h"
#include "transport.h"
#include "init.h"
#include "write.h"
/* ts A61007 */
/* #include <a ssert.h> */
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "libdax_msgs.h"
extern struct libdax_msgs *libdax_messenger;
struct burn_write_opts *burn_write_opts_new(struct burn_drive *drive)
{
struct burn_write_opts *opts;
opts = calloc(1, sizeof(struct burn_write_opts));
if (opts == NULL) {
libdax_msgs_submit(libdax_messenger, -1, 0x00020111,
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
"Could not allocate new auxiliary object", 0, 0);
return NULL;
}
opts->drive = drive;
opts->refcount = 1;
opts->write_type = BURN_WRITE_TAO;
opts->block_type = BURN_BLOCK_MODE1;
opts->toc_entry = NULL;
opts->toc_entries = 0;
opts->simulate = 0;
opts->underrun_proof = drive->mdata->p2a_valid > 0 &&
drive->mdata->underrun_proof;
opts->perform_opc = 1;
opts->obs = -1;
#ifdef Libburn_dvd_always_obs_paD
opts->obs_pad = 1;
#else
opts->obs_pad = 0;
#endif
opts->start_byte = -1;
opts->fill_up_media = 0;
opts->force_is_set = 0;
opts->do_stream_recording = 0;
opts->dvd_obs_override = 0;
opts->stdio_fsync_size = Libburn_stdio_fsync_limiT;
opts->text_packs = NULL;
opts->num_text_packs = 0;
opts->no_text_pack_crc_check = 0;
opts->has_mediacatalog = 0;
opts->format = BURN_CDROM;
opts->multi = 0;
opts->control = 0;
return opts;
}
void burn_write_opts_free(struct burn_write_opts *opts)
{
if (--opts->refcount > 0)
return;
if (opts->text_packs != NULL)
free(opts->text_packs);
free(opts);
}
int burn_write_opts_clone(struct burn_write_opts *from,
struct burn_write_opts **to, int flag)
{
if (*to != NULL)
burn_write_opts_free(*to);
if (from == NULL)
return 1;
*to = calloc(1, sizeof(struct burn_write_opts));
if (*to == NULL) {
out_of_mem:;
libdax_msgs_submit(libdax_messenger, -1, 0x00000003,
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
"Out of virtual memory", 0, 0);
return -1;
}
memcpy(*to, from, sizeof(struct burn_write_opts));
(*to)->text_packs = NULL;
(*to)->num_text_packs = 0;
if (from->text_packs != NULL && from->num_text_packs > 0) {
(*to)->text_packs = calloc(1, from->num_text_packs * 18);
if ((*to)->text_packs == NULL)
goto out_of_mem;
memcpy((*to)->text_packs, from->text_packs,
from->num_text_packs * 18);
}
(*to)->refcount= 1;
return 1;
}
struct burn_read_opts *burn_read_opts_new(struct burn_drive *drive)
{
struct burn_read_opts *opts;
opts = calloc(1, sizeof(struct burn_read_opts));
opts->drive = drive;
opts->refcount = 1;
opts->raw = 0;
opts->c2errors = 0;
opts->subcodes_audio = 0;
opts->subcodes_data = 0;
opts->hardware_error_recovery = 0;
opts->report_recovered_errors = 0;
opts->transfer_damaged_blocks = 0;
opts->hardware_error_retries = 3;
opts->dap_bit = 0;
return opts;
}
void burn_read_opts_free(struct burn_read_opts *opts)
{
if (--opts->refcount <= 0)
free(opts);
}
int burn_write_opts_set_write_type(struct burn_write_opts *opts,
enum burn_write_types write_type,
int block_type)
{
int sector_get_outmode(enum burn_write_types write_type,
enum burn_block_types block_type);
int spc_block_type(enum burn_block_types b);
/* ts A61007 */
if (! ( (write_type == BURN_WRITE_SAO && block_type == BURN_BLOCK_SAO)
|| (opts->drive->block_types[write_type] & block_type) ) ) {
bad_combination:;
libdax_msgs_submit(libdax_messenger, -1, 0x00020112,
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
"Bad combination of write_type and block_type", 0, 0);
return 0;
}
/* ts A61007 : obsoleting Assert in sector.c:get_outmode() */
if (sector_get_outmode(write_type, (enum burn_block_types) block_type)
== -1)
goto bad_combination;
/* ts A61007 : obsoleting Assert in spc.c:spc_block_type() */
if (spc_block_type((enum burn_block_types) block_type) == -1)
goto bad_combination;
opts->write_type = write_type;
opts->block_type = block_type;
return 1;
/* a ssert(0); */
}
void burn_write_opts_set_toc_entries(struct burn_write_opts *opts, int count,
struct burn_toc_entry *toc_entries)
{
opts->toc_entries = count;
opts->toc_entry = calloc(count, sizeof(struct burn_toc_entry));
memcpy(opts->toc_entry, &toc_entries,
sizeof(struct burn_toc_entry) * count);
}
void burn_write_opts_set_format(struct burn_write_opts *opts, int format)
{
opts->format = format;
}
int burn_write_opts_set_simulate(struct burn_write_opts *opts, int sim)
{
opts->simulate = !!sim;
return 1;
}
int burn_write_opts_set_underrun_proof(struct burn_write_opts *opts,
int underrun_proof)
{
if (opts->drive->mdata->p2a_valid <= 0 ||
opts->drive->mdata->underrun_proof) {
opts->underrun_proof = underrun_proof;
return 1;
}
return 0;
}
void burn_write_opts_set_perform_opc(struct burn_write_opts *opts, int opc)
{
opts->perform_opc = opc;
}
void burn_write_opts_set_has_mediacatalog(struct burn_write_opts *opts,
int has_mediacatalog)
{
opts->has_mediacatalog = has_mediacatalog;
}
void burn_write_opts_set_mediacatalog(struct burn_write_opts *opts,
unsigned char mediacatalog[13])
{
memcpy(opts->mediacatalog, mediacatalog, 13);
}
/* ts A61106 */
void burn_write_opts_set_multi(struct burn_write_opts *opts, int multi)
{
opts->multi = !!multi;
}
/* ts B31024 */
/* API */
void burn_write_opts_set_fail21h_sev(struct burn_write_opts *opts,
char *severity)
{
int ret, sevno;
ret = libdax_msgs__text_to_sev(severity, &sevno, 0);
if (ret <= 0)
opts->feat21h_fail_sev = 0;
else
opts->feat21h_fail_sev = sevno;
}
/* ts B11204 */
/* @param flag bit0=do not verify checksums
bit1= repair mismatching checksums
bit2= repair checksums if they are 00 00 with each pack
*/
int burn_write_opts_set_leadin_text(struct burn_write_opts *opts,
unsigned char *text_packs,
int num_packs, int flag)
{
int ret;
unsigned char *pack_buffer = NULL;
if (num_packs > Libburn_leadin_cdtext_packs_maX ) {
libdax_msgs_submit(libdax_messenger, opts->drive->global_index,
0x0002018b,
LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH,
"Too many CD-TEXT packs", 0, 0);
ret= 0; goto ex;
}
if (num_packs > 0)
BURN_ALLOC_MEM(pack_buffer, unsigned char, num_packs * 18);
if (opts->text_packs != NULL) {
free(opts->text_packs);
opts->text_packs = NULL;
}
if (flag & 1) {
opts->no_text_pack_crc_check = 1;
} else {
opts->no_text_pack_crc_check = 0;
ret = burn_cdtext_crc_mismatches(text_packs, num_packs,
(flag >> 1) & 3);
if (ret > 0) {
libdax_msgs_submit(libdax_messenger, -1, 0x0002018f,
LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH,
"CD-TEXT pack CRC mismatch", 0, 0);
ret = 0; goto ex;
} else if (ret < 0) {
libdax_msgs_submit(libdax_messenger, -1, 0x00020190,
LIBDAX_MSGS_SEV_WARNING, LIBDAX_MSGS_PRIO_HIGH,
"CD-TEXT pack CRC mismatch had to be corrected",
0, 0);
}
}
if (num_packs > 0) {
memcpy(pack_buffer, text_packs, num_packs * 18);
opts->text_packs = pack_buffer;
pack_buffer = NULL;
}
opts->num_text_packs = num_packs;
ret = 1;
ex:;
BURN_FREE_MEM(pack_buffer);
return ret;
}
/* ts A61222 */
void burn_write_opts_set_start_byte(struct burn_write_opts *opts, off_t value)
{
opts->start_byte = value;
}
/* ts A70207 API */
/** @param flag Bitfield for control purposes:
bit0= do not choose type but check the one that is already set
bit1= do not issue error messages via burn_msgs queue
*/
enum burn_write_types burn_write_opts_auto_write_type(
struct burn_write_opts *opts, struct burn_disc *disc,
char reasons[BURN_REASONS_LEN], int flag)
{
struct burn_multi_caps *caps = NULL;
struct burn_drive *d = opts->drive;
struct burn_disc_mode_demands demands;
enum burn_write_types wt;
int ret, would_do_sao = 0;
char *reason_pt;
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)
strcat(reasons, "MEDIA: closed or not recordable, ");
else
strcat(reasons,"MEDIA: no writeable media detected, ");
if (!(flag & 3))
libdax_msgs_submit(libdax_messenger, d->global_index,
0x0002013a,
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
"No suitable media detected", 0, 0);
return BURN_WRITE_NONE;
}
ret = burn_disc_get_write_mode_demands(disc, opts, &demands,
!!opts->fill_up_media);
if (ret <= 0) {
strcat(reasons, "cannot recognize job demands, ");
{wt = BURN_WRITE_NONE; goto ex;}
}
if (demands.exotic_track && !d->current_is_cd_profile) {
if (demands.audio)
strcat(reasons, "audio track prohibited by non-CD, ");
else
strcat(reasons, "exotic track prohibited by non-CD, ");
{wt = BURN_WRITE_NONE; goto ex;}
}
if ((flag & 1) && opts->write_type != BURN_WRITE_SAO)
goto try_tao;
reason_pt = reasons + strlen(reasons);
strcat(reasons, "SAO: ");
if (d->status != BURN_DISC_BLANK) {
strcat(reasons, "write type SAO works only on blank media, ");
goto try_tao;
}
burn_disc_free_multi_caps(&caps);
ret = burn_disc_get_multi_caps(d, BURN_WRITE_SAO, &caps, 0);
if (ret < 0) {
no_caps:;
strcat(reasons, "cannot inquire write mode capabilities, ");
{wt = BURN_WRITE_NONE; goto ex;}
} else if (ret == 0) {
strcat(reasons, "no SAO offered by drive and media, ");
goto no_sao;
}
if ((opts->multi || demands.multi_session) &&
!caps->multi_session)
strcat(reasons, "multi session capability lacking, ");
if (demands.will_append)
strcat(reasons, "appended session capability lacking, ");
if (demands.multi_track && !caps->multi_track)
strcat(reasons, "multi track capability lacking, ");
if (demands.unknown_track_size == 1 &&
(caps->might_do_sao == 1 || caps->might_do_sao == 3))
strcat(reasons, "track size unpredictable, ");
if (demands.mixed_mode)
strcat(reasons, "tracks of different modes mixed, ");
if (demands.exotic_track && !d->current_is_cd_profile)
strcat(reasons, "non-data track on non-cd, ");
else if (d->current_is_cd_profile)
if ((d->block_types[BURN_WRITE_TAO] & demands.block_types) !=
demands.block_types)
strcat(reasons, "drive dislikes block type, ");
if (d->current_is_cd_profile && opts->fill_up_media)
strcat(reasons, "cd sao cannot do media fill up yet, ");
if (strcmp(reason_pt, "SAO: ") != 0)
goto no_sao;
would_do_sao = 1;
if (demands.unknown_track_size == 2 && (!(flag & 1)) &&
(caps->might_do_sao == 1 || caps->might_do_sao == 3)) {
strcat(reasons, "would have to use default track sizes, ");
goto no_sao;
} else if (caps->might_do_sao >= 3 && !(flag & 1))
goto try_tao;
do_sao:;
if (caps->might_simulate == 0 && opts->simulate && !opts->force_is_set)
goto no_simulate;
if (!(flag & 1))
burn_write_opts_set_write_type(
opts, BURN_WRITE_SAO, BURN_BLOCK_SAO);
{wt = BURN_WRITE_SAO; goto ex;}
no_sao:;
try_tao:;
if (opts->num_text_packs > 0) {
strcat(reasons, "CD-TEXT: write type SAO required, ");
{wt = BURN_WRITE_NONE; goto ex;}
}
if ((flag & 1) && opts->write_type != BURN_WRITE_TAO)
goto try_raw;
reason_pt = reasons + strlen(reasons);
strcat(reasons, "TAO: ");
burn_disc_free_multi_caps(&caps);
ret = burn_disc_get_multi_caps(d, BURN_WRITE_TAO, &caps, 0);
if (ret < 0)
goto no_caps;
if (ret == 0) {
strcat(reasons, "no TAO offered by drive and media, ");
goto no_tao;
}
if ((opts->multi || demands.multi_session) && !caps->multi_session)
strcat(reasons, "multi session capability lacking, ");
if (demands.multi_track && !caps->multi_track)
strcat(reasons, "multi track capability lacking, ");
if (demands.exotic_track && !d->current_is_cd_profile)
strcat(reasons, "non-data track on non-cd, ");
if (d->current_is_cd_profile && !opts->force_is_set)
if ((d->block_types[BURN_WRITE_TAO] & demands.block_types) !=
demands.block_types)
strcat(reasons, "drive dislikes block type, ");
if (strcmp(reason_pt, "TAO: ") != 0)
goto no_tao;
/* ( TAO data/audio block size will be handled automatically ) */
if (caps->might_simulate == 0 && opts->simulate && !opts->force_is_set)
goto no_simulate;
if (!(flag & 1))
burn_write_opts_set_write_type(
opts, BURN_WRITE_TAO, BURN_BLOCK_MODE1);
{wt = BURN_WRITE_TAO; goto ex;}
no_tao:;
if (would_do_sao && !(flag & 1))
goto do_sao;
if (!d->current_is_cd_profile)
goto no_write_mode;
try_raw:;
if ((flag & 1) && opts->write_type != BURN_WRITE_RAW)
goto no_write_mode;
if (!(flag & 1)) /* For now: no automatic raw write modes */
goto no_write_mode;
reason_pt = reasons + strlen(reasons);
strcat(reasons, "RAW: ");
if (!d->current_is_cd_profile)
strcat(reasons, "write type RAW prohibited by non-cd, ");
else if (d->status != BURN_DISC_BLANK)
strcat(reasons, "write type RAW works only on blank media, ");
else if ((d->block_types[BURN_WRITE_TAO] & demands.block_types) !=
demands.block_types)
strcat(reasons, "drive dislikes block type, ");
if (strcmp(reason_pt, "RAW: ") != 0)
goto no_write_mode;
if (!opts->force_is_set)
goto no_simulate;
/* For now: no setting of raw write modes */
{wt = BURN_WRITE_RAW; goto ex;}
no_write_mode:;
{wt = BURN_WRITE_NONE; goto ex;}
no_simulate:;
strcat(reasons,
"simulation of write job not supported by drive and media, ");
{wt = BURN_WRITE_NONE; goto ex;}
ex:;
burn_disc_free_multi_caps(&caps);
if (wt == BURN_WRITE_NONE && !(flag & 3)) {
libdax_msgs_submit(libdax_messenger, d->global_index,
0x0002012b,
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
"Drive offers no suitable write mode with this job",
0, 0);
}
return wt;
}
/* ts A70213 : new API function */
void burn_write_opts_set_fillup(struct burn_write_opts *opts,int fill_up_media)
{
opts->fill_up_media = !!fill_up_media;
return;
}
/* ts A70303: API */
void burn_write_opts_set_force(struct burn_write_opts *opts, int use_force)
{
opts->force_is_set = !!use_force;
}
/* ts A80412: API */
void burn_write_opts_set_stream_recording(struct burn_write_opts *opts,
int value)
{
opts->do_stream_recording = value;
}
/* ts A91115: API */
void burn_write_opts_set_dvd_obs(struct burn_write_opts *opts, int obs)
{
if (obs != 0 && obs != 32 * 1024 && obs != 64 * 1024)
return;
opts->dvd_obs_override = obs;
}
/* ts B20406: API */
void burn_write_opts_set_obs_pad(struct burn_write_opts *opts, int pad)
{
opts->obs_pad = 2 * !!pad;
}
/* ts A91115: API */
void burn_write_opts_set_stdio_fsync(struct burn_write_opts *opts, int rythm)
{
if (rythm == -1)
opts->stdio_fsync_size = -1; /* never */
else if (rythm == 0)
opts->stdio_fsync_size = Libburn_stdio_fsync_limiT;
else if (rythm == 1)
opts->stdio_fsync_size = 0; /* only at end of writing */
else if (rythm >= 32)
opts->stdio_fsync_size = rythm;
}
/* ts A70901: API */
struct burn_drive *burn_write_opts_get_drive(struct burn_write_opts *opts)
{
return opts->drive;
}
void burn_read_opts_set_raw(struct burn_read_opts *opts, int raw)
{
opts->raw = raw;
}
void burn_read_opts_set_c2errors(struct burn_read_opts *opts, int c2errors)
{
opts->c2errors = c2errors;
}
void burn_read_opts_read_subcodes_audio(struct burn_read_opts *opts,
int subcodes_audio)
{
opts->subcodes_audio = subcodes_audio;
}
void burn_read_opts_read_subcodes_data(struct burn_read_opts *opts,
int subcodes_data)
{
opts->subcodes_data = subcodes_data;
}
void burn_read_opts_set_hardware_error_recovery(struct burn_read_opts *opts,
int hardware_error_recovery)
{
opts->hardware_error_recovery = hardware_error_recovery;
}
void burn_read_opts_report_recovered_errors(struct burn_read_opts *opts,
int report_recovered_errors)
{
opts->report_recovered_errors = report_recovered_errors;
}
void burn_read_opts_transfer_damaged_blocks(struct burn_read_opts *opts,
int transfer_damaged_blocks)
{
opts->transfer_damaged_blocks = transfer_damaged_blocks;
}
void burn_read_opts_set_hardware_error_retries(struct burn_read_opts *opts,
unsigned char
hardware_error_retries)
{
opts->hardware_error_retries = hardware_error_retries;
}

157
libburn/options.h Normal file
View File

@ -0,0 +1,157 @@
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
Copyright (c) 2006 - 2013 Thomas Schmitt <scdbackup@gmx.net>
Provided under GPL version 2 or later.
*/
#ifndef BURN__OPTIONS_H
#define BURN__OPTIONS_H
#include "libburn.h"
/** Options for disc writing operations. This should be created with
burn_write_opts_new() and freed with burn_write_opts_free(). */
struct burn_write_opts
{
/** Drive the write opts are good for */
struct burn_drive *drive;
/** For internal use. */
int refcount;
/** The method/style of writing to use. */
enum burn_write_types write_type;
/** format of the data to send to the drive */
enum burn_block_types block_type;
/** Number of toc entries. if this is 0, they will be auto generated*/
int toc_entries;
/** Toc entries for the disc */
struct burn_toc_entry *toc_entry;
/** Simulate the write so that the disc is not actually written */
unsigned int simulate:1;
/** If available, enable a drive feature which prevents buffer
underruns if not enough data is available to keep up with the
drive. */
unsigned int underrun_proof:1;
/** Perform calibration of the drive's laser before beginning the
write. */
unsigned int perform_opc:1;
/* ts A61219 : Output block size to trigger buffer flush if hit.
-1 with CD, 32 kB with DVD */
int obs;
int obs_pad; /* >0 pad up last block to obs, 0 do not
2 indicates burn_write_opts_set_obs_pad(,1)
*/
/* 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 */
int fill_up_media;
/* ts A70303 : Wether to override conformance checks:
- the check wether CD write+block type is supported by the drive
*/
int force_is_set;
/* ts A80412 : whether to use WRITE12 with Streaming bit set
rather than WRITE10. Speeds up DVD-RAM. Might help with BD-RE.
This gets transferred to burn_drive.do_stream_recording
*/
int do_stream_recording;
/* ts A91115 : override value for .obs on DVD media.
Only values 0, 32K and 64K are allowed for now. */
int dvd_obs_override;
/* ts A91115 : size of the fsync() interval for stdio writing.
Values 0 or >= 32 counted in 2 KB blocks. */
int stdio_fsync_size;
/* ts B11203 : CD-TEXT */
unsigned char *text_packs;
int num_text_packs;
int no_text_pack_crc_check;
/** A disc can have a media catalog number */
int has_mediacatalog;
unsigned char mediacatalog[13];
/** Session format */
int format;
/* internal use only */
unsigned char control;
/* Whether to keep medium appendable */
unsigned char multi;
/* ts B31024 */
/* The severity to be attributed to error messages about failed
write attempt with blank DVD-RW, possibly due to falsely reported
feature 21h Incremental Streaming Writable
*/
int feat21h_fail_sev;
};
/* Default value for burn_write_opts.stdio_flush_size
*/
#define Libburn_stdio_fsync_limiT 8192
/* Maximum number of Lead-in text packs.
READ TOC/PMA/ATIP can at most return 3640.7 packs.
The sequence counters of the packs have 8 bits. There are 8 blocks at most.
Thus max 2048 packs.
*/
#define Libburn_leadin_cdtext_packs_maX 2048
/** Options for disc reading operations. This should be created with
burn_read_opts_new() and freed with burn_read_opts_free(). */
struct burn_read_opts
{
/** Drive the read opts are good for */
struct burn_drive *drive;
/** For internal use. */
int refcount;
/** Read in raw mode, so that everything in the data tracks on the
disc is read, including headers. Not needed if just reading a
filesystem off a disc, but it should usually be used when making a
disc image or copying a disc. */
unsigned int raw:1;
/** Report c2 errors. Useful for statistics reporting */
unsigned int c2errors:1;
/** Read subcodes from audio tracks on the disc */
unsigned int subcodes_audio:1;
/** Read subcodes from data tracks on the disc */
unsigned int subcodes_data:1;
/** Have the drive recover errors if possible */
unsigned int hardware_error_recovery:1;
/** Report errors even when they were recovered from */
unsigned int report_recovered_errors:1;
/** Read blocks even when there are unrecoverable errors in them */
unsigned int transfer_damaged_blocks:1;
/** The number of retries the hardware should make to correct
errors. */
unsigned char hardware_error_retries;
/* ts B21119 */
/* >>> Needs API access */
/** Whether to set DAP bit which allows the drive to apply
"flaw obscuring mechanisms like audio data mute and interpolate"
*/
unsigned int dap_bit;
};
int burn_write_opts_clone(struct burn_write_opts *from,
struct burn_write_opts **to, int flag);
#endif /* BURN__OPTIONS_H */

88
libburn/os-dummy.h Normal file
View File

@ -0,0 +1,88 @@
/* os-dummy.h
Operating system specific libburn definitions and declarations. Included
by os.h in case of compilation for
Unknown POSIX like systems
with the dummy MMC transport adapter sg-dummy.c
Copyright (C) 2009 - 2013 Thomas Schmitt <scdbackup@gmx.net>
Provided under GPLv2+
*/
/** List of all signals which shall be caught by signal handlers and trigger
a graceful abort of libburn. (See man 7 signal.)
*/
/* Once as system defined macros */
#define BURN_OS_SIGNAL_MACRO_LIST \
SIGHUP, SIGINT, SIGQUIT, SIGILL, SIGABRT, \
SIGFPE, SIGSEGV, SIGPIPE, SIGALRM, SIGTERM, \
SIGUSR1, SIGUSR2, SIGXCPU
/* Once as text 1:1 list of strings for messages and interpreters */
#define BURN_OS_SIGNAL_NAME_LIST \
"SIGHUP", "SIGINT", "SIGQUIT", "SIGILL", "SIGABRT", \
"SIGFPE", "SIGSEGV", "SIGPIPE", "SIGALRM", "SIGTERM", \
"SIGUSR1", "SIGUSR2", "SIGXCPU"
/* The number of above list items */
#define BURN_OS_SIGNAL_COUNT 13
/** The list of all signals which shall surely not be caught.
It depends on the particular signal whether it can be ignored or whether
it will lead to sudden death of the process.
Some signals are not POSIX,
but nevertheless ought to be ignored if they are defined.
*/
#ifdef SIGWINCH
#define BURN_OS_SIG_WINCH ,SIGWINCH
#define BURN_OS_SIG_WINCH_CNT 1
#else
#define BURN_OS_SIG_WINCH
#define BURN_OS_SIG_WINCH_CNT 0
#endif
#ifdef SIGURG
#define BURN_OS_SIG_URG ,SIGURG
#define BURN_OS_SIG_URG_CNT 1
#else
#define BURN_OS_SIG_URG
#define BURN_OS_SIG_URG_CNT 0
#endif
/** The combined list of all signals which shall not be caught.
*/
#define BURN_OS_NON_SIGNAL_MACRO_LIST \
SIGKILL, SIGCHLD, SIGSTOP, SIGTSTP, SIGCONT, SIGTTIN, SIGTTOU \
BURN_OS_SIG_WINCH BURN_OS_SIG_URG
/* The number of above list items */
#define BURN_OS_NON_SIGNAL_COUNT \
( 7 + BURN_OS_SIG_WINCH_CNT + BURN_OS_SIG_URG_CNT )
/* The maximum size for a (SCSI) i/o transaction */
/* Important : MUST be at least 32768 ! */
#define BURN_OS_TRANSPORT_BUFFER_SIZE 65536
/* To hold the position of the most recently delivered address from
device enumeration.
*/
struct burn_drive_enumerator_struct {
int pos;
int info_count;
char **info_list;
};
#define BURN_OS_DEFINE_DRIVE_ENUMERATOR_T \
typedef struct burn_drive_enumerator_struct burn_drive_enumerator_t;
/* The list of operating system dependent elements in struct burn_drive.
Usually they are initialized in sg-*.c:enumerate_common().
*/
#define BURN_OS_TRANSPORT_DRIVE_ELEMENTS \
int just_a_dummy;

65
libburn/os-freebsd.h Normal file
View File

@ -0,0 +1,65 @@
/* os-freebsd.h
Operating system specific libburn definitions and declarations. Included
by os.h in case of compilation for
FreeBSD with CAM
Copyright (C) 2006 - 2013 Thomas Schmitt <scdbackup@gmx.net>,
Provided under GPLv2+
*/
/** List of all signals which shall be caught by signal handlers and trigger
a graceful abort of libburn. (See man 7 signal.)
*/
/* Once as system defined macros */
#define BURN_OS_SIGNAL_MACRO_LIST \
SIGHUP, SIGINT, SIGQUIT, SIGILL, SIGABRT, \
SIGFPE, SIGSEGV, SIGPIPE, SIGALRM, SIGTERM, \
SIGUSR1, SIGUSR2, SIGXCPU, SIGBUS, SIGPROF, \
SIGSYS, SIGTRAP, SIGVTALRM, SIGXCPU, SIGXFSZ
/* Once as text 1:1 list of strings for messages and interpreters */
#define BURN_OS_SIGNAL_NAME_LIST \
"SIGHUP", "SIGINT", "SIGQUIT", "SIGILL", "SIGABRT", \
"SIGFPE", "SIGSEGV", "SIGPIPE", "SIGALRM", "SIGTERM", \
"SIGUSR1", "SIGUSR2", "SIGXCPU", "SIGBUS", "SIGPROF", \
"SIGSYS", "SIGTRAP", "SIGVTALRM", "SIGXCPU", "SIGXFSZ"
/* The number of above list items */
#define BURN_OS_SIGNAL_COUNT 20
/** To list all signals which shall surely not be caught */
#define BURN_OS_NON_SIGNAL_MACRO_LIST \
SIGKILL, SIGCHLD, SIGSTOP, SIGTSTP, SIGCONT, SIGTTIN, SIGTTOU, SIGURG, SIGWINCH
/* The number of above list items */
#define BURN_OS_NON_SIGNAL_COUNT 9
/* The maximum size for a (SCSI) i/o transaction */
/* Important : MUST be at least 32768 ! */
/* Older BSD info says that 32 kB is maximum. But 64 kB seems to work well
on 8-STABLE. It is by default only used with BD in streaming mode.
So older systems should still be quite safe with this buffer max size.
*/
#define BURN_OS_TRANSPORT_BUFFER_SIZE 65536
/** To hold all state information of BSD device enumeration
which are now local in sg_enumerate() . So that sg_give_next_adr()
can work in BSD and sg_enumerate() can use it.
*/
#define BURN_OS_DEFINE_DRIVE_ENUMERATOR_T \
struct burn_drive_enumeration_state; \
typedef struct burn_drive_enumeration_state *burn_drive_enumerator_t;
/* The list of operating system dependent elements in struct burn_drive.
To be initialized and used within sg-*.c .
*/
#define BURN_OS_TRANSPORT_DRIVE_ELEMENTS \
struct cam_device* cam; \
int lock_fd; \
int is_ahci; \

95
libburn/os-libcdio.h Normal file
View File

@ -0,0 +1,95 @@
/* os-libcdio.h
Operating system specific libburn definitions and declarations. Included
by os.h in case of compilation for
Unknown X/Open-like systems
with GNU libcdio MMC transport adapter sg-libcdio.c
Copyright (C) 2009 - 2013 Thomas Schmitt <scdbackup@gmx.net>
Provided under GPLv2+
*/
/** List of all signals which shall be caught by signal handlers and trigger
a graceful abort of libburn. (See man 7 signal.)
*/
/* Once as system defined macros */
#define BURN_OS_SIGNAL_MACRO_LIST \
SIGHUP, SIGINT, SIGQUIT, SIGILL, SIGABRT, \
SIGFPE, SIGSEGV, SIGPIPE, SIGALRM, SIGTERM, \
SIGUSR1, SIGUSR2, SIGXCPU
/* Once as text 1:1 list of strings for messages and interpreters */
#define BURN_OS_SIGNAL_NAME_LIST \
"SIGHUP", "SIGINT", "SIGQUIT", "SIGILL", "SIGABRT", \
"SIGFPE", "SIGSEGV", "SIGPIPE", "SIGALRM", "SIGTERM", \
"SIGUSR1", "SIGUSR2", "SIGXCPU"
/* The number of above list items */
#define BURN_OS_SIGNAL_COUNT 13
/** The list of all signals which shall surely not be caught.
It depends on the particular signal whether it can be ignored or whether
it will lead to sudden death of the process.
Some signals are not POSIX,
but nevertheless ought to be ignored if they are defined.
*/
#ifdef SIGWINCH
#define BURN_OS_SIG_WINCH ,SIGWINCH
#define BURN_OS_SIG_WINCH_CNT 1
#else
#define BURN_OS_SIG_WINCH
#define BURN_OS_SIG_WINCH_CNT 0
#endif
#ifdef SIGURG
#define BURN_OS_SIG_URG ,SIGURG
#define BURN_OS_SIG_URG_CNT 1
#else
#define BURN_OS_SIG_URG
#define BURN_OS_SIG_URG_CNT 0
#endif
/** The combined list of all signals which shall not be caught.
*/
#define BURN_OS_NON_SIGNAL_MACRO_LIST \
SIGKILL, SIGCHLD, SIGSTOP, SIGTSTP, SIGCONT, SIGTTIN, SIGTTOU \
BURN_OS_SIG_WINCH BURN_OS_SIG_URG
/* The number of above list items */
#define BURN_OS_NON_SIGNAL_COUNT \
( 7 + BURN_OS_SIG_WINCH_CNT + BURN_OS_SIG_URG_CNT )
/* The maximum size for a (SCSI) i/o transaction */
/* My Blu-ray burner LG GGW-H20 writes junk if stream recording is combined
with buffer size 32 kB. So stream recording is allowed only with size 64k.
Older BSD info says that 32 kB is maximum. But 64 kB seems to work well
on 8-STABLE. It is by default only used with BD in streaming mode.
So older systems should still be quite safe with this buffer max size.
*/
/* Important : MUST be at least 32768 ! */
#define BURN_OS_TRANSPORT_BUFFER_SIZE 65536
/* To hold the position of the most recently delivered address from
device enumeration.
*/
struct burn_drive_enumerator_struct {
char **ppsz_cd_drives;
char **pos;
};
#define BURN_OS_DEFINE_DRIVE_ENUMERATOR_T \
typedef struct burn_drive_enumerator_struct burn_drive_enumerator_t;
/* The list of operating system dependent elements in struct burn_drive.
Usually they are initialized in sg-*.c:enumerate_common().
*/
#define BURN_OS_TRANSPORT_DRIVE_ELEMENTS \
void *p_cdio; /* actually a pointer to CdIo_t */ \
char libcdio_name[4096]; /* The drive path as used by libcdio */ \

81
libburn/os-linux.h Normal file
View File

@ -0,0 +1,81 @@
/* os-linux.h
Operating system specific libburn definitions and declarations. Included
by os.h in case of compilation for
Linux kernels 2.4 and 2.6, GNU/Linux SCSI Generic (sg)
Copyright (C) 2006 - 2013 Thomas Schmitt <scdbackup@gmx.net>
Provided under GPL version 2 or later.
*/
/** List of all signals which shall be caught by signal handlers and trigger
a graceful abort of libburn. (See man 7 signal.)
*/
/* Once as system defined macros */
#define BURN_OS_SIGNAL_MACRO_LIST \
SIGHUP, SIGINT, SIGQUIT, SIGILL, SIGABRT, \
SIGFPE, SIGSEGV, SIGPIPE, SIGALRM, SIGTERM, \
SIGUSR1, SIGUSR2, SIGXCPU, SIGBUS, SIGPOLL, \
SIGPROF, SIGSYS, SIGTRAP, SIGVTALRM, SIGXCPU, \
SIGXFSZ
/* Once as text 1:1 list of strings for messages and interpreters */
#define BURN_OS_SIGNAL_NAME_LIST \
"SIGHUP", "SIGINT", "SIGQUIT", "SIGILL", "SIGABRT", \
"SIGFPE", "SIGSEGV", "SIGPIPE", "SIGALRM", "SIGTERM", \
"SIGUSR1", "SIGUSR2", "SIGXCPU", "SIGBUS", "SIGPOLL", \
"SIGPROF", "SIGSYS", "SIGTRAP", "SIGVTALRM", "SIGXCPU", \
"SIGXFSZ"
/* The number of above list items */
#define BURN_OS_SIGNAL_COUNT 21
/** To list all signals which shall surely not be caught */
#define BURN_OS_NON_SIGNAL_MACRO_LIST \
SIGKILL, SIGCHLD, SIGSTOP, SIGTSTP, SIGCONT, SIGURG, SIGWINCH, SIGTTIN, SIGTTOU
/* The number of above list items */
#define BURN_OS_NON_SIGNAL_COUNT 9
/* The maximum size for a (SCSI) i/o transaction */
/* Important : MUST be at least 32768 ! */
/* ts A70523 : >32k seems not good with kernel 2.4 USB drivers and audio
#define BURN_OS_TRANSPORT_BUFFER_SIZE 32768
*/
/* ts A80414 : curbed in write.c CD media to Libburn_cd_obS = 32 kiB
re-enlarged transport to 64 kiB for BD-RE experiments
*/
#define BURN_OS_TRANSPORT_BUFFER_SIZE 65536
/* To hold the position of the most recently delivered address from
device enumeration.
*/
struct burn_drive_enumerator_struct {
int pos;
int info_count;
char **info_list;
};
#define BURN_OS_DEFINE_DRIVE_ENUMERATOR_T \
typedef struct burn_drive_enumerator_struct burn_drive_enumerator_t;
/* Parameters for sibling list. See sibling_fds, sibling_fnames */
#define BURN_OS_SG_MAX_SIBLINGS 5
#define BURN_OS_SG_MAX_NAMELEN 16
/* The list of operating system dependent elements in struct burn_drive.
Usually they are initialized in sg-*.c:enumerate_common().
*/
#define BURN_OS_TRANSPORT_DRIVE_ELEMENTS \
int fd; \
\
/* ts A60926 : trying to lock against growisofs /dev/srN, /dev/scdN */ \
int sibling_count; \
int sibling_fds[BURN_OS_SG_MAX_SIBLINGS]; \
/* ts A70409 : DDLP */ \
char sibling_fnames[BURN_OS_SG_MAX_SIBLINGS][BURN_OS_SG_MAX_NAMELEN];

99
libburn/os-netbsd.h Normal file
View File

@ -0,0 +1,99 @@
/* os-netbsd.h
Operating system specific libburn definitions and declarations. Included
by os.h in case of compilation for
NetBSD 6 or OpenBSD 5.9
with MMC transport adapter sg-netbsd.c
Copyright (C) 2010 - 2016 Thomas Schmitt <scdbackup@gmx.net>
provided under GPLv2+
Derived 2014 from libburn/os-solaris.c
Adapted 2016 to OpenBSD by help of SASANO Takayoshi <uaa@mx5.nisiq.net>
*/
/** List of all signals which shall be caught by signal handlers and trigger
a graceful abort of libburn. (See man signal.h)
*/
/* Once as system defined macros */
#define BURN_OS_SIGNAL_MACRO_LIST \
SIGHUP, SIGINT, SIGQUIT, SIGILL, SIGTRAP, \
SIGABRT, SIGEMT, SIGFPE, SIGBUS, SIGSEGV, \
SIGSYS, SIGPIPE, SIGALRM, SIGTERM, SIGXCPU, \
SIGXFSZ, SIGVTALRM, SIGPROF, SIGUSR1, SIGUSR2
/* Once as text 1:1 list of strings for messages and interpreters */
#define BURN_OS_SIGNAL_NAME_LIST \
"SIGHUP", "SIGINT", "SIGQUIT", "SIGILL", "SIGTRAP", \
"SIGABRT", "SIGEMT", "SIGFPE", "SIGBUS", "SIGSEGV", \
"SIGSYS", "SIGPIPE", "SIGALRM", "SIGTERM", "SIGXCPU", \
"SIGXFSZ", "SIGVTALRM", "SIGPROF", "SIGUSR1", "SIGUSR2"
/* The number of above list items */
#define BURN_OS_SIGNAL_COUNT 20
#ifdef __OpenBSD__
/** To list all signals which shall surely not be caught */
#define BURN_OS_NON_SIGNAL_MACRO_LIST \
SIGKILL, SIGURG, SIGSTOP, SIGTSTP, SIGCONT, \
SIGCHLD, SIGTTIN, SIGTTOU, SIGIO, SIGWINCH, \
SIGINFO
/* The number of above list items */
#define BURN_OS_NON_SIGNAL_COUNT 11
/* ts B60730 */
/* Either OpenBSD or SASANO Takayoshi's LG BH14NS48 throw 2,0,0
on Immed bit with BLANK and SYNCHRONIZE CACHE.
Until it is clear that the drive is to blame, the OpenBSD default is
not to use Immed.
This may be overridden at ./configure time by
export CFLAGS
CFLAGS="$CFLAGS -DLibburn_do_no_immed_defaulT=0"
*/
#ifndef Libburn_do_no_immed_defaulT
#define Libburn_do_no_immed_defaulT 1
#endif
#else /* __OpenBSD__ */
/** To list all signals which shall surely not be caught */
#define BURN_OS_NON_SIGNAL_MACRO_LIST \
SIGKILL, SIGURG, SIGSTOP, SIGTSTP, SIGCONT, \
SIGCHLD, SIGTTIN, SIGTTOU, SIGIO, SIGWINCH, \
SIGINFO, SIGPWR
/* The number of above list items */
#define BURN_OS_NON_SIGNAL_COUNT 12
#endif /* ! __OpenBSD__ */
/* The maximum size for a (SCSI) i/o transaction */
/* Important : MUST be at least 32768 ! */
/* My Blu-ray burner LG GGW-H20 writes junk if stream recording is combined
with buffer size 32 kB. So stream recording is allowed only with size 64k.
*/
/* >>> ??? Does it do 64 kB ? */
#define BURN_OS_TRANSPORT_BUFFER_SIZE 65536
/* To hold the position of the most recently delivered address from
device enumeration.
*/
struct burn_drive_enumerator_struct {
int cdno;
};
#define BURN_OS_DEFINE_DRIVE_ENUMERATOR_T \
typedef struct burn_drive_enumerator_struct burn_drive_enumerator_t;
/* The list of operating system dependent elements in struct burn_drive.
Usually they are initialized in sg-*.c:enumerate_common().
*/
#define BURN_OS_TRANSPORT_DRIVE_ELEMENTS \
int fd;

65
libburn/os-solaris.h Normal file
View File

@ -0,0 +1,65 @@
/* os-solaris.h
Operating system specific libburn definitions and declarations. Included
by os.h in case of compilation for
Solaris based systems, e.g. SunOS 5.11
with Solaris uscsi MMC transport adapter sg-solaris.c
Copyright (C) 2010 - 2013 Thomas Schmitt <scdbackup@gmx.net>
provided under GPLv2+
*/
/** List of all signals which shall be caught by signal handlers and trigger
a graceful abort of libburn. (See man signal.h)
*/
/* Once as system defined macros */
#define BURN_OS_SIGNAL_MACRO_LIST \
SIGHUP, SIGINT, SIGQUIT, SIGILL, SIGABRT, \
SIGFPE, SIGSEGV, SIGPIPE, SIGALRM, SIGTERM, \
SIGUSR1, SIGUSR2, SIGXCPU
/* Once as text 1:1 list of strings for messages and interpreters */
#define BURN_OS_SIGNAL_NAME_LIST \
"SIGHUP", "SIGINT", "SIGQUIT", "SIGILL", "SIGABRT", \
"SIGFPE", "SIGSEGV", "SIGPIPE", "SIGALRM", "SIGTERM", \
"SIGUSR1", "SIGUSR2", "SIGXCPU"
/* The number of above list items */
#define BURN_OS_SIGNAL_COUNT 13
/** To list all signals which shall surely not be caught */
#define BURN_OS_NON_SIGNAL_MACRO_LIST \
SIGKILL, SIGCHLD, SIGSTOP, SIGTSTP, SIGCONT, SIGTTIN, SIGTTOU, SIGURG, SIGWINCH
/* The number of above list items */
#define BURN_OS_NON_SIGNAL_COUNT 9
/* The maximum size for a (SCSI) i/o transaction */
/* Important : MUST be at least 32768 ! */
/* My Blu-ray burner LG GGW-H20 writes junk if stream recording is combined
with buffer size 32 kB. So stream recording is allowed only with size 64k.
*/
#define BURN_OS_TRANSPORT_BUFFER_SIZE 65536
/* >>> */
/* To hold the position of the most recently delivered address from
device enumeration.
*/
struct burn_drive_enumerator_struct {
void *dir;
};
#define BURN_OS_DEFINE_DRIVE_ENUMERATOR_T \
typedef struct burn_drive_enumerator_struct burn_drive_enumerator_t;
/* The list of operating system dependent elements in struct burn_drive.
Usually they are initialized in sg-*.c:enumerate_common().
*/
#define BURN_OS_TRANSPORT_DRIVE_ELEMENTS \
int fd;

98
libburn/os.h Normal file
View File

@ -0,0 +1,98 @@
/* os.h
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 - 2016 Thomas Schmitt <scdbackup@gmx.net>,
provided under GPLv2+
*/
#ifndef BURN_OS_H_INCLUDED
#define BURN_OS_H_INCLUDED 1
/*
Operating system case distinction
*/
#ifdef Libburn_use_sg_dummY
/* --------- Any other system. With dummy MMC transport sg-dummy.c --------- */
#include "os-dummy.h"
#else
#ifdef Libburn_use_libcdiO
/* -------------------------- X/Open with GNU libcdio ---------------------- */
#include "os-libcdio.h"
#else
#ifdef __NetBSD__
/* -------------------------- NetBSD with SCIOCCOMMAND --------------------- */
#include "os-netbsd.h"
#else
#ifdef __OpenBSD__
/* -------------------------- OpenBSD with SCIOCCOMMAND -------------------- */
#include "os-netbsd.h"
#else
#ifdef __FreeBSD__
/* ----------------------------- FreeBSD with CAM -------------------------- */
#include "os-freebsd.h"
#else
#ifdef __FreeBSD_kernel__
/* ----------------------- FreeBSD with CAM under Debian ------------------- */
#include "os-freebsd.h"
#else
#ifdef __linux
/* ------- Linux kernels 2.4 and 2.6 with GNU/Linux SCSI Generic (sg) ------ */
#include "os-linux.h"
#else
#ifdef __sun
/* ------- Solaris (e.g. SunOS 5.11) with uscsi ------ */
#include "os-solaris.h"
#else
/* --------- Any other system. With dummy MMC transport sg-dummy.c --------- */
#include "os-dummy.h"
#endif /* ! __sun*/
#endif /* ! __linux */
#endif /* ! __FreeBSD__kernel__ */
#endif /* ! __FreeBSD__ */
#endif /* ! __OpenBSD__ */
#endif /* ! __NetBSD__ */
#endif /* ! Libburn_use_libcdiO */
#endif /* ! Libburn_use_sg_dummY */
#endif /* ! BURN_OS_H_INCLUDED */

778
libburn/read.c Normal file
View File

@ -0,0 +1,778 @@
/* -*- 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>
Provided under GPL version 2 or later.
*/
#ifdef HAVE_CONFIG_H
#include "../config.h"
#endif
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
/* ts A61007 */
/* #include <a ssert.h> */
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <fcntl.h>
#include <errno.h>
/* ts B41126 : O_BINARY is needed for Cygwin but undefined elsewhere */
#ifndef O_BINARY
#define O_BINARY 0
#endif
#include "sector.h"
#include "libburn.h"
#include "drive.h"
#include "transport.h"
/* ts A60925 : obsoleted by libdax_msgs.h
#include "message.h"
*/
#include "crc.h"
#include "debug.h"
#include "init.h"
#include "toc.h"
#include "util.h"
#include "mmc.h"
#include "sg.h"
#include "read.h"
#include "options.h"
/* ts A70812 */
#include "error.h"
#include "libdax_msgs.h"
extern struct libdax_msgs *libdax_messenger;
void burn_disc_read(struct burn_drive *d, const struct burn_read_opts *o)
{
#if 0
int i, end, maxsects, finish;
int seclen;
int drive_lba;
unsigned short crc;
unsigned char fakesub[96];
struct buffer page; <- needs to become dynamic memory
int speed;
/* ts A61007 : if this function gets revived, then these
tests have to be done more graceful */
a ssert((o->version & 0xfffff000) == (OPTIONS_VERSION & 0xfffff000));
a ssert(!d->busy);
a ssert(d->toc->valid);
a ssert(o->datafd != -1);
/* moved up from spc_select_error_params alias d->send_parameters() */
a ssert(d->mdata->valid);
/* XXX not sure this is a good idea. copy it? */
/* XXX also, we have duplicated data now, do we remove the fds from struct
drive, or only store a subset of the _opts structs in drives */
/* set the speed on the drive */
speed = o->speed > 0 ? o->speed : d->mdata->max_read_speed;
d->set_speed(d, speed, 0);
d->params.retries = o->hardware_error_retries;
d->send_parameters(d, o);
d->cancel = 0;
d->busy = BURN_DRIVE_READING;
d->currsession = 0;
/* drive_lba = 232000;
d->currtrack = 18;
*/
d->currtrack = 0;
drive_lba = 0;
/* XXX removal of this line obviously breaks *
d->track_end = burn_track_end(d, d->currsession, d->currtrack);*/
printf("track ends at %d\n", d->track_end);
page.sectors = 0;
page.bytes = 0;
if (o->subfd != -1) {
memset(fakesub, 0xFF, 12);
memset(fakesub + 12, 0, 84);
fakesub[13] = 1;
fakesub[14] = 1;
fakesub[20] = 2;
fakesub[12] = (d->toc->toc_entry[0].control << 4) +
d->toc->toc_entry[0].adr;
#ifdef Libburn_no_crc_C
crc = 0; /* dummy */
#else
crc = crc_ccitt(fakesub + 12, 10);
#endif
fakesub[22] = crc >> 8;
fakesub[23] = crc & 0xFF;
write(o->subfd, fakesub, 96);
}
while (1) {
seclen = burn_sector_length_read(d, o);
for (i = 0; i < page.sectors; i++) {
burn_packet_process(d, page.data + seclen * i, o);
d->track_end--;
drive_lba++;
}
if ((d->cancel) || (drive_lba == LAST_SESSION_END(d))) {
d->busy = BURN_DRIVE_IDLE;
if (!d->cancel)
d->toc->complete = 1;
return;
}
/* XXX: removal of this line obviously breaks *
end = burn_track_end(d, d->currsession, d->currtrack); */
if (drive_lba == end) {
d->currtrack++;
if (d->currtrack >
d->toc->session[d->currsession].lasttrack) {
d->currsession++;
/* session switch to d->currsession */
/* skipping a lead out */
drive_lba = CURRENT_SESSION_START(d);
/* XXX more of the same
end = burn_track_end(d, d->currsession,
d->currtrack);
*/
}
}
page.sectors = 0;
page.bytes = 0;
maxsects = BUFFER_SIZE / seclen;
finish = end - drive_lba;
d->track_end = finish;
page.sectors = (finish < maxsects) ? finish : maxsects;
printf("reading %d sectors from %d\n", page.sectors,
drive_lba);
/* >>> ts A61009 : ensure page.sectors >= 0 before calling */
/* >>> ts B21123 : Would now be d->read_cd() with
with sectype = 0 , mainch = 0xf8 */
d->r ead_sectors(d, drive_lba, page.sectors, o, &page);
printf("Read %d\n", page.sectors);
}
#endif
}
int burn_sector_length_read(struct burn_drive *d,
const struct burn_read_opts *o)
{
int dlen = 2352;
int data;
/*XXX how do we handle this crap now?*/
/* data = d->toc->track[d->currtrack].toc_entry->control & 4;*/
data = 1;
if (o->report_recovered_errors)
dlen += 294;
if ((o->subcodes_data) && data)
dlen += 96;
if ((o->subcodes_audio) && !data)
dlen += 96;
return dlen;
}
static int bitcount(unsigned char *data, int n)
{
int i, j, count = 0;
unsigned char tem;
for (i = 0; i < n; i++) {
tem = data[i];
for (j = 0; j < 8; j++) {
count += tem & 1;
tem >>= 1;
}
}
return count;
}
void burn_packet_process(struct burn_drive *d, unsigned char *data,
const struct burn_read_opts *o)
{
unsigned char sub[96];
int ptr = 2352, i, j, code, fb;
int audio = 1;
#ifndef Libburn_no_crc_C
unsigned short crc;
#endif
if (o->c2errors) {
fb = bitcount(data + ptr, 294);
if (fb) {
/* bitcount(data + ptr, 294) damaged bits */;
}
ptr += 294;
}
/*
if (d->toc->track[d->currtrack].mode == BURN_MODE_UNINITIALIZED) {
if ((d->toc->track[d->currtrack].toc_entry->control & 4) == 0)
d->toc->track[d->currtrack].mode = BURN_MODE_AUDIO;
else
switch (data[15]) {
case 0:
d->toc->track[d->currtrack].mode = BURN_MODE0;
break;
case 1:
d->toc->track[d->currtrack].mode = BURN_MODE1;
break;
case 2:
d->toc->track[d->currtrack].mode =
BURN_MODE2_FORMLESS;
break;
}
}
*/
if ((audio && o->subcodes_audio)
|| (!audio && o->subcodes_data)) {
memset(sub, 0, sizeof(sub));
for (i = 0; i < 12; i++) {
for (j = 0; j < 8; j++) {
for (code = 0; code < 8; code++) {
sub[code * 12 + i] <<= 1;
if (data[ptr + j + i * 8] &
(1 << (7 - code)))
sub[code * 12 + i]++;
}
}
}
#ifndef Libburn_no_crc_C
crc = (*(sub + 22) << 8) + *(sub + 23);
if (crc != crc_ccitt(sub + 12, 10)) {
/*
burn_print(1, "sending error on %s %s\n",
d->idata->vendor, d->idata->product);
e = burn_error();
e->drive = d;
burn_print(1, "crc mismatch in Q\n");
*/;
}
#endif
/* else process_q(d, sub + 12); */
/*
if (o->subfd != -1) write(o->subfd, sub, 96); */
}
/*
if ((d->track_end <= 150)
&& (drive_lba + 150 < CURRENT_SESSION_END(d))
&& (TOC_ENTRY(d->toc, d->currtrack).control == 4)
&& (TOC_ENTRY(d->toc, d->currtrack + 1).control == 0)) {
burn_print(12, "pregap : %d\n", d->track_end);
write(o->binfd, zeros, 2352);
#warning XXX WHERE ARE MY SUBCODES
} else
*//* write(o->datafd, data, 2352); */
}
/* so yeah, when you uncomment these, make them write zeros insted of crap
static void write_empty_sector(int fd)
{
static char sec[2352], initialized = 0;
if (!initialized) {
memset(sec, 0, 2352);
initialized = 1;
}
burn_print(1, "writing an 'empty' sector\n");
write(fd, sec, 2352);
}
static void write_empty_subcode(int fd)
{
char sub[96];
write(fd, sub, 96);
}
static void flipq(unsigned char *sub)
{
*(sub + 12 + 10) = ~*(sub + 12 + 10);
*(sub + 12 + 11) = ~*(sub + 12 + 11);
}
*/
/** @param flag bit1= be silent on failure
bit5= report failure with severity DEBUG
*/
static int burn_stdio_seek(int fd, off_t byte_address, struct burn_drive *d,
int flag)
{
char msg[80];
if (lseek(fd, byte_address, SEEK_SET) != -1)
return 1;
if (!(flag & 2)) {
sprintf(msg, "Cannot address start byte %.f",
(double) byte_address);
libdax_msgs_submit(libdax_messenger,
d->global_index, 0x00020147,
(flag & 32) ?
LIBDAX_MSGS_SEV_DEBUG : LIBDAX_MSGS_SEV_SORRY,
LIBDAX_MSGS_PRIO_HIGH, msg, errno, 0);
}
return 0;
}
/* ts A70904 */
/** @param flag bit0= be silent on data shortage
bit5= report data shortage with severity DEBUG
*/
int burn_stdio_read(int fd, char *buf, int bufsize, struct burn_drive *d,
int flag)
{
int todo, count = 0;
for(todo = bufsize; todo > 0; ) {
count = read(fd, buf + (bufsize - todo), todo);
if(count <= 0)
break;
todo -= count;
}
if(todo > 0 && !(flag & 1)) {
libdax_msgs_submit(libdax_messenger, d->global_index,
0x0002014a,
(flag & 32) ?
LIBDAX_MSGS_SEV_DEBUG : LIBDAX_MSGS_SEV_SORRY,
LIBDAX_MSGS_PRIO_HIGH,
"Cannot read desired amount of data", errno, 0);
}
if (count < 0)
return -1;
return (bufsize - todo);
}
/* With DVD and BD media, the minimum ECC entity is read instead of single
blocks.
@param flag see burn_read_data() in libburn.h
*/
static int retry_mmc_read(struct burn_drive *d, int chunksize, int sose_mem,
int start, char **wpt, off_t *data_count,
int flag)
{
int i, err, todo;
int retry_at, retry_size;
retry_at = start;
retry_size = chunksize;
todo = chunksize;
retry_size = 16; /* DVD ECC block size */
if (d->current_is_cd_profile) {
retry_size = 1; /* CD block size */
} else if (d->current_profile >= 0x40 && d->current_profile <= 0x43) {
retry_size = 32; /* BD cluster size */
}
for (i = 0; todo > 0; i++) {
if (flag & 2)
d->silent_on_scsi_error = 1;
else if (flag & 32)
d->silent_on_scsi_error = 3;
retry_at = start + i * retry_size;
if (retry_size > todo)
retry_size = todo;
err = d->read_10(d, retry_at, retry_size, d->buffer);
if (flag & (2 | 32))
d->silent_on_scsi_error = sose_mem;
if (err == BE_CANCELLED)
return 0;
memcpy(*wpt, d->buffer->data, retry_size * 2048);
*wpt += retry_size * 2048;
*data_count += retry_size * 2048;
todo -= retry_size;
}
return 1;
}
/* @param flag see burn_read_data() in libburn.h
*/
static int retry_stdio_read(struct burn_drive *d, int fd, int chunksize,
int start, char **wpt, off_t *data_count,
int flag)
{
int i, ret, to_read, todo;
ret = burn_stdio_seek(fd, ((off_t) start) * 2048, d, flag & 2);
if (ret <= 0)
return ret;
todo = chunksize * 2048;
for (i = 0; todo > 0; i += 2048) {
to_read = todo;
if (to_read > 2048)
to_read = 2048;
ret = burn_stdio_read(fd, (char *) d->buffer->data, to_read,
d, 1);
if (ret <= 0)
return 0;
memcpy(*wpt, d->buffer->data, to_read);
*wpt += to_read;
*data_count += to_read;
todo -= to_read;
}
return 1;
}
/* ts A70812 : API function */
int burn_read_data(struct burn_drive *d, off_t byte_address,
char data[], off_t data_size, off_t *data_count, int flag)
{
int alignment = 2048, start, upto, chunksize = 1, err, cpy_size;
int sose_mem = 0, fd = -1, ret;
char msg[81], *wpt;
struct buffer *buf = NULL, *buffer_mem = d->buffer;
/*
#define Libburn_read_data_adr_logginG 1
*/
#ifdef Libburn_read_data_adr_logginG
static FILE *log_fp= NULL;
if(log_fp == NULL)
log_fp = fopen("/tmp/burn_read_data_log", "a");
if(log_fp!=NULL)
fprintf(log_fp, "%d\n", (int) (byte_address / 2048));
#endif /* Libburn_read_data_logginG */
BURN_ALLOC_MEM(buf, struct buffer, 1);
*data_count = 0;
sose_mem = d->silent_on_scsi_error;
if (d->released) {
libdax_msgs_submit(libdax_messenger,
d->global_index, 0x00020142,
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
"Drive is not grabbed on random access read", 0, 0);
{ret = 0; goto ex;}
}
if (d->drive_role == 0) {
libdax_msgs_submit(libdax_messenger, d->global_index,
0x00020146,
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
"Drive is a virtual placeholder (null-drive)", 0, 0);
{ret = 0; goto ex;}
} else if (d->drive_role == 3) {
libdax_msgs_submit(libdax_messenger, d->global_index,
0x00020151,
LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH,
"Read attempt on write-only drive", 0, 0);
{ret = 0; goto ex;}
}
if ((byte_address % alignment) != 0) {
sprintf(msg,
"Read start address not properly aligned (%d bytes)",
alignment);
libdax_msgs_submit(libdax_messenger, d->global_index,
0x00020143,
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
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 (!(flag & 2)) {
sprintf(msg,
"Read start address %ds larger than number of readable blocks %d",
(int) (byte_address / 2048 + !!(byte_address % 2048)),
d->media_read_capacity + 1);
libdax_msgs_submit(libdax_messenger, d->global_index,
0x00020172, (flag & 32) ?
LIBDAX_MSGS_SEV_DEBUG : LIBDAX_MSGS_SEV_SORRY,
LIBDAX_MSGS_PRIO_HIGH, msg, 0, 0);
}
{ret = 0; goto ex;}
}
if (d->busy != BURN_DRIVE_IDLE) {
libdax_msgs_submit(libdax_messenger,
d->global_index, 0x00020145,
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
"Drive is busy on attempt to read data", 0, 0);
{ret = 0; goto ex;}
}
if (d->drive_role != 1) {
/* <<< We need _LARGEFILE64_SOURCE defined by the build system.
*/
#ifndef O_LARGEFILE
#define O_LARGEFILE 0
#endif
fd = d->stdio_fd;
if (fd < 0)
d->stdio_fd = fd =
open(d->devname,
O_RDONLY | O_LARGEFILE | O_BINARY);
if (fd == -1) {
if (errno == EACCES && (flag & 2)) {
if (!(flag & 8))
libdax_msgs_submit(libdax_messenger,
d->global_index, 0x00020183,
LIBDAX_MSGS_SEV_WARNING,
LIBDAX_MSGS_PRIO_HIGH,
"Failed to open device (a pseudo-drive) for reading",
errno, 0);
} else if (errno != ENOENT || !(flag & 2))
libdax_msgs_submit(libdax_messenger,
d->global_index, 0x00020005,
(flag & 32) && errno == ENOENT ?
LIBDAX_MSGS_SEV_DEBUG :
LIBDAX_MSGS_SEV_SORRY,
LIBDAX_MSGS_PRIO_HIGH,
"Failed to open device (a pseudo-drive) for reading",
errno, 0);
ret = 0;
if (errno == EACCES && (flag & 8))
ret= -2;
goto ex;
}
ret = burn_stdio_seek(fd, byte_address, d, flag & (2 | 32));
if (ret <= 0)
goto ex;
}
d->busy = BURN_DRIVE_READING_SYNC;
d->buffer = buf;
start = byte_address / 2048;
upto = start + data_size / 2048;
if (data_size % 2048)
upto++;
wpt = data;
for (; start < upto; start += chunksize) {
chunksize = upto - start;
if (chunksize > (BUFFER_SIZE / 2048)) {
chunksize = (BUFFER_SIZE / 2048);
cpy_size = BUFFER_SIZE;
} else
cpy_size = data_size - *data_count;
if (flag & 2)
d->silent_on_scsi_error = 1;
else if (flag & 32)
d->silent_on_scsi_error = 3;
if (flag & 16) {
d->had_particular_error &= ~1;
if (!d->silent_on_scsi_error)
d->silent_on_scsi_error = 2;
}
if (d->drive_role == 1) {
err = d->read_10(d, start, chunksize, d->buffer);
} else {
ret = burn_stdio_read(fd, (char *) d->buffer->data,
cpy_size, d,
(flag & 32) | !!(flag & 2));
err = 0;
if (ret <= 0)
err = BE_CANCELLED;
}
if (flag & (2 | 16 | 32))
d->silent_on_scsi_error = sose_mem;
if (err == BE_CANCELLED) {
if ((flag & 16) && (d->had_particular_error & 1))
{ret = -3; goto ex;}
/* Retry: with CD read by single blocks
with other media: retry in full chunks
*/
if(flag & 4)
goto bad_read;
if (d->drive_role == 1) {
ret = retry_mmc_read(d, chunksize, sose_mem,
start, &wpt, data_count, flag);
} else {
ret = retry_stdio_read(d, fd, chunksize,
start, &wpt, data_count, flag);
}
if (ret <= 0)
goto bad_read;
} else {
memcpy(wpt, d->buffer->data, cpy_size);
wpt += cpy_size;
*data_count += cpy_size;
}
}
ret = 1;
ex:;
BURN_FREE_MEM(buf);
d->buffer = buffer_mem;
d->busy = BURN_DRIVE_IDLE;
return ret;
bad_read:;
if (!(flag & 2))
libdax_msgs_submit(libdax_messenger, d->global_index,
0x00020000,
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH,
"burn_read_data() returns 0", 0, 0);
ret = 0; goto ex;
}
/* ts B21119 : API function*/
int burn_read_audio(struct burn_drive *d, int sector_no,
char data[], off_t data_size, off_t *data_count, int flag)
{
int alignment = 2352, start, upto, chunksize = 1, err, cpy_size, i;
int sose_mem = 0, ret;
char msg[81], *wpt;
struct buffer *buf = NULL, *buffer_mem = d->buffer;
BURN_ALLOC_MEM(buf, struct buffer, 1);
*data_count = 0;
sose_mem = d->silent_on_scsi_error;
if (d->released) {
libdax_msgs_submit(libdax_messenger,
d->global_index, 0x00020142,
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
"Drive is not grabbed on random access read", 0, 0);
{ret = 0; goto ex;}
}
if (d->drive_role != 1) {
libdax_msgs_submit(libdax_messenger, d->global_index,
0x00020146,
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
"Drive is a virtual placeholder (stdio-drive or null-drive)",
0, 0);
{ret = 0; goto ex;}
}
if ((data_size % alignment) != 0) {
sprintf(msg,
"Audio read size not properly aligned (%d bytes)",
alignment);
libdax_msgs_submit(libdax_messenger, d->global_index,
0x0002019d,
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
msg, 0, 0);
{ret = 0; goto ex;}
}
if (d->busy != BURN_DRIVE_IDLE) {
libdax_msgs_submit(libdax_messenger,
d->global_index, 0x00020145,
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
"Drive is busy on attempt to read audio", 0, 0);
{ret = 0; goto ex;}
}
d->busy = BURN_DRIVE_READING_SYNC;
d->buffer = buf;
start = sector_no;
upto = start + data_size / alignment;
wpt = data;
for (; start < upto; start += chunksize) {
chunksize = upto - start;
if (chunksize > (BUFFER_SIZE / alignment))
chunksize = (BUFFER_SIZE / alignment);
cpy_size = chunksize * alignment;
if (flag & 2)
d->silent_on_scsi_error = 1;
else if (flag & 32)
d->silent_on_scsi_error = 3;
if (flag & 16) {
d->had_particular_error &= ~1;
if (!d->silent_on_scsi_error)
d->silent_on_scsi_error = 2;
}
err = d->read_cd(d, start, chunksize, 1, 0x10, NULL, d->buffer,
(flag & 8) >> 3);
if (flag & (2 | 16 | 32))
d->silent_on_scsi_error = sose_mem;
if (err == BE_CANCELLED) {
if ((flag & 16) && (d->had_particular_error & 1))
{ret = -3; goto ex;}
if(!(flag & 4))
for (i = 0; i < chunksize - 1; i++) {
if (flag & 2)
d->silent_on_scsi_error = 1;
else if (flag & 32)
d->silent_on_scsi_error = 3;
err = d->read_cd(d, start + i, 1, 1, 0x10,
NULL, d->buffer, (flag & 8) >> 3);
if (flag & (2 | 32))
d->silent_on_scsi_error = sose_mem;
if (err == BE_CANCELLED)
break;
memcpy(wpt, d->buffer->data, alignment);
wpt += alignment;
*data_count += alignment;
}
ret = 0; goto ex;
}
memcpy(wpt, d->buffer->data, cpy_size);
wpt += cpy_size;
*data_count += cpy_size;
}
ret = 1;
ex:
BURN_FREE_MEM(buf);
d->buffer = buffer_mem;
d->busy = BURN_DRIVE_IDLE;
return ret;
}
#ifdef Libburn_develop_quality_scaN
/* B21108 ts */
int burn_nec_optiarc_rep_err_rate(struct burn_drive *d,
int start_lba, int rate_period, int flag)
{
int ret, lba = 0, error_rate1 = 0, error_rate2 = 0, enabled = 0, dret;
/* Sub Operation Code 1 : Enable Error Rate reporting function */
ret = mmc_nec_optiarc_f3(d, 1, start_lba, rate_period,
&lba, &error_rate1, &error_rate2);
if (ret <= 0)
goto ex;
enabled = 1;
/* >>> Sub Operation Code 2 : Seek to starting address
start_lba , rate_period
*/;
/* >>> Loop with Sub Operation Code 3 : Send Error Rate information
reply: 4-byte LBA , 2-byte C1/PIE , 2-byte C2/PIF
*/;
ret = 1;
ex:;
if (enabled) {
/* Code F : Disable Error Rate reporting function */
dret = mmc_nec_optiarc_f3(d, 0xf, 0, 0,
&lba, &error_rate1, &error_rate2);
if (dret < ret)
ret = dret;
}
return ret;
}
#endif /* Libburn_develop_quality_scaN */

14
libburn/read.h Normal file
View File

@ -0,0 +1,14 @@
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
#ifndef __LIBBURN_READ
#define __LIBBURN_READ
struct burn_drive;
struct burn_read_opts;
int burn_sector_length_read(struct burn_drive *d,
const struct burn_read_opts *o);
void burn_packet_process(struct burn_drive *d, unsigned char *data,
const struct burn_read_opts *o);
#endif /* __LIBBURN_READ */

186
libburn/sbc.c Normal file
View File

@ -0,0 +1,186 @@
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
/* scsi block commands */
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
Copyright (c) 2006 - 2010 Thomas Schmitt <scdbackup@gmx.net>
Provided under GPL version 2 or later.
*/
#ifdef HAVE_CONFIG_H
#include "../config.h"
#endif
#include <string.h>
#include <unistd.h>
#include "transport.h"
#include "sbc.h"
#include "spc.h"
#include "options.h"
/* ts A70910
debug: for tracing calls which might use open drive fds
or for catching SCSI usage of emulated drives. */
int mmc_function_spy(struct burn_drive *d, char * text);
/* START STOP UNIT as of SBC-1 and SBC-2
0: Opcode 0x1B
1: bit0= Immed
bit1-7= reserved
2: reserved
3: reserved
4: bit0= Start (else Stop unit)
bit1= Load/Eject (according to Start resp. Stop)
bit2-3= reserved
bit4-7= Power Condition
0= Start Valid: process Start and Load/Eject bits
1= assume Active state
2= assume Idle state
3= assume Stanby state
(5= SBC-1 only: assume Sleep state)
7= transfer control of power conditions to logical unit
10= force idle condition timer to 0
11= force standby condition timer to 0
All others are reserved.
5: Control (set to 0)
*/
static unsigned char SBC_LOAD[] = { 0x1b, 0, 0, 0, 3, 0 };
static unsigned char SBC_UNLOAD[] = { 0x1b, 0, 0, 0, 2, 0 };
static unsigned char SBC_START_UNIT[] = { 0x1b, 0, 0, 0, 1, 0 };
static unsigned char SBC_STOP_UNIT[] = { 0x1b, 0, 0, 0, 0, 0 };
void sbc_load(struct burn_drive *d)
{
struct command *c;
c = &(d->casual_command);
if (mmc_function_spy(d, "load") <= 0)
return;
scsi_init_command(c, SBC_LOAD, sizeof(SBC_LOAD));
c->retry = 1;
/* ts A70921 : Had to revoke Immed because of LG GSA-4082B */
/* c->opcode[1] |= 1; / * ts A70918 : Immed */
c->dir = NO_TRANSFER;
c->timeout = Libburn_mmc_load_timeouT;
d->issue_command(d, c);
if (c->error)
return;
/* ts A70923 : Needed regardless of Immed bit. Was once 1 minute, now
5 minutes for loading. If this does not suffice then other commands
shall fail righteously. */
spc_wait_unit_attention(d, 300, "waiting after START UNIT (+ LOAD)",0);
}
void sbc_eject(struct burn_drive *d)
{
struct command *c;
c = &(d->casual_command);
if (mmc_function_spy(d, "eject") <= 0)
return;
scsi_init_command(c, SBC_UNLOAD, sizeof(SBC_UNLOAD));
/* c->opcode[1] |= 1; / * ts A70918 : Immed , ts B00109 : revoked */
c->page = NULL;
c->dir = NO_TRANSFER;
d->issue_command(d, c);
/* ts A70918 : Wait long. A late eject could surprise or hurt user.
ts B00109 : Asynchronous eject revoked, as one cannot reliably
distinguish out from unready.
if (c->error)
return;
spc_wait_unit_attention(d, 1800, "STOP UNIT (+ EJECT)", 0);
*/
}
/* ts A91112 : Now with flag */
/* @param flag bit0= asynchronous waiting
*/
int sbc_start_unit_flag(struct burn_drive *d, int flag)
{
struct command *c;
int ret;
c = &(d->casual_command);
if (mmc_function_spy(d, "start_unit") <= 0)
return 0;
scsi_init_command(c, SBC_START_UNIT, sizeof(SBC_START_UNIT));
c->retry = 1;
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 (d->do_no_immed || !(flag & 1))
return 1;
/* ts A70918 : asynchronous */
ret = spc_wait_unit_attention(d, 1800, "START UNIT", 0);
return ret;
}
int sbc_start_unit(struct burn_drive *d)
{
int ret;
d->is_stopped = 0; /* no endless starting attempts */
/* Asynchronous, not to block controller by waiting */
ret = sbc_start_unit_flag(d, 1);
if (ret <= 0)
return ret;
/* Synchronous to catch Pioneer DVR-216D which is ready too early.
A pending START UNIT can prevent ejecting of the tray.
*/
ret = sbc_start_unit_flag(d, 0);
return ret;
}
/* ts A90824 : Trying to reduce drive noise */
int sbc_stop_unit(struct burn_drive *d)
{
struct command *c;
int ret;
c = &(d->casual_command);
if (mmc_function_spy(d, "stop_unit") <= 0)
return 0;
scsi_init_command(c, SBC_STOP_UNIT, sizeof(SBC_STOP_UNIT));
c->retry = 0;
c->opcode[1] |= 1; /* Immed */
c->dir = NO_TRANSFER;
d->issue_command(d, c);
if (c->error)
return 0;
ret = spc_wait_unit_attention(d, 1800, "STOP UNIT", 0);
d->is_stopped = 1;
return ret;
}
/* ts A61021 : the sbc specific part of sg.c:enumerate_common()
*/
int sbc_setup_drive(struct burn_drive *d)
{
d->eject = sbc_eject;
d->load = sbc_load;
d->start_unit = sbc_start_unit;
d->stop_unit = sbc_stop_unit;
d->is_stopped = 0;
return 1;
}

24
libburn/sbc.h Normal file
View File

@ -0,0 +1,24 @@
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
Copyright (c) 2006 - 2010 Thomas Schmitt <scdbackup@gmx.net>
Provided under GPL version 2 or later.
*/
#ifndef __SBC
#define __SBC
struct burn_drive;
void sbc_load(struct burn_drive *);
void sbc_eject(struct burn_drive *);
/* ts A61118 */
int sbc_start_unit(struct burn_drive *);
/* ts A61021 : the sbc specific part of sg.c:enumerate_common()
*/
int sbc_setup_drive(struct burn_drive *d);
#endif /* __SBC */

953
libburn/sector.c Normal file
View File

@ -0,0 +1,953 @@
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
Copyright (c) 2006 - 2016 Thomas Schmitt <scdbackup@gmx.net>
Provided under GPL version 2 or later.
*/
#ifdef HAVE_CONFIG_H
#include "../config.h"
#endif
#include <stdio.h>
/* ts A61010 */
/* #include <a ssert.h> */
#include <unistd.h>
#include <string.h>
#include "error.h"
#include "options.h"
#include "transport.h"
#include "libburn.h"
#include "drive.h"
#include "sector.h"
#include "crc.h"
#include "debug.h"
#include "toc.h"
#include "write.h"
#include "libdax_msgs.h"
extern struct libdax_msgs *libdax_messenger;
#include "ecma130ab.h"
#ifdef Libburn_log_in_and_out_streaM
/* ts A61031 */
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#endif /* Libburn_log_in_and_out_streaM */
/* ts B41126 : O_BINARY is needed for Cygwin but undefined elsewhere */
#ifndef O_BINARY
#define O_BINARY 0
#endif
/*static unsigned char isrc[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";*/
#define sector_common(X) d->alba++; d->rlba X;
static void uncook_subs(unsigned char *dest, unsigned char *source)
{
int i, j, code;
memset(dest, 0, 96);
for (i = 0; i < 12; i++) {
for (j = 0; j < 8; j++) {
for (code = 0; code < 8; code++) {
if (source[code * 12 + i] & 0x80)
dest[j + i * 8] |= (1 << (7 - code));
source[code * 12 + i] <<= 1;
}
}
}
}
/* @return >=0 : valid , <0 invalid */
int sector_get_outmode(enum burn_write_types write_type,
enum burn_block_types block_type)
{
/* ts A61103 : extended SAO condition to TAO */
if (write_type == BURN_WRITE_SAO || write_type == BURN_WRITE_TAO)
return 0;
else
switch (block_type) {
case BURN_BLOCK_RAW0:
return BURN_MODE_RAW;
case BURN_BLOCK_RAW16:
return BURN_MODE_RAW | BURN_SUBCODE_P16;
case BURN_BLOCK_RAW96P:
return BURN_MODE_RAW | BURN_SUBCODE_P96;
case BURN_BLOCK_RAW96R:
return BURN_MODE_RAW | BURN_SUBCODE_R96;
case BURN_BLOCK_MODE1:
return BURN_MODE1;
default:
return -1;
}
/* ts A61007 : now handled in burn_write_opts_set_write_type() */
/* a ssert(0); */ /* return BURN_MODE_UNIMPLEMENTED :) */
}
/* 0 means "same as inmode" */
static int get_outmode(struct burn_write_opts *o)
{
/* ts A61007 */
return sector_get_outmode(o->write_type, o->block_type);
/* -1 is prevented by check in burn_write_opts_set_write_type() */
/* a ssert(0); */ /* return BURN_MODE_UNIMPLEMENTED :) */
}
static void get_bytes(struct burn_track *track, int count, unsigned char *data)
{
int valid, shortage, curr, i, tr;
#ifdef Libburn_log_in_and_out_streaM
/* ts A61031 */
static int tee_fd= -1;
if(tee_fd==-1)
tee_fd= open("/tmp/libburn_sg_readin",
O_WRONLY | O_CREAT | O_TRUNC | O_BINARY,
S_IRUSR | S_IWUSR);
#endif /* Libburn_log_in_and_out_streaM */
/* no track pointer means we're just generating 0s */
if (!track) {
memset(data, 0, count);
return;
}
/* first we use up any offset */
valid = track->offset - track->offsetcount;
if (valid > count)
valid = count;
if (valid) {
track->offsetcount += valid;
memset(data, 0, valid);
}
shortage = count - valid;
if (!shortage)
goto ex;
/* Next we use source data */
curr = valid;
if (!track->eos) {
if (track->source->read != NULL)
valid = track->source->read(track->source,
data + curr, count - curr);
else
valid = track->source->read_xt(track->source,
data + curr, count - curr);
} else valid = 0;
if (valid <= 0) { /* ts A61031 : extended from (valid == -1) */
track->eos = 1;
valid = 0;
}
track->sourcecount += valid;
#ifdef Libburn_log_in_and_out_streaM
/* ts A61031 */
if(tee_fd!=-1 && valid>0) {
write(tee_fd, data + curr, valid);
}
#endif /* Libburn_log_in_and_out_streaM */
curr += valid;
shortage = count - curr;
if (!shortage)
goto ex;
/* Before going to the next track, we run through any tail */
valid = track->tail - track->tailcount;
if (valid > count - curr)
valid = count - curr;
if (valid) {
track->tailcount += valid;
memset(data + curr, 0, valid);
}
curr += valid;
shortage -= valid;
if (!shortage)
goto ex;
/* ts A61031 - B10103 */
if (shortage >= count)
track->track_data_done = 1;
if (track->end_on_premature_eoi && shortage >= count &&
!track->open_ended) {
char msg[80];
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);
missing = track_blocks * inp_block_size - track->sourcecount;
sprintf(msg,
"Premature end of input encountered. Missing: %.f bytes",
(double) missing);
libdax_msgs_submit(libdax_messenger, -1, 0x00020180,
LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH,
msg, 0,0);
/* Memorize that premature end of input happened */
track->end_on_premature_eoi = 2;
}
if (track->open_ended || track->end_on_premature_eoi)
goto ex;
/* If we're still short, and there's a "next" pointer, we pull from that.
if that depletes, we'll just fill with 0s.
*/
if (track->source->next) {
struct burn_source *src;
printf("pulling from next track\n");
src = track->source->next;
valid = src->read(src, data + curr, shortage);
if (valid > 0) {
shortage -= valid;
curr += valid;
}
}
ex:;
/* ts A61024 : general finalizing processing */
if(shortage)
memset(data + curr, 0, shortage); /* this is old icculus.org */
if (track->swap_source_bytes == 1) {
for (i = 1; i < count; i += 2) {
tr = data[i];
data[i] = data[i-1];
data[i-1] = tr;
}
}
}
/* ts B20113 : outsourced from get_sector() */
int sector_write_buffer(struct burn_drive *d,
struct burn_track *track, int flag)
{
int err, i;
struct buffer *out;
out = d->buffer;
if (out->sectors <= 0)
return 2;
err = d->write(d, d->nwa, out);
if (err == BE_CANCELLED)
return 0;
/* ts A61101 */
if(track != NULL) {
track->writecount += out->bytes;
track->written_sectors += out->sectors;
/* Determine current index */
for (i = d->progress.index; i + 1 < track->indices; i++) {
if (track->index[i + 1] > d->nwa + out->sectors)
break;
d->progress.index = i + 1;
}
}
/* ts A61119 */
d->progress.buffered_bytes += out->bytes;
d->nwa += out->sectors;
out->bytes = 0;
out->sectors = 0;
return 1;
}
/* ts A61009 : seems to hand out sector start pointer in opts->drive->buffer
and to count hand outs as well as reserved bytes */
/* ts A61101 : added parameter track for counting written bytes */
static unsigned char *get_sector(struct burn_write_opts *opts,
struct burn_track *track, int inmode)
{
struct burn_drive *d = opts->drive;
struct buffer *out = d->buffer;
int outmode, seclen, write_ret;
unsigned char *ret;
outmode = get_outmode(opts);
if (outmode == 0)
outmode = inmode;
/* ts A61009 : react on eventual failure of burn_sector_length()
(should not happen if API tested properly).
Ensures out->bytes >= out->sectors */
seclen = burn_sector_length(outmode);
if (seclen <= 0)
return NULL;
seclen += burn_subcode_length(outmode);
/* ts A61219 : opts->obs is eventually a 32k trigger for DVD */
/* (there is enough buffer size reserve for track->cdxa_conversion) */
if (out->bytes + seclen > BUFFER_SIZE ||
(opts->obs > 0 && out->bytes + seclen > opts->obs)) {
write_ret = sector_write_buffer(d, track, 0);
if (write_ret <= 0)
return NULL;
}
ret = out->data + out->bytes;
out->bytes += seclen;
out->sectors++;
return ret;
}
/* ts A61031 */
/* Revoke the counting of the most recent sector handed out by get_sector() */
static void unget_sector(struct burn_write_opts *opts, int inmode)
{
struct burn_drive *d = opts->drive;
struct buffer *out = d->buffer;
int outmode;
int seclen;
outmode = get_outmode(opts);
if (outmode == 0)
outmode = inmode;
/* ts A61009 : react on eventual failure of burn_sector_length()
(should not happen if API tested properly).
Ensures out->bytes >= out->sectors */
seclen = burn_sector_length(outmode);
if (seclen <= 0)
return;
seclen += burn_subcode_length(outmode);
out->bytes -= seclen;
out->sectors--;
}
/* either inmode == outmode, or outmode == raw. anything else is bad news */
/* ts A61010 : changed type to int in order to propagate said bad news */
/** @return 1 is ok, <= 0 is failure */
static int convert_data(struct burn_write_opts *o, struct burn_track *track,
int inmode, unsigned char *data)
{
int outlen, inlen;
int offset = -1;
int outmode;
outmode = get_outmode(o);
if (outmode == 0)
outmode = inmode;
outlen = burn_sector_length(outmode);
inlen = burn_sector_length(inmode);
/* ts A61010 */
/* a ssert(outlen >= inlen); */
if (outlen < inlen || outlen < 0 || inlen < 0)
return 0;
if ((outmode & BURN_MODE_BITS) == (inmode & BURN_MODE_BITS)) {
/* see MMC-5 4.2.3.8.5.3 Block Format for Mode 2 form 1 Data
Table 24 Mode 2 Formed Sector Sub-header Format */
if (track != NULL)
if (track->cdxa_conversion == 1)
inlen += 8;
get_bytes(track, inlen, data);
if (track != NULL)
if (track->cdxa_conversion == 1)
memmove(data, data + 8, inlen - 8);
return 1;
}
/* ts A61010 */
/* a ssert(outmode & BURN_MODE_RAW); */
if (!(outmode & BURN_MODE_RAW))
return 0;
if (inmode & BURN_MODE1)
offset = 16;
if (inmode & BURN_MODE_RAW)
offset = 0;
if (inmode & BURN_AUDIO)
offset = 0;
/* ts A61010 */
/* a ssert(offset != -1); */
if (offset == -1)
return 0;
get_bytes(track, inlen, data + offset);
return 1;
}
static void convert_subs(struct burn_write_opts *o, int inmode,
unsigned char *subs, unsigned char *sector)
{
unsigned char *out;
int outmode;
outmode = get_outmode(o);
if (outmode == 0)
outmode = inmode;
sector += burn_sector_length(outmode);
/* XXX for sao with subs, we'd need something else... */
switch (o->block_type) {
case BURN_BLOCK_RAW96R:
uncook_subs(sector, subs);
break;
case BURN_BLOCK_RAW16:
memcpy(sector, subs + 12, 12);
out = sector + 12;
out[0] = 0;
out[1] = 0;
out[2] = 0;
/*XXX find a better way to deal with partially damaged P channels*/
if (subs[2] != 0)
out[3] = 0x80;
else
out[3] = 0;
out = sector + 10;
out[0] = ~out[0];
out[1] = ~out[1];
break;
/* ts A61119 : to silence compiler warnings */
default:;
}
}
static void subcode_toc(struct burn_drive *d, int mode, unsigned char *data)
{
unsigned char *q;
int track;
int crc;
int min, sec, frame;
track = d->toc_temp / 3;
memset(data, 0, 96);
q = data + 12;
burn_lba_to_msf(d->rlba, &min, &sec, &frame);
/*XXX track numbers are BCD
a0 - 1st track ctrl
a1 - last track ctrl
a2 - lout ctrl
*/
q[0] = (d->toc_entry[track].control << 4) + 1;
q[1] = 0;
if (d->toc_entry[track].point < 100)
q[2] = dec_to_bcd(d->toc_entry[track].point);
else
q[2] = d->toc_entry[track].point;
q[3] = dec_to_bcd(min);
q[4] = dec_to_bcd(sec);
q[5] = dec_to_bcd(frame);
q[6] = 0;
q[7] = dec_to_bcd(d->toc_entry[track].pmin);
q[8] = dec_to_bcd(d->toc_entry[track].psec);
q[9] = dec_to_bcd(d->toc_entry[track].pframe);
#ifdef Libburn_no_crc_C
crc = 0; /* dummy */
#else
crc = crc_ccitt(q, 10);
#endif
q[10] = crc >> 8;
q[11] = crc & 0xFF;
d->toc_temp++;
d->toc_temp %= (d->toc_entries * 3);
}
int sector_toc(struct burn_write_opts *o, int mode)
{
struct burn_drive *d = o->drive;
unsigned char *data;
unsigned char subs[96];
data = get_sector(o, NULL, mode);
if (data == NULL)
return 0;
/* ts A61010 */
if (convert_data(o, NULL, mode, data) <= 0)
return 0;
subcode_toc(d, mode, subs);
convert_subs(o, mode, subs, data);
if (sector_headers(o, data, mode, 1) <= 0)
return 0;
sector_common(++)
return 1;
}
int sector_pregap(struct burn_write_opts *o,
unsigned char tno, unsigned char control, int mode)
{
struct burn_drive *d = o->drive;
unsigned char *data;
unsigned char subs[96];
data = get_sector(o, NULL, mode);
if (data == NULL)
return 0;
/* ts A61010 */
if (convert_data(o, NULL, mode, data) <= 0)
return 0;
subcode_user(o, subs, tno, control, 0, NULL, 1);
convert_subs(o, mode, subs, data);
if (sector_headers(o, data, mode, 0) <= 0)
return 0;
sector_common(--)
return 1;
}
int sector_postgap(struct burn_write_opts *o,
unsigned char tno, unsigned char control, int mode)
{
struct burn_drive *d = o->drive;
unsigned char subs[96];
unsigned char *data;
data = get_sector(o, NULL, mode);
if (data == NULL)
return 0;
/* ts A61010 */
if (convert_data(o, NULL, mode, data) <= 0)
return 0;
/* use last index in track */
subcode_user(o, subs, tno, control, 1, NULL, 1);
convert_subs(o, mode, subs, data);
if (sector_headers(o, data, mode, 0) <= 0)
return 0;
sector_common(++)
return 1;
}
static void subcode_lout(struct burn_write_opts *o, unsigned char control,
unsigned char *data)
{
struct burn_drive *d = o->drive;
unsigned char *q;
int crc;
int rmin, min, rsec, sec, rframe, frame;
memset(data, 0, 96);
q = data + 12;
burn_lba_to_msf(d->alba, &min, &sec, &frame);
burn_lba_to_msf(d->rlba, &rmin, &rsec, &rframe);
if (((rmin == 0) && (rsec == 0) && (rframe == 0)) ||
((rsec >= 2) && !((rframe / 19) % 2)))
memset(data, 0xFF, 12);
q[0] = (control << 4) + 1;
q[1] = 0xAA;
q[2] = 0x01;
q[3] = dec_to_bcd(rmin);
q[4] = dec_to_bcd(rsec);
q[5] = dec_to_bcd(rframe);
q[6] = 0;
q[7] = dec_to_bcd(min);
q[8] = dec_to_bcd(sec);
q[9] = dec_to_bcd(frame);
#ifdef Libburn_no_crc_C
crc = 0; /* dummy */
#else
crc = crc_ccitt(q, 10);
#endif
q[10] = crc >> 8;
q[11] = crc & 0xFF;
}
static char char_to_isrc(char c)
{
if (c >= '0' && c <= '9')
return c - '0';
if (c >= 'A' && c <= 'Z')
return 0x11 + (c - 'A');
if (c >= 'a' && c <= 'z')
return 0x11 + (c - 'a');
/* ts A61008 : obsoleted by test in burn_track_set_isrc() */
/* a ssert(0); */
return 0;
}
void subcode_user(struct burn_write_opts *o, unsigned char *subcodes,
unsigned char tno, unsigned char control,
unsigned char indx, struct isrc *isrc, int psub)
{
struct burn_drive *d = o->drive;
unsigned char *p, *q;
int crc;
int m, s, f, c, qmode; /* 1, 2 or 3 */
memset(subcodes, 0, 96);
p = subcodes;
if ((tno == 1) && (d->rlba == -150))
memset(p, 0xFF, 12);
if (psub)
memset(p, 0xFF, 12);
q = subcodes + 12;
qmode = 1;
/* every 1 in 10 we can do something different */
if (d->rlba % 10 == 0) {
/* each of these can occur 1 in 100 */
if ((d->rlba / 10) % 10 == 0) {
if (o->has_mediacatalog)
qmode = 2;
} else if ((d->rlba / 10) % 10 == 1) {
if (isrc && isrc->has_isrc)
qmode = 3;
}
}
/* ts A61010 : this cannot happen. Assert for fun ? */
/* a ssert(qmode == 1 || qmode == 2 || qmode == 3); */
switch (qmode) {
case 1:
q[1] = dec_to_bcd(tno); /* track number */
q[2] = dec_to_bcd(indx); /* index XXX read this shit
from the track array */
burn_lba_to_msf(d->rlba, &m, &s, &f);
q[3] = dec_to_bcd(m); /* rel min */
q[4] = dec_to_bcd(s); /* rel sec */
q[5] = dec_to_bcd(f); /* rel frame */
q[6] = 0; /* zero */
burn_lba_to_msf(d->alba, &m, &s, &f);
q[7] = dec_to_bcd(m); /* abs min */
q[8] = dec_to_bcd(s); /* abs sec */
q[9] = dec_to_bcd(f); /* abs frame */
break;
case 2:
/* media catalog number */
q[1] = (o->mediacatalog[0] << 4) + o->mediacatalog[1];
q[2] = (o->mediacatalog[2] << 4) + o->mediacatalog[3];
q[3] = (o->mediacatalog[4] << 4) + o->mediacatalog[5];
q[4] = (o->mediacatalog[6] << 4) + o->mediacatalog[7];
q[5] = (o->mediacatalog[8] << 4) + o->mediacatalog[9];
q[6] = (o->mediacatalog[10] << 4) + o->mediacatalog[11];
q[7] = o->mediacatalog[12] << 4;
q[8] = 0;
burn_lba_to_msf(d->alba, &m, &s, &f);
q[9] = dec_to_bcd(f); /* abs frame */
break;
case 3:
c = char_to_isrc(isrc->country[0]);
/* top 6 bits of [1] is the first country code */
q[1] = c << 2;
c = char_to_isrc(isrc->country[1]);
/* bottom 2 bits of [1] is part of the second country code */
q[1] += (c >> 4);
/* top 4 bits if [2] is the rest of the second country code */
q[2] = c << 4;
c = char_to_isrc(isrc->owner[0]);
/* bottom 4 bits of [2] is part of the first owner code */
q[2] += (c >> 2);
/* top 2 bits of [3] is the rest of the first owner code */
q[3] = c << 6;
c = char_to_isrc(isrc->owner[1]);
/* bottom 6 bits of [3] is the entire second owner code */
q[3] += c;
c = char_to_isrc(isrc->owner[2]);
/* top 6 bits of [4] are the third owner code */
q[4] = c << 2;
/* [5] is the year in 2 BCD numbers */
q[5] = dec_to_bcd(isrc->year % 100);
/* [6] is the first 2 digits in the serial */
q[6] = dec_to_bcd(isrc->serial % 100);
/* [7] is the next 2 digits in the serial */
q[7] = dec_to_bcd((isrc->serial / 100) % 100);
/* the top 4 bits of [8] is the last serial digit, the rest is
zeros */
q[8] = dec_to_bcd((isrc->serial / 10000) % 10) << 4;
burn_lba_to_msf(d->alba, &m, &s, &f);
q[9] = dec_to_bcd(f); /* abs frame */
break;
}
q[0] = (control << 4) + qmode;
#ifdef Libburn_no_crc_C
crc = 0; /* dummy */
#else
crc = crc_ccitt(q, 10);
#endif
q[10] = crc >> 8;
q[11] = crc & 0xff;
}
int sector_lout(struct burn_write_opts *o, unsigned char control, int mode)
{
struct burn_drive *d = o->drive;
unsigned char subs[96];
unsigned char *data;
data = get_sector(o, NULL, mode);
if (!data)
return 0;
/* ts A61010 */
if (convert_data(o, NULL, mode, data) <= 0)
return 0;
subcode_lout(o, control, subs);
convert_subs(o, mode, subs, data);
if (sector_headers(o, data, mode, 0) <= 0)
return 0;
sector_common(++)
return 1;
}
int sector_data(struct burn_write_opts *o, struct burn_track *t, int psub)
{
struct burn_drive *d = o->drive;
unsigned char subs[96];
unsigned char *data;
data = get_sector(o, t, t->mode);
if (data == NULL)
return 0;
/* ts A61010 */
if (convert_data(o, t, t->mode, data) <= 0)
return 0;
/* ts A61031 */
if ((t->open_ended || t->end_on_premature_eoi) && t->track_data_done) {
unget_sector(o, t->mode);
return 2;
}
/* ts A61219 : allow track without .entry */
if (t->entry == NULL)
;
else if (!t->source->read_sub)
subcode_user(o, subs, t->entry->point,
t->entry->control, 1, &t->isrc, psub);
else if (!t->source->read_sub(t->source, subs, 96))
subcode_user(o, subs, t->entry->point,
t->entry->control, 1, &t->isrc, psub);
convert_subs(o, t->mode, subs, data);
if (sector_headers(o, data, t->mode, 0) <= 0)
return 0;
sector_common(++)
return 1;
}
int burn_msf_to_lba(int m, int s, int f)
{
if (m < 90)
return (m * 60 + s) * 75 + f - 150;
else
return (m * 60 + s) * 75 + f - 450150;
}
void burn_lba_to_msf(int lba, int *m, int *s, int *f)
{
if (lba >= -150) {
*m = (lba + 150) / (60 * 75);
*s = (lba + 150 - *m * 60 * 75) / 75;
*f = lba + 150 - *m * 60 * 75 - *s * 75;
} else {
*m = (lba + 450150) / (60 * 75);
*s = (lba + 450150 - *m * 60 * 75) / 75;
*f = lba + 450150 - *m * 60 * 75 - *s * 75;
}
}
int dec_to_bcd(int d)
{
int top, bottom;
top = d / 10;
bottom = d - (top * 10);
return (top << 4) + bottom;
}
int sector_headers_is_ok(struct burn_write_opts *o, int mode)
{
if (mode & BURN_AUDIO) /* no headers for "audio" */
return 1;
if (o->write_type == BURN_WRITE_SAO)
return 1;
/* ts A61031 */
if (o->write_type == BURN_WRITE_TAO)
return 1;
if (mode & BURN_MODE1)
return 2;
return 0;
}
/* ts A90830 : changed return type to int
@return 0= failure
1= success
*/
int sector_headers(struct burn_write_opts *o, unsigned char *out,
int mode, int leadin)
{
#ifdef Libburn_ecma130ab_includeD
struct burn_drive *d = o->drive;
unsigned int crc;
int min, sec, frame;
int modebyte = -1;
int ret;
ret = sector_headers_is_ok(o, mode);
if (ret != 2)
return !!ret;
modebyte = 1;
out[0] = 0;
memset(out + 1, 0xFF, 10); /* sync */
out[11] = 0;
if (leadin) {
burn_lba_to_msf(d->rlba, &min, &sec, &frame);
out[12] = dec_to_bcd(min) + 0xA0;
out[13] = dec_to_bcd(sec);
out[14] = dec_to_bcd(frame);
out[15] = modebyte;
} else {
burn_lba_to_msf(d->alba, &min, &sec, &frame);
out[12] = dec_to_bcd(min);
out[13] = dec_to_bcd(sec);
out[14] = dec_to_bcd(frame);
out[15] = modebyte;
}
if (mode & BURN_MODE1) {
#ifdef Libburn_no_crc_C
crc = 0; /* dummy */
#else
crc = crc_32(out, 2064);
#endif
out[2064] = crc & 0xFF;
crc >>= 8;
out[2065] = crc & 0xFF;
crc >>= 8;
out[2066] = crc & 0xFF;
crc >>= 8;
out[2067] = crc & 0xFF;
}
if (mode & BURN_MODE1) {
memset(out + 2068, 0, 8);
burn_rspc_parity_p(out);
burn_rspc_parity_q(out);
}
burn_ecma130_scramble(out);
return 1;
#else /* Libburn_ecma130ab_includeD */
int ret;
ret = sector_headers_is_ok(o, mode);
if (ret != 2)
return (!! ret);
/* ts A90830 : lec.c is copied from cdrdao.
I have no idea yet how lec.c implements the Reed-Solomon encoding
which is described in ECMA-130 for CD-ROM.
So this got removed for now.
*/
libdax_msgs_submit(libdax_messenger, o->drive->global_index,
0x0002010a,
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
"Raw CD write modes are not supported", 0, 0);
return 0;
#endif /* ! Libburn_ecma130ab_includeD */
}
#if 0
void process_q(struct burn_drive *d, unsigned char *q)
{
unsigned char i[5];
int mode;
mode = q[0] & 0xF;
/* burn_print(12, "mode: %d : ", mode);*/
switch (mode) {
case 1:
/* burn_print(12, "tno = %d : ", q[1]);
burn_print(12, "index = %d\n", q[2]);
*/
/* q[1] is the track number (starting at 1) q[2] is the index
number (starting at 0) */
#warning this is totally bogus
if (q[1] - 1 > 99)
break;
if (q[2] > d->toc->track[q[1] - 1].indices) {
burn_print(12, "new index at %d\n", d->alba);
d->toc->track[q[1] - 1].index[q[2]] = d->alba;
d->toc->track[q[1] - 1].indices++;
}
break;
case 2:
/* XXX do not ignore these */
break;
case 3:
/* burn_print(12, "ISRC data in mode 3 q\n");*/
i[0] = isrc[(q[1] << 2) >> 2];
/* burn_print(12, "0x%x 0x%x 0x%x 0x%x 0x%x\n", q[1], q[2], q[3], q[4], q[5]);
burn_print(12, "ISRC - %c%c%c%c%c\n", i[0], i[1], i[2], i[3], i[4]);
*/
break;
default:
/* ts A61009 : if reactivated then witout Assert */
a ssert(0);
}
}
#endif
/* this needs more info. subs in the data? control/adr? */
/* 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.
*/
/*
#warning sector_identify needs to be written
*/
int sector_identify(unsigned char *data)
{
/*
burn_ecma130_scramble(data);
check mode byte for 1 or 2
test parity to see if it's a valid sector
if invalid, return BURN_MODE_AUDIO;
else return mode byte (what about mode 2 formless? heh)
*/
return BURN_MODE1;
}

44
libburn/sector.h Normal file
View File

@ -0,0 +1,44 @@
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
Copyright (c) 2006 - 2010 Thomas Schmitt <scdbackup@gmx.net>
Provided under GPL version 2 or later.
*/
#ifndef __SECTOR
#define __SECTOR
#include "libburn.h"
#include "transport.h"
struct burn_drive;
struct isrc;
int dec_to_bcd(int);
int sector_toc(struct burn_write_opts *, int mode);
int sector_pregap(struct burn_write_opts *, unsigned char tno,
unsigned char control, int mode);
int sector_postgap(struct burn_write_opts *, unsigned char tno,
unsigned char control, int mode);
int sector_lout(struct burn_write_opts *, unsigned char control, int mode);
int sector_data(struct burn_write_opts *, struct burn_track *t, int psub);
/* ts B20113 */
int sector_write_buffer(struct burn_drive *d,
struct burn_track *track, int flag);
/* ts A61009 */
int sector_headers_is_ok(struct burn_write_opts *o, int mode);
int sector_headers(struct burn_write_opts *, unsigned char *,
int mode, int leadin);
void subcode_user(struct burn_write_opts *, unsigned char *s,
unsigned char tno, unsigned char control,
unsigned char index, struct isrc *isrc, int psub);
int sector_identify(unsigned char *);
void process_q(struct burn_drive *d, unsigned char *q);
#endif /* __SECTOR */

359
libburn/sg-dummy.c Normal file
View File

@ -0,0 +1,359 @@
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
/*
Copyright (c) 2009 - 2011 Thomas Schmitt <scdbackup@gmx.net>
Provided under GPL version 2 or later.
*/
#ifdef HAVE_CONFIG_H
#include "../config.h"
#endif
/*
This is the main operating system dependent SCSI part of libburn. It implements
the transport level aspects of SCSI control and command i/o.
Present implementation: default dummy which enables libburn only to work
with stdio: pseudo drive addresses.
For real implementations see sg-linux.c, sg-freebsd.c,
sg-libcdio.c
*/
#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <string.h>
#include <stdlib.h>
#ifdef Libburn_os_has_statvfS
#include <sys/statvfs.h>
#endif /* Libburn_os_has_stavtfS */
/* ts B41126 : O_BINARY is needed for Cygwin but undefined elsewhere */
#ifndef O_BINARY
#define O_BINARY 0
#endif
#include "transport.h"
#include "drive.h"
#include "sg.h"
#include "spc.h"
#include "mmc.h"
#include "sbc.h"
#include "debug.h"
#include "toc.h"
#include "util.h"
#include "init.h"
#include "libdax_msgs.h"
extern struct libdax_msgs *libdax_messenger;
/** Returns the id string of the SCSI transport adapter and eventually
needed operating system facilities.
This call is usable even if sg_initialize() was not called yet. In that
case a preliminary constant message might be issued if detailed info is
not available yet.
@param msg returns id string
@param flag unused yet, submit 0
@return 1 = success, <=0 = failure
*/
int sg_id_string(char msg[1024], int flag)
{
strcpy(msg, "internal X/Open adapter sg-dummy");
return 1;
}
/** Performs global initialization of the SCSI transport adapter and eventually
needed operating system facilities. Checks for compatibility supporting
software components.
@param msg returns ids and/or error messages of eventual helpers
@param flag unused yet, submit 0
@return 1 = success, <=0 = failure
*/
int sg_initialize(char msg[1024], int flag)
{
return sg_id_string(msg, 0);
}
/** Performs global finalization of the SCSI transport adapter and eventually
needed operating system facilities. Releases globally acquired resources.
@param flag unused yet, submit 0
@return 1 = success, <=0 = failure
*/
int sg_shutdown(int flag)
{
return 1;
}
/** Finalizes BURN_OS_TRANSPORT_DRIVE_ELEMENTS, the components of
struct burn_drive which are defined in os-*.h.
This will be called when a burn_drive gets disposed.
@param d the drive to be finalized
@param flag unused yet, submit 0
@return 1 = success, <=0 = failure
*/
int sg_dispose_drive(struct burn_drive *d, int flag)
{
return 1;
}
/** Returns the next index number and the next enumerated drive address.
The enumeration has to cover all available and accessible drives. It is
allowed to return addresses of drives which are not available but under
some (even exotic) circumstances could be available. It is on the other
hand allowed, only to hand out addresses which can really be used right
in the moment of this call. (This implementation chooses the former.)
@param idx An opaque handle. Make no own theories about it.
@param adr Takes the reply
@param adr_size Gives maximum size of reply including final 0
@param initialize 1 = start new,
0 = continue, use no other values for now
-1 = finish
@return 1 = reply is a valid address , 0 = no further address available
-1 = severe error (e.g. adr_size too small)
*/
int sg_give_next_adr(burn_drive_enumerator_t *idx,
char adr[], int adr_size, int initialize)
{
return 0;
}
/** Brings all available, not-whitelist-banned, and accessible drives into
libburn's list of drives.
*/
/* ts A61115: replacing call to sg-implementation internals from drive.c */
int scsi_enumerate_drives(void)
{
libdax_msgs_submit(libdax_messenger, -1, 0x0002016b,
LIBDAX_MSGS_SEV_WARNING, LIBDAX_MSGS_PRIO_HIGH,
"No MMC transport adapter is present. Running on sg-dummy.c.",
0, 0);
return 1;
}
/** Tells wether libburn has the given drive in use or exclusively reserved.
If it is "open" then libburn will eventually call sg_release() on it when
it is time to give up usage and reservation.
*/
/** Published as burn_drive.drive_is_open() */
int sg_drive_is_open(struct burn_drive * d)
{
return 0;
}
/** Opens the drive for SCSI commands and - if burn activities are prone
to external interference on your system - obtains an exclusive access lock
on the drive. (Note: this is not physical tray locking.)
A drive that has been opened with sg_grab() will eventually be handed
over to sg_release() for closing and unreserving.
*/
int sg_grab(struct burn_drive *d)
{
libdax_msgs_submit(libdax_messenger, d->global_index, 0x0002016a,
LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH,
"No MMC transport adapter is present. Running on sg-dummy.c.",
0, 0);
return 0;
}
/** Gives up the drive for SCSI commands and releases eventual access locks.
(Note: this is not physical tray locking.)
*/
int sg_release(struct burn_drive *d)
{
return 0;
}
/** Sends a SCSI command to the drive, receives reply and evaluates wether
the command succeeded or shall be retried or finally failed.
Returned SCSI errors shall not lead to a return value indicating failure.
The callers get notified by c->error. An SCSI failure which leads not to
a retry shall be notified via scsi_notify_error().
The Libburn_log_sg_commandS facility might be of help when problems with
a drive have to be examined. It shall stay disabled for normal use.
@return: 1 success , <=0 failure
*/
int sg_issue_command(struct burn_drive *d, struct command *c)
{
libdax_msgs_submit(libdax_messenger, d->global_index, 0x0002016a,
LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH,
"No MMC transport adapter is present. Running on sg-dummy.c.",
0, 0);
return -1;
}
/** Tries to obtain SCSI address parameters.
@return 1 is success , 0 is failure
*/
int sg_obtain_scsi_adr(char *path, int *bus_no, int *host_no, int *channel_no,
int *target_no, int *lun_no)
{
libdax_msgs_submit(libdax_messenger, -1, 0x0002016c,
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH,
"No MMC transport adapter is present. Running on sg-dummy.c.",
0, 0);
return 0;
}
/** Tells wether a text is a persistent address as listed by the enumeration
functions.
*/
int sg_is_enumerable_adr(char *adr)
{
return(0);
}
/* Return 1 if the given path leads to a regular file or a device that can be
fseeked, read, and possibly written with 2 kB granularity.
*/
int burn_os_is_2k_seekrw(char *path, int flag)
{
struct stat stbuf;
if (stat(path, &stbuf) == -1)
return 0;
if (S_ISREG(stbuf.st_mode))
return 1;
if (S_ISBLK(stbuf.st_mode))
return 1;
return 0;
}
/** Estimate the potential payload capacity of a file address.
@param path The address of the file to be examined. If it does not
exist yet, then the directory will be inquired.
@param bytes The pointed value gets modified, but only if an estimation is
possible.
@return -2 = cannot perform necessary operations on file object
-1 = neither path nor dirname of path exist
0 = could not estimate size capacity of file object
1 = estimation has been made, bytes was set
*/
int burn_os_stdio_capacity(char *path, off_t write_start, off_t *bytes)
{
struct stat stbuf;
#ifdef Libburn_os_has_statvfS
struct statvfs vfsbuf;
#endif
char *testpath = NULL, *cpt;
off_t add_size = 0;
int ret;
BURN_ALLOC_MEM(testpath, char, 4096);
testpath[0] = 0;
if (stat(path, &stbuf) == -1) {
strcpy(testpath, path);
cpt = strrchr(testpath, '/');
if(cpt == NULL)
strcpy(testpath, ".");
else if(cpt == testpath)
testpath[1] = 0;
else
*cpt = 0;
if (stat(testpath, &stbuf) == -1)
{ret = -1; goto ex;}
#ifdef Libburn_if_this_was_linuX
} else if(S_ISBLK(stbuf.st_mode)) {
long blocks;
blocks = *bytes / 512;
fd = open(path, open_mode | O_BINARY);
if (fd == -1)
{ret = -2; goto ex;}
ret = ioctl(fd, BLKGETSIZE, &blocks);
close(fd);
if (ret == -1)
{ret = -2; goto ex;}
*bytes = ((off_t) blocks) * (off_t) 512;
#endif /* Libburn_if_this_was_linuX */
} else if(S_ISREG(stbuf.st_mode)) {
add_size = burn_sparse_file_addsize(write_start, &stbuf);
strcpy(testpath, path);
} else
{ret = 0; goto ex;}
if (testpath[0]) {
#ifdef Libburn_os_has_statvfS
if (statvfs(testpath, &vfsbuf) == -1)
{ret = -2; goto ex;}
*bytes = add_size + ((off_t) vfsbuf.f_frsize) *
(off_t) vfsbuf.f_bavail;
#else /* Libburn_os_has_statvfS */
{ret = 0; goto ex;}
#endif /* ! Libburn_os_has_stavtfS */
}
ret = 1;
ex:;
BURN_FREE_MEM(testpath);
return ret;
}
/* ts A91122 : an interface to open(O_DIRECT) or similar OS tricks. */
#ifdef Libburn_read_o_direcT
/* No special O_DIRECT-like precautions are implemented here */
#endif /* Libburn_read_o_direcT */
int burn_os_open_track_src(char *path, int open_flags, int flag)
{
int fd;
fd = open(path, open_flags | O_BINARY);
return fd;
}
void *burn_os_alloc_buffer(size_t amount, int flag)
{
void *buf = NULL;
buf = calloc(1, amount);
return buf;
}
int burn_os_free_buffer(void *buffer, size_t amount, int flag)
{
if (buffer == NULL)
return 0;
free(buffer);
return 1;
}

830
libburn/sg-freebsd-port.c Normal file
View File

@ -0,0 +1,830 @@
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
/*
Copyright (c) 2006 - 2011 Thomas Schmitt <scdbackup@gmx.net>
Provided under GPL version 2 or later.
*/
/* THIS CODE IS NOT FUNCTIONAL YET !!! */
/*
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: FreeBSD CAM (untested)
PORTING:
Porting libburn typically will consist of adding a new operating system case
to the following switcher files:
os.h Operating system specific libburn definitions and declarations.
sg.c Operating system dependent transport level modules.
and of deriving the following system specific files from existing examples:
os-*.h Included by os.h. You will need some general system knowledge
about signals and knowledge about the storage object needs of your
transport level module sg-*.c.
sg-*.c This source module. You will need special system knowledge about
how to detect all potentially available drives, how to open them,
eventually how to exclusively reserve them, how to perform
SCSI transactions, how to inquire the (pseudo-)SCSI driver.
You will not need to care about CD burning, MMC or other high-level
SCSI aspects.
Said sg-*.c operations are defined by a public function interface, which has
to be implemented in a way that provides libburn with the desired services:
sg_id_string() returns an id string of the SCSI transport adapter.
It may be called before initialization but then may
return only a preliminary id.
sg_initialize() performs global initialization of the SCSI transport
adapter and eventually needed operating system
facilities. Checks for compatibility of supporting
software components.
sg_shutdown() performs global finalizations and releases golbally
aquired resources.
sg_give_next_adr() iterates over the set of potentially useful drive
address strings.
scsi_enumerate_drives() brings all available, not-whitelist-banned, and
accessible drives into libburn's list of drives.
sg_dispose_drive() finalizes adapter specifics of struct burn_drive
on destruction. Releases resources which were aquired
underneath scsi_enumerate_drives().
sg_drive_is_open() tells wether libburn has the given drive in use.
sg_grab() opens the drive for SCSI commands and ensures
undisturbed access.
sg_release() closes a drive opened by sg_grab()
sg_issue_command() sends a SCSI command to the drive, receives reply,
and evaluates wether the command succeeded or shall
be retried or finally failed.
sg_obtain_scsi_adr() tries to obtain SCSI address parameters.
burn_os_is_2k_seekrw() tells whether the given path leads to a file object
that can be used in 2 kB granularity by lseek(2),
read(2), and possibly write(2) if not read-only.
E.g. a USB stick or a hard disk.
burn_os_stdio_capacity() estimates the emulated media space of stdio-drives.
burn_os_open_track_src() opens a disk file in a way that offers best
throughput with file reading and/or SCSI write command
transmission.
burn_os_alloc_buffer() allocates a memory area that is suitable for file
descriptors issued by burn_os_open_track_src().
The buffer size may be rounded up for alignment
reasons.
burn_os_free_buffer() delete a buffer obtained by burn_os_alloc_buffer().
Porting hints are marked by the text "PORTING:".
Send feedback to libburn-hackers@pykix.org .
*/
#ifdef HAVE_CONFIG_H
#include "../config.h"
#endif
/** PORTING : ------- OS dependent headers and definitions ------ */
#include <errno.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <stdlib.h>
#include <string.h>
#include <sys/poll.h>
#include <camlib.h>
#include <cam/scsi/scsi_message.h>
#include <cam/scsi/scsi_pass.h>
#include <err.h> /* XXX */
/* ts A70909 */
#include <sys/statvfs.h>
/** PORTING : ------ libburn portable headers and definitions ----- */
#include "transport.h"
#include "drive.h"
#include "sg.h"
#include "spc.h"
#include "mmc.h"
#include "sbc.h"
#include "debug.h"
#include "toc.h"
#include "util.h"
#include "libdax_msgs.h"
extern struct libdax_msgs *libdax_messenger;
/* is in portable part of libburn */
int burn_drive_is_banned(char *device_address);
/* ------------------------------------------------------------------------ */
/* ts A61115: Private functions. Port only if needed by public functions */
/* (Public functions are listed below) */
/* ------------------------------------------------------------------------ */
/* Helper function for scsi_give_next_adr() */
static int sg_init_enumerator(burn_drive_enumerator_t *idx)
{
idx->skip_device = 0;
if ((idx->fd = open(XPT_DEVICE, O_RDWR)) == -1) {
warn("couldn't open %s", XPT_DEVICE);
return -1;
}
memset(&(idx->ccb), 0, sizeof(union ccb));
idx->ccb.ccb_h.path_id = CAM_XPT_PATH_ID;
idx->ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
idx->ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
idx->ccb.ccb_h.func_code = XPT_DEV_MATCH;
idx->bufsize = sizeof(struct dev_match_result) * 100;
idx->ccb.cdm.match_buf_len = idx->bufsize;
idx->ccb.cdm.matches = (struct dev_match_result *)
calloc(1, idx->bufsize);
if (idx->ccb.cdm.matches == NULL) {
warnx("cannot allocate memory for matches");
close(idx->fd);
return -1;
}
idx->ccb.cdm.num_matches = 0;
idx->i = idx->ccb.cdm.num_matches; /* to trigger buffer load */
/*
* We fetch all nodes, since we display most of them in the default
* case, and all in the verbose case.
*/
idx->ccb.cdm.num_patterns = 0;
idx->ccb.cdm.pattern_buf_len = 0;
return 1;
}
/* Helper function for scsi_give_next_adr() */
static int sg_next_enumeration_buffer(burn_drive_enumerator_t *idx)
{
/*
* We do the ioctl multiple times if necessary, in case there are
* more than 100 nodes in the EDT.
*/
if (ioctl(idx->fd, CAMIOCOMMAND, &(idx->ccb)) == -1) {
warn("error sending CAMIOCOMMAND ioctl");
return -1;
}
if ((idx->ccb.ccb_h.status != CAM_REQ_CMP)
|| ((idx->ccb.cdm.status != CAM_DEV_MATCH_LAST)
&& (idx->ccb.cdm.status != CAM_DEV_MATCH_MORE))) {
warnx("got CAM error %#x, CDM error %d\n",
idx->ccb.ccb_h.status, idx->ccb.cdm.status);
return -1;
}
return 1;
}
static int sg_close_drive(struct burn_drive * d)
{
if (d->cam != NULL) {
cam_close_device(d->cam);
d->cam = NULL;
}
return 0;
}
/* ----------------------------------------------------------------------- */
/* PORTING: Private functions which contain publicly needed functionality. */
/* Their portable part must be performed. So it is probably best */
/* to replace the non-portable part and to call these functions */
/* in your port, too. */
/* ----------------------------------------------------------------------- */
/** Wraps a detected drive into libburn structures and hands it over to
libburn drive list.
*/
static void enumerate_common(char *fname, int bus_no, int host_no,
int channel_no, int target_no, int lun_no)
{
int ret;
struct burn_drive out;
/* General libburn drive setup */
burn_setup_drive(&out, fname);
/* This transport adapter uses SCSI-family commands and models
(seems the adapter would know better than its boss, if ever) */
ret = burn_scsi_setup_drive(&out, bus_no, host_no, channel_no,
target_no, lun_no, 0);
if (ret<=0)
return;
/* PORTING: ------------------- non portable part --------------- */
/* Operating system adapter is CAM */
/* Adapter specific handles and data */
out.cam = NULL;
/* PORTING: ---------------- end of non portable part ------------ */
/* Adapter specific functions with standardized names */
out.grab = sg_grab;
out.release = sg_release;
out.drive_is_open = sg_drive_is_open;
out.issue_command = sg_issue_command;
/* Finally register drive and inquire drive information */
burn_drive_finish_enum(&out);
}
/* ts A61115 */
/* ------------------------------------------------------------------------ */
/* PORTING: Public functions. These MUST be ported. */
/* ------------------------------------------------------------------------ */
/** Returns the id string of the SCSI transport adapter and eventually
needed operating system facilities.
This call is usable even if sg_initialize() was not called yet. In that
case a preliminary constant message might be issued if detailed info is
not available yet.
@param msg returns id string
@param flag unused yet, submit 0
@return 1 = success, <=0 = failure
*/
int sg_id_string(char msg[1024], int flag)
{
strcpy(msg, "internal FreeBSD CAM adapter sg-freebsd-port");
return 1;
}
/** Performs global initialization of the SCSI transport adapter and eventually
needed operating system facilities. Checks for compatibility supporting
software components.
@param msg returns ids and/or error messages of eventual helpers
@param flag unused yet, submit 0
@return 1 = success, <=0 = failure
*/
int sg_initialize(char msg[1024], int flag)
{
return sg_id_string(msg, 0);
}
/** Performs global finalization of the SCSI transport adapter and eventually
needed operating system facilities. Releases globally aquired resources.
@param flag unused yet, submit 0
@return 1 = success, <=0 = failure
*/
int sg_shutdown(int flag)
{
return 1;
}
/** Finalizes BURN_OS_TRANSPORT_DRIVE_ELEMENTS, the components of
struct burn_drive which are defined in os-*.h.
The eventual initialization of those components was made underneath
scsi_enumerate_drives().
This will be called when a burn_drive gets disposed.
@param d the drive to be finalized
@param flag unused yet, submit 0
@return 1 = success, <=0 = failure
*/
int sg_dispose_drive(struct burn_drive *d, int flag)
{
return 1;
}
/** Returns the next index number and the next enumerated drive address.
The enumeration has to cover all available and accessible drives. It is
allowed to return addresses of drives which are not available but under
some (even exotic) circumstances could be available. It is on the other
hand allowed, only to hand out addresses which can really be used right
in the moment of this call. (This implementation chooses the latter.)
@param idx An opaque handle. Make no own theories about it.
@param adr Takes the reply
@param adr_size Gives maximum size of reply including final 0
@param initialize 1 = start new,
0 = continue, use no other values for now
-1 = finish
@return 1 = reply is a valid address , 0 = no further address available
-1 = severe error (e.g. adr_size too small)
*/
int sg_give_next_adr(burn_drive_enumerator_t *idx,
char adr[], int adr_size, int initialize)
{
int ret;
if (initialize == 1) {
ret = sg_init_enumerator(idx);
if (ret<=0)
return ret;
} else if (initialize == -1) {
if(idx->fd != -1)
close(idx->fd);
idx->fd = -1;
return 0;
}
try_item:; /* This spaghetti loop keeps the number of tabs small */
/* Loop content from old scsi_enumerate_drives() */
while (idx->i >= idx->ccb.cdm.num_matches) {
ret = sg_next_enumeration_buffer(idx);
if (ret<=0)
return -1;
if (!((idx->ccb.ccb_h.status == CAM_REQ_CMP)
&& (idx->ccb.cdm.status == CAM_DEV_MATCH_MORE)) )
return 0;
idx->i = 0;
}
switch (idx->ccb.cdm.matches[idx->i].type) {
case DEV_MATCH_BUS:
break;
case DEV_MATCH_DEVICE: {
struct device_match_result* result;
result = &(idx->ccb.cdm.matches[i].result.device_result);
if (result->flags & DEV_RESULT_UNCONFIGURED)
idx->skip_device = 1;
else
idx->skip_device = 0;
break;
}
case DEV_MATCH_PERIPH: {
struct periph_match_result* result;
char buf[64];
result = &(idx->ccb.cdm.matches[i].result.periph_result);
if (idx->skip_device ||
strcmp(result->periph_name, "pass") == 0)
break;
snprintf(buf, sizeof (buf), "/dev/%s%d",
result->periph_name, result->unit_number);
if(adr_size <= strlen(buf))
return -1;
strcpy(adr, buf);
/* Found next enumerable address */
return 1;
}
default:
/* printf(stderr, "unknown match type\n"); */
break;
}
(idx->i)++;
goto try_item; /* Regular function exit is return 1 above */
}
/** Brings all available, not-whitelist-banned, and accessible drives into
libburn's list of drives.
*/
int scsi_enumerate_drives(void)
{
burn_drive_enumerator_t idx;
int initialize = 1, ret;
char buf[64];
while(1) {
ret = sg_give_next_adr(&idx, buf, sizeof(buf), initialize);
initialize = 0;
if (ret <= 0)
break;
if (burn_drive_is_banned(buf))
continue;
enumerate_common(buf, idx.result->path_id, idx.result->path_id,
0, idx.result->target_id,
idx.result->target_lun);
}
sg_give_next_adr(&idx, buf, sizeof(buf), -1);
return 1;
}
/** Tells wether libburn has the given drive in use or exclusively reserved.
If it is "open" then libburn will eventually call sg_release() on it when
it is time to give up usage and reservation.
*/
/** Published as burn_drive.drive_is_open() */
int sg_drive_is_open(struct burn_drive * d)
{
return (d->cam != NULL);
}
/** Opens the drive for SCSI commands and - if burn activities are prone
to external interference on your system - obtains an exclusive access lock
on the drive. (Note: this is not physical tray locking.)
A drive that has been opened with sg_grab() will eventually be handed
over to sg_release() for closing and unreserving.
*/
int sg_grab(struct burn_drive *d)
{
struct cam_device *cam;
if(d->cam != NULL) {
d->released = 0;
return 1;
}
cam = cam_open_device(d->devname, O_RDWR);
if (cam == NULL) {
libdax_msgs_submit(libdax_messenger, d->global_index,
0x00020003,
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
"Could not grab drive", 0/*os_errno*/, 0);
return 0;
}
d->cam = cam;
fcntl(cam->fd, F_SETOWN, getpid());
d->released = 0;
return 1;
}
/** PORTING: Is mainly about the call to sg_close_drive() and wether it
implements the demanded functionality.
*/
/** Gives up the drive for SCSI commands and releases eventual access locks.
(Note: this is not physical tray locking.)
*/
int sg_release(struct burn_drive *d)
{
if (d->cam == NULL)
return 0;
sg_close_drive(d);
return 0;
}
/** Sends a SCSI command to the drive, receives reply and evaluates wether
the command succeeded or shall be retried or finally failed.
Returned SCSI errors shall not lead to a return value indicating failure.
The callers get notified by c->error. An SCSI failure which leads not to
a retry shall be notified via scsi_notify_error().
The Libburn_log_sg_commandS facility might be of help when problems with
a drive have to be examined. It shall stay disabled for normal use.
@return: 1 success , <=0 failure
*/
int sg_issue_command(struct burn_drive *d, struct command *c)
{
int done = 0;
int err;
union ccb *ccb;
if (d->cam == NULL) {
c->error = 0;
return 0;
}
c->error = 0;
ccb = cam_getccb(d->cam);
cam_fill_csio(&ccb->csio,
1, /* retries */
NULL, /* cbfncp */
CAM_DEV_QFRZDIS, /* flags */
MSG_SIMPLE_Q_TAG, /* tag_action */
NULL, /* data_ptr */
0, /* dxfer_len */
sizeof (ccb->csio.sense_data), /* sense_len */
0, /* cdb_len */
30*1000); /* timeout */
switch (c->dir) {
case TO_DRIVE:
ccb->csio.ccb_h.flags |= CAM_DIR_OUT;
break;
case FROM_DRIVE:
ccb->csio.ccb_h.flags |= CAM_DIR_IN;
break;
case NO_TRANSFER:
ccb->csio.ccb_h.flags |= CAM_DIR_NONE;
break;
}
ccb->csio.cdb_len = c->oplen;
memcpy(&ccb->csio.cdb_io.cdb_bytes, &c->opcode, c->oplen);
if (c->page) {
ccb->csio.data_ptr = c->page->data;
if (c->dir == FROM_DRIVE) {
ccb->csio.dxfer_len = BUFFER_SIZE;
/* touch page so we can use valgrind */
memset(c->page->data, 0, BUFFER_SIZE);
} else {
/* ts A61115: removed a ssert() */
if(c->page->bytes <= 0)
return 0;
ccb->csio.dxfer_len = c->page->bytes;
}
} else {
ccb->csio.data_ptr = NULL;
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);
if (err == -1) {
libdax_msgs_submit(libdax_messenger,
d->global_index, 0x0002010c,
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
"Failed to transfer command to drive",
errno, 0);
cam_freeccb(ccb);
sg_close_drive(d);
d->released = 1;
d->busy = BURN_DRIVE_IDLE;
c->error = 1;
return -1;
}
/* 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;
cam_freeccb(ccb);
return 1;
}
switch (scsi_error(d, c->sense, 0)) {
case RETRY:
done = 0;
break;
case FAIL:
done = 1;
c->error = 1;
break;
}
} else {
done = 1;
}
if (!done)
spc_register_retry(c);
} while (!done);
cam_freeccb(ccb);
return 1;
}
/** Tries to obtain SCSI address parameters.
@return 1 is success , 0 is failure
*/
int sg_obtain_scsi_adr(char *path, int *bus_no, int *host_no, int *channel_no,
int *target_no, int *lun_no)
{
burn_drive_enumerator_t idx;
int initialize = 1, ret;
char buf[64];
struct periph_match_result* result;
while(1) {
ret = sg_give_next_adr(&idx, buf, sizeof(buf), initialize);
initialize = 0;
if (ret <= 0)
break;
if (strcmp(path, buf) != 0)
continue;
result = &(idx->ccb.cdm.matches[i].result.periph_result);
*bus_no = result->path_id;
*host_no = result->path_id;
*channel_no = 0;
*target_no = result->target_id
*lun_no = result->target_lun;
sg_give_next_adr(&idx, buf, sizeof(buf), -1);
return 1;
}
sg_give_next_adr(&idx, buf, sizeof(buf), -1);
return (0);
}
/** Tells wether a text is a persistent address as listed by the enumeration
functions.
*/
int sg_is_enumerable_adr(char* adr)
{
burn_drive_enumerator_t idx;
int initialize = 1, ret;
char buf[64];
while(1) {
ret = sg_give_next_adr(&idx, buf, sizeof(buf), initialize);
initialize = 0;
if (ret <= 0)
break;
if (strcmp(adr, buf) == 0) {
sg_give_next_adr(&idx, buf, sizeof(buf), -1);
return 1;
}
}
sg_give_next_adr(&idx, buf, sizeof(buf), -1);
return (0);
}
/* ts B00115 */
/* Return 1 if the given path leads to a regular file or a device that can be
seeked, written, and read with 2 kB granularity.
*/
int burn_os_is_2k_seekrw(char *path, int flag)
{
struct stat stbuf;
char *spt;
int i, e;
if (stat(path, &stbuf) == -1)
return 0;
if (S_ISREG(stbuf.st_mode))
return 1;
if (!S_ISCHR(stbuf.st_mode))
return 0;
spt = strrchr(path, '/');
if (spt == NULL)
spt = path;
else
spt++;
e = strlen(spt);
for (i = strlen(spt) - 1; i > 0; i--)
if (spt[i] >= '0' && spt[i] <= '9')
e = i;
if (strncmp(spt, "da", e) == 0) /* SCSI disk. E.g. USB stick. */
return 1;
if (strncmp(spt, "cd", e) == 0) /* SCSI CD drive might be writeable. */
return 1;
if (strncmp(spt, "ad", e) == 0) /* IDE hard drive */
return 1;
if (strncmp(spt, "acd", e) == 0) /* IDE CD drive might be writeable */
return 1;
if (strncmp(spt, "fd", e) == 0) /* Floppy disk */
return 1;
if (strncmp(spt, "fla", e) == 0) /* Flash drive */
return 1;
return 0;
}
/* ts A70909 */
/** Estimate the potential payload capacity of a file address.
@param path The address of the file to be examined. If it does not
exist yet, then the directory will be inquired.
@param bytes This value gets modified if an estimation is possible
@return -2 = cannot perform necessary operations on file object
-1 = neither path nor dirname of path exist
0 = could not estimate size capacity of file object
1 = estimation has been made, bytes was set
*/
int burn_os_stdio_capacity(char *path, off_t write_start, off_t *bytes)
{
struct stat stbuf;
struct statvfs vfsbuf;
char *testpath = NULL, *cpt;
off_t add_size = 0;
int fd, ret;
BURN_ALLOC_MEM(testpath, char, 4096);
testpath[0] = 0;
if (stat(path, &stbuf) == -1) {
strcpy(testpath, path);
cpt = strrchr(testpath, '/');
if(cpt == NULL)
strcpy(testpath, ".");
else if(cpt == testpath)
testpath[1] = 0;
else
*cpt = 0;
if (stat(testpath, &stbuf) == -1)
{ret = -1; goto ex;}
#ifdef Libburn_if_this_was_linuX
} else if(S_ISBLK(stbuf.st_mode)) {
int open_mode = O_RDWR, fd, ret;
long blocks;
blocks = *bytes / 512;
if(burn_sg_open_o_excl)
open_mode |= O_EXCL;
fd = open(path, open_mode);
if (fd == -1)
{ret = -2; goto ex;}
ret = ioctl(fd, BLKGETSIZE, &blocks);
close(fd);
if (ret == -1)
{ret = -2; goto ex;}
*bytes = ((off_t) blocks) * (off_t) 512;
#endif /* Libburn_if_this_was_linuX */
} else if(S_ISCHR(stbuf.st_mode)) {
fd = open(path, O_RDONLY);
if (fd == -1)
{ret = -2; goto ex;}
ret = ioctl(fd, DIOCGMEDIASIZE, &add_size);
close(fd);
if (ret == -1)
{ret = -2; goto ex;}
*bytes = add_size;
} else if(S_ISREG(stbuf.st_mode)) {
add_size = burn_sparse_file_addsize(write_start, &stbuf);
strcpy(testpath, path);
} else
{ret = 0; goto ex;}
if (testpath[0]) {
if (statvfs(testpath, &vfsbuf) == -1)
{ret = -2; goto ex;}
*bytes = add_size + ((off_t) vfsbuf.f_frsize) *
(off_t) vfsbuf.f_bavail;
}
ret = 1;
ex:
BURN_FREE_MEM(testpath);
return ret;
}
/* ts A91122 : an interface to open(O_DIRECT) or similar OS tricks. */
#ifdef Libburn_read_o_direcT
/* No special O_DIRECT-like precautions are implemented here */
#endif /* Libburn_read_o_direcT */
int burn_os_open_track_src(char *path, int open_flags, int flag)
{
int fd;
fd = open(path, open_flags);
return fd;
}
void *burn_os_alloc_buffer(size_t amount, int flag)
{
void *buf = NULL;
buf = calloc(1, amount);
return buf;
}
int burn_os_free_buffer(void *buffer, size_t amount, int flag)
{
if (buffer == NULL)
return 0;
free(buffer);
return 1;
}

1181
libburn/sg-freebsd.c Normal file

File diff suppressed because it is too large Load Diff

1019
libburn/sg-libcdio.c Normal file

File diff suppressed because it is too large Load Diff

2553
libburn/sg-linux.c Normal file

File diff suppressed because it is too large Load Diff

916
libburn/sg-netbsd.c Normal file
View File

@ -0,0 +1,916 @@
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
/*
Copyright (c) 2010 - 2016 Thomas Schmitt <scdbackup@gmx.net>
Provided under GPL version 2 or later.
Derived 2014 from libburn/sg-solaris.c with information learned from
dvd+rw-tools, http://fxr.watson.org/fxr/source/sys/scsiio.h?v=NETBSD,
http://netbsd.gw.com/cgi-bin/man-cgi?scsi+4+NetBSD-current,
and experiments made by Freddy Fisker.
Adapted 2016 to OpenBSD by help of SASANO Takayoshi <uaa@mx5.nisiq.net>.
*/
/*
This is the main operating system dependent SCSI part of libburn. It implements
the transport level aspects of SCSI control and command i/o.
Present implementation: NetBSD 6, ioctl SCIOCCOMMAND
OpenBSD 5.9, ioctl SCIOCCOMMAND
PORTING:
Porting libburn typically will consist of adding a new operating system case
to the following switcher files:
os.h Operating system specific libburn definitions and declarations.
sg.c Operating system dependent transport level modules.
and of deriving the following system specific files from existing examples:
os-*.h Included by os.h. You will need some general system knowledge
about signals and knowledge about the storage object needs of your
transport level module sg-*.c.
sg-*.c This source module. You will need special system knowledge about
how to detect all potentially available drives, how to open them,
eventually how to exclusively reserve them, how to perform
SCSI transactions, how to inquire the (pseudo-)SCSI driver.
You will not need to care about CD burning, MMC or other high-level
SCSI aspects.
Said sg-*.c operations are defined by a public function interface, which has
to be implemented in a way that provides libburn with the desired services:
sg_id_string() returns an id string of the SCSI transport adapter.
It may be called before initialization but then may
return only a preliminary id.
sg_initialize() performs global initialization of the SCSI transport
adapter and eventually needed operating system
facilities. Checks for compatibility of supporting
software components.
sg_shutdown() performs global finalizations and releases golbally
acquired resources.
sg_give_next_adr() iterates over the set of potentially useful drive
address strings.
scsi_enumerate_drives() brings all available, not-whitelist-banned, and
accessible drives into libburn's list of drives.
sg_dispose_drive() finalizes adapter specifics of struct burn_drive
on destruction. Releases resources which were acquired
underneath scsi_enumerate_drives().
sg_drive_is_open() tells wether libburn has the given drive in use.
sg_grab() opens the drive for SCSI commands and ensures
undisturbed access.
sg_release() closes a drive opened by sg_grab()
sg_issue_command() sends a SCSI command to the drive, receives reply,
and evaluates wether the command succeeded or shall
be retried or finally failed.
sg_obtain_scsi_adr() tries to obtain SCSI address parameters.
burn_os_is_2k_seekrw() tells whether the given path leads to a file object
that can be used in 2 kB granularity by lseek(2),
read(2), and possibly write(2) if not read-only..
E.g. a USB stick or a hard disk.
burn_os_stdio_capacity() estimates the emulated media space of stdio-drives.
burn_os_open_track_src() opens a disk file in a way that offers best
throughput with file reading and/or SCSI write command
transmission.
burn_os_alloc_buffer() allocates a memory area that is suitable for file
descriptors issued by burn_os_open_track_src().
The buffer size may be rounded up for alignment
reasons.
burn_os_free_buffer() delete a buffer obtained by burn_os_alloc_buffer().
Porting hints are marked by the text "PORTING:".
Send feedback to libburn-hackers@pykix.org .
*/
#ifdef HAVE_CONFIG_H
#include "../config.h"
#endif
/** PORTING : ------- OS dependent headers and definitions ------ */
#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <string.h>
#include <stdlib.h>
#ifdef Libburn_os_has_statvfS
#include <sys/statvfs.h>
#endif /* Libburn_os_has_stavtfS */
#include <sys/ioctl.h>
#include <sys/scsiio.h>
/** PORTING : ------ libburn portable headers and definitions ----- */
#include "transport.h"
#include "drive.h"
#include "sg.h"
#include "spc.h"
#include "sbc.h"
#include "debug.h"
#include "toc.h"
#include "util.h"
#include "init.h"
#include "libdax_msgs.h"
extern struct libdax_msgs *libdax_messenger;
/* is in portable part of libburn */
int burn_drive_is_banned(char *device_address);
int burn_drive_resolve_link(char *path, char adr[],
int *recursion_count, int flag); /* drive.c */
/* Whether to log SCSI commands:
bit0= log in /tmp/libburn_sg_command_log
bit1= log to stderr
bit2= flush every line
*/
extern int burn_sg_log_scsi;
/* ------------------------------------------------------------------------ */
/* PORTING: Private definitions. Port only if needed by public functions. */
/* (Public functions are listed below) */
/* ------------------------------------------------------------------------ */
/* Storage object is in libburn/init.c
whether to strive for exclusive access to the drive
*/
extern int burn_sg_open_o_excl;
/* ------------------------------------------------------------------------ */
/* PORTING: Private functions. Port only if needed by public functions */
/* (Public functions are listed below) */
/* ------------------------------------------------------------------------ */
static int sg_close_drive(struct burn_drive * d)
{
if (d->fd != -1) {
close(d->fd);
d->fd = -1;
return 1;
}
return 0;
}
/* ----------------------------------------------------------------------- */
/* PORTING: Private functions which contain publicly needed functionality. */
/* Their portable part must be performed. So it is probably best */
/* to replace the non-portable part and to call these functions */
/* in your port, too. */
/* ----------------------------------------------------------------------- */
/** Wraps a detected drive into libburn structures and hands it over to
libburn drive list.
*/
static void enumerate_common(char *fname,
int bus_no, int host_no,
int channel_no, int target_no, int lun_no)
{
int ret;
struct burn_drive out;
/* General libburn drive setup */
burn_setup_drive(&out, fname);
/* This transport adapter uses SCSI-family commands and models
(seems the adapter would know better than its boss, if ever) */
ret = burn_scsi_setup_drive(&out, bus_no, host_no, channel_no,
target_no, lun_no, 0);
if (ret <= 0)
return;
/* PORTING: ------------------- non portable part --------------- */
/* Transport adapter is NetBSD/OpenBSD ioctl SCIOCCOMMAND */
/* Adapter specific handles and data */
out.fd = -1;
/* PORTING: ---------------- end of non portable part ------------ */
/* Adapter specific functions with standardized names */
out.grab = sg_grab;
out.release = sg_release;
out.drive_is_open = sg_drive_is_open;
out.issue_command = sg_issue_command;
/* Finally register drive and inquire drive information */
burn_drive_finish_enum(&out);
}
static int start_enum_rcdNx(burn_drive_enumerator_t *idx, int flag)
{
idx->cdno = -1;
return 1;
}
/* Trying /dev/rcd[0..63][dc] */
#define Libburn_netbsd_max_cdnuM 63
static int next_enum_rcdNx(burn_drive_enumerator_t *idx,
char adr[], int adr_size, int flag)
{
static char suffix[2] = {'d', 'c'};
struct stat stbuf;
int i, stat_ret;
char path[16];
while (idx->cdno < Libburn_netbsd_max_cdnuM) {
idx->cdno++;
for (i = 0; i < 2; i++) {
sprintf(path, "/dev/rcd%d%c", idx->cdno, suffix[i]);
stat_ret = stat(path, &stbuf);
if (stat_ret == -1)
continue;
if (!S_ISCHR(stbuf.st_mode))
continue;
if ((int) strlen(path) >= adr_size)
continue;
strcpy(adr, path);
return 1;
}
}
return 0;
}
/* Searching the first byte address that cannot be lseeked and read
*/
static int guess_size_by_seek_set(int fd, off_t *bytes, int flag)
{
static off_t abs_limit = ((off_t) 1024) * 1024 * 1024 * 1024 * 1024;
off_t i, step = ((off_t) 1024) * 1024 * 1024 * 1024, ret;
char buf[1];
*bytes = 0;
for (i = step; i < abs_limit; i += step) {
ret = lseek(fd, i, SEEK_SET);
if (ret == -1) {
i -= step;
step = step >> 1;
if (step > 0)
continue;
return 1;
}
ret = read(fd, buf, 1);
if (ret == -1) {
i -= step;
step = step >> 1;
if (step > 0)
continue;
return 1;
}
*bytes = i + 1;
}
return 0;
}
/* ------------------------------------------------------------------------ */
/* PORTING: Public functions. These MUST be ported. */
/* ------------------------------------------------------------------------ */
/** Returns the id string of the SCSI transport adapter and eventually
needed operating system facilities.
This call is usable even if sg_initialize() was not called yet. In that
case a preliminary constant message might be issued if detailed info is
not available yet.
@param msg returns id string
@param flag unused yet, submit 0
@return 1 = success, <=0 = failure
*/
int sg_id_string(char msg[1024], int flag)
{
#ifdef __OpenBSD__
sprintf(msg, "internal OpenBSD SCIOCCOMMAND adapter sg-netbsd");
#else
sprintf(msg, "internal NetBSD SCIOCCOMMAND adapter sg-netbsd");
#endif
return 1;
}
/** Performs global initialization of the SCSI transport adapter and eventually
needed operating system facilities. Checks for compatibility of supporting
software components.
@param msg returns ids and/or error messages of eventual helpers
@param flag unused yet, submit 0
@return 1 = success, <=0 = failure
*/
int sg_initialize(char msg[1024], int flag)
{
return sg_id_string(msg, 0);
}
/** Performs global finalization of the SCSI transport adapter and eventually
needed operating system facilities. Releases globally acquired resources.
@param flag unused yet, submit 0
@return 1 = success, <=0 = failure
*/
int sg_shutdown(int flag)
{
return 1;
}
/** Finalizes BURN_OS_TRANSPORT_DRIVE_ELEMENTS, the components of
struct burn_drive which are defined in os-*.h.
The eventual initialization of those components was made underneath
scsi_enumerate_drives().
This will be called when a burn_drive gets disposed.
@param d the drive to be finalized
@param flag unused yet, submit 0
@return 1 = success, <=0 = failure
*/
int sg_dispose_drive(struct burn_drive *d, int flag)
{
return 1;
}
/** Returns the next index number and the next enumerated drive address.
The enumeration has to cover all available and accessible drives. It is
allowed to return addresses of drives which are not available but under
some (even exotic) circumstances could be available. It is on the other
hand allowed, only to hand out addresses which can really be used right
in the moment of this call. (This implementation chooses the former.)
@param idx An opaque handle. Make no own theories about it.
@param adr Takes the reply
@param adr_size Gives maximum size of reply including final 0
@param initialize 1 = start new,
0 = continue, use no other values for now
-1 = finish
@return 1 = reply is a valid address , 0 = no further address available
-1 = severe error (e.g. adr_size too small)
*/
int sg_give_next_adr(burn_drive_enumerator_t *idx,
char adr[], int adr_size, int initialize)
{
int ret;
if (initialize == 1) {
ret = start_enum_rcdNx(idx, 0);
if (ret <= 0)
return ret;
} else if (initialize == -1) {
return 0;
}
ret = next_enum_rcdNx(idx, adr, adr_size, 0);
return ret;
}
/** Brings all available, not-whitelist-banned, and accessible drives into
libburn's list of drives.
*/
int scsi_enumerate_drives(void)
{
burn_drive_enumerator_t idx;
int initialize = 1, ret, i_bus_no = -1, buf_size = 4096;
int i_host_no = -1, i_channel_no = -1, i_target_no = -1, i_lun_no = -1;
char *buf = NULL;
BURN_ALLOC_MEM(buf, char, buf_size);
while(1) {
ret = sg_give_next_adr(&idx, buf, buf_size, initialize);
initialize = 0;
if (ret <= 0)
break;
if (burn_drive_is_banned(buf))
continue;
sg_obtain_scsi_adr(buf, &i_bus_no, &i_host_no,
&i_channel_no, &i_target_no, &i_lun_no);
enumerate_common(buf,
i_bus_no, i_host_no, i_channel_no,
i_target_no, i_lun_no);
}
sg_give_next_adr(&idx, buf, buf_size, -1);
ret = 1;
ex:;
BURN_FREE_MEM(buf);
return ret;
}
/** Tells whether libburn has the given drive in use or exclusively reserved.
If it is "open" then libburn will eventually call sg_release() on it when
it is time to give up usage and reservation.
*/
/** Published as burn_drive.drive_is_open() */
int sg_drive_is_open(struct burn_drive * d)
{
return (d->fd != -1);
}
/** Opens the drive for SCSI commands and - if burn activities are prone
to external interference on your system - obtains an exclusive access lock
on the drive. (Note: this is not physical tray locking.)
A drive that has been opened with sg_grab() will eventually be handed
over to sg_release() for closing and unreserving.
*/
int sg_grab(struct burn_drive *d)
{
char *msg = NULL;
int os_errno, ret;
BURN_ALLOC_MEM(msg, char, 4096);
if (d->fd != -1) {
d->released = 0;
{ret = 1; goto ex;}
}
d->fd = open(d->devname, O_RDWR | O_NDELAY);
if (d->fd == -1) {
os_errno = errno;
sprintf(msg, "Could not grab drive '%s'", d->devname);
/* (errno == ENXIO is a device file with no drive attached) */
libdax_msgs_submit(libdax_messenger, d->global_index,
0x00020003,
errno == ENXIO ? LIBDAX_MSGS_SEV_DEBUG :
LIBDAX_MSGS_SEV_SORRY,
LIBDAX_MSGS_PRIO_HIGH,
msg, os_errno, 0);
{ret = 0; goto ex;}
}
d->released = 0;
/* Make sure by INQUIRY that this is really a MMC drive */
ret = spc_confirm_cd_drive(d, 0);
if (ret <= 0)
goto revoke;
/* # define Libburn_sg_netbsd_scsi_debuG */
#ifdef Libburn_sg_netbsd_scsi_debuG
{
static int sc_db = SC_DB_CMDS | SC_DB_FLOW;
ret = ioctl(d->fd, SCIOCDEBUG, &sc_db);
if (ret == -1)
fprintf(stderr,
"libburn_DEBUG: ioctl(%d, SCIOCDEBUG, &(0x%X)) returns %d, errno = %d\n",
d->fd, (unsigned int) sc_db, ret, errno);
}
#endif
{ret = 1; goto ex;}
revoke:;
sprintf(msg, "Could not grab drive '%s'.", d->devname);
libdax_msgs_submit(libdax_messenger, d->global_index,
0x00020003,
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
msg, 0, 0);
if (d->fd >= 0) {
close(d->fd);
d->fd = -1;
d->released = 1;
}
ret = 0;
ex:;
BURN_FREE_MEM(msg);
return ret;
}
/** PORTING: Is mainly about the call to sg_close_drive() and whether it
implements the demanded functionality.
*/
/** Gives up the drive for SCSI commands and releases eventual access locks.
(Note: this is not physical tray locking.)
*/
int sg_release(struct burn_drive *d)
{
if (d->fd < 0)
return 0;
sg_close_drive(d);
return 0;
}
/** Sends a SCSI command to the drive, receives reply and evaluates wether
the command succeeded or shall be retried or finally failed.
Returned SCSI errors shall not lead to a return value indicating failure.
The callers get notified by c->error. An SCSI failure which leads not to
a retry shall be notified via scsi_notify_error().
The Libburn_log_sg_commandS facility might be of help when problems with
a drive have to be examined. It shall stay disabled for normal use.
@return: 1 success , <=0 failure
*/
int sg_issue_command(struct burn_drive *d, struct command *c)
{
int i, timeout_ms, ret, key, asc, ascq, done = 0, sense_len, max_sl;
time_t start_time;
scsireq_t req;
char msg[160];
static FILE *fp = NULL;
c->error = 0;
if (d->fd == -1)
return 0;
if (burn_sg_log_scsi & 1) {
if (fp == NULL) {
fp= fopen("/tmp/libburn_sg_command_log", "a");
fprintf(fp,
"\n-----------------------------------------\n");
}
}
if (burn_sg_log_scsi & 3)
scsi_log_cmd(c,fp,0);
if (c->timeout > 0)
timeout_ms = c->timeout;
else
timeout_ms = 200000;
memset (&req, 0, sizeof(req));
memcpy(req.cmd, c->opcode, c->oplen);
req.cmdlen = c->oplen;
req.databuf = (caddr_t) c->page->data;
req.flags = SCCMD_ESCAPE; /* probably to make req.cmdlen significant */
req.timeout = timeout_ms;
max_sl = sizeof(c->sense) > SENSEBUFLEN ?
SENSEBUFLEN : sizeof(c->sense);
req.senselen = max_sl;
if (c->dir == TO_DRIVE) {
req.datalen = c->page->bytes;
req.flags |= SCCMD_WRITE;
} else if (c->dir == FROM_DRIVE) {
req.flags |= SCCMD_READ;
if (c->dxfer_len >= 0)
req.datalen = c->dxfer_len;
else
req.datalen = BUFFER_SIZE;
/* touch page so we can use valgrind */
memset(c->page->data, 0, BUFFER_SIZE);
} else {
req.flags |= SCCMD_READ;
req.datalen = 0;
}
/* ts B90523 : Record effective transfer length request for debugging*/
c->dxfer_len = req.datalen;
/* retry-loop */
start_time = time(NULL);
for(i = 0; !done; i++) {
memset(c->sense, 0, sizeof(c->sense));
c->start_time = burn_get_time(0);
ret = ioctl(d->fd, SCIOCCOMMAND, &req);
/* <<< Fault mock-up
if (c->opcode[0] == 0x28) {
ret = -1;
errno = 9;
}
*/
c->end_time = burn_get_time(0);
/* #define Libburn_debug_sg_netbsD */
#ifdef Libburn_debug_sg_netbsD
fprintf(stderr, "libburn_DEBUG: ret= %d, retsts = 0x%X, senselen_used = %d, status = 0x%X, error= 0x%X\n", ret, (unsigned int) req.retsts, (int) req.senselen_used, (unsigned int) req.status, req.error);
fprintf(stderr, "libburn_DEBUG: datalen_used = %u\n",
(unsigned int) req.datalen_used);
#endif
if (ret != 0 ||
(req.retsts != SCCMD_SENSE && req.retsts != SCCMD_OK)) {
sprintf(msg, "Failed to transfer command to drive. (ioctl(%d, SCIOCCOMMAND) = %d, scsireq_t.retsts = 0x%X, errno= %d)",
d->fd, ret, (unsigned int) req.retsts, errno);
if (burn_sg_log_scsi & 3)
scsi_log_message(d, fp, msg, 0);
libdax_msgs_submit(libdax_messenger,
d->global_index, 0x0002010c,
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
msg, errno, 0);
sg_close_drive(d);
d->released = 1;
d->busy = BURN_DRIVE_IDLE;
c->error = 1;
return -1;
}
sense_len = 0;
if (req.retsts == SCCMD_SENSE) {
memcpy(c->sense, req.sense, max_sl);
sense_len = req.senselen > max_sl ?
max_sl : req.senselen;
}
spc_decode_sense(c->sense, sense_len, &key, &asc, &ascq);
if (key || asc || ascq)
sense_len = req.senselen;
else
sense_len = 0;
/* <<< Fault mock-up
if (c->opcode[0] == 0x5a) {
req.datalen_used = 0;
memset(c->page->data, 0, BUFFER_SIZE);
}
*/
if (c->dir == FROM_DRIVE && sense_len == 0 &&
req.datalen > 0 && req.datalen_used < req.datalen) {
sprintf(msg, "Short reply from SCSI command %2.2X: expected: %d, got: %d, req.retsts: 0x%X",
(unsigned int) c->opcode[0],
(int) req.datalen, (int) req.datalen_used,
(unsigned int) req.retsts);
if (burn_sg_log_scsi & 3)
scsi_log_message(d, fp, msg, 0);
libdax_msgs_submit(libdax_messenger,
d->global_index, 0x00000002,
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH,
msg, 0, 0);
if (req.datalen_used == 0)
c->error = 1;
c->dxfer_len = req.datalen_used;
}
done = scsi_eval_cmd_outcome(d, c, fp, c->sense, sense_len,
start_time, timeout_ms, i, 0);
if (d->cancel)
done = 1;
if (!done)
spc_register_retry(c);
} /* end of retry-loop */
return 1;
}
/** Tries to obtain SCSI address parameters.
@return 1 is success , 0 is failure
*/
int sg_obtain_scsi_adr(char *path, int *bus_no, int *host_no, int *channel_no,
int *target_no, int *lun_no)
{
int ret, fd = -1;
struct scsi_addr addr;
fd = open(path, O_RDWR | O_NDELAY);
if (fd == -1)
return 0;
*bus_no = *host_no = *channel_no = *target_no = *lun_no = 0;
memset(&addr, 0, sizeof(addr));
ret = ioctl(fd, SCIOCIDENTIFY, &addr);
if (ret != 0)
{ret = 0; goto ex;}
if (addr.type != TYPE_SCSI)
{ret = 0; goto ex;}
#ifdef __OpenBSD__
*bus_no = *host_no = addr.scbus;
*target_no = addr.target;
*lun_no = addr.lun;
#else /* __OpenBSD__ */
*bus_no = *host_no = addr.addr.scsi.scbus;
*target_no = addr.addr.scsi.target;
*lun_no = addr.addr.scsi.lun;
#endif /* ! __OpenBSD__ */
ret = 1;
ex:;
if (fd != -1)
close(fd);
return (0);
}
/** Tells wether a text is a persistent address as listed by the enumeration
functions.
*/
int sg_is_enumerable_adr(char* adr)
{
burn_drive_enumerator_t idx;
int initialize = 1, ret;
char buf[64];
while(1) {
ret = sg_give_next_adr(&idx, buf, sizeof(buf), initialize);
initialize = 0;
if (ret <= 0)
break;
if (strcmp(adr, buf) == 0) {
sg_give_next_adr(&idx, buf, sizeof(buf), -1);
return 1;
}
}
sg_give_next_adr(&idx, buf, sizeof(buf), -1);
return (0);
}
/* Return 1 if the given path leads to a regular file or a device that can be
fseeked, read, and possibly written with 2 kB granularity.
*/
int burn_os_is_2k_seekrw(char *path, int flag)
{
struct stat stbuf;
int l, i, dev, tl;
char try[16];
/* >>> ??? Is this a comprehensive list of lseek()-capable devices ? */
/* http://www.netbsd.org/docs/guide/en/chap-rmmedia.html */
static char dev_names[][4] = {
"fd", "rfd", "sd" , "cd", "rcd", "wd", ""};
if (path[0] == 0)
return 0;
if (stat(path, &stbuf) == -1)
return 0;
if (S_ISREG(stbuf.st_mode))
return 1;
if (S_ISBLK(stbuf.st_mode))
return 1;
/* Look for known device names which promise the desired capabilities */
if (strncmp(path, "/dev/", 5) != 0)
return 0;
l = strlen(path);
for (dev = 0; dev_names[dev][0] != 0; dev++) {
sprintf(try, "/dev/%s", dev_names[dev]);
tl = strlen(try);
if (strncmp(path, try, tl) != 0)
continue;
l -= tl;
for (i = 0; i < Libburn_netbsd_max_cdnuM; i++) {
sprintf(try + tl, "%d", i);
if (strncmp(path, try, strlen(try)) == 0)
break;
}
if (i >= Libburn_netbsd_max_cdnuM)
continue;
tl += strlen(try + tl);
if (l == tl)
return 1;
if (l > tl + 1)
continue;
if (path[l - 1] >= 'a' && path[l - 1] <= 'z')
return 1;
}
return 0;
}
/** Estimate the potential payload capacity of a file address.
@param path The address of the file to be examined. If it does not
exist yet, then the directory will be inquired.
@param bytes The pointed value gets modified, but only if an estimation is
possible.
@return -2 = cannot perform necessary operations on file object
-1 = neither path nor dirname of path exist
0 = could not estimate size capacity of file object
1 = estimation has been made, bytes was set
*/
int burn_os_stdio_capacity(char *path, off_t write_start, off_t *bytes)
{
struct stat stbuf;
int ret;
#ifdef Libburn_os_has_statvfS
struct statvfs vfsbuf;
#endif
char *testpath = NULL, *cpt;
off_t add_size = 0;
BURN_ALLOC_MEM(testpath, char, 4096);
testpath[0] = 0;
if (stat(path, &stbuf) == -1) {
strcpy(testpath, path);
cpt = strrchr(testpath, '/');
if(cpt == NULL)
strcpy(testpath, ".");
else if(cpt == testpath)
testpath[1] = 0;
else
*cpt = 0;
if (stat(testpath, &stbuf) == -1)
{ret = -1; goto ex;}
} else if(S_ISBLK(stbuf.st_mode)) {
int open_mode = O_RDONLY, fd;
fd = open(path, open_mode);
if (fd == -1)
{ret = -2; goto ex;}
*bytes = lseek(fd, 0, SEEK_END);
if (*bytes <= 0)
guess_size_by_seek_set(fd, bytes, 0);
close(fd);
if (*bytes == -1) {
*bytes = 0;
{ret = 0; goto ex;}
}
} else if(S_ISREG(stbuf.st_mode)) {
add_size = burn_sparse_file_addsize(write_start, &stbuf);
strcpy(testpath, path);
} else
{ret = 0; goto ex;}
if (testpath[0]) {
#ifdef Libburn_os_has_statvfS
if (statvfs(testpath, &vfsbuf) == -1)
{ret = -2; goto ex;}
*bytes = add_size + ((off_t) vfsbuf.f_frsize) *
(off_t) vfsbuf.f_bavail;
#else /* Libburn_os_has_statvfS */
{ret = 0; goto ex;}
#endif /* ! Libburn_os_has_stavtfS */
}
ret = 1;
ex:;
BURN_FREE_MEM(testpath);
return ret;
}
/* ts A91122 : an interface to open(O_DIRECT) or similar OS tricks. */
#ifdef Libburn_read_o_direcT
/* No special O_DIRECT-like precautions are implemented here */
#endif /* Libburn_read_o_direcT */
int burn_os_open_track_src(char *path, int open_flags, int flag)
{
int fd;
fd = open(path, open_flags);
return fd;
}
void *burn_os_alloc_buffer(size_t amount, int flag)
{
void *buf = NULL;
buf = calloc(1, amount);
return buf;
}
int burn_os_free_buffer(void *buffer, size_t amount, int flag)
{
if (buffer == NULL)
return 0;
free(buffer);
return 1;
}

1018
libburn/sg-solaris.c Normal file

File diff suppressed because it is too large Load Diff

93
libburn/sg.c Normal file
View File

@ -0,0 +1,93 @@
/* sg.c
Switcher for operating system dependent transport level modules of libburn.
Copyright (C) 2009 - 2016 Thomas Schmitt <scdbackup@gmx.net>,
provided under GPLv2+
*/
#ifdef HAVE_CONFIG_H
#include "../config.h"
#undef HAVE_CONFIG_H
#endif
#ifdef Libburn_use_sg_dummY
#include "sg-dummy.c"
#else
#ifdef Libburn_use_libcdiO
#include "sg-libcdio.c"
#else
#ifdef __NetBSD__
#include "sg-netbsd.c"
#else
#ifdef __OpenBSD__
#include "sg-netbsd.c"
#else
#ifdef __FreeBSD__
#ifdef Libburn_use_sg_freebsd_porT
#include "sg-freebsd-port.c"
#else
#include "sg-freebsd.c"
#endif
#else
#ifdef __FreeBSD_kernel__
#ifdef Libburn_use_sg_freebsd_porT
#include "sg-freebsd-port.c"
#else
#include "sg-freebsd.c"
#endif
#else
#ifdef __linux
#include "sg-linux.c"
#else
#ifdef __sun
#include "sg-solaris.c"
#else
/* The dummy adapter formally fulfills the expectations of libburn towards
its SCSI command transport. It will show no drives and perform no SCSI
commands.
libburn will then be restricted to using its stdio pseudo drives.
*/
static int intentional_compiler_warning(void)
{
int INTENTIONAL_COMPILER_WARNING_;
int Cannot_recognize_supported_operating_system_;
int Like_GNU_Linux_or_FreeBSD_or_Solaris_or_NetBSD_;
int Have_to_use_dummy_MMC_transport_adapter_;
int This_libburn_will_not_be_able_to_operate_on_real_CD_drives;
int Have_to_use_dummy_MMC_transport_adapter;
int Like_GNU_Linux_or_FreeBSD_or_Solaris_or_NetBSD;
int Cannot_recognize_supported_operating_system;
int INTENTIONAL_COMPILER_WARNING;
return(0);
}
#include "sg-dummy.c"
#endif /* ! __sun */
#endif /* ! __linux */
#endif /* ! __FreeBSD_kernel__ */
#endif /* ! __FreeBSD__ */
#endif /* ! __OpenBSD__ */
#endif /* ! __NetBSD__ */
#endif /* ! Libburn_use_libcdiO */
#endif /* ! Libburn_use_sg_dummY */

84
libburn/sg.h Normal file
View File

@ -0,0 +1,84 @@
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
/* Copyright (C) 2009 Thomas Schmitt <scdbackup@gmx.net>, provided under GPLv2+
*/
#ifndef __SG
#define __SG
#include "os.h"
/* see os.h for name of particular os-*.h where this is defined */
BURN_OS_DEFINE_DRIVE_ENUMERATOR_T
struct burn_drive;
struct command;
/* ts A60922 ticket 33 */
int sg_give_next_adr(burn_drive_enumerator_t *enm_context,
char adr[], int adr_size, int initialize);
int sg_is_enumerable_adr(char *adr);
int sg_obtain_scsi_adr(char *path, int *bus_no, int *host_no, int *channel_no,
int *target_no, int *lun_no);
int sg_grab(struct burn_drive *);
int sg_release(struct burn_drive *);
int sg_issue_command(struct burn_drive *, struct command *);
/* ts A61115 : formerly sg_enumerate();ata_enumerate() */
int scsi_enumerate_drives(void);
int sg_drive_is_open(struct burn_drive * d);
int burn_os_is_2k_seekrw(char *path, int flag);
int burn_os_stdio_capacity(char *path, off_t write_start, off_t *bytes);
/* ts A91227 */
/** Returns the id string of the SCSI transport adapter and eventually
needed operating system facilities.
This call is usable even if sg_initialize() was not called yet. In that
case a preliminary constant message might be issued if detailed info is
not available yet.
@param msg returns id string
@param flag unused yet, submit 0
@return 1 = success, <=0 = failure
*/
int sg_id_string(char msg[1024], int flag);
/* ts A91225 */
/** Performs global initialization of the SCSI transport adapter and eventually
needed operating system facilities. Checks for compatibility supporting
software components.
@param msg returns ids and/or error messages of eventual helpers
@param flag unused yet, submit 0
@return 1 = success, <=0 = failure
*/
int sg_initialize(char msg[1024], int flag);
/* ts A91227 */
/** Performs global finalization of the SCSI transport adapter and eventually
needed operating system facilities. Releases globally acquired resources.
@param flag unused yet, submit 0
@return 1 = success, <=0 = failure
*/
int sg_shutdown(int flag);
/* ts A91227 */
/** Finalizes BURN_OS_TRANSPORT_DRIVE_ELEMENTS, the components of
struct burn_drive which are defined in os-*.h.
The eventual initialization of those components was made underneath
scsi_enumerate_drives().
This will be called when a burn_drive gets disposed.
@param d the drive to be finalized
@param flag unused yet, submit 0
@return 1 = success, <=0 = failure
*/
int sg_dispose_drive(struct burn_drive *d, int flag);
#endif /* __SG */

Some files were not shown because too many files have changed in this diff Show More