Compare commits

...

253 Commits

Author SHA1 Message Date
77eee54ee6 Documented changes and release timestamp 2009-08-27 14:13:46 +00:00
f143123ae1 Updated cdrskin tarball generator 2009-08-27 13:42:43 +00:00
edf242dd39 Made number transition and activated development documentation 2009-08-27 13:41:34 +00:00
7fd995e0e4 Branching for libburn release 0.7.0 2009-08-27 12:04:14 +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
6660ef7ece Allowed BD-ROM and BD-R for read-only purposes 2008-05-09 14:51:48 +00:00
37092086d9 Documented read-only profiles CD-ROM and DVD-ROM 2008-05-09 14:31:12 +00:00
35d1394262 Declared BD-RE to be supported 2008-05-06 18:35:48 +00:00
4dec38984d Declared BD-RE to be supported 2008-05-06 18:17:05 +00:00
be0626ae9e Declared BD-RE to be supported 2008-05-06 18:10:44 +00:00
a54113267e Declared BD-RE to be supported 2008-05-06 18:08:04 +00:00
2d9d250471 Mapped undefined size to 0 with burn_disc_get_formats() and DVD-RW 2008-05-06 08:41:48 +00:00
ff7520f2f5 Avoided to report negative burn_multi_caps.start_range_high with DVD-RW 2008-05-06 08:24:11 +00:00
d0d90fc902 Updated project history 2008-05-03 11:16:12 +00:00
1d41767348 Documented newest enhancements 2008-04-27 16:36:13 +00:00
12b0fbf17c New blank type as_needed 2008-04-27 14:02:32 +00:00
44368aef6c New blank type format_if_needed 2008-04-27 08:47:55 +00:00
43b6ad6008 New blank subtypes format_defectmgt_cert_[on|off], on is default 2008-04-26 15:10:35 +00:00
f006ee5436 Enabled quick formatting with DVD-RAM, made slow formatting default with BD-RE 2008-04-26 15:07:39 +00:00
5e4da147a5 Documented newest enhancements 2008-04-25 13:44:01 +00:00
103b301b09 Incremented LT_CURRENT and LT_AGE to reflect API enhancements 2008-04-25 13:36:19 +00:00
0386feabfe Documented experimental support for BD-RE formatting 2008-04-25 13:24:39 +00:00
4e949d79fe Preparations for formatting BD-RE 2008-04-25 13:16:23 +00:00
422a97a2f2 Mentioned new features 2008-04-24 18:37:46 +00:00
a52ea438a5 Wrote down what was learned about DVD-RAM formatting 2008-04-24 18:37:02 +00:00
62f41452bb New blank type blank=format_by_index_<number> 2008-04-23 11:02:11 +00:00
015bc00a91 New option --list_formats 2008-04-22 20:10:38 +00:00
d6fde26824 Adjustments with DVD-RAM formatting 2008-04-22 16:13:05 +00:00
1cfb29f032 Adjustments with DVD-RAM formatting 2008-04-18 19:46:18 +00:00
65cf751a30 Began to implement formatting of DVD-RAM and experimentally of BD-RE 2008-04-18 09:28:16 +00:00
4683386de1 Began to implement formatting of DVD-RAM and experimentally of BD-RE 2008-04-18 09:27:16 +00:00
5d51869c3b Made burn_read_data() obey its flag bit1 2008-04-16 08:22:14 +00:00
fe8a6c6224 Some adjustments of cdrskin man page 2008-04-15 09:43:33 +00:00
db5568c03b Enforced tail padding with stream_recording, enlarged transport buffer 2008-04-15 09:42:32 +00:00
a07631c57b New option stream_recording=on|off 2008-04-12 16:46:05 +00:00
e522db6220 New API call burn_write_opts_set_stream_recording() 2008-04-12 16:42:45 +00:00
51ac900de6 Trying to fix bugs about BD-RE, macro for simulating BD-RE on DVD-RAM 2008-04-10 21:16:07 +00:00
cdea153443 Switched from configure.ac versioning to libburn.h versioning 2008-04-08 13:35:43 +00:00
0ce3f7c224 Updated cdrskin tarball generator 2008-04-08 13:34:14 +00:00
8de0a3dc6c Made number transition 2008-04-08 13:32:07 +00:00
e75e5e04b8 Corrected GPL version 2008-04-02 07:48:24 +00:00
86d5bdfef8 Got rid of a cumbersome open-close cycle with burn_read_data() on stdio: 2008-03-03 20:30:10 +00:00
c1298d82a6 Updated changelog 2008-03-01 18:48:32 +00:00
5c6366ecbd Mentioned support for DVD+R/DL. 2008-02-28 13:24:08 +00:00
616454c737 Made support for DVD+R DL official, enabled untested support for BD-RE 2008-02-28 12:32:34 +00:00
ea6957ef68 Changed meaning of unrecognized severity texts from FATAL to ALL 2008-02-22 21:38:09 +00:00
f9398c08e6 Imported changes from libiso_msgs.h 2008-02-22 21:36:08 +00:00
b4617c679c New error code 0x00040008 2008-02-22 15:10:21 +00:00
42bb74881a Weakened demand to print file path in following message 2008-02-21 21:53:26 +00:00
61671b41d7 Mapped unknown severity text to ALL rather than NEVER 2008-02-21 20:22:53 +00:00
1e74d7a04e Introduced severity ERRFILE 2008-02-21 20:14:23 +00:00
c48244abfc Directed error message to proper output channel 2008-02-21 20:11:20 +00:00
13492efe4b Testwise inquiry of ioctl(CDROM_MEDIA_CHANGED) (disabled by default) 2008-02-21 20:10:38 +00:00
bccb39efd8 Updated project interrelations 2008-02-16 12:37:09 +00:00
6fc60be93c Corrected typo in comment 2008-02-16 12:11:42 +00:00
d69b856b6a Pointed to ldconfig 2008-02-14 08:39:12 +00:00
b5e2d60c68 Updated year 2008-02-14 08:36:02 +00:00
ff1ad50119 Micro corrections in comment text 2008-02-14 07:41:51 +00:00
4cb6706307 Introduced LIBDAX_MSGS_SEV_MISHAP 2008-02-11 19:15:21 +00:00
6e74c8bc2e Allowed DVD +/- DL for reading 2008-02-08 07:34:58 +00:00
fdbed06f84 Added debug message in case of burn_read_data() return 0 2008-02-07 23:29:26 +00:00
67e4282b82 Installed a simple address logger in burn_read_data 2008-02-06 23:01:45 +00:00
bd8d4bb49f Copied usage discussion about *_header_version_* from libisoburn 2008-02-06 18:23:06 +00:00
623edf9d9d Re-instated range "vreixo" with old and new codes, adjusted severity definitions 2008-02-06 17:41:00 +00:00
d4fe8c75be Registered range "libisoburn" 0x00060000 to 0x00006ffff 2008-02-04 17:52:56 +00:00
9ebd020847 Announced deprecation of libisofs-0.2.x, temporory employment of libisofs-0.6.1 2008-02-04 17:52:06 +00:00
a93d18231a New API call burn_sev_to_text() 2008-02-03 09:25:58 +00:00
ec8b75217f Incremented LT_* to get libburn.so.4.8.0 (forgot to do 4.7.1 anyway) 2008-02-03 09:22:29 +00:00
99767afe1f Registered error code range "libisofs-xorriso" 2008-02-03 09:21:01 +00:00
024076ad54 Changed "libburn interface :" version message to libburn.h macros 2008-02-01 10:06:21 +00:00
c39e7d8ce4 Renamed libburn-5.pc to libburn-1.pc 2008-02-01 10:03:56 +00:00
95609061f1 Introduced compile time check of libburn header version 2008-01-31 11:11:50 +00:00
d498003515 Corrected description of major.minor.micro definition in libburn.h 2008-01-29 21:41:59 +00:00
b1630a3b33 Moving the major.minor.micro definition from configure.ac to libburn.h 2008-01-29 21:09:16 +00:00
eddf4e6b13 Updated cdrskin tarball generator 2008-01-27 15:18:12 +00:00
654e25d40a Made number transition to 0.4.3 , still libburn.so.4.7.0 2008-01-27 14:53:55 +00:00
69e1d4a51f Disabled debugging messages about thread properties 2008-01-26 18:03:36 +00:00
305917fe86 Made a sudden end to all stdio drives in burn_abort() 2008-01-26 13:16:12 +00:00
b3b42ff649 Ported change in vreixo message range from isoburn_msgs 2008-01-26 12:31:42 +00:00
63d1f5dcbf Adapted to man -H on my new system 2008-01-26 12:30:22 +00:00
77a9a1fc92 Dynamic cdrskin linking patch by Simon Huggins. 2008-01-23 21:37:26 +00:00
beb1c1d2d1 Implemented run time check of libburn version. 2008-01-23 21:18:25 +00:00
e449654c7b Introduced message severity "FAILURE" 2008-01-23 19:39:38 +00:00
d66a40bc0e Made burn_read_data() issue messages about hopeless drive access errors 2008-01-23 19:34:38 +00:00
bed900f3f4 Fixed small bug about error messages with burn_read_data 2008-01-19 20:18:13 +00:00
922fc6c90b Removed a reference to future GPL versions 2008-01-17 18:54:38 +00:00
adac21d6ee Changed meaning of .driveno to .origin, introduced LIBDAX_MSGS_ORIGIN_* macros 2008-01-17 18:51:46 +00:00
d9e056c3ac Implemented burn_source.cancel() in a binary backwards compatible way 2007-12-24 14:21:23 +00:00
32a6bd1f82 Some changes in the comments 2007-12-08 13:49:46 +00:00
9f7be91aba Made postponed change in thread management 2007-12-07 18:53:22 +00:00
fec4fd864f An attempt to rectify .so numbering: SONAME=10, REV=1, AGE=6 2007-12-07 18:51:57 +00:00
e48014caea Adjusted meaning of --read_and_print count= -1 2007-11-29 18:55:52 +00:00
82c6e92da0 Enabled reading of TOC from ROM drives (direly needed for xorriso) 2007-11-29 18:55:06 +00:00
206910da4e Reacted on build warnings on another system 2007-11-26 15:49:39 +00:00
0a27b188a3 Reacted on build warnings on a 64 Bit system 2007-11-18 09:36:41 +00:00
6705389f14 Corrected a typo in cdrskin man page 2007-11-18 09:35:36 +00:00
5c8d6865b5 Marked loss of binary backward compatibility back in rev 655, libburn-0.3.1 2007-11-18 09:34:33 +00:00
2d6d2679a0 Updated cdrskin release generator scripts 2007-10-29 16:47:49 +00:00
5432612965 Returned to -5 naming 2007-10-28 22:37:18 +00:00
9b1a57d84a Revekod changes to trunk 2007-10-28 22:36:09 +00:00
e5ea580e3b Fixed completely things wrt pc-in files 2007-10-28 19:15:52 +00:00
981a1bf5e1 Fixed build system wrt pc-in files 2007-10-28 19:14:21 +00:00
49925ad2ba Changed sonumber to 4, and changed pc.in file 2007-10-28 12:53:18 +00:00
fc5f2a4745 Reacted on cdwrite@ message about INT_MAX in cdrom.h of kernel 2.6.23 2007-10-27 07:52:54 +00:00
903a12c90b Added forgotten help text lines 2007-10-25 13:18:48 +00:00
0f50c21888 Updated cdrskin tarball generator 2007-10-25 09:37:06 +00:00
f3739013fa Made number transition to 0.4.1 2007-10-25 09:26:02 +00:00
57 changed files with 8233 additions and 1212 deletions

View File

@ -1,13 +1,12 @@
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-2007 Mario Danic, Thomas Schmitt
Copyright (C) 2006-2009 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 as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
it under the terms of the GNU General Public License version 2 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

View File

@ -1,4 +1,8 @@
pkgconfigdir=$(libdir)/pkgconfig
# 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
@ -82,29 +86,35 @@ noinst_PROGRAMS = \
bin_PROGRAMS = \
cdrskin/cdrskin
LIBBURN_EXTRALIBS = $(LIBBURN_ARCH_LIBS) $(THREAD_LIBS)
test_libburner_CPPFLAGS = -Ilibburn
test_libburner_LDADD = $(libburn_libburn_la_OBJECTS) $(THREAD_LIBS)
test_libburner_LDADD = $(libburn_libburn_la_OBJECTS) $(LIBBURN_EXTRALIBS)
test_libburner_SOURCES = test/libburner.c
test_telltoc_CPPFLAGS = -Ilibburn
test_telltoc_LDADD = $(libburn_libburn_la_OBJECTS) $(THREAD_LIBS)
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) $(THREAD_LIBS)
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) $(THREAD_LIBS)
test_poll_LDADD = $(libburn_libburn_la_OBJECTS) $(LIBBURN_EXTRALIBS)
test_poll_SOURCES = test/poll.c
test_structest_CPPFLAGS = -Ilibburn
test_structest_LDADD = $(libburn_libburn_la_OBJECTS) $(THREAD_LIBS)
test_structest_LDADD = $(libburn_libburn_la_OBJECTS) $(LIBBURN_EXTRALIBS)
test_structest_SOURCES = test/structest.c
## cdrskin construction site - ts A60816 - A70720
## cdrskin construction site - ts A60816 - A90507
cdrskin_cdrskin_CPPFLAGS = -Ilibburn
cdrskin_cdrskin_CFLAGS = -DCdrskin_libburn_0_3_9
cdrskin_cdrskin_LDADD = $(libburn_libburn_la_OBJECTS) $(THREAD_LIBS)
cdrskin_cdrskin_CFLAGS = -DCdrskin_libburn_0_7_0
# 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"
@ -163,13 +173,13 @@ indent: $(indent_files)
# Extra things
nodist_pkgconfig_DATA = \
libburn-5.pc
libburn-1.pc
# http://www.nada.kth.se/cgi-bin/info?(automake.info)Man%20pages
man_MANS = cdrskin/cdrskin.1
EXTRA_DIST = \
libburn-5.pc.in \
libburn-1.pc.in \
version.h.in \
doc/comments \
doc/doxygen.conf.in \

311
README
View File

@ -4,50 +4,70 @@
This all is under GPL.
(See GPL reference, our clarification and commitment at the end of this text)
------------------------------------------------------------------------------
libburnia-project.org
libburn-project.org
By Mario Danic <mario.danic@gmail.com> and Thomas Schmitt <scdbackup@gmx.net>
Copyright (C) 2006-2007 Mario Danic, Thomas Schmitt
Still containing parts of
Libburn. By Derek Foreman <derek@signalmarketing.com> and
Ben Jansens <xor@orodu.net>
Copyright (C) 2006-2009 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
These parts are to be replaced by own code of above libburnia-project.org
copyright holders and then libburnia-project.org is to be their sole copyright.
This is done to achieve the right to issue the clarification and the
commitment as written at the end of this text.
The rights and merits of the Libburn-copyright holders Derek Foreman and
Ben Jansens will be duely respected.
This libburnia-project.org toplevel README (C) 2006-2007 Thomas Schmitt
http://files.libburnia-project.org/releases/libburn-0.7.0.pl00.tar.gz
------------------------------------------------------------------------------
Build and Installation
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.
Check out from SVN by
svn co http://svn.libburnia-project.org/libburn/trunk libburn
go into directory libburn and apply autotools by
./bootstrap
From tarball
Alternatively you may unpack a release tarball for which you do not need
autotools installed.
Obtain libburn-0.7.0.pl00.tar.gz, take it to a directory of your choice and do:
To build a libburnia-project.org subproject it should be sufficient to go
into its toplevel directory (here: "libburn") and execute
tar xzf libburn-0.7.0.pl00.tar.gz
cd libburn-0.7.0
./configure --prefix=/usr
make
To make the libraries accessible for running resp. developing applications
To make libburn accessible for running resp. 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.
The other half of the project, libisofs, is hosted in the libburnia SVN, too:
svn co http://svn.libburnia-project.org/libisofs/trunk libisofs
See README file there.
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.
------------------------------------------------------------------------------
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.
------------------------------------------------------------------------------
@ -55,41 +75,54 @@ See README file there.
libburnia-project.org is an open-source software project for reading, mastering
and writing optical discs.
For now this means only CD media and all single layer DVD media except DVD+R.
For now this means CD media, all DVD media except DVD-R DL, 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 Linux with kernels >= 2.4 and on FreeBSD versions
with ATAPI/CAM support enabled in the kernel, see atapicam(4).
On other X/Open compliant systems there will only be pseudo drives, but no
direct MMC operation on real CD/DVD/BD drives.
Our scope is currently Linux 2.4 and 2.6 only. For ports to other systems
we would need : login on a development machine resp. a live OS on CD or DVD,
advise from a system person about the equivalent of Linux sg or FreeBSD CAM,
volunteers for testing of realistic use cases.
For full ports to other systems we would need : login on a development machine
resp. a live OS on CD or DVD, advise from a system person about the equivalent
of Linux sg or FreeBSD CAM, volunteers for testing of realistic use cases.
We have a workable code base for burning CD and most single layer DVD.
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 binary which emulates parts of cdrecord in order to
prove that usability, and in order to allow you to explore libburnia's scope
by help of existing cdrecord frontends.
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/hdX (e.g. on kernel 2.6).
/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 media via libburn.
ISO 9660 disk image. This may then be brought to CD via libburn.
libisofs is to be the foundation of our upcoming mkisofs emulation.
- libisoburn is an add-on to libburn and libisofs which coordinates both and
also allows to grow ISO-9660 filesystem images on multi-session
media as well as on overwriteable media via the same API.
All media peculiarities are handled automatically.
- cdrskin is a limited cdrecord compatibility wrapper for libburn.
Cdrecord is a powerful GPL'ed burn program included in Joerg
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
@ -97,14 +130,42 @@ The project components (list subject to growth, hopefully):
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 and man cdrskin/cdrskin.1 for more.
See cdrskin/README for more.
- test is a collection of application gestures and examples given by the
authors of the library features. The main API example for libburn
is test/libburner.c .
- 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.
See xorriso/README for more.
- "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 plan to be a responsive upstream. Bear with us. We are still practicing.
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. Not to use 64 bit file i/o will keep the
application from producing and processing ISO images of more than 2 GB size.
------------------------------------------------------------------------------
@ -133,7 +194,7 @@ Project history as far as known to me:
discontent.
The situation first caused me to publically regret it and then - after i
got the opportunity to move in with cdrskin - gave me true reason to
personally apologize to Derek Foreman, Ben Jansens and the contibutors at
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
@ -204,6 +265,166 @@ Project history as far as known to me:
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 upcomming 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 allow future development.
- 29th Apr 2008 libisoburn-0.1.4 was made more efficient with reading of
image tree nodes. It now depends on libisofs-0.6.4 and libburn-0.4.4.
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 to allow libisoburn emulation of multisession on those media.
- 19th May 2008 libisoburn-0.1.6 brings better table-of-content emulation
on overwriteble media and disk files.
- 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 adressable. 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 allows very
large data files in the image.
- 20th Sep 2008 libisoburn/xorriso-0.2.6 takes into respect the new Level 3
capabilities of libisofs.
- 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 allows to produce ISO images which resemble old mkisofs images.
- 2nd Dec 2008 libisoburn-0.3.0. xorriso now is ready for exotic character
sets, for legacy FreeBSD systems which expect an outdated Rock Ridge
signature, and for producing ISO images with MBR which boot from hard disk
or USB stick. Three minor bugs were fixed.
- 7th Dec 2008 libburn-0.5.8 prevents a SIGSEGV with wierd CD table-of-content
and improves BD-RE formatting.
- 9th Dec 2008 Our project received a donation from Thomas Weber.
- 2nd Jan 2009 libburn-0.6.0 allows to format BD-R and to write to either
formatted or unformatted BD-R.
- 6th Jan 2009 libisoburn-0.3.2. xorriso can produce and execute commands for
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 allowed to lift the
ban to build libburn on operating systems other than Linux and FreeBSD.
- 16 Mar 2009 libisoburn-0.3.6: xorriso uses RRIP version 1.10 as default
in order to be mountable where mkisofs images are mountable.
- 17 Apr 2009 libisofs-0.6.18 introduces content filtering of data files.
Built-in filters allow compression to formats gzip and zisofs. External
filter processes allow arbitrary data conversions like encryption.
- 19 Apr 2009 libisoburn-0.3.8 makes use of the new libisofs capability to
perform content filtering of data files.
- 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 allow to verify superblock and
directory tree before importing them.
- 27 Aug 2009 libburn-0.7.0 allows to calm down a drive and to inquire its
supported profiles. It works around some pitfalls with U3 enhanced memory
sticks which emulate a CD-ROM.
------------------------------------------------------------------------------

View File

@ -1,9 +1,11 @@
AC_DEFUN([TARGET_SHIZZLE],
[
ARCH=""
LIBBURNIA_PKGCONFDIR="$libdir"/pkgconfig
AC_MSG_CHECKING([target operating system])
case $target in
*-*-linux*)
ARCH=linux
@ -12,11 +14,66 @@ AC_DEFUN([TARGET_SHIZZLE],
*-*-freebsd*)
ARCH=freebsd
LIBBURN_ARCH_LIBS=-lcam
LIBBURNIA_PKGCONFDIR=$(echo "$libdir" | sed 's/\/lib$/\/libdata/')/pkgconfig
;;
*)
AC_ERROR([You are attempting to compile for an unsupported platform])
ARCH=
LIBBURN_ARCH_LIBS=
# AC_ERROR([You are attempting to compile for an unsupported platform])
;;
esac
AC_MSG_RESULT([$ARCH])
])
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])
])

View File

@ -4,15 +4,19 @@
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-0.3.9.tar.gz
Copyright (C) 2006-2007 Thomas Schmitt, provided under GPL version 2.
http://scdbackup.sourceforge.net/cdrskin-0.7.0.pl00.tar.gz
Copyright (C) 2006-2009 Thomas Schmitt, provided under GPL version 2.
------------------------------------------------------------------------------
cdrskin is a limited cdrecord compatibility wrapper which allows to use
most of the libburn features from the command line.
Currently it is only supported on Linux with kernels >= 2.4.
Currently it is supported on Linux with kernels >= 2.4 and on FreeBSD versions
with ATAPI/CAM support enabled in the kernel, see atapicam(4).
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 ..."
@ -20,17 +24,17 @@ By using this software you agree to the disclaimer at the end of this text
Compilation, First Glimpse, Installation
Obtain cdrskin-0.3.9.tar.gz, take it to a directory of your choice and do:
Obtain cdrskin-0.7.0.pl00.tar.gz, take it to a directory of your choice and do:
tar xzf cdrskin-0.3.9.tar.gz
cd cdrskin-0.3.9
tar xzf cdrskin-0.7.0.pl00.tar.gz
cd cdrskin-0.7.0
Within that directory execute:
./configure --prefix=/usr
make
This will already produce a cdrskin binary. But it might be necessary to
This will already produce a cdrskin binary. But it will be necessary to
install libburn in order to use this binary. Installation of libburn is
beyond the scope of cdrskin. For this, see included libburn docs.
@ -44,11 +48,21 @@ Version identification and help texts available afterwards:
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
Copy your standalone binary to exactly the address which you get as reply.
E.g.:
cp cdrskin/cdrskin /usr/bin/cdrskin
@ -108,6 +122,11 @@ 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.
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
Usage examples
@ -129,8 +148,8 @@ Obtain some info about the drive
Obtain some info about the drive and the inserted media
cdrskin dev=0,1,0 -atip -v
Make used CD-RW or used unformatted DVD-RW writeable again
cdrskin -v dev=0,1,0 blank=fast -eject
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
@ -142,18 +161,18 @@ 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
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 -tao 2.iso
cdrskin dev=/dev/hdc padsize=300k -multi -tao 3.iso
cdrskin dev=/dev/hdc padsize=300k -tao 4.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 -tao \
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).
@ -176,8 +195,6 @@ See output of command
cdrskin --list_ignored_options
If you have use cases for them, please report your wishes and expectations.
DVD support is restricted to single layer DVD for now. Double layer media
are implemented but untested.
On the other hand, the capability of multi-session and of writing streams
of unpredicted lenght surpass the current DVD capabilities of cdrecord.
@ -252,17 +269,30 @@ I myself am not into audio. So libburn-hackers@pykix.org might be the
best address for suggestions, requests and bug reports.
DVD+RW and DVD-RAM
DVD+RW , DVD-RAM , BD-RE
DVD+RW and DVD-RAM media get treated as blank media regardless wether they
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). Currently
there is no difference between -sao and -tao. If ever, then -tao will be the
mode which preserves the current behavior.
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.
Program growisofs can append to an ISO filesystem on DVD+RW by additionally
manipulating the first session. Meanwhile cdrskin can do the same.
Option --grow_overwriteable_iso allows -multi (although unneeded), enables
-msinfo and -toc, and makes blank=fast an invalidator for ISO filesystems
on overwriteable media.
@ -331,11 +361,24 @@ 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 , 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
@ -384,9 +427,9 @@ 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 implied the need to reboot the
The worst mishaps which hit the author imposed the need to reboot the
system because of drives gnawing endlessly on ill media. Permanent hardware
damage did not occur in 1.5 years of development.
damage did not occur in 3.5 years of development. But one never knows ...
------------------------------------------------------------------------------
@ -398,9 +441,8 @@ 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 as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
it under the terms of the GNU General Public License version 2
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
@ -415,7 +457,7 @@ contributions in a due way.
Based on and sub project of:
libburnia-project.org
By Mario Danic <mario.danic@gmail.com> and Thomas Schmitt <scdbackup@gmx.net>
Copyright (C) 2006-2007 Mario Danic, Thomas Schmitt
Copyright (C) 2006-2009 Mario Danic, Thomas Schmitt
libburnia-project.org is inspired by and in other components still containing
parts of

View File

@ -38,7 +38,7 @@ original="./libburn_svn_release.tgz"
# My changes are in $changes , mainly in $changes/cdrskin
changes="./libburn-release"
skin_release="0.3.8"
skin_release="0.7.0"
patch_level=".pl00"
skin_rev="$skin_release""$patch_level"
@ -58,7 +58,8 @@ compile_result="cdrskin/cdrskin"
man_to_html_cmd="./cdrskin/convert_man_to_html.sh"
man_page_html="cdrskin/man_1_cdrskin.html"
bintarget_dynamic="cdrskin_${skin_rev}-x86-suse9_0"
# bintarget_dynamic="cdrskin_${skin_rev}-x86-suse9_0"
bintarget_dynamic="cdrskin_${skin_rev}-amd64-suse10_2"
bintarget_static="$bintarget_dynamic"-static
if test -d "$changes"
@ -103,9 +104,9 @@ 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
# 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"
@ -154,6 +155,10 @@ do
fi
done
# Remove libcevap
rm -rf "$target"/libcevap
# Remove unwanted SVN stuff (TODO: avoid downloading it)
for i in "$target"/.svn "$target"/*/.svn
do

View File

@ -38,7 +38,7 @@ original="./libburn_svn.tgz"
# My changes are in $changes , mainly in $changes/cdrskin
changes="./libburn-develop"
skin_release="0.3.9"
skin_release="0.7.1"
patch_level=""
skin_rev="$skin_release""$patch_level"
@ -58,7 +58,7 @@ compile_result="cdrskin/cdrskin"
man_to_html_cmd="./cdrskin/convert_man_to_html.sh"
man_page_html="cdrskin/man_1_cdrskin.html"
bintarget_dynamic="cdrskin_${skin_rev}-x86-suse9_0"
bintarget_dynamic="cdrskin_${skin_rev}-amd64-suse10_2"
bintarget_static="$bintarget_dynamic"-static
if test -d "$changes"
@ -143,6 +143,9 @@ 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
@ -222,6 +225,8 @@ tar czf "$cdrskin_tarball" "$target"
"$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
"$man_to_html_cmd"
mv "$man_page_html" ..
)

View File

@ -2,7 +2,7 @@
.\" First parameter, NAME, should be all caps
.\" Second parameter, SECTION, should be 1-8, maybe w/ subsection
.\" other parameters are allowed: see man(7), man(1)
.TH CDRSKIN 1 "September 26, 2007"
.TH CDRSKIN 1 "May 07, 2009"
.\" Please adjust this date whenever revising the manpage.
.\"
.\" Some roff macros, for reference:
@ -16,8 +16,7 @@
.\" .sp <n> insert n+1 empty lines
.\" for manpage-specific macros, see man(7)
.SH NAME
cdrskin \- burns preformatted data to CD-R[W], DVD-R[W], DVD+R[W], DVD-RAM
via libburn.
cdrskin \- burns preformatted data to CD, DVD, and BD via libburn.
.SH SYNOPSIS
.B cdrskin
.RI [ options | track_source_addresses ]
@ -29,13 +28,15 @@ via libburn.
.\" respectively.
.PP
\fBcdrskin\fP is a program that provides some of cdrecord's options
in a compatible way for CD media. With DVD it has its own ways.
in a compatible way for CD media. With DVD and BD it has its own ways.
You do not need to be superuser for its daily usage.
.SS
.B Overview of features:
.br
Blanking of CD-RW and DVD-RW.
.br
Formatting of DVD-RW, DVD+RW, DVD-RAM, BD.
.br
Burning of data or audio tracks to CD,
.br
either in versatile Track at Once mode (TAO)
@ -44,13 +45,13 @@ or in Session at Once mode for seamless tracks.
.br
Multi session on CD (follow-up sessions in TAO only)
.br
or on DVD-R[W] (in Incremental mode) or on DVD+R.
or on DVD-R[W] (in Incremental mode) or DVD+R[/DL] or BD-R.
.br
Single session on DVD-RW or DVD-R (Disk-at-once).
.br
Single session or emulated ISO-9660 multi-session
.br
on overwriteable DVD+RW, DVD-RW, DVD-RAM,
on overwriteable DVD+RW, DVD-RW, DVD-RAM, BD-RE
.br
or on data file or block device.
.br
@ -66,9 +67,9 @@ Write mode selection
.br
Recordable CD Media
.br
Sequentially Recordable DVD Media
Sequentially Recordable DVD or BD Media
.br
Overwriteable DVD Media
Overwriteable DVD or BD Media
.br
Drive preparation and addressing
.br
@ -96,7 +97,7 @@ These informations are also used by the operating systems' CD-ROM read drivers.
.PP
In general there are two types of tracks: data and audio. They differ in
sector size, throughput and readability via the systems' CD-ROM drivers
resp. by music CD players. With DVD there is only type data.
resp. by music CD players. With DVD and BD there is only type data.
.br
If not explicitely option -audio is given, then any track is burned as type
data, unless the track source is a file with suffix ".wav" or ".au" and has a
@ -107,8 +108,9 @@ While audio tracks just contain a given time span of acoustic vibrations,
data tracks may have an arbitray meaning. Nevertheless, ISO-9660 filesystems
are established as a format which can represent a tree of directories and
files on all major operating systems. Such filesystem images can be
produced by programs mkisofs or genisoimage. They can also be extended by
follow-up tracks if prepared properly. See the man pages of said programs.
produced by programs mkisofs or genisoimage or xorriso.
They can also be extended by follow-up tracks if prepared properly.
See the man pages of said programs.
cdrskin is able to fulfill the needs about their option -C.
.br
Another type of data track content are archive formats which originally
@ -148,8 +150,8 @@ read-only. Closing is done automatically unless option
is given which keeps the media appendable.
.br
Write mode
-tao allows to use track source of unpredictable length (like stdin) and allows
to write further sessions to appendable media.
-tao allows to use track sources of unpredictable length (like stdin) and
allows to write further sessions to appendable media.
-sao produces audio sessions with seamless tracks but needs predicted track
sizes and cannot append sessions to media.
.br
@ -159,14 +161,16 @@ round of overwriting. Usually
is the appropriate option.
Blanking damages the previous content but does not
make it completely unreadable. It is no effective privacy precaution.
Multiple cycles of blanking and overwriting with random numbers might be.
Multiple cycles of blanking and overwriting with random numbers might be
needed.
.SS
.B Sequentially Recordable DVD Media:
.B Sequentially Recordable DVD or BD Media:
.br
Currently DVD-RW, DVD-R and DVD+R can be used for the Sequential recording
model.
Currently DVD-RW, DVD-R , DVD+R[/DL], and BD-R can be used for the Sequential
recording model. It resembles the model of CD media. Only DVD-RW can be
blanked and re-used from scratch.
.br
DVD-RW must be in state "Sequential Recording".
DVD-RW are sequential media if they are in state "Sequential Recording".
The media must be either blank or appendable.
Newly purchased DVD-RW and DVD-R media are in this state.
Used DVD-RW get into blank sequential state by option
@ -198,25 +202,27 @@ unpredicted length and to keep media appendable by option
The only restriction towards CD-R[W] is the lack of support for -audio tracks.
Multiple tracks per session are permissible.
.br
The write modes for DVD+R resemble those with DVD-R except that with DVD+R
each track gets wrapped in an own session. There is no -dummy writing with
DVD+R.
The write modes for DVD+R[/DL] and BD-R resemble those with DVD-R except that
each track gets wrapped in an own session. There is no -dummy writing
with DVD+R[/DL] or BD-R.
.br
Quite deliberately write mode -sao insists in the tradition of a predicted
track size and blank media, whereas -tao writes the tracks open ended and
allows appendable media.
.br
BD-R may be formatted before first use to enable the Defect Management which
might catch and repair some bad spots at the expense of slow speed
even with flawless media.
.br
.B Note:
Option -multi might make DVD media unreadable in some DVD-ROM drives.
Best reader compatibility is achieved without it
(i.e. by single session media).
.SS
.B Overwriteable DVD Media:
.B Overwriteable DVD or BD Media:
.br
Currently types DVD+RW, DVD-RW and DVD-RAM can be overwritten via cdrskin.
.br
DVD+RW and DVD-RAM media need no special initial formatting. They offer a
single continuous data area for blockwise random access.
Currently types DVD+RW, DVD-RW, DVD-RAM and BD-RE can be overwritten via
cdrskin.
.br
Option -audio is not allowed. Only one track is allowed.
Option -multi cannot mark a recognizeable end of overwriteable media.
@ -229,6 +235,12 @@ media get treated as blank regardless wether they hold data or not.
.br
Currently there is no difference between -sao and -tao. If ever, then -tao
will be the mode which preserves the current behavior.
.PP
DVD+RW and DVD-RAM media need no special initial formatting. They offer a
single continuous data area for blockwise random access. BD-RE need
explicit formatting before use. See
.B blank=as_needed
or blank=format_defectmgt .
.br
DVD-RW are sold in state "Sequential Recording". To become suitable for the
Overwriteable DVD recording model they need to get formatted to state
@ -242,7 +254,7 @@ that it has to be formatted again. If in doubt, just give it a try.
.SS
.B Drive preparation and addressing:
.br
The drives, either CD burners or DVD burners, are accessed via addresses which
The drives, CD, DVD, or BD burners, are accessed via addresses which
are specific to libburn and the operating system. Those addresses get listed
by a run of \fBcdrskin --devices\fP.
.br
@ -278,7 +290,9 @@ and device files which have the same SCSI address parameters (e.g. /dev/sg0).
.SS
.B Emulated drives:
.br
Option --allow_emulated_drives enables addressing of pseudo-drives
Option
.B --allow_emulated_drives
enables addressing of pseudo-drives
which get emulated on top of filesystem objects. Regular data files and
block devices result in pseudo-drives which behave much like DVD-RAM.
If the given address does not exist yet but its directory exists, then
@ -329,7 +343,8 @@ original cdrecord by Joerg Schilling:
.TP
.BI \-atip
Retrieve some info about media state. With CD-RW print "Is erasable".
With DVD media print "book type:" and a media type text.
With DVD media print "book type:" and a media type text. With BD media
print "Mounted Media:" and media type text.
.TP
.BI \-audio
Announces that the subsequent tracks are to be burned as audio.
@ -340,16 +355,26 @@ stereo. For little-endian byte order (which is usual on PCs) use option
those parameters and eventually raw audio data get extracted and burned as
audio track. Same is done for suffix ".au" and SUN Audio.
.br
Option -audio may be used only with CD media and not with DVD.
Option -audio may be used only with CD media and not with DVD or BD.
.TP
.BI blank= type
Blank a CD-RW, a DVD-RW, or format a DVD+/-RW.
Blank a CD-RW, DVD-RW, or format a DVD-RW, DVD+RW, DVD-RAM, BD.
This is combinable with burning in the same run of cdrskin.
The type given with blank= selects the particular behavior:
.RS
.TP
help
Print this list of blanking types.
as_needed
Try to make the media ready for writing from scratch. If it needs formatting,
then format it. If it is not blank, then try to apply blank=fast.
It is a reason to abort if the media cannot assume thoroughly writeable state,
e.g. if it is non-blank write-once.
.br
This leaves unformatted DVD-RW in unformatted blank state. To format DVD-RW use
blank=format_overwriteable. Blank unformatted BD-R stay unformatted.
.br
(Note: blank=as_needed is not an original cdrecord option.)
.TP
The following blank types are specific to particular media familes. Use them if special features are desired.
.TP
all
Blank an entire CD-RW or an unformatted DVD-RW.
@ -359,10 +384,36 @@ fast
Minimally blank an entire CD-RW or blank an unformatted DVD-RW.
(See also --prodvd_cli_compatible, --grow_overwriteable_iso)
.TP
deformat_sequential
Like blank=all but with the additional ability to blank overwriteable DVD-RW.
This will destroy their formatting and make them sequentially recordable.
Another peculiarity is the ability to blank media which appear already blank.
This is similar to option -force but does not try to blank media other than
recognizable CD-RW and DVD-RW.
.br
(Note: blank=deformat_* are not original cdrecord options.)
.TP
deformat_sequential_quickest
Like blank=deformat_sequential but blanking DVD-RW only minimally.
This is faster than full blanking but may yield media incapable of
Incremental Streaming (-tao).
.TP
format_if_needed
Format a media if it is not formatted yet,
and if cdrskin supports formatting for the media type,
and if formatting will not happen automatically during write.
This currently applies to unformatted DVD-RW, DVD-RAM, BD-RE,
and blank unformatted BD-R.
Eventually the appropriate default formatting is chosen.
If other media or states are encountered then nothing happens.
.br
The following formatting types are more specialized to particular
media families.
.TP
format_overwrite
Format a DVD-RW to "Restricted Overwrite". The user should bring some patience.
.br
(Note: blank=format_overwrite* are not original cdrecord options.)
(Note: blank=format_* are not original cdrecord options.)
.TP
format_overwrite_quickest
Like format_overwrite without creating a 128 MiB trailblazer session.
@ -381,19 +432,59 @@ This option treats already formatted media even if not option -force is given.
For DVD+RW this is the only supported explicit formatting type. It provides
complete "de-icing" so no reader slips on unwritten data areas.
.TP
deformat_sequential
Like blank=all but with the additional ability to blank overwriteable DVD-RW.
This will destroy their formatting and make them sequentially recordable.
Another peculiarity is the ability to blank media which appear already blank.
This is similar to option -force but does not try to blank media other than
recognizable CD-RW and DVD-RW.
format_defectmgt
Format DVD-RAM or BD to reserve the default amount of spare blocks for
defect management.
.br
(Note: blank=deformat_sequential* are not original cdrecord options.)
The following format_defectmgt_* allow to submit user wishes which
nevertheless have to match one of the available formats. These formats are
offered by the drive after examining the media.
.TP
deformat_sequential_quickest
Like blank=deformat_sequential but blanking DVD-RW only minimally.
This is faster than full blanking but may yield media incapable of
Incremental Streaming (-tao).
format_defectmgt_cert_off
Disable the usual media quality certification in order to save time and
format to default size.
The certification setting persists even if subsequent blank= options override
the size of the format selection.
.br
Whether formatting without certification works properly depends much on the
drive. One should check the "Format status:" from --list_formats afterwards.
.TP
format_defectmgt_cert_on
Re-enable the usual media quality certification and format to default size.
The certification setting persists like with format_defectmgt_cert_off.
.br
Whether there happens certification at all depends much on the media state
and the actually selected format descriptor.
.TP
format_defectmgt_max
Format DVD-RAM or BD to reserve a maximum number of spare blocks.
.TP
format_defectmgt_min
Format DVD-RAM or BD to reserve a minimum number of spare blocks.
It might be necessary to format format_defectmgt_none first in order to get
offered the most minmal spare blocks sizes for format_defectmgt_min.
.TP
format_defectmgt_none
Format DVD-RAM or BD-RE to the largest available payload in the hope to disable
defect management at all. This may or may not have a speed increasing effect.
Unformatted blank BD-R will be left unformatted.
.TP
format_defectmgt_payload_<size>
Format DVD-RAM or BD. The text after "format_defectmgt_payload_" gives a
number of bytes, eventually with suffixes "s", "k", "m". The largest number
of spare blocks will be chosen which allows at least the given payload size.
.TP
format_by_index_<number>
Format DVD-RW, DVD+RW, DVD-RAM or BD.
The number after "format_by_index_" is used as index to the list of available
format descriptors. This list can be obtained by option --list_formats.
The numbers after text "Format idx" are the ones to be used with
format_by_index_. Format descriptor lists are volatile. Do neither eject
nor write the media between the run of --list_formats and the run of
blank=format_by_index_ or else you may get a different format than desired.
.TP
help
Print this list of blanking types.
.RE
.TP
.BI \-checkdrive
@ -534,7 +625,8 @@ Note: msifile=path is actually an option of wodim and not of cdrecord.
.TP
.BI \-msinfo
Retrieve multi-session info for preparing a follow-up session by option -C
of programs mkisofs or genisoimage. Print result to standard output.
of programs mkisofs, genisoimage, or xorriso -as mkisofs.
Print result to standard output.
This option redirects to stderr all message output except the one of option
--tell_media_space and its own result string, which consists of two numbers.
The result string shall be used as argument of option -C with said programs.
@ -546,8 +638,8 @@ To have a chance for working on overwriteable media, this option has to be
accompanied by option --grow_overwriteable_iso.
.TP
.BI \-multi
This option keeps the CD or unformatted DVD-R[W] appendable after the current
session has been written.
This option keeps CD, unformatted DVD-R[W], DVD+R, or BD-R appendable
after the current session has been written.
Without it the disc gets closed and may not be written any more - unless it
is a -RW and gets blanked which causes loss of its content.
.br
@ -565,7 +657,7 @@ To retrieve an archive file which was written as follow-up session,
you may use option -toc to learn about the "lba" of the desired track number.
This lba is the address of the 2048 byte block where the archive begins.
.br
With overwriteable DVD media, -multi cannot mark the end of the session.
With overwriteable DVD or BD media, -multi cannot mark the end of the session.
So when adding a new session this end has to be determined from the payload.
Currently only ISO-9660 filesystems can be used that way. See option
.B \--grow_overwriteable_iso
@ -595,8 +687,8 @@ then behave strange or even go bad for the next few attempts to burn a CD.
One should use it only if inavoidable.
.TP
.BI \-sao
Write CD in Session At Once mode, a sequential DVD-R[W] in Disc-at-once
(DAO) mode, or a DVD+R.
Write CD in Session At Once mode or sequential DVD-R[W] in Disc-at-once
(DAO) mode.
.br
With CD this mode is able to put several audio tracks on media without
producing audible gaps between them.
@ -604,8 +696,8 @@ producing audible gaps between them.
With DVD-R[W] this mode can only write a single track.
No -multi is allowed with DVD-R[W] -sao.
.br
-sao is permissible with overwriteable DVD and with DVD+R but actually only
imposes restrictions without providing known advantages.
-sao is permissible with overwriteable DVD, or DVD+R[/DL], or BD but actually
only imposes restrictions without providing known advantages.
.br
-sao can only be used for tracks of fixely predicted size. This implies that
track arguments which depict stdin or named pipes need to be preceeded by
@ -629,6 +721,7 @@ Bus,Target,Lun Number) 'Vendor' 'Mode' 'Revision'
.BI speed= number
Set speed of drive. With data CD, 1x speed corresponds to a throughput of
150,000 bytes/second. With DVD, 1x = 1,385,000 bytes/second.
With BD 1x = 4,495,625 bytes/second.
It is not an error to set a speed higher than is suitable for drive
and media. One should stay within a realistic speed range, though.
Special speed settings are:
@ -645,8 +738,8 @@ suffix ".wav".
.TP
.BI \-tao
Write CD in Track At Once (TAO) mode, sequential DVD-R[W] in Incremental
Streaming mode, or DVD+R without traditional -sao restrictions.
This mode also applies pro-forma to overwriteable DVD media.
Streaming mode, or DVD+R[/DL] without traditional -sao restrictions.
This mode also applies pro-forma to overwriteable media
.br
Mode -tao can be used with track sources of unpredictable size, like standard
input or named pipes. It is also the only mode that can be used for writing
@ -776,8 +869,9 @@ be the only finalization. It is advised to eject the media afterwards because
the write operations circumvent the usual system i/o with its caches and
buffers. By ejecting, those invalid memory copies get surely discarded.
.br
Only few media can be written this way: DVD-RAM, RVD+RW and overwriteable
DVD-RW. Writing is restricted to the already formatted area of the media.
Only few media can be written this way: DVD-RAM, BD-RE, RVD+RW and
overwriteable DVD-RW. Writing is restricted to the already formatted
area of the media.
.br
Writing starts at byte 0 of the media or at the address given by option
.B write_start_address= .
@ -792,7 +886,7 @@ padded up to the necessary size by zeros. Size -1 revokes direct writing
and switches back to normal session oriented writing.
.br
Both, write_start_address and direct_write_amount size must be aligned to a
media dependend transaction size. With DVD-RAM and DVD+RW this is 2k, with
media dependend transaction size. With DVD-RAM, BD-RE, DVD+RW this is 2k, with
overwriteable DVD-RW it is 32k.
.TP
.BI fallback_program= command
@ -872,6 +966,16 @@ With multi-session DVD, blank=fast will act like dvd+rw-format -blank=full .
.br
growisofs -dvd-compat is roughly equivalent to cdrskin without option -multi.
.TP
.BI \--list_formats
List the available format descriptors as reported by the drive for the
loaded media. Each descriptor line begins with "Format idx" and the
descriptor's list index, followed by a ":", the format type, the number
of payload blocks and that same number converted to MiB.
.br
The meaning of the format types is defined by the MMC standard
with command FORMAT UNIT. A user will more be interested in the
sizes than in the types.
.TP
.BI \--list_ignored_options
List all ignored cdrecord options. The "-" options cannot be used as addresses
of track sources. No track source address may begin with a text equal to an
@ -928,8 +1032,8 @@ This option redirects to stderr all message output except its own result
string and eventual output of -msinfo.
.TP
.BI write_start_address= byte_offset
Set the address on media where to start writing the track. With DVD+RW or
DVD-RAM byte_offset must be aligned to 2 kiB blocks, but better is 32 kiB.
Set the address on media where to start writing the track. With DVD+RW, DVD-RAM
or BD-RE byte_offset must be aligned to 2 kiB blocks, but better is 32 kiB.
With DVD-RW 32 kiB alignment is mandatory.
.br
Other media are not suitable for this option yet.
@ -949,8 +1053,6 @@ tested. Currently this applies to :
.br
Profile 0015h , DVD-R/DL Sequential (will not allow -multi).
.br
Profile 002Bh , DVD+R/DL.
.br
If you really test such media, then please report the outcome on
libburn-hackers@pykix.org
.TP
@ -987,8 +1089,9 @@ Linux specific: Do not ask the operating system to prevent opening busy drives.
Wether this leads to senseful behavior depends on operating system and kernel.
.TP
.BI drive_scsi_dev_family= sr | scd | sg
Linux specific: Select a SCSI device file family to be used for drive command
transactions. Normally this is /dev/sgN on kernel versions < 2.6 and /dev/srN
Linux specific: Select a SCSI device file family to be scanned for by
options --devices and -scanbus.
Normally this is /dev/sgN on kernel versions < 2.6 and /dev/srN
on kernels >= 2.6 . This option allows to explicitely override that default
in order to meet other programs at a common device file for each drive.
On kernel 2.4 families sr and scd will find no drives.
@ -1082,7 +1185,16 @@ Linux specific:
Use and report literal Bus,Target,Lun addresses rather than real SCSI and
pseudo ATA addresses. This method is outdated and was never compatible with
original cdrecord.
.TP
.BI stream_recording="on"|"off"|number
By setting "on" request that compliance to the desired speed setting is
preferred over management of write errors. With DVD-RAM and BD this can
bring effective write speed near to the nominal write speed of the media.
But it will also disable the automatic use of replacement blocks
if write errors occur. It might as well be disliked or ignored by the drive.
.br
If a number is given, then error management stays enabled for all byte
addresses below that number. Any number below 16s is the same as "off".
.SH EXAMPLES
.SS
.B Get an overview of drives and their addresses:
@ -1101,11 +1213,9 @@ cdrskin dev=ATA:1,0,0 -v -atip
.br
cdrskin dev=/dev/hdc -toc
.SS
.B Make used CD-RW or used unformatted DVD-RW writable again:
.B Prepare CD-RW or DVD-RW for re-use, DVD-RAM or BD-RE for first use:
.br
cdrskin -v dev=/dev/sg1 blank=fast -eject
.br
cdrskin -v dev=/dev/dvd blank=all -eject
cdrskin -v dev=/dev/sg1 blank=as_needed -eject
.SS
.B Format DVD-RW to avoid need for blanking before re-use:
.br
@ -1119,7 +1229,7 @@ cdrskin -v dev=/dev/sr0 blank=deformat_sequential
.br
cdrskin -v dev=/dev/hdc speed=12 fs=8m \\
.br
-sao -eject padsize=300k my_image.iso
blank=as_needed -eject padsize=300k my_image.iso
.SS
.B Write compressed afio archive on-the-fly (not possible with minimally blanked DVD-RW):
.br
@ -1127,17 +1237,17 @@ find . | afio -oZ - | \\
.br
cdrskin -v dev=0,1,0 fs=32m speed=8 \\
.br
-tao padsize=300k -
blank=as_needed padsize=300k -
.SS
.B Write multi-session to the same CD, DVD-R[W] or DVD+R:
.B Write multi-session to the same CD, DVD-R[W], DVD+R[/DL], or BD-R:
.br
cdrskin dev=/dev/hdc -v padsize=300k -multi -tao 1.iso
cdrskin dev=/dev/sr0 -v padsize=300k -multi 1.iso
.br
cdrskin dev=/dev/hdc -v padsize=300k -multi -tao 2.iso
cdrskin dev=/dev/sr0 -v padsize=300k -multi 2.iso
.br
cdrskin dev=/dev/hdc -v padsize=300k -multi -tao 3.iso
cdrskin dev=/dev/sr0 -v padsize=300k -multi 3.iso
.br
cdrskin dev=/dev/hdc -v padsize=300k -tao 4.iso
cdrskin dev=/dev/sr0 -v padsize=300k 4.iso
.SS
.B Get multi-session info for option -C of program mkisofs:
.br
@ -1145,9 +1255,9 @@ c_values=$(cdrskin dev=/dev/hdc -msinfo 2>/dev/null)
.br
mkisofs ... -C "$c_values" ...
.SS
.B Inquire free space on media for a -tao -multi run:
.B Inquire free space on media for a -multi run:
.br
x=$(cdrskin dev=/dev/sr0 -tao -multi \\
x=$(cdrskin dev=/dev/sr0 -multi \\
.br
--tell_media_space 2>/dev/null)
.br
@ -1212,23 +1322,25 @@ Formatting data track sources for cdrskin:
.br
.BR mkisofs (8),
.BR genisoimage (8),
.BR xorriso (1),
.BR afio (1),
.BR star (1)
.br
.TP
Other CD/DVD burn programs:
Other CD/DVD/BD burn programs:
.br
.BR cdrecord (1),
.BR wodim (1)
.BR wodim (1),
.BR xorriso (1)
.br
.TP
For DVD burning (also tutor of libburn's DVD capabilities):
For DVD/BD burning (also tutor of libburn's DVD/BD capabilities):
.br
.BR growisofs (1)
.br
.SH AUTHOR
cdrskin was written by Thomas Schmitt <scdbackup@gmx.net>.
.PP
This manual page was written by George Danchev <danchev@spnet.net> and
Thomas Schmitt, for the Debian project and for all others.
This manual page was started by George Danchev <danchev@spnet.net> and
is now maintained by Thomas Schmitt.

File diff suppressed because it is too large Load Diff

View File

@ -2,7 +2,7 @@
<HEAD>
<META NAME="description" CONTENT="cdrskin, a limited cdrecord compatibility wrapper for libburn">
<META NAME="keywords" CONTENT="cdrskin, libburn, libburnia, burn, CD, DVD, linux, recording, burning, CD-R, CD-RW, DVD-R, DVD-RW, DVD+RW, DVD+R, cdrecord, compatible, scdbackup">
<META NAME="keywords" CONTENT="cdrskin, libburn, libburnia, burn, CD, DVD, linux, recording, burning, CD-R, CD-RW, DVD-R, 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>
@ -17,26 +17,29 @@
</A>
<P><H2> Homepage of </H2>
<H1> cdrskin </H1>
<!-- <FONT SIZE=+0><A HREF="cdrskin_ger.html">deutsch (german)</A></FONT> -->
<H2>Limited cdrecord compatibility wrapper for libburn</H2>
</CENTER>
<P>
<H2>Purpose:</H2>
Burns preformatted data to CD and single layer DVD media:<BR>
CD-R, DVD-R, DVD+R, CD-RW, DVD-RW, DVD-RAM, DVD+RW
Burns preformatted data to CD, DVD, and BD media:<BR>
CD-R, DVD-R, 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>
A CD/DVD recorder suitable for
<A HREF="http://libburnia-project.org">http://libburnia-project.org</A> <BR>
(SCSI , ATA , USB , or SATA writers compliant to standard MMC-3 for CD
and to MMC-5 for DVD).
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 and FreeBSD allow to access drives connected
via SCSI, PATA (aka IDE, ATA), USB, or SATA.
<BR>
</P>
@ -46,6 +49,8 @@ and to MMC-5 for DVD).
<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 the drive should not be under ide-scsi.</DD>
<DT>or FreeBSD (with libc, of course) :</DT>
<DD>ATAPI/CAM support has to be enabled in the kernel, see atapicam(4).</DD>
<DT>libpthread</DT>
<DD>is supposed to be a standard system component.</DD>
</DL>
@ -56,14 +61,18 @@ and to MMC-5 for DVD).
GPL software included:<BR>
</H2>
<DL>
<DT>libburn-0.3.8</DT>
<DD>(by Derek Foreman, Ben Jansens, and team of libburnia-project.org)</DD>
<DD>transfers data to CD and DVD</DD>
<DT>libburn-0.7.0</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 Linux systems only.<BR>
This program system has been tested on Intel/AMD Linux and FreeBSD systems
only.<BR>
Ports to other usable systems are appreciated. Reports are welcome.
</P>
@ -83,10 +92,10 @@ Ports to other usable systems are appreciated. Reports are welcome.
<DL>
<DT>The most common options of cdrecord for data and audio on CD media
are provided in a compatible way.<BR>
On single layer DVD media cdrskin is able to perform any recording job
On all DVD media except DVD-R DL, cdrskin is able to perform any recording job
which is possible with cdrecord.
Other than with cdrecord, options -multi and -tao are supported with
certain DVD types.
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.
</DT>
<BR><BR>
<DT>Get an overview of drives and their addresses</DT>
@ -104,9 +113,8 @@ as listed by option --devices.</DT>
<DD>$<KBD>&nbsp;cdrskin dev=ATA:1,0,0 -v -atip</KBD></DD>
<DD>$<KBD>&nbsp;cdrskin dev=/dev/hdc -toc</KBD></DD>
<DT>Make used CD-RW or used unformatted DVD-RW writable again:</DT>
<DD>$<KBD>&nbsp;cdrskin -v dev=/dev/sg1 blank=fast -eject</KBD></DD>
<DD>$<KBD>&nbsp;cdrskin -v dev=/dev/dvd blank=all -eject</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>
@ -117,31 +125,34 @@ as listed by option --devices.</DT>
<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;-sao -eject padsize=300k my_image.iso</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:</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;-tao padsize=300k -</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:</DT>
<DD>$<KBD>&nbsp;cdrskin dev=/dev/hdc -v padsize=300k -multi -tao 1.iso</KBD>
<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 -tao 2.iso</KBD>
<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 -tao 3.iso</KBD>
<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 -tao 4.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 -tao -multi run:</DT>
<DD>$<KBD>&nbsp;x=$(cdrskin dev=/dev/sr0 -tao -multi \</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>
@ -165,39 +176,51 @@ man cdrecord</A></KBD></DD>
this "don't bother Joerg" demand.)
</DD>
</DL>
Testers wanted who are willing to risk some double layer DVD media.
<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-0.3.8.pl00.tar.gz">cdrskin-0.3.8.pl00.tar.gz</A>
(615 KB).
<DD><A HREF="cdrskin-0.7.0.pl00.tar.gz">cdrskin-0.7.0.pl00.tar.gz</A>
(820 KB).
</DD>
<DD>
The "stable" cdrskin tarballs are source code identical with "stable"
libburn releases or with "stabilized" libburn SVN snapshots. They get
produced via a different procedure, though.<BR>
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.3.8.pl00-x86-suse9_0.tar.gz">
cdrskin_0.3.8.pl00-x86-suse9_0.tar.gz</A>, (90 KB),
<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.3.8.pl00-x86-suse9_0-static.tar.gz">
cdrskin_0.3.8.pl00-x86-suse9_0-static.tar.gz</A>, (290 KB), -static compiled,
<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>
@ -220,53 +243,55 @@ cdrskin_0.3.8.pl00-x86-suse9_0-static.tar.gz</A>, (290 KB), -static compiled,
<HR>
<P>
Enhancements towards previous stable version cdrskin-0.3.6:
Enhancements towards previous stable version cdrskin-0.6.8.pl00:
<UL>
<LI>Now able to cope with the peculiarities of Linux 2.4 USB</LI>
<LI>Refusal to perform -dummy runs on media which cannot simulate burning</LI>
<LI>Precautions against using the burner drive as track source</LI>
<LI>New option modesty_on_drive= may help with hda -> hdb burns</LI>
<LI>New option minbuf= , cdrecord compatible frontend of modesty_on_drive=</LI>
<LI>New option --adjust_speed_to_drive</LI>
</UL>
<LI>Adapted to pitfalls of U3 memory sticks which appear as CD-ROM drives</LI>
<LI>Listing all supported profiles with option -atip -v</LI>
<!--
Bug fixes towards cdrskin-0.3.8.pl00:
<UL>
<LI>none yet</LI>
</UL>
<LI>none</LI>
-->
</UL>
</P>
Bug fixes towards cdrskin-0.6.8.pl00:
<UL>
<LI>none</LI>
<!--
-->
</UL>
<HR>
<P>
<DL>
<DT><H3>Development snapshot, version 0.3.9 :</H3></DT>
<DD>Enhancements towards stable version 0.3.8.pl00:
<DT><H3>Development snapshot, version 0.7.1 :</H3></DT>
<DD>Enhancements towards current stable version 0.7.0.pl00:
<UL>
<LI>New option direct_write_amount=</LI>
<LI>New option --grow_overwriteable_iso</LI>
<LI>New option --allow_emulated_drives dev=stdio:&lt;path&gt;</LI>
<LI>More cdrecord options supported:
-format, -inq, -load, -lock, -immed, -waiti</LI>
<!--
<LI>none yet</LI>
<!--
-->
</UL>
</DD>
<DD>Bug fixes towards cdrskin-0.7.0.pl00:
<UL>
<LI>none yet</LI>
<!--
-->
</UL>
</DD>
<DD>&nbsp;</DD>
<DD><A HREF="README_cdrskin_devel">README 0.3.9</A>
<DD><A HREF="cdrskin__help_devel">cdrskin_0.3.9 --help</A></DD>
<DD><A HREF="cdrskin_help_devel">cdrskin_0.3.9 -help</A></DD>
<DD><A HREF="man_1_cdrskin_devel.html">man cdrskin (as of 0.3.9)</A></DD>
<DD><A HREF="README_cdrskin_devel">README 0.7.1</A>
<DD><A HREF="cdrskin__help_devel">cdrskin_0.7.1 --help</A></DD>
<DD><A HREF="cdrskin_help_devel">cdrskin_0.7.1 -help</A></DD>
<DD><A HREF="man_1_cdrskin_devel.html">man cdrskin (as of 0.7.1)</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</B>
<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.
@ -274,22 +299,29 @@ 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 downloads are intended for adventurous end users or
<DT>The following download is intended for adventurous end users or
admins with full system souvereignty.</DT>
<DD>Source (./bootstrap is already applied, build tested, for more see
<A HREF="README_cdrskin_devel">upcoming README</A> ):
</DD>
<DD>
<A HREF="cdrskin-0.3.9.tar.gz">cdrskin-0.3.9.tar.gz</A>
(640 KB).
<A HREF="cdrskin-0.7.1.tar.gz">cdrskin-0.7.1.tar.gz</A>
(820 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.3.9-x86-suse9_0.tar.gz">
cdrskin_0.3.9-x86-suse9_0.tar.gz</A>, (90 KB).
<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.3.9-x86-suse9_0-static.tar.gz">
cdrskin_0.3.9-x86-suse9_0-static.tar.gz</A>, (290 KB)
<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>
@ -307,7 +339,7 @@ Historic versions based on Derek's and Ben's
<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 media.
provide libburn with invaluable examples on how to deal with DVD and BD media.
</P>
<HR>
@ -315,14 +347,33 @@ provide libburn with invaluable examples on how to deal with DVD media.
<A NAME="examples">
<P>
<DL>
<DT>Example for a setup of device permissions. To be done by the superuser:</DT>
<DT>(CD devices which offer no rw-permission are invisible to normal users.)
<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; rwrwr- :&nbsp; 'TEAC' 'CD-ROM CD-532S'</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>
@ -337,6 +388,8 @@ Example how to setup K3b to use cdrskin for burning data CD projects.
is a GUI frontend which uses cdrecord for CD burning.)
</P>
<!--
<HR>
<A NAME="scdbackup">
@ -391,6 +444,8 @@ and try again.
</DL>
</P>
-->
<HR>
<A NAME="cdrecord">
@ -403,7 +458,7 @@ cdrecord but not vice versa.
I am a long time user of cdrecord and it works fine for me.
Especially i do appreciate its write mode -tao which allows to pipe arbitrary
data on CD and CD-RW via stdin. cdrecord is reliable, versatile and well
maintained. So for me - there would be not problem with it.
maintained. So for me - there would be no problem with it.
<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).
@ -446,17 +501,34 @@ 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></DL>
(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>

View File

@ -1 +1 @@
#define Cdrskin_timestamP "2007.10.23.150436"
#define Cdrskin_timestamP "2009.08.27.123001"

File diff suppressed because it is too large Load Diff

View File

@ -1,13 +1,13 @@
#!/bin/sh
# compile_cdrskin.sh
# Copyright 2005 - 2007 Thomas Schmitt, scdbackup@gmx.net, GPL
# Copyright 2005 - 2009 Thomas Schmitt, scdbackup@gmx.net, GPL version 2
# to be executed within ./libburn-* resp ./cdrskin-*
debug_opts="-O2"
def_opts=
largefile_opts="-D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE=1"
libvers="-DCdrskin_libburn_0_3_9"
libvers="-DCdrskin_libburn_0_7_0"
cleanup_src_or_obj="libburn/cleanup.o"
libdax_msgs_o="libburn/libdax_msgs.o"
libdax_audioxtr_o="libburn/libdax_audioxtr.o"
@ -33,15 +33,15 @@ do
libdax_audioxtr_o=
libdax_msgs_o="libburn/message.o"
cleanup_src_or_obj="-DCleanup_has_no_libburn_os_H cdrskin/cleanup.c"
elif test "$i" = "-libburn_0_3_8"
elif test "$i" = "-libburn_0_7_0"
then
libvers="-DCdrskin_libburn_0_3_8"
libvers="-DCdrskin_libburn_0_7_0"
libdax_audioxtr_o="libburn/libdax_audioxtr.o"
libdax_msgs_o="libburn/libdax_msgs.o"
cleanup_src_or_obj="libburn/cleanup.o"
elif test "$i" = "-libburn_svn"
then
libvers="-DCdrskin_libburn_0_3_9"
libvers="-DCdrskin_libburn_0_7_1"
libdax_audioxtr_o="libburn/libdax_audioxtr.o"
libdax_msgs_o="libburn/libdax_msgs.o"
cleanup_src_or_obj="libburn/cleanup.o"
@ -75,10 +75,8 @@ do
echo "Options:"
echo " -compile_cdrfifo compile program cdrskin/cdrfifo."
echo " -compile_dewav compile program test/dewav without libburn."
echo " -cvs_A60220 set macro to match libburn-CVS of 20 Feb 2006."
echo " -libburn_0_3_8 set macro to match libburn-0.3.8."
echo " -libburn_0_7_0 set macro to match libburn-0.7.0"
echo " -libburn_svn set macro to match current libburn-SVN."
echo " -no_largefile do not use 64 bit off_t (must match libburn)."
echo " -do_not_compile_cdrskin omit compilation of cdrskin/cdrskin."
echo " -experimental use newly introduced libburn features."
echo " -oldfashioned use pre-0.2.2 libburn features only."

View File

@ -16,7 +16,7 @@ manpage="cdrskin"
raw_html=$(pwd)/"cdrskin/raw_man_1_cdrskin.html"
htmlpage=$(pwd)/"cdrskin/man_1_cdrskin.html"
if test -r "$manpage"
if test -r "$man_dir"/"$manpage".1
then
dummy=dummy
else
@ -56,7 +56,7 @@ then
-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>/\&nbsp;<BR><b>Emulated drives:<\/b>/' \
-e 's/^Alphabetical list of options/\&nbsp;<BR>Alphabetical list of options/' \
-e 's/and for all others\.<\/td><\/table>/and for all others.<\/td><\/table> <BR><HR><FONT SIZE=-1><CENTER>(HTML generated from '"$manpage"'.1 on '"$(date)"' by '$(basename "$0")' )<\/CENTER><\/FONT>/' \
-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>/' \
<"$2" >"$htmlpage"

View File

@ -8,10 +8,10 @@
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 and DVD-RW are handled differently than
with cdrecord-ProDVD in order to offer TAO-like single track recording.
Sequential DVD-R[W] and DVD+R are handled like CD-R[W] with TAO and
multi-session. Additionally cdrskin offers cdrecord-ProDVD-like mode DAO
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.
@ -23,8 +23,7 @@ About libburn API for burning CD and DVD: http://api.libburnia-project.org
--------------------------------------------------------------------------
For dual layer DVD types and for appending sessions to ISO filesystems on
DVD other than DVD-RW, DVD-R, DVD+R see the advise to use dvd+rw-tools at
For yet unsupported media types see the advice to use dvd+rw-tools at
the end of this text.
--------------------------------------------------------------------------
@ -80,12 +79,58 @@ 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 aquire 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 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.
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
@ -94,9 +139,9 @@ disc from its initial profile "Sequential Recording" into profile state
cdrskin dev=/dev/sr0 -v blank=format_overwrite
}}}
DVD-RAM, DVD+RW 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.
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 ...
}}}
@ -107,8 +152,9 @@ 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.
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".
@ -117,6 +163,13 @@ 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> allows to ensure that the start block address which
@ -228,10 +281,10 @@ for an illustrated example with K3b 0.10 .
DVD advise:
For burning of DVD media other than DVD-RAM, DVD+RW, DVD+R, DVD-RW, DVD-R,
the cdrskin project currently advises to use Andy Polyakov's dvd+rw-tools
which despite their historic name are capable of all the media above
and also do dual layer and even BD discs.
For burning of DVD/BD media other than DVD-RAM, DVD+RW, DVD+R, DVD+R DL,
DVD-RW, DVD-R, BD-RE, the cdrskin project currently advises to use
Andy Polyakov's dvd+rw-tools which despite their historic name are
capable of all the media above and more, including BD discs.
http://fy.chalmers.se/~appro/linux/DVD+RW/tools
@ -239,19 +292,27 @@ They are not compatible or related to cdrecord resp. cdrecord-ProDVD
(now obsoleted by original source cdrtools cdrecord with identical
capabilities besides the license key).
--------------------------------------------------------------------------
Advanced multi-session use cases:
A special feature of dvd+rw-tools is growing of ISO-9660 filesystems on
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 for growable ISO filesystems on DVD-RAM or DVD+RW growisofs is the only
choice, currently.
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.
cdrskin can offer DVD multi-session only with sequential DVD-R[W] and with
DVD+R.
Associated options blank=, -multi, -msinfo and -toc are available in this case.
Thus sequential DVD-RW behave much like large CD-RW with possibly more than 99
tracks.
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].
--------------------------------------------------------------------------

View File

@ -1,4 +1,4 @@
AC_INIT([libburn], [0.3.9], [http://libburnia-project.org])
AC_INIT([libburn], [0.7.0], [http://libburnia-project.org])
AC_PREREQ([2.50])
dnl AC_CONFIG_HEADER([config.h])
@ -7,35 +7,119 @@ AC_CANONICAL_TARGET
AM_INIT_AUTOMAKE([subdir-objects])
dnl Making releases:
dnl BURN_MICRO_VERSION += 1;
dnl BURN_INTERFACE_AGE += 1;
dnl BURN_BINARY_AGE += 1;
dnl if any functions have been added, set BURN_INTERFACE_AGE to 0.
dnl if backwards compatibility has been broken,
dnl set BURN_BINARY_AGE and BURN_INTERFACE_AGE to 0.
dnl Notes by ts A71207 - A90827 :
dnl
dnl if MAJOR or MINOR version changes, be sure to change AC_INIT above to match
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
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=0
BURN_MINOR_VERSION=3
BURN_MICRO_VERSION=9
BURN_INTERFACE_AGE=0
BURN_BINARY_AGE=0
BURN_MINOR_VERSION=7
BURN_MICRO_VERSION=0
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_INTERFACE_AGE)
AC_SUBST(BURN_BINARY_AGE)
AC_SUBST(BURN_VERSION)
dnl Libtool versioning
LT_RELEASE=$BURN_MAJOR_VERSION.$BURN_MINOR_VERSION
LT_CURRENT=`expr $BURN_MICRO_VERSION - $BURN_INTERFACE_AGE`
LT_REVISION=$BURN_INTERFACE_AGE
LT_AGE=`expr $BURN_BINARY_AGE - $BURN_INTERFACE_AGE`
LT_RELEASE=$BURN_MAJOR_VERSION.$BURN_MINOR_VERSION.$BURN_MICRO_VERSION
dnl
dnl ts A90827
dnl This is the release version libburn-0.7.0 = libburn.so.4.35.0
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 = 39 - 35 = 4 . Linux library name = libburn.so.4.35.0
LT_CURRENT=39
LT_AGE=35
LT_REVISION=0
LT_CURRENT_MINUS_AGE=`expr $LT_CURRENT - $LT_AGE`
AC_SUBST(LT_RELEASE)
@ -44,6 +128,12 @@ 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
@ -75,8 +165,19 @@ 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="$CFLAGS $STATVFS_DEF"
dnl Add compiler-specific flags
dnl See if the user wants aggressive optimizations of the code
@ -96,10 +197,17 @@ else
CFLAGS="$CFLAGS -DDEBUG"
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-5.pc
libburn-1.pc
])
AC_OUTPUT

View File

@ -1,75 +1,51 @@
/**
@author Mario Danic, Thomas Schmitt
@mainpage Libburnia Documentation Index
@mainpage Libburn Documentation Index
@section intro Introduction
Libburnia is an open-source project for reading, mastering and writing
optical discs.
For now this means CD-R, CD-RW, DVD-RAM, DVD+RW, DVD+R, DVD-RW, DVD-R.
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, BD-R, BD-RE.
Not supported yet are dual layer media, HD-DVD, BD (blue ray). Testers for
dual layer DVD+/-R are wanted, though.
Not supported yet are DVD-R/DL. Testers wanted.
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.
Our scope is currently Linux 2.4 and 2.6, or FreeBSD . For ports to other
systems we would need : login on a development machine resp. a live OS on CD
or DVD, advise from a system person about the equivalent of Linux sg or FreeBSD
CAM, volunteers for testing of realistic use cases.
Our scope is currently Linux 2.4 and 2.6 only. For ports to other systems
we would need : login on a development machine resp. a live OS on CD or DVD,
advise from a system person about the equivalent of Linux sg or FreeBSD CAM,
volunteers for testing of realistic use cases.
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.
We have a workable code base for burning data and audio CDs and many DVD types.
The burn API is quite comprehensively documented and can be used to build a
presentable application.
We have a functional binary 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.
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.
@subsection components The project components (list subject to growth, hopefully):
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.
- 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.
libisofs is to be the foundation of our upcoming mkisofs emulation.
- 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.
- "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 plan to be a responsive upstream. Bear with us.
SONAME:
libburn.so.4 (since 0.3.4, March 2007),
@section using Using the libraries
@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 subprojects it should be sufficient to go into
its toplevel directory and execute
To build libburn and its companion applications go into its toplevel directory
and execute
- ./bootstrap (needed if you downloaded from SVN)
@ -81,29 +57,24 @@ To make the libraries accessible for running resp. developing applications
- make install
Both libraries are written in C language and get built by autotools.
Thus we expect them to be useable by a wide range of Linux-implemented
languages and development tools.
@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 blank a CD-RW or DVD-RW and
can burn to recordable CD and recordable single layer DVD.
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 three gestures can be implemented and
stay upward compatible for a good while.
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_overwrite]
[--try_to_simulate]
[--blank_fast|--blank_full|--format] [--try_to_simulate]
[--multi] [<one or more imagefiles>|"-"]
Examples
A bus scan (needs rw-permissions to see a drive):
@ -116,8 +87,8 @@ 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 to avoid need for blanking before re-use:
test/libburner --drive /dev/hdc --format_overwrite
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

View File

@ -1,11 +1,12 @@
libburnia-project.org Optical Media Rotisserie Recipes as of August 2007
libburnia-project.org Optical Media Rotisserie Recipes as of January 2009
Content:
- TAO Multi-Session CD Cookbook (CD-R, CD-RW)
- SAO CD Cookbook (CD-R, CD-RW, pure audio or pure data only)
- Overwriteable DVD Cookbook (DVD-RAM, DVD+RW, DVD-RW)
- Overwriteable DVD Cookbook (DVD-RAM, DVD+RW, DVD-RW, BD-RE)
- Sequential DVD-R[W] Cookbook
- DVD+R Cookbook
- DVD+R[/DL] Cookbook
- BD-R Cookbook
-------------------------------------------------------------------------------
TAO Multi-Session CD Cookbook
@ -403,7 +404,8 @@ correctness of Pre-gap and Post-gap would become evident.
-------------------------------------------------------------------------------
Inspired by Andy Polyakov's http://fy.chalmers.se/~appro/linux/DVD+RW/tools ,
backed by reading mmc5r03c.pdf from http://www.t10.org/ftp/t10/drafts/mmc5/
and by experiments with drives NEC ND-4570A and LG GSA-4082B.
by own experiments with drives NEC ND-4570A, LG GSA-4082B, PHILIPS SPD3300L,
LG GGW H20L, and by BD-RE experiments done by Giulio Orsero on LG BE06LU10.
For libburnia-project.org by Thomas Schmitt <scdbackup@gmx.net>
@ -416,18 +418,24 @@ DVD-RAM 0012h
DVD-RW Restricted Overwrite 0013h
DVD-RW Sequential Recording 0014h (i.e. unformatted)
DVD+RW 001Ah
BD-RE 0043h
A short compilation of the write model:
- Overwriting in general
The recipes described here are depending on formatting state:
- DVD-RAM, fully formatted DVD+RW or DVD-RW
- DVD-RAM, fully formatted DVD+RW, DVD-RW, BD-RE
- Unformatted DVD+RW
- Partly formatted DVD+RW
- Unformatted DVD-RW
- Partly formatted DVD-RW
- Intermediate state DVD-RW
- DVD-RAM and BD-RE formatting
- DVD-RAM and BD-RE speed tuning
Slightly off topic are
- ISO 9660 multi-session emulation on overwriteable media
- ISO 9660 based TOC emulation on overwriteable media
-------------------------------------------------------------------------------
Overwriting in general :
@ -444,7 +452,7 @@ Optimal performance is promised without any speed setting. But my experiments
showed that SET STREAMING values persist after media change.
In the formatted area of the media, coarse random access is possible.
For DVD-RAM and DVD+RW write addresses and data size need to be aligned
For DVD-RAM, DVD+RW, BD-RE write addresses and data size need to be aligned
to 2 KiB. For DVD-RW alignment has to be 32 KiB. Within these limitations
the write address is at the discretion of the sending program.
Just use 2Ah WRITE to send data.
@ -483,9 +491,12 @@ software did anything wrong.
-------------------------------------------------------------------------------
DVD-RAM, fully formatted DVD+RW or DVD-RW :
DVD-RAM, fully formatted DVD+RW, DVD-RW, BD-RE :
Full format is the natural state of DVD-RAM.
Full format is the natural state of DVD-RAM.
BD-RE are sold unformatted and need to be fully formatted first.
See paragraph about DVD-RAM and BD-RE formatting below.
DVD+RW reaches this state if Background Formatting is allowed to finish without
being stopped by 5Bh CLOSE TRACK SESSION.
@ -516,7 +527,7 @@ with Close Function 010b despite there is no session open in this scenario.)
-------------------------------------------------------------------------------
Unformatted DVD+RW
Unformatted DVD+RW :
This is the state of previously unused DVD+RW media.
@ -671,6 +682,166 @@ of Intermediate state by 5Bh CLOSE TRACK SESSION with Close Function 010b.
(mmc5r03c.pdf 6.3.3.2.3)
-------------------------------------------------------------------------------
DVD-RAM and BD-RE formatting :
Although DVD-RAM usually are sold formatted, there may still arise the wish
to adjust formatting.
BD-RE are sold unformatted and need to be formatted prior to usage.
Two format types are relevant for DVD-RAM : 00h and 01h.
00h offers the default size format and usually a maximum payload size format.
Even with that maximum size payload there is hardware defect management.
(mmc5r03c.pdf 6.5.4.2.1.2)
01h allows to convert payload capacity into spare blocks for defect
managment. There is no way to increase payload capacity by format 01h.
(mmc5r03c.pdf 6.5.4.2.2.1)
With BD-RE there are three format types : 00h, 30h and 31h.
00h offers the default size format. This may be the only fast formatting
mode that is offered by the drive.
Feature 0023h tells whether format 31h and certain 30h subtypes are available.
(mmc5r03c.pdf 5.3.13)
30h offers several sizes with defect management. Usually there are three
sizes given: #1: default size, #2: maximum spare area, #3: minimal spare.
One may demand any spare size between maximum and minimum. There may be quick
certification and full certification. See feature 0023h.
31h offers a single size and disables defect management. This has the side
effect to speed up writing to nominal speed.
(mmc5r03c.pdf 6.5.4.2.15, 6.24.3.3, Table 472)
Only format sizes from the list of format descriptors are permissible
for DVD-RAM. The format list can be obtained by 23h READ FORMAT CAPACITIES.
It also includes a description of the current formatting state.
(mmc5r03c.pdf 6.24, 6.24.3.2, 6.24.3.3)
Formatting is done by command 04h FORMAT UNIT. Its data payload consists
of a Format List Header and a Format Descriptor. It is advisable to set
the Immed bit and the FOV bit in header byte number 1. The descriptor should
be a copy of a descriptor from 23h READ FORMAT CAPACITIES.
(mmc5r03c.pdf 6.5, 6.5.3.2, 6.5.3.3)
With nearly all formats Sub-type should be set to 0. But with BD-RE formats
30h and 31h the Sub-type selects the certification mode.
Usable with 30h seem 10b Full Certification and 11b Quick Certification.
Usable with 31h seem also 00b Quick Reformat and 01b No Certification.
(mmc5r03c.pdf 6.5.4.2.15.1)
Other format types have their certification intensity controlled by
a pair of bits: CmpList and DCRT.
CmpList resides in CDB byte 1 as bit 3. DCRT resides in the payload byte 1
as bit 5. Both together should request a quick size change without lengthy
certification but maintaining the list of known defects.
(mmc5r03c.pdf 6.5, table 249, 6.5.3.2)
With DVD-RAM on my PHILIPS SPD3300L drive they prevent any format size
change though. The TSSTcorp SH-S203B works properly.
With BD-RE format 00h, the default is specified to be Quick Reformat,
and with 00h in general certification can only be disabled not enabled.
(mmc5r03c.pdf 6.5.4.2.1.7)
-------------------------------------------------------------------------------
DVD-RAM and BD-RE tuning :
A special aspect of DVD-RAM and BD-RE is their low speed with write operations,
which usually is only half than the nominal speed of media and drive.
This is blamed to the automatic checkreading which happens for managing
eventual defects.
Defect management of BD-RE can be disabled by format type 31h. See above.
There is no drive known yet which would apply command 2Ah WRITE10 to DVD-RAM
with full speed.
The only known way to get full speed from DVD-RAM or BD-RE with enabled defect
management is the use of AAh WRITE12 with Streaming Bit set to 1.
(mmc5r03c.pdf 6.45)
With some DVD-RAM drives this fails if a write buffer is not full 32 kB.
With the tested BD-RE one has to write full 64 kB buffers.
Although it seems not optimal, this is specified not only to disable the
cumbersome checkread but also to ignore known defects and to write data
to these defective addresses.
(mmc5r03c.pdf 4.8.5)
So the speed-up is only advisable as long as the media are free of
incorrectable errors.
Caveat:
MMC-5 does not guarantee AAh WRITE12 to work on DVD-RAM or BD-RE at all.
None of the features of profiles 0012h and 0043h promises the existence of
AAh WRITE12.
(mmc5r03c.pdf 5.4.13, 6.45)
Nevertheless it worked on all tested drives if proper alignment was observed.
-------------------------------------------------------------------------------
ISO 9660 multi-session emulation on overwriteable media :
Overwriteable media provide a single overwriteable track which may grow up to
the full media capacity. There is no builtin table-of-content which records
the history of write sessions.
mount -t iso9660 will use sbsector=0 as default.
The term "superblock" shall depict the first 64 KiB after the sbsector address.
ISO 9660 multi-session depends on typical TOC information in two ways:
It needs the superblock address MSC1 of the most recently recorded session and
it needs the Next Writeable Address NWA for which to prepare the adress offset.
The following is learned from growisofs and from ECMA-119:
http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-119.pdf
ISO 9660 filesystems provide information about the number of sectors which
is also the lowest unused block address and thus a suitable NWA.
This block address is stored in the Primary Volume Descriptor which is supposed
to be stored in block 16 (eventually relative to MSC1).
The bytes 0 to 5 of a PVD block are
0x01 'C' 'D' '0' '0' '1'
The sector count can then be read from byte 80 to 83
sectors= pvd[80] | (pvd[81] << 8) | (pvd[82] << 16) | (pvd[83] << 24);
(Ecma-119.pdf 8.4)
To support CD, DVD and BD media alike, it is advisable to round the NWA
to the next multiple of 32 (= 64 KiB).
So one can use 0 as MSC1 and prepare a new ISO session for the computed NWA.
After writing the session it is necessary to patch the PVD at LBA 16.
The minimal change would be to update the number of image sectors.
It is stored in both notations LSB and MSB:
for(i= 0; i < 4; i++)
pvd[87 - i]= pvd[80 + i]= (sectors >> (8 * i)) & 0xff;
cdrskin --grow_overwriteable_iso not only patches the sector fields of the
PVD block but also the blocks up to LBA 31 which begin with
0xff 'C' 'D' '0' '0' '1'
libisoburn submits 64 KiB data buffer to libisofs before image generation and
afterwards writes these 64 KiB as new superblock to LBA 0.
-------------------------------------------------------------------------------
ISO 9660 based TOC emulation on overwriteable media :
Above method of multi-session emulation yields a single session image after
each add-on session. No reliable session history can be read because the
sector size of the existing session gets overwritten by the new one.
A TOC with session history is nevertheless desirable with incremental backups
in order to access older backup states by mounting older superblocks at the
start addresses of older sessions.
All usual ISO 9660 formatter programs write a complete superblock to the
start of each session.
With a uniform NWA rounding rule it is possible to compute the address of
superblock N+1 as the NWA after session N. The only problem is N=1
because it gets overwritten by later sessions.
libisoburn preserves the information of session 1 by writing the first session
to LBA 32 rather than LBA 0. Afterwards it writes the overall superblock to
LBA 0 (up to 31).
So with all further add-on sessions the superblock at LBA 0 will enclose the
overall image, while the superblocks of the sessions form a chain beginning
at LBA 32. Each session superblock points to the next one by its sector count
rounded up to 32. The chain end is marked by the overall image size.
This chain gives the start addresses of sessions. The sector count minus start
address gives the size of a particular session. ECMA-119 explains how to
retrieve more info from the PVD (e.g. the volume id).
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
@ -990,7 +1161,7 @@ close session if multi-session is demanded.
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
DVD+R Cookbook
DVD+R[/DL] Cookbook
-------------------------------------------------------------------------------
Inspired by reading mmc5r03c.pdf from http://www.t10.org/ftp/t10/drafts/mmc5/
backed by Andy Polyakov's http://fy.chalmers.se/~appro/linux/DVD+RW/tools ,
@ -1006,7 +1177,7 @@ DVD+R/DL 002bh
- About empty, appendable and finalized DVD+R
- Writing a Pseudo Session to DVD+R
- >>> Hearsay about DVD+R/DL (Dual Layer) :
- DVD+R/DL (Dual Layer
The following two chapters of the Sequential DVD-R[W] Cookbook are valid for
DVD+R media too:
@ -1100,9 +1271,126 @@ by closing them already after the first session.
-------------------------------------------------------------------------------
Hearsay about DVD+R/DL (Dual Layer) :
DVD+R/DL (Dual Layer) :
>>>
libburn treats DL media just like their single layer equivalents.
This seems to work fine for DVD+R/DL, according to a report by nightmorph
in http://libburnia-project.org/ticket/13 .
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
BD-R Cookbook
-------------------------------------------------------------------------------
Inspired by reading mmc5r03c.pdf from http://www.t10.org/ftp/t10/drafts/mmc5/
backed by experiments iwith drive LG GGW H20L.
For libburnia-project.org by Thomas Schmitt <scdbackup@gmx.net>
-------------------------------------------------------------------------------
Media type can be recognized by Current Profile from 46h GET CONFIGURATION.
(mmc5r03c.pdf 6.6.2.1)
BD-R 0042h
There are two basic recording modes defined: Sequential Recording Mode SRM and
Random Recording Mode RRM. The latter is optional and for now not topic of this
text.
(mmc5r03c.pdf 4.5.3.5)
- SRM Formatting
- Writing a session in SRM-POW
(- Pseudo-OverWrite SRM+POW)
-------------------------------------------------------------------------------
SRM Formatting:
Despite being write-once media BD-R can optionally carry some formatting.
SRM has a disc structure model with tracks and sessions.
Several tracks may be open at the same time, each having its own NWA.
(mmc5r03c.pdf 4.5.3.5.2.2)
This structure is formatted onto blank media automatically as soon as the
first serious write attempt occurs.
(mmc5r03c.pdf 4.5.3.5)
Before such a write attempt, blank media may be explicitely formatted with
spares, which provide defect management.
(mmc5r03c.pdf 4.5.3.5.3)
Tracks get created from other tracks via RESERVE TRACK splitting.
(mmc5r03c.pdf 4.5.3.5.2.5)
On top of defect management there may be Pseudo-OverWrite SRM+POW, a costly
way to write several times to the same LBA. See below.
Fully sequential states are called SRM-POW.
(mmc5r03c.pdf 4.5.3.5.4)
Explicite formatting is done by 04h FORMAT UNIT. Its data payload consists
of a Format List Header and a Format Descriptor. It is advisable to set
the Immed bit and the FOV bit in header byte number 1. The descriptor should
be a copy of a descriptor from 23h READ FORMAT CAPACITIES but the size may be
adjusted within a certain range.
(mmc5r03c.pdf 6.5, 6.5.3.2, 6.5.3.3)
Format type 00h creates SRM layouts with a default number of spares (or
eventually RRM) chosen by the format sub-type:
00b = SRM with support for POW
01b = SRM without POW (but with some spares for defect management)
10b = (RRM)
(mmc5r03c.pdf 6.5.4.2.1.6)
Format type 32h uses the same sub-types but allows to allocate non-default
amounts of spares. Similar to BD-RE format 31h, three format descriptors are
offered: #1: default size, #2: maximum spare area, #3: minimal spare.
The size may be chosen within that range.
The sense behind the Type Dependent Parameters is obscure
to me. Best will be to set ISA_V and TDMA_V to 0.
(mmc5r03c.pdf 6.5.4.2.1.17)
-------------------------------------------------------------------------------
Writing a session in SRM:
The procedure and constraints for writing BD-R SRM-POW are very similar to
DVD+R. libburn flatly re-uses its DVD+R code except the Close Function for
finalizing a disc.
In short:
If all written sessions are closed, then there is exactly one NWA.
In the beginning there is an empty session and track. A new track can be
written either with pre-announced size (by RESERVE TRACK) or open-end by
simply starting to write to the NWA. When done the track gets closed by
close function 001b. Then either session or disc gets closed depending on
the Close Function used:
- Close Function 010b closes the session and keeps the media appendable
(same as with DVD+R)
- Close Function 110b finalizes the media and makes it read-only.
(differs from libburn DVD+R procedure which uses 101b)
-------------------------------------------------------------------------------
Pseudo-OverWrite POW: (no used yet by libburn)
This enhancement of SRM emulates overwriting of existing data blocks.
(mmc5r03c.pdf 4.5.3.5.4)
POW establishes a virtual vLBA space on top of the real address space rLBA.
All read and write commands deal with vLBA. It seems that track NWAs are
assumed to be identical in vLBA space and in rLBA space.
It is not clear whether one may write to vLBA blocks which are neither written
yet nor at one of the track NWAs. Probably not, or else one could make NWAs run
into vLBAs which are associated with older rLBAs.
Replacing invalidated blocks consumes addresses in rLBA space at the NWA of
some track. I.e. no spares are consumed by POW. Nevertheless it is costly by
a special map called Orphanage. It covers rLBA which have been consumed
by differing vLBAs. It never shrinks and can grow with each write to remapped
addresses.
To avoid heavy Orphanage growth it is advised to write mostly to vLBA which
still coincide with their rLBA. E.g. those addresses which have neither been
written as rLBA nor as vLBA yet. So one should begin the vLBA of new sessions
at the NWA of a sufficiently sized track.
(mmc5r03c.pdf 4.5.3.5.4.2 , 4.5.3.6.9)
-------------------------------------------------------------------------------

View File

@ -38,7 +38,7 @@ PROJECT_NUMBER = @PACKAGE_VERSION@
# If a relative path is entered, it will be relative to the location
# where doxygen was started. If left blank the current directory will be used.
OUTPUT_DIRECTORY =
OUTPUT_DIRECTORY = @abs_top_builddir@
# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create
# 4096 sub-directories (in 2 levels) under the output directory of each output
@ -104,7 +104,7 @@ INLINE_INHERITED_MEMB = NO
# path before files name in the file list and in the header files. If set
# to NO the shortest path that makes the file name unique will be used.
FULL_PATH_NAMES = YES
FULL_PATH_NAMES = NO
# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag
# can be used to strip a user-defined part of the path. Stripping is
@ -113,7 +113,7 @@ FULL_PATH_NAMES = YES
# If left blank the directory from which doxygen is run is used as the
# path to strip.
STRIP_FROM_PATH = @top_srcdir@
STRIP_FROM_PATH =
# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of
# the path mentioned in the documentation of a class, which tells

View File

@ -4,7 +4,7 @@ libdir=@libdir@
includedir=@includedir@
Name: libburn
Description: Disc reading/writing library
Description: Library to read/write optical discs
Version: @VERSION@
Requires:
Libs: -L${libdir} -lburn

View File

@ -10,9 +10,8 @@
even if joinable and even if never joined.
To be activated after release of libburn-0.4.0
#define Libburn_create_detached_threadS 1
*/
#define Libburn_create_detached_threadS 1
/* Alternative : Threads are created joinable.
Threads get detached in remove_worker() and thus should dispose themselves.
@ -26,9 +25,9 @@
#include "drive.h"
#include "write.h"
#include "options.h"
#include "file.h"
#include "async.h"
#include "init.h"
#include "file.h"
#include "back_hacks.h"
#include <pthread.h>
@ -44,7 +43,15 @@
#include "libdax_msgs.h"
extern struct libdax_msgs *libdax_messenger;
#define SCAN_GOING() (workers && !workers->drive)
/* 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 *);
@ -86,6 +93,9 @@ struct fifo_opts
struct w_list
{
/* ts A80714 */
int w_type; /* see above define Burnworker_type_* */
struct burn_drive *drive;
pthread_t thread;
@ -114,7 +124,8 @@ static struct w_list *find_worker(struct burn_drive *d)
return NULL;
}
static void add_worker(struct burn_drive *d, WorkerFunc f, void *data)
static void add_worker(int w_type, struct burn_drive *d,
WorkerFunc f, void *data)
{
struct w_list *a;
struct w_list *tmp;
@ -125,6 +136,7 @@ static void add_worker(struct burn_drive *d, WorkerFunc f, void *data)
#endif
a = malloc(sizeof(struct w_list));
a->w_type = w_type;
a->drive = d;
a->u = *(union w_list_data *)data;
@ -144,9 +156,11 @@ static void add_worker(struct burn_drive *d, WorkerFunc f, void *data)
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
attr_pt= &attr;
/*
libdax_msgs_submit(libdax_messenger, -1, 0x00020158,
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_LOW,
"add_worker(): Creating detached thread.", 0, 0);
*/
#endif
if (pthread_create(&a->thread, attr_pt, f, a)) {
@ -179,12 +193,14 @@ static void remove_worker(pthread_t th)
dispose themselves.
*/
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 */
@ -256,7 +272,8 @@ drive_is_active:;
o.drives = drives;
o.n_drives = n_drives;
o.done = 0;
add_worker(NULL, (WorkerFunc) scan_worker_func, &o);
add_worker(Burnworker_type_scaN, NULL,
(WorkerFunc) scan_worker_func, &o);
} else if (workers->u.scan.done) {
/* its done */
ret = workers->u.scan.done;
@ -300,7 +317,7 @@ void burn_disc_erase(struct burn_drive *drive, int fast)
"NULL pointer caught in burn_disc_erase", 0, 0);
return;
}
if ((SCAN_GOING()) || find_worker(drive)) {
if ((SCAN_GOING()) || find_worker(drive) != NULL) {
libdax_msgs_submit(libdax_messenger, drive->global_index,
0x00020102,
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
@ -340,7 +357,8 @@ void burn_disc_erase(struct burn_drive *drive, int fast)
o.drive = drive;
o.fast = fast;
add_worker(drive, (WorkerFunc) erase_worker_func, &o);
add_worker(Burnworker_type_erasE, drive,
(WorkerFunc) erase_worker_func, &o);
}
@ -358,10 +376,10 @@ static void *format_worker_func(struct w_list *w)
void burn_disc_format(struct burn_drive *drive, off_t size, int flag)
{
struct format_opts o;
int ok = 0;
int ok = 0, ret;
char msg[160];
if ((SCAN_GOING()) || find_worker(drive)) {
if ((SCAN_GOING()) || find_worker(drive) != NULL) {
libdax_msgs_submit(libdax_messenger, drive->global_index,
0x00020102,
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
@ -389,6 +407,84 @@ void burn_disc_format(struct burn_drive *drive, off_t size, int flag)
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 ((flag & 6) != 6 || (flag & 128)) {
if ((flag & 64) && !(drive->current_feat23h_byte4 & 2)) {
if (drive->current_feat23h_byte4 & 1) {
libdax_msgs_submit(libdax_messenger,
drive->global_index, 0x00020165,
LIBDAX_MSGS_SEV_WARNING,
LIBDAX_MSGS_PRIO_HIGH,
"Drive does not support fast formatting",
0, 0);
flag &= ~64;
} else {
no_non_default_bd_re:;
libdax_msgs_submit(libdax_messenger,
drive->global_index, 0x00020167,
LIBDAX_MSGS_SEV_SORRY,
LIBDAX_MSGS_PRIO_HIGH,
"Drive does not support non-default formatting",
0, 0);
drive->cancel = 1;
return;
}
}
if ((!(flag & 64)) && !(drive->current_feat23h_byte4 & 1)){
if (drive->current_feat23h_byte4 & 2) {
libdax_msgs_submit(libdax_messenger,
drive->global_index, 0x00020166,
LIBDAX_MSGS_SEV_WARNING,
LIBDAX_MSGS_PRIO_HIGH,
"Drive does not support full formatting",
0, 0);
flag |= 64;
} else
goto no_non_default_bd_re;
}
}
}
if (!ok) {
@ -404,7 +500,8 @@ void burn_disc_format(struct burn_drive *drive, off_t size, int flag)
o.drive = drive;
o.size = size;
o.flag = flag;
add_worker(drive, (WorkerFunc) format_worker_func, &o);
add_worker(Burnworker_type_formaT, drive,
(WorkerFunc) format_worker_func, &o);
}
@ -430,12 +527,15 @@ void burn_disc_write(struct burn_write_opts *opts, struct burn_disc *disc)
{
struct write_opts o;
char reasons[BURN_REASONS_LEN+80];
struct burn_drive *d;
d = opts->drive;
/* ts A61006 */
/* a ssert(!SCAN_GOING()); */
/* a ssert(!find_worker(opts->drive)); */
if ((SCAN_GOING()) || find_worker(opts->drive)) {
libdax_msgs_submit(libdax_messenger, opts->drive->global_index,
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)",
@ -444,14 +544,14 @@ void burn_disc_write(struct burn_write_opts *opts, struct burn_disc *disc)
}
/* For the next lines any return indicates failure */
opts->drive->cancel = 1;
d->cancel = 1;
/* ts A70203 : people have been warned in API specs */
if (opts->write_type == BURN_WRITE_NONE)
return;
if (opts->drive->drive_role == 0) {
libdax_msgs_submit(libdax_messenger, opts->drive->global_index,
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);
@ -459,9 +559,9 @@ void burn_disc_write(struct burn_write_opts *opts, struct burn_disc *disc)
}
/* ts A61007 : obsolete Assert in spc_select_write_params() */
if (opts->drive->drive_role == 1 && !opts->drive->mdata->valid) {
if (d->drive_role == 1 && d->mdata->valid <= 0) {
libdax_msgs_submit(libdax_messenger,
opts->drive->global_index, 0x00020113,
d->global_index, 0x00020113,
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
"Drive capabilities not inquired yet", 0, 0);
return;
@ -472,28 +572,47 @@ void burn_disc_write(struct burn_write_opts *opts, struct burn_disc *disc)
*/
strcpy(reasons, "Write job parameters are unsuitable:\n");
if (burn_precheck_write(opts, disc, reasons + strlen(reasons), 1)
== BURN_WRITE_NONE) {
<= 0) {
libdax_msgs_submit(libdax_messenger,
opts->drive->global_index, 0x00020139,
d->global_index, 0x00020139,
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
reasons, 0, 0);
return;
}
opts->drive->cancel = 0; /* End of the return = failure area */
/* 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;
}
o.drive = opts->drive;
d->cancel = 0; /* End of the return = failure area */
o.drive = d;
o.opts = opts;
o.disc = disc;
opts->refcount++;
add_worker(opts->drive, (WorkerFunc) write_disc_worker_func, &o);
add_worker(Burnworker_type_writE, d,
(WorkerFunc) write_disc_worker_func, &o);
}
static void *fifo_worker_func(struct w_list *w)
{
int old;
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &old);
pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &old);
/* Note: Only burn_fifo_abort() shall cancel the fifo thread */
burn_fifo_source_shoveller(w->u.fifo.source, w->u.fifo.flag);
remove_worker(pthread_self());
return NULL;
@ -516,12 +635,34 @@ int burn_fifo_start(struct burn_source *source, int flag)
o.source = source;
o.flag = flag;
add_worker(NULL, (WorkerFunc) fifo_worker_func, &o);
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;
if (fs->thread_is_valid <= 0 || fs->thread_handle == NULL)
return(2);
#ifdef NIX
libdax_msgs_submit(libdax_messenger, -1, 0x00000002,
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH,
"Aborting running burn_source_fifo thread", 0, 0);
#endif /* NIX */
pt= *((pthread_t *) fs->thread_handle);
remove_worker(pt);
ret = pthread_cancel(pt);
return (ret == 0);
}
#ifdef Libburn_has_burn_async_join_alL
/* ts A71019 : never used */

View File

@ -10,5 +10,9 @@ struct burn_write_opts;
/* 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);
#endif /* BURN__ASYNC_H */

View File

@ -97,8 +97,8 @@ static int Cleanup_handler_exit(int exit_value, int signum, int flag)
return(2);
}
if(cleanup_exiting) {
fprintf(stderr,"cleanup: ABORT : repeat by pid=%d, signum=%d\n",
getpid(),signum);
fprintf(stderr,"cleanup: ABORT : repeat by pid=%.f, signum=%d\n",
(double) getpid(), signum);
return(0);
}
cleanup_exiting= 1;

View File

@ -40,12 +40,18 @@
/* A70903 : for burn_scsi_setup_drive() */
#include "spc.h"
/* A90815 : for mmc_obtain_profile_name() */
#include "mmc.h"
#include "libdax_msgs.h"
extern struct libdax_msgs *libdax_messenger;
static struct burn_drive drive_array[255];
static int drivetop = -1;
/* ts A80410 : in init.c */
extern int burn_support_untested_profiles;
/* ts A61021 : the unspecific part of sg.c:enumerate_common()
*/
int burn_setup_drive(struct burn_drive *d, char *fname)
@ -58,6 +64,8 @@ int burn_setup_drive(struct burn_drive *d, char *fname)
d->released = 1;
d->stdio_fd = -1;
d->status = BURN_DISC_UNREADY;
d->do_stream_recording = 0;
d->stream_recording_start= 0;
return 1;
}
@ -192,6 +200,31 @@ unsigned int burn_drive_count(void)
}
/* ts A80801 */
int burn_drive_is_listed(char *path, struct burn_drive **found, int flag)
{
int i, ret;
char drive_adr[BURN_DRIVE_ADR_LEN], off_adr[BURN_DRIVE_ADR_LEN];
ret = burn_drive_convert_fs_adr(path, off_adr);
if (ret <= 0)
strcpy(off_adr, path);
for (i = 0; i <= drivetop; i++) {
if (drive_array[i].global_index < 0)
continue;
ret = burn_drive_d_get_adr(&(drive_array[i]), drive_adr);
if (ret <= 0)
continue;
if(strcmp(off_adr, drive_adr) == 0) {
if (found != NULL)
*found= &(drive_array[i]);
return 1;
}
}
return 0;
}
/* ts A61125 : media status aspects of burn_drive_grab() */
int burn_drive_inquire_media(struct burn_drive *d)
{
@ -201,7 +234,9 @@ int burn_drive_inquire_media(struct burn_drive *d)
/* ts A61020 : d->status was set to BURN_DISC_BLANK as pure guess */
if (d->mdata->cdr_write || d->mdata->cdrw_write ||
/* ts A71128 : run read_disc_info() for any recognizeable profile */
if (d->current_profile > 0 || d->current_is_guessed_profile ||
d->mdata->cdr_write || d->mdata->cdrw_write ||
d->mdata->dvdr_write || d->mdata->dvdram_write) {
#define Libburn_knows_correct_state_after_loaD 1
@ -386,6 +421,9 @@ int burn_drive_unregister(struct burn_drive *d)
struct burn_drive *burn_drive_finish_enum(struct burn_drive *d)
{
struct burn_drive *t;
char msg[BURN_DRIVE_ADR_LEN + 160];
int ret;
/* ts A60821
<<< debug: for tracing calls which might use open drive fds */
int mmc_function_spy(struct burn_drive *d, char * text);
@ -398,13 +436,19 @@ struct burn_drive *burn_drive_finish_enum(struct burn_drive *d)
mmc_function_spy(NULL, "enumerate_common : -------- doing grab");
/* try to get the drive info */
if (t->grab(t)) {
ret = t->grab(t);
if (ret) {
burn_print(2, "getting drive info\n");
t->getcaps(t);
t->unlock(t);
t->released = 1;
} else {
burn_print(2, "unable to grab new located drive\n");
/* ts A90602 */
d->mdata->valid = -1;
sprintf(msg, "Unable to grab scanned drive %s", d->devname);
libdax_msgs_submit(libdax_messenger, d->global_index,
0x0002016f, LIBDAX_MSGS_SEV_DEBUG,
LIBDAX_MSGS_PRIO_LOW, msg, 0, 0);
burn_drive_unregister(t);
t = NULL;
}
@ -437,6 +481,9 @@ int burn_drive_mark_unready(struct burn_drive *d)
burn_disc_free(d->disc);
d->disc = NULL;
}
if (d->stdio_fd >= 0)
close (d->stdio_fd);
d->stdio_fd = -1;
return 1;
}
@ -486,6 +533,22 @@ int burn_drive_release_fl(struct burn_drive *d, int flag)
}
/* API */
/* ts A90824
@param flag bit0= wake up (else start snoozing)
*/
int burn_drive_snooze(struct burn_drive *d, int flag)
{
if (d->drive_role != 1)
return 0;
if (flag & 1)
d->start_unit(d);
else
d->stop_unit(d);
return 1;
}
/* API */
void burn_drive_release(struct burn_drive *d, int le)
{
@ -583,14 +646,14 @@ void burn_disc_erase_sync(struct burn_drive *d, int fast)
/*
@param flag: bit0 = fill formatted size with zeros
bit1, bit2 , bit4, bit7 - bit15 are for d->format_unit()
bit1, bit2 , bit4, bit5, bit7 - bit15 are for d->format_unit()
*/
void burn_disc_format_sync(struct burn_drive *d, off_t size, int flag)
{
int ret, buf_secs, err, i, stages = 1, pbase, pfill, pseudo_sector;
off_t num_bufs;
char msg[80];
struct buffer buf;
struct buffer buf, *buf_mem = d->buffer;
/* reset the progress */
d->progress.session = 0;
@ -606,7 +669,7 @@ void burn_disc_format_sync(struct burn_drive *d, off_t size, int flag)
d->cancel = 0;
d->busy = BURN_DRIVE_FORMATTING;
ret = d->format_unit(d, size, flag & 0xff96); /* forward bits */
ret = d->format_unit(d, size, flag & 0xfff6); /* forward bits */
if (ret <= 0)
d->cancel = 1;
@ -672,7 +735,7 @@ void burn_disc_format_sync(struct burn_drive *d, off_t size, int flag)
ex:;
d->progress.sector = 0x10000;
d->busy = BURN_DRIVE_IDLE;
d->buffer = NULL;
d->buffer = buf_mem;
}
@ -758,6 +821,18 @@ enum burn_drive_status burn_drive_get_status(struct burn_drive *d,
return d->busy;
}
int burn_drive_set_stream_recording(struct burn_drive *d, int recmode,
int start, int flag)
{
if (recmode == 1)
d->do_stream_recording = 1;
else if (recmode == -1)
d->do_stream_recording = 0;
d->stream_recording_start = start;
return(1);
}
void burn_drive_cancel(struct burn_drive *d)
{
pthread_mutex_lock(&d->access_lock);
@ -808,7 +883,7 @@ static int drive_getcaps(struct burn_drive *d, struct burn_drive_info *out)
a ssert(d->mdata);
#endif
if (!d->idata->valid || !d->mdata->valid)
if(d->idata->valid <= 0 || d->mdata->valid <= 0)
return 0;
id = (struct burn_scsi_inquiry_data *)d->idata;
@ -874,7 +949,7 @@ int burn_drive_scan_sync(struct burn_drive_info *drives[],
*/
unsigned char scanned[32];
unsigned count = 0;
int i;
int i, ret;
/* ts A61007 : moved up to burn_drive_scan() */
/* a ssert(burn_running); */
@ -931,13 +1006,22 @@ int burn_drive_scan_sync(struct burn_drive_info *drives[],
if (drive_array[i].global_index < 0)
continue; /* invalid device */
while (!drive_getcaps(&drive_array[i],
&(*drives)[*n_drives])) {
/* ts A90602 : This old loop is not plausible. See A70907.
while (!drive_getcaps(&drive_array[i],
&(*drives)[*n_drives])) {
sleep(1);
}
(*n_drives)++;
}
*/
/* ts A90602 : A single call shall do (rather than a loop) */
ret = drive_getcaps(&drive_array[i], &(*drives)[*n_drives]);
if (ret > 0)
(*n_drives)++;
scanned[i / 8] |= 1 << (i % 8);
}
if (*drives != NULL && *n_drives == 0) {
free ((char *) *drives);
*drives = NULL;
}
return(1);
}
@ -1093,14 +1177,14 @@ void burn_sectors_to_msf(int sectors, int *m, int *s, int *f)
int burn_drive_get_read_speed(struct burn_drive *d)
{
if(!d->mdata->valid)
if(d->mdata->valid <= 0)
return 0;
return d->mdata->max_read_speed;
}
int burn_drive_get_write_speed(struct burn_drive *d)
{
if(!d->mdata->valid)
if(d->mdata->valid <= 0)
return 0;
return d->mdata->max_write_speed;
}
@ -1108,7 +1192,7 @@ int burn_drive_get_write_speed(struct burn_drive *d)
/* ts A61021 : New API function */
int burn_drive_get_min_write_speed(struct burn_drive *d)
{
if(!d->mdata->valid)
if(d->mdata->valid <= 0)
return 0;
return d->mdata->min_write_speed;
}
@ -1157,6 +1241,20 @@ int burn_drive_is_banned(char *device_address)
}
/* ts A80731 */
int burn_drive_whitelist_count(void)
{
return enumeration_whitelist_top + 1;
}
char *burn_drive_whitelist_item(int idx, int flag)
{
if (idx < 0 || idx > enumeration_whitelist_top)
return NULL;
return enumeration_whitelist[idx];
}
/* ts A70924 */
int burn_drive__fd_from_special_adr(char *adr)
{
@ -1251,7 +1349,7 @@ int burn_drive_grab_dummy(struct burn_drive_info *drive_infos[], char *fname)
d->current_is_supported_profile = 1;
d->block_types[BURN_WRITE_TAO] = BURN_BLOCK_MODE1;
d->block_types[BURN_WRITE_SAO] = BURN_BLOCK_SAO;
d->media_capacity_remaining = size;
burn_drive_set_media_capacity_remaining(d, size);
/* >>> ? open file for a test ? (>>> beware of "-" = stdin) */;
@ -1681,6 +1779,10 @@ int burn_abort(int patience,
unsigned long wait_grain= 100000;
time_t start_time, current_time, pacifier_time, end_time;
#ifndef NIX
time_t stdio_patience = 3;
#endif
current_time = start_time = pacifier_time = time(0);
end_time = start_time + patience;
@ -1696,6 +1798,37 @@ int burn_abort(int patience,
occup = burn_drive_is_occupied(&(drive_array[i]));
if(occup == -2)
continue;
if(drive_array[i].drive_role != 1) {
#ifdef NIX
/* ts A90302
<<< this causes a race condition with drive
usage and drive disposal.
*/
drive_array[i].busy = BURN_DRIVE_IDLE;
burn_drive_forget(&(drive_array[i]), 1);
continue;
#else /* NIX */
/* ts A90318
>>> but if a pipe breaks then the drive
never gets idle.
So for now with a short patience timespan
and eventually a deliberate memory leak.
*/
if (current_time - start_time >
stdio_patience) {
drive_array[i].global_index = -1;
continue;
}
#endif /* ! NIX */
}
if(occup <= 10) {
burn_drive_forget(&(drive_array[i]), 1);
} else if(occup <= 100) {
@ -1775,11 +1908,16 @@ int burn_disc_read_atip(struct burn_drive *d)
}
if(d->drive_role != 1)
return 0;
if (d->current_profile == -1 || d->current_is_cd_profile) {
if ((d->current_profile == -1 || d->current_is_cd_profile)
&& (d->mdata->cdrw_write || d->current_profile != 0x08)) {
d->read_atip(d);
/* >>> some control of success would be nice :) */
} else {
/* mmc5r03c.pdf 6.26.3.6.3 : ATIP is undefined for non-CD */;
/* mmc5r03c.pdf 6.26.3.6.3 : ATIP is undefined for non-CD
(and it seems meaningless for non-burners).
ts A90823: Pseudo-CD U3 memory stick stalls with ATIP.
It is !cdrw_write and profile is 0x08.
*/
return 0;
}
return 1;
@ -1860,8 +1998,8 @@ off_t burn_disc_available_space(struct burn_drive *d,
return 0;
if (d->drive_role != 1) {
if (d->media_capacity_remaining <= 0)
d->media_capacity_remaining =
((off_t) (512 * 1024 * 1024 - 1) * (off_t) 2048);
burn_drive_set_media_capacity_remaining(d,
(off_t) (512 * 1024 * 1024 - 1) * (off_t) 2048);
} else {
if (o != NULL)
d->send_write_parameters(d, o);
@ -1887,6 +2025,30 @@ int burn_disc_get_profile(struct burn_drive *d, int *pno, char name[80])
}
/* ts A90815 : New API function */
int burn_drive_get_all_profiles(struct burn_drive *d, int *num_profiles,
int profiles[64], char is_current[64])
{
int i;
*num_profiles = d->num_profiles;
for (i = 0; i < d->num_profiles; i++) {
profiles[i] = (d->all_profiles[i * 4] << 8) |
d->all_profiles[i * 4 + 1];
is_current[i] = d->all_profiles[i * 4 + 2] & 1;
}
return 1;
}
/* ts A90815 : New API function */
int burn_obtain_profile_name(int profile_number, char name[80])
{
strcpy(name, mmc_obtain_profile_name(profile_number));
return(name[0] != 0);
}
/* ts A61223 : New API function */
int burn_drive_wrote_well(struct burn_drive *d)
{
@ -1986,7 +2148,7 @@ int burn_drive_get_speedlist(struct burn_drive *d,
struct burn_speed_descriptor *sd, *csd = NULL;
(*speed_list) = NULL;
if(!d->mdata->valid)
if(d->mdata->valid <= 0)
return 0;
for (sd = d->mdata->speed_descriptors; sd != NULL; sd = sd->next) {
ret = burn_speed_descriptor_new(&csd, NULL, csd, 0);
@ -2011,7 +2173,7 @@ int burn_drive_get_best_speed(struct burn_drive *d, int speed_goal,
if (speed_goal < 0)
best_speed = 2000000000;
*best_descr = NULL;
if(!d->mdata->valid)
if(d->mdata->valid <= 0)
return 0;
for (sd = d->mdata->speed_descriptors; sd != NULL; sd = sd->next) {
if (flag & 1)
@ -2093,7 +2255,7 @@ int burn_disc_get_multi_caps(struct burn_drive *d, enum burn_write_types wt,
o->start_adr = 1;
size = d->media_capacity_remaining;
burn_os_stdio_capacity(d->devname, &size);
d->media_capacity_remaining = size;
burn_drive_set_media_capacity_remaining(d, size);
o->start_range_high = size;
o->start_alignment = 2048; /* imposting a drive, not a file */
o->might_do_sao = 4;
@ -2158,9 +2320,12 @@ int burn_disc_get_multi_caps(struct burn_drive *d, enum burn_write_types wt,
if (wt == BURN_WRITE_NONE || wt == BURN_WRITE_SAO ||
wt == BURN_WRITE_TAO)
o->might_simulate = 1;
} else if (d->current_profile == 0x12 || d->current_profile == 0x13 ||
d->current_profile == 0x1a) {
/* DVD-RAM, overwriteable DVD-RW, DVD+RW */
} else if (d->current_profile == 0x12 ||
d->current_profile == 0x13 ||
d->current_profile == 0x1a ||
d->current_profile == 0x43
) {
/* DVD-RAM, overwriteable DVD-RW, DVD+RW, BD-RE */
o->start_adr = 1;
ret = burn_disc_get_formats(d, &status, &size, &dummy,
&num_formats);
@ -2179,6 +2344,8 @@ int burn_disc_get_multi_caps(struct burn_drive *d, enum burn_write_types wt,
}
if (i >= num_formats) /* not expandable */
o->start_range_high -= 32 * 1024;
if (o->start_range_high < 0)
o->start_range_high = 0;
} else {
o->start_alignment = 2 * 1024;
if (d->best_format_size - 2048 >
@ -2190,8 +2357,9 @@ int burn_disc_get_multi_caps(struct burn_drive *d, enum burn_write_types wt,
o->might_do_sao = 4;
o->might_do_tao = 2;
o->advised_write_mode = BURN_WRITE_TAO;
} else if (d->current_profile == 0x1b || d->current_profile == 0x2b) {
/* DVD+R , DVD+R/DL */
} else if (d->current_profile == 0x1b || d->current_profile == 0x2b ||
d->current_profile == 0x41) {
/* DVD+R , DVD+R/DL , BD-R SRM */
o->multi_session = o->multi_track = 1;
o->might_do_tao = 2;
o->might_do_sao = 1;
@ -2442,3 +2610,18 @@ int burn_drive_find_by_thread_pid(struct burn_drive **d, pid_t pid)
}
/* ts A80422 : centralizing this setting for debugging purposes
*/
int burn_drive_set_media_capacity_remaining(struct burn_drive *d, off_t value)
{
d->media_capacity_remaining = value;
return 1;
}
/* ts A81215 : API */
int burn_get_read_capacity(struct burn_drive *d, int *capacity, int flag)
{
*capacity = d->media_read_capacity;
return (d->media_read_capacity != 0x7fffffff);
}

View File

@ -125,4 +125,14 @@ int burn_drive__fd_from_special_adr(char *adr);
int burn_drive_find_by_thread_pid(struct burn_drive **d, pid_t pid);
/* 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);
#endif /* __DRIVE */

View File

@ -9,6 +9,8 @@
#include <unistd.h>
#include <fcntl.h>
#include <time.h>
#include <pthread.h>
#include "source.h"
#include "libburn.h"
#include "file.h"
@ -188,115 +190,8 @@ struct burn_source *burn_fd_source_new(int datafd, int subfd, off_t size)
}
/* ts A70930 */
/* ----------------------------- fifo ---------------------------- */
/* The fifo mechanism consists of a burn_source proxy which is here,
a thread management team which is located in async.c,
and a synchronous shoveller which is here.
*/
/* fifo_ng has a ringbuffer and runs in a thread. og is on its way out. */
#define Libburn_fifo_nG 1
#ifndef Libburn_fifo_nG
static int fifo_read(struct burn_source *source,
unsigned char *buffer,
int size)
{
struct burn_source_fifo *fs = source->data;
int ret;
if (fs->is_started == 0) {
ret = burn_fifo_start(source, 0);
if (ret <= 0) {
libdax_msgs_submit(libdax_messenger, -1, 0x00020152,
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
"Cannot start fifo thread", 0, 0);
return -1;
}
fs->is_started = 1;
}
if (size == 0)
return 0;
ret = read_full_buffer(fs->outlet[0], buffer, size);
if (ret > 0)
fs->out_counter += ret;
return ret;
}
static off_t fifo_get_size(struct burn_source *source)
{
struct burn_source_fifo *fs = source->data;
return fs->inp->get_size(fs->inp);
}
static int fifo_set_size(struct burn_source *source, off_t size)
{
struct burn_source_fifo *fs = source->data;
return fs->inp->set_size(fs->inp, size);
}
static void fifo_free(struct burn_source *source)
{
struct burn_source_fifo *fs = source->data;
if (fs->outlet[1] >= 0)
close(fs->outlet[1]);
free(fs);
}
int burn_fifo_source_shoveller_og(struct burn_source *source, int flag)
{
struct burn_source_fifo *fs = source->data;
int ret;
fs->thread_pid = getpid();
fs->thread_pid_valid = 1;
while (1) {
ret = fs->inp->read(fs->inp, (unsigned char *) fs->buf,
fs->chunksize);
if (ret > 0)
fs->in_counter += ret;
else if (ret == 0)
break; /* EOF */
else {
libdax_msgs_submit(libdax_messenger, -1, 0x00020153,
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
"Read error on fifo input", errno, 0);
break;
}
ret = write(fs->outlet[1], fs->buf, ret);
if (ret == -1) {
/* >>> write error */;
break;
}
}
/* >>> check and destroy ring buffer */;
free(fs->buf);
fs->buf = NULL;
if (fs->outlet[1] >= 0)
close(fs->outlet[1]);
fs->outlet[1] = -1;
return (ret >= 0);
}
#endif /* Libburn_fifo_nG */
/* ts A71003 */
/* ----------------------------- fifo ng ------------------------- */
/* ------------------------------ fifo --------------------------- */
/* The fifo mechanism consists of a burn_source proxy which is here,
a thread management team which is located in async.c,
@ -311,7 +206,7 @@ static int fifo_sleep(int flag)
}
static int fifo_read_ng(struct burn_source *source,
static int fifo_read(struct burn_source *source,
unsigned char *buffer,
int size)
{
@ -341,7 +236,7 @@ static int fifo_read_ng(struct burn_source *source,
/* This needs no mutex because each volatile variable has one thread
which may write and the other which only reads and is aware of
volatility.
The feeder of the ringbuffer is in burn_fifo_source_shoveller_ng().
The feeder of the ringbuffer is in burn_fifo_source_shoveller().
*/
todo = size;
bufsize = fs->chunksize * fs->chunks;
@ -394,7 +289,7 @@ static int fifo_read_ng(struct burn_source *source,
}
static off_t fifo_get_size_ng(struct burn_source *source)
static off_t fifo_get_size(struct burn_source *source)
{
struct burn_source_fifo *fs = source->data;
@ -402,7 +297,7 @@ static off_t fifo_get_size_ng(struct burn_source *source)
}
static int fifo_set_size_ng(struct burn_source *source, off_t size)
static int fifo_set_size(struct burn_source *source, off_t size)
{
struct burn_source_fifo *fs = source->data;
@ -410,10 +305,11 @@ static int fifo_set_size_ng(struct burn_source *source, off_t size)
}
static void fifo_free_ng(struct burn_source *source)
static void fifo_free(struct burn_source *source)
{
struct burn_source_fifo *fs = source->data;
burn_fifo_abort(fs, 0);
if (fs->inp != NULL)
burn_source_free(fs->inp);
if (fs->buf != NULL)
@ -422,14 +318,17 @@ static void fifo_free_ng(struct burn_source *source)
}
int burn_fifo_source_shoveller_ng(struct burn_source *source, int flag)
int burn_fifo_source_shoveller(struct burn_source *source, int flag)
{
struct burn_source_fifo *fs = source->data;
int ret, bufsize, diff, wpos, rpos, trans_end, free_bytes;
char *bufpt;
pthread_t thread_handle_storage;
fs->thread_handle= &thread_handle_storage;
*((pthread_t *) fs->thread_handle)= pthread_self();
fs->thread_pid = getpid();
fs->thread_pid_valid = 1;
fs->thread_is_valid = 1;
bufsize = fs->chunksize * fs->chunks;
while (!fs->end_of_consumption) {
@ -469,8 +368,12 @@ int burn_fifo_source_shoveller_ng(struct burn_source *source, int flag)
}
/* Obtain next chunk */
ret = fs->inp->read(fs->inp, (unsigned char *) bufpt,
fs->chunksize);
if (fs->inp->read != NULL)
ret = fs->inp->read(fs->inp,
(unsigned char *) bufpt, fs->chunksize);
else
ret = fs->inp->read_xt( fs->inp,
(unsigned char *) bufpt, fs->chunksize);
if (ret > 0)
fs->in_counter += ret;
else if (ret == 0)
@ -533,19 +436,18 @@ int burn_fifo_source_shoveller_ng(struct burn_source *source, int flag)
free(fs->buf); /* Give up fifo buffer. Next fifo might start soon. */
fs->buf = NULL;
fs->thread_handle= NULL;
fs->thread_is_valid = 0;
return (fs->input_error == 0);
}
#define Libburn_fifo_nG 1
int burn_fifo_source_shoveller(struct burn_source *source, int flag)
int burn_fifo_cancel(struct burn_source *source)
{
#ifndef Libburn_fifo_nG
return burn_fifo_source_shoveller_og(source, flag);
#else
return burn_fifo_source_shoveller_ng(source, flag);
#endif
struct burn_source_fifo *fs = source->data;
burn_source_cancel(fs->inp);
return(1);
}
@ -554,9 +456,6 @@ struct burn_source *burn_fifo_source_new(struct burn_source *inp,
{
struct burn_source_fifo *fs;
struct burn_source *src;
#ifndef Libburn_fifo_nG
int ret, outlet[2];
#endif
if (((double) chunksize) * ((double) chunks) > 1024.0*1024.0*1024.0) {
libdax_msgs_submit(libdax_messenger, -1, 0x00020155,
@ -570,29 +469,14 @@ struct burn_source *burn_fifo_source_new(struct burn_source *inp,
"Desired fifo buffer too small", 0, 0);
return NULL;
}
#ifndef Libburn_fifo_nG
outlet[0] = outlet[1] = -1;
ret = pipe(outlet);
if (ret == -1) {
/* >>> error on pipe creation */;
return NULL;
}
#endif /* ! Libburn_fifo_nG */
fs = malloc(sizeof(struct burn_source_fifo));
if (fs == NULL)
return NULL;
fs->is_started = 0;
fs->thread_handle = NULL;
fs->thread_pid = 0;
fs->thread_pid_valid = 0;
fs->thread_is_valid = 0;
fs->inp = NULL; /* set later */
#ifndef Libburn_fifo_nG
fs->outlet[0] = outlet[0];
fs->outlet[1] = outlet[1];
#endif
fs->chunksize = chunksize;
fs->chunks = chunks;
fs->buf = NULL;
@ -607,23 +491,15 @@ struct burn_source *burn_fifo_source_new(struct burn_source *inp,
free((char *) fs);
return NULL;
}
#ifndef Libburn_fifo_nG
src->read = fifo_read;
src->read = NULL;
src->read_sub = NULL;
src->get_size = fifo_get_size;
src->set_size = fifo_set_size;
src->free_data = fifo_free;
#else /* Libburn_fifo_nG */
src->read = fifo_read_ng;
src->read_sub = NULL;
src->get_size = fifo_get_size_ng;
src->set_size = fifo_set_size_ng;
src->free_data = fifo_free_ng;
#endif /* ! Libburn_fifo_nG */
src->data = fs;
src->version= 1;
src->read_xt = fifo_read;
src->cancel= burn_fifo_cancel;
fs->inp = inp;
inp->refcount++; /* make sure inp lives longer than src */
@ -644,7 +520,7 @@ int burn_fifo_inquire_status(struct burn_source *source,
*status_text = NULL;
*size = 0;
if (source->free_data != fifo_free_ng) {
if (source->free_data != fifo_free) {
libdax_msgs_submit(libdax_messenger, -1, 0x00020157,
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
"burn_source is not a fifo object", 0, 0);
@ -673,4 +549,64 @@ int burn_fifo_inquire_status(struct burn_source *source,
return ret;
}
int burn_fifo_peek_data(struct burn_source *source, char *buf, int bufsize,
int flag)
{
int size, free_bytes, ret, wait_count= 0;
char *status_text;
struct burn_source_fifo *fs = source->data;
/* Eventually start fifo thread by reading 0 bytes */
ret = fifo_read(source, (unsigned char *) NULL, 0);
if (ret<0)
return 0;
/* wait for at least bufsize bytes being ready */
while (1) {
ret= burn_fifo_inquire_status(source,
&size, &free_bytes, &status_text);
if (size < bufsize) {
libdax_msgs_submit(libdax_messenger, -1, 0x0002015c,
LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH,
"Fifo size is smaller than desired peek buffer", 0, 0);
return -1;
}
if (fs->out_counter > 0 || (ret & 4) || fs->buf == NULL) {
libdax_msgs_submit(libdax_messenger, -1, 0x0002015e,
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
"Fifo is already under consumption when peeking is desired",
0, 0);
return -1;
}
if(size - free_bytes >= bufsize) {
/* <<<
fprintf(stderr,
"libburn_DEBUG: after waiting cycle %d : fifo %s , %d bytes\n",
wait_count, status_text, size - free_bytes);
*/
memcpy(buf, fs->buf, bufsize);
return 1;
}
if (ret&2) { /* input has ended, not enough data arrived */
libdax_msgs_submit(libdax_messenger, -1, 0x0002015d,
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
"Fifo input ended short of desired peek buffer size",
0, 0);
return 0;
}
usleep(100000);
wait_count++;
/* <<<
if(wait_count%10==0)
fprintf(stderr,
"libburn_DEBUG: waiting cycle %d : fifo %s , %d bytes\n",
wait_count, status_text, size - free_bytes);
*/
}
return(0);
}

View File

@ -29,8 +29,9 @@ struct burn_source_fifo {
*/
int is_started;
void *thread_handle; /* actually a pointer to a thread_t */
int thread_pid;
int thread_pid_valid;
int thread_is_valid;
/* the burn_source for which this fifo is acting as proxy */
struct burn_source *inp;

View File

@ -247,7 +247,7 @@ int burn_msgs_submit(int error_code, char msg_text[], int os_errno,
ret = libdax_msgs__text_to_sev(severity, &sevno, 0);
if (ret <= 0)
sevno = LIBDAX_MSGS_SEV_FATAL;
sevno = LIBDAX_MSGS_SEV_ALL;
if (error_code <= 0) {
switch(sevno) {
case LIBDAX_MSGS_SEV_ABORT: error_code = 0x00040000;
@ -258,7 +258,7 @@ int burn_msgs_submit(int error_code, char msg_text[], int os_errno,
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 = 0x00040001;
break; default: error_code = 0x00040008;
}
}
if (d != NULL)
@ -275,8 +275,16 @@ int burn_text_to_sev(char *severity_name, int *sevno, int flag)
int ret;
ret = libdax_msgs__text_to_sev(severity_name, sevno, 0);
if (ret <= 0)
*sevno = LIBDAX_MSGS_SEV_FATAL;
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;
}

File diff suppressed because it is too large Load Diff

View File

@ -34,7 +34,7 @@ int libdax_audioxtr_new(struct libdax_audioxtr **xtr, char *path, int flag)
if(o==NULL)
return(-1);
strncpy(o->path,path,LIBDAX_AUDIOXTR_STRLEN-1);
o->path[LIBDAX_AUDIOXTR_STRLEN]= 0;
o->path[LIBDAX_AUDIOXTR_STRLEN-1]= 0;
o->fd= -1;
strcpy(o->fmt,"unidentified");
o->fmt_info[0]= 0;

View File

@ -1,8 +1,8 @@
/* libdax_msgs
Message handling facility of libdax.
Copyright (C) 2006 - 2007 Thomas Schmitt <scdbackup@gmx.net>,
provided under GPL
Copyright (C) 2006 - 2009 Thomas Schmitt <scdbackup@gmx.net>,
provided under GPL version 2
*/
#include <stdio.h>
@ -40,7 +40,7 @@ static int libdax_msgs_item_new(struct libdax_msgs_item **item,
if(ret==0)
o->timestamp= tv.tv_sec+0.000001*tv.tv_usec;
o->process_id= getpid();
o->driveno= -1;
o->origin= -1;
o->severity= LIBDAX_MSGS_SEV_ALL;
o->priority= LIBDAX_MSGS_PRIO_ZERO;
o->error_code= 0;
@ -109,12 +109,12 @@ int libdax_msgs_item_get_msg(struct libdax_msgs_item *item,
int libdax_msgs_item_get_origin(struct libdax_msgs_item *item,
double *timestamp, pid_t *process_id, int *driveno,
double *timestamp, pid_t *process_id, int *origin,
int flag)
{
*timestamp= item->timestamp;
*process_id= item->process_id;
*driveno= item->driveno;
*origin= item->origin;
return(1);
}
@ -252,6 +252,10 @@ int libdax_msgs__text_to_sev(char *severity_name, int *severity,
*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)
@ -264,10 +268,12 @@ int libdax_msgs__text_to_sev(char *severity_name, int *severity,
*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_NEVER;
*severity= LIBDAX_MSGS_SEV_ALL;
return(0);
}
return(1);
@ -278,8 +284,7 @@ int libdax_msgs__sev_to_text(int severity, char **severity_name,
int flag)
{
if(flag&1) {
*severity_name=
"NEVER\nABORT\nFATAL\nSORRY\nWARNING\nHINT\nNOTE\nUPDATE\nDEBUG\nALL";
*severity_name= "NEVER\nABORT\nFATAL\nFAILURE\nMISHAP\nSORRY\nWARNING\nHINT\nNOTE\nUPDATE\nDEBUG\nERRFILE\nALL";
return(1);
}
*severity_name= "";
@ -289,6 +294,10 @@ int libdax_msgs__sev_to_text(int severity, char **severity_name,
*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)
@ -301,6 +310,8 @@ int libdax_msgs__sev_to_text(int severity, char **severity_name,
*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 {
@ -311,7 +322,7 @@ int libdax_msgs__sev_to_text(int severity, char **severity_name,
}
int libdax_msgs_submit(struct libdax_msgs *m, int driveno, int error_code,
int libdax_msgs_submit(struct libdax_msgs *m, int origin, int error_code,
int severity, int priority, char *msg_text,
int os_errno, int flag)
{
@ -349,7 +360,7 @@ int libdax_msgs_submit(struct libdax_msgs *m, int driveno, int error_code,
ret= libdax_msgs_item_new(&item,m->youngest,0);
if(ret<=0)
goto failed;
item->driveno= driveno;
item->origin= origin;
item->error_code= error_code;
item->severity= severity;
item->priority= priority;

View File

@ -1,8 +1,8 @@
/* libdax_msgs
Message handling facility of libdax.
Copyright (C) 2006-2007 Thomas Schmitt <scdbackup@gmx.net>,
provided under GPL
Copyright (C) 2006-2009 Thomas Schmitt <scdbackup@gmx.net>,
provided under GPL version 2
*/
@ -23,7 +23,7 @@ struct libdax_msgs_item {
double timestamp;
pid_t process_id;
int driveno;
int origin;
int severity;
int priority;
@ -120,6 +120,19 @@ struct libdax_msgs_item;
*/
#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
@ -140,15 +153,70 @@ struct libdax_msgs_item;
*/
#define LIBDAX_MSGS_SEV_WARNING 0x50000000
/** Non-fatal error messages indicating that parts of the action failed
but processing will/should go on
/** 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
@ -173,6 +241,16 @@ struct libdax_msgs_item;
#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) */
@ -211,7 +289,10 @@ int libdax_msgs_refer(struct libdax_msgs **pt, struct libdax_msgs *o, int flag);
/** Submit a message to a message handling facility.
@param driveno program specific drive number. Use -1 if no number is known.
@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
@ -224,11 +305,12 @@ int libdax_msgs_refer(struct libdax_msgs **pt, struct libdax_msgs *o, int flag);
@param flag Bitfield for control purposes (unused yet, submit 0)
@return 1 on success, 0 on rejection, <0 for severe errors
*/
int libdax_msgs_submit(struct libdax_msgs *m, int driveno, int error_code,
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) */
@ -300,7 +382,7 @@ int libdax_msgs_item_get_msg(struct libdax_msgs_item *item,
@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 *driveno,
double *timestamp, pid_t *process_id, int *origin,
int flag);
@ -350,6 +432,8 @@ Range "scdbackup" : 0x00020000 to 0x0002ffff
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
General library operations:
@ -441,7 +525,31 @@ Range "scdbackup" : 0x00020000 to 0x0002ffff
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 is smaller than 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 accidently open session
libdax_audioxtr:
0x00020200 (SORRY,HIGH) = Cannot open audio source file
@ -453,34 +561,81 @@ Range "scdbackup" : 0x00020000 to 0x0002ffff
------------------------------------------------------------------------------
Range "vreixo" : 0x00030000 to 0x0003ffff
General:
0x00031001 (SORRY,HIGH) = Cannot read file (ignored)
0x00031002 (FATAL,HIGH) = Cannot read file (operation canceled)
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
Image reading:
0x00031000 (FATAL,HIGH) = Unsupported ISO-9660 image
0x00031001 (HINT,MEDIUM) = Unsupported Vol Desc that will be ignored
0x00031002 (FATAL,HIGH) = Damaged ISO-9660 image
0x00031003 (SORRY,HIGH) = Cannot read previous image file
Rock-Ridge:
0x00030101 (HINT,MEDIUM) = Unsupported SUSP entry that will be ignored
0x00030102 (SORRY,HIGH) = Wrong/damaged SUSP entry
0x00030103 (WARNING,MEDIUM)= Multiple SUSP ER entries where found
0x00030111 (SORRY,HIGH) = Unsupported RR feature
0x00030112 (SORRY,HIGH) = Error in a Rock Ridge entry
El-Torito:
0x00030201 (HINT,MEDIUM) = Unsupported Boot Vol Desc that will be ignored
0x00030202 (SORRY,HIGH) = Wrong El-Torito catalog
0x00030203 (HINT,MEDIUM) = Unsupported El-Torito feature
0x00030204 (SORRY,HIGH) = Invalid file to be an El-Torito image
0x00030205 (WARNING,MEDIUM)= Cannot properly patch isolinux image
0x00030206 (WARNING,MEDIUM)= Copying El-Torito from a previous image without
enought info about it
Joliet:
0x00030301 (NOTE,MEDIUM) = Unsupported file type for Joliet tree
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
------------------------------------------------------------------------------
@ -494,6 +649,23 @@ Range "application" : 0x00040000 to 0x0004ffff
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
------------------------------------------------------------------------------

File diff suppressed because it is too large Load Diff

View File

@ -72,6 +72,11 @@ int mmc_compose_mode_page_5(struct burn_drive *d,
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." */

View File

@ -38,6 +38,7 @@ struct burn_write_opts *burn_write_opts_new(struct burn_drive *drive)
opts->start_byte = -1;
opts->fill_up_media = 0;
opts->force_is_set = 0;
opts->do_stream_recording = 0;
opts->has_mediacatalog = 0;
opts->format = BURN_CDROM;
opts->multi = 0;
@ -142,7 +143,7 @@ int burn_write_opts_set_simulate(struct burn_write_opts *opts, int sim)
int burn_write_opts_set_underrun_proof(struct burn_write_opts *opts,
int underrun_proof)
{
if (!opts->drive->mdata->valid)
if (opts->drive->mdata->valid <= 0)
return 0;
if (opts->drive->mdata->underrun_proof) {
opts->underrun_proof = underrun_proof;
@ -380,6 +381,16 @@ void burn_write_opts_set_force(struct burn_write_opts *opts, int 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 A70901: API */
struct burn_drive *burn_write_opts_get_drive(struct burn_write_opts *opts)
{

View File

@ -49,6 +49,11 @@ struct burn_write_opts
*/
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;
/** A disc can have a media catalog number */
int has_mediacatalog;
unsigned char mediacatalog[13];

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

@ -0,0 +1,63 @@
/* 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 Thomas Schmitt <scdbackup@gmx.net>, provided under GPL
*/
/** 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, SIGTSTP, SIGTTIN, \
SIGTTOU
/* Once as text 1:1 list of strings for messages and interpreters */
#define BURN_OS_SIGNAL_NAME_LIST \
"SIGHUP", "SIGINT", "SIGQUIT", "SIGILL", "SIGABRT", \
"SIGFPE", "SIGSEGV", "SIGPIPE", "SIGALRM", "SIGTERM", \
"SIGUSR1", "SIGUSR2", "SIGXCPU", "SIGTSTP", "SIGTTIN", \
"SIGTTOU"
/* The number of above list items */
#define BURN_OS_SIGNAL_COUNT 16
/** To list all signals which shall surely not be caught */
#define BURN_OS_NON_SIGNAL_MACRO_LIST \
SIGKILL, SIGCHLD, SIGSTOP
/* The number of above list items */
#define BURN_OS_NON_SIGNAL_COUNT 3
/* 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;

View File

@ -43,16 +43,25 @@ SIGKILL, SIGCHLD, SIGSTOP, SIGURG, SIGWINCH
/* 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 65536
#define BURN_OS_TRANSPORT_BUFFER_SIZE 32768
*/
#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 index number of the most recently delivered address from
/* 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 int burn_drive_enumerator_t;
typedef struct burn_drive_enumerator_struct burn_drive_enumerator_t;
/* Parameters for sibling list. See sibling_fds, sibling_fnames */

View File

@ -3,7 +3,7 @@
Operating system specific libburn definitions and declarations.
The macros defined here are used by libburn modules in order to
avoid own system dependent case distinctions.
Copyright (C) 2006 Thomas Schmitt <scdbackup@gmx.net>, provided under GPL
Copyright (C) 2009 Thomas Schmitt <scdbackup@gmx.net>, provided under GPL
*/
#ifndef BURN_OS_H_INCLUDED
@ -20,14 +20,23 @@
#include "os-freebsd.h"
#else /* operating system case distinction */
#else
#ifdef __linux
/* --------- Linux kernels 2.4 and 2.6 with Linux SCSI Generic (sg) -------- */
#include "os-linux.h"
#endif /* End of operating system case distinction */
#else
/* --------- Any other system. With dummy MMC transport sg-dummy.c --------- */
#include "os-dummy.h"
#endif /* ! __linux */
#endif /* ! __FreeBSD__ */
#endif /* ! BURN_OS_H_INCLUDED */

View File

@ -292,7 +292,7 @@ static void flipq(unsigned char *sub)
/* ts A70904 */
/** @param flag bit=be silent on data shortage */
/** @param flag bit0=be silent on data shortage */
int burn_stdio_read(int fd, char *buf, int bufsize, struct burn_drive *d,
int flag)
{
@ -323,7 +323,20 @@ int burn_read_data(struct burn_drive *d, off_t byte_address,
int alignment = 2048, start, upto, chunksize = 1, err, cpy_size, i;
int sose_mem = 0, fd = -1, ret;
char msg[81], *wpt;
struct buffer buf;
struct buffer buf, *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 */
*data_count = 0;
sose_mem = d->silent_on_scsi_error;
@ -375,9 +388,12 @@ int burn_read_data(struct burn_drive *d, off_t byte_address,
#define O_LARGEFILE 0
#endif
fd = open(d->devname, O_RDONLY | O_LARGEFILE);
fd = d->stdio_fd;
if (fd < 0)
d->stdio_fd = fd =
open(d->devname, O_RDONLY | O_LARGEFILE);
if (fd == -1) {
if (!(flag & 1))
if (errno != ENOENT || !(flag & 2))
libdax_msgs_submit(libdax_messenger,
d->global_index,
0x00020005,
@ -387,10 +403,12 @@ int burn_read_data(struct burn_drive *d, off_t byte_address,
ret = 0; goto ex;
}
if (lseek(fd, byte_address, SEEK_SET) == -1) {
libdax_msgs_submit(libdax_messenger, d->global_index,
0x00020147,
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
"Cannot address start byte", errno, 0);
if (!(flag & 2))
libdax_msgs_submit(libdax_messenger,
d->global_index,
0x00020147,
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
"Cannot address start byte", errno, 0);
ret = 0; goto ex;
}
}
@ -416,7 +434,7 @@ int burn_read_data(struct burn_drive *d, off_t byte_address,
err = d->read_10(d, start, chunksize, d->buffer);
} else {
ret = burn_stdio_read(fd, (char *) d->buffer->data,
cpy_size, d, 0);
cpy_size, d, !!(flag & 2));
err = 0;
if (ret <= 0)
err = BE_CANCELLED;
@ -425,7 +443,8 @@ int burn_read_data(struct burn_drive *d, off_t byte_address,
d->silent_on_scsi_error = sose_mem;
if (err == BE_CANCELLED) {
/* Try to read a smaller part of the chunk */
for (i = 0; i < chunksize - 1; i++) {
if(!(flag & 4))
for (i = 0; i < chunksize - 1; i++) {
if (flag & 2)
d->silent_on_scsi_error = 1;
if (d->drive_role == 1) {
@ -446,6 +465,13 @@ int burn_read_data(struct burn_drive *d, off_t byte_address,
wpt += 2048;
*data_count += 2048;
}
if (!(flag & 2))
libdax_msgs_submit(libdax_messenger,
d->global_index,
0x00020000,
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH,
"burn_read_data() returns 0",
0, 0);
ret = 0; goto ex;
}
memcpy(wpt, d->buffer->data, cpy_size);
@ -455,9 +481,11 @@ int burn_read_data(struct burn_drive *d, off_t byte_address,
ret = 1;
ex:;
/* <<< let it open until drive is given up or writing shall happen
if (fd != -1)
close(fd);
d->buffer = NULL;
*/
d->buffer = buffer_mem;
d->busy = BURN_DRIVE_IDLE;
return ret;
}

View File

@ -21,6 +21,7 @@ int mmc_function_spy(struct burn_drive *d, char * text);
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)
{
@ -79,28 +80,46 @@ void sbc_eject(struct burn_drive *d)
int sbc_start_unit(struct burn_drive *d)
{
struct command c;
int ret;
if (mmc_function_spy(d, "start_unit") <= 0)
return 0;
scsi_init_command(&c, SBC_START_UNIT, sizeof(SBC_START_UNIT));
/*
memcpy(c.opcode, SBC_START_UNIT, sizeof(SBC_START_UNIT));
c.oplen = sizeof(SBC_START_UNIT);
c.page = NULL;
*/
c.retry = 1;
c.opcode[1] |= 1; /* ts A70918 : Immed */
c.dir = NO_TRANSFER;
d->issue_command(d, &c);
if (c.error)
return 0;
/* ts A70918 : now asynchronous */
return spc_wait_unit_attention(d, 1800, "START UNIT", 0);
d->is_stopped = 0;
ret = spc_wait_unit_attention(d, 1800, "START UNIT", 0);
return ret;
}
/* ts A90824 : Trying to reduce drive noise */
int sbc_stop_unit(struct burn_drive *d)
{
struct command c;
int ret;
if (mmc_function_spy(d, "stop_unit") <= 0)
return 0;
scsi_init_command(&c, SBC_STOP_UNIT, sizeof(SBC_STOP_UNIT));
c.retry = 1;
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()
*/
@ -109,6 +128,8 @@ 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;
}

View File

@ -123,7 +123,12 @@ static void get_bytes(struct burn_track *track, int count, unsigned char *data)
/* Next we use source data */
curr = valid;
if (!track->eos) {
valid = track->source->read(track->source, data + curr, count - curr);
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) */

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

@ -0,0 +1,229 @@
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
/*
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 or sg-freebsd.c
*/
#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <string.h>
#ifdef Libburn_os_has_statvfS
#include <sys/statvfs.h>
#endif /* Libburn_os_has_stavtfS */
#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;
/** 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 resp. 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);
}
/** 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 *bytes)
{
struct stat stbuf;
#ifdef Libburn_os_has_statvfS
struct statvfs vfsbuf;
#endif
char testpath[4096], *cpt;
long blocks;
off_t add_size = 0;
testpath[0] = 0;
blocks = *bytes / 512;
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)
return -1;
#ifdef Libburn_if_this_was_linuX
} else if(S_ISBLK(stbuf.st_mode)) {
fd = open(path, open_mode);
if (fd == -1)
return -2;
ret = ioctl(fd, BLKGETSIZE, &blocks);
close(fd);
if (ret == -1)
return -2;
*bytes = ((off_t) blocks) * (off_t) 512;
#endif /* Libburn_if_this_was_linuX */
} else if(S_ISREG(stbuf.st_mode)) {
add_size = stbuf.st_blocks * (off_t) 512;
strcpy(testpath, path);
} else
return 0;
if (testpath[0]) {
#ifdef Libburn_os_has_statvfS
if (statvfs(testpath, &vfsbuf) == -1)
return -2;
*bytes = add_size + ((off_t) vfsbuf.f_bsize) *
(off_t) vfsbuf.f_bavail;
#else /* Libburn_os_has_statvfS */
return 0;
#endif /* ! Libburn_os_has_stavtfS */
}
return 1;
}

View File

@ -76,7 +76,7 @@ Send feedback to libburn-hackers@pykix.org .
#include <err.h> /* XXX */
/* ts A70909 : >>> untestet yet wether this compiles */
/* ts A70909 */
#include <sys/statvfs.h>

View File

@ -1,6 +1,5 @@
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
#include <assert.h>
#include <errno.h>
#include <unistd.h>
#include <stdio.h>
@ -18,7 +17,7 @@
#include <err.h> /* XXX */
/* ts A70909 : >>> untestet yet wether this compiles */
/* ts A70909 */
#include <sys/statvfs.h>
@ -553,11 +552,26 @@ int sg_issue_command(struct burn_drive *d, struct command *c)
if (c->page) {
ccb->csio.data_ptr = c->page->data;
if (c->dir == FROM_DRIVE) {
ccb->csio.dxfer_len = BUFFER_SIZE;
/* ts A90430 : Ticket 148 , by jwehle :
"On ... FreeBSD 6.4 which has a usb memory reader in
addition to a ATAPI DVD burner sg_issue_command
will hang while the SCSI bus is being scanned"
*/
if (c->dxfer_len >= 0)
ccb->csio.dxfer_len = c->dxfer_len;
else
ccb->csio.dxfer_len = BUFFER_SIZE;
/* touch page so we can use valgrind */
memset(c->page->data, 0, BUFFER_SIZE);
} else {
assert(c->page->bytes > 0);
/* ts A90430 */
/* a ssert(c->page->bytes > 0); */
if (c->page->bytes <= 0) {
c->error = 1;
return 0;
}
ccb->csio.dxfer_len = c->page->bytes;
}
} else {
@ -622,7 +636,6 @@ int burn_os_stdio_capacity(char *path, off_t *bytes)
struct statvfs vfsbuf;
char testpath[4096], *cpt;
long blocks;
int open_mode = O_RDWR, fd, ret;
off_t add_size = 0;
testpath[0] = 0;
@ -642,6 +655,8 @@ int burn_os_stdio_capacity(char *path, off_t *bytes)
#ifdef Libburn_if_this_was_linuX
} else if(S_ISBLK(stbuf.st_mode)) {
int open_mode = O_RDWR, fd, ret;
if(burn_sg_open_o_excl)
open_mode |= O_EXCL;
fd = open(path, open_mode);

View File

@ -90,6 +90,7 @@ Hint: You should also look into sg-freebsd-port.c, which is a younger and
/* ts A61211 : to eventually recognize CD devices on /dev/sr* */
#include <limits.h>
#include <linux/cdrom.h>
@ -259,6 +260,37 @@ static void sg_select_device_family(void)
}
/* ts A80701 */
/* This cares for the case that no /dev/srNN but only /dev/scdNN exists.
A theoretical case which has its complement in SuSE 10.2 having
/dev/sr but not /dev/scd.
*/
static int sg_exchange_scd_for_sr(char *fname, int flag)
{
struct stat stbuf;
char scd[17], msg[160];
if (burn_sg_use_family != 0 || strncmp(fname, "/dev/sr", 7)!=0 ||
strlen(fname)>9 || strlen(fname)<8)
return 2;
if (fname[7] < '0' || fname[7] > '9')
return 2;
if (fname [8] != 0 && (fname[7] < '0' || fname[7] > '9'))
return 2;
if (stat(fname, &stbuf) != -1)
return 2;
strcpy(scd, "/dev/scd");
strcpy(scd + 8, fname + 7);
if (stat(scd, &stbuf) == -1)
return 2;
sprintf(msg, "%s substitutes for non-existent %s", scd, fname);
libdax_msgs_submit(libdax_messenger, -1, 0x00000002,
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH, msg, 0, 0);
strcpy(fname, scd);
return 1;
}
static int sgio_test(int fd)
{
unsigned char test_ops[] = { 0, 0, 0, 0, 0, 0 };
@ -278,6 +310,33 @@ static int sgio_test(int fd)
static int sg_handle_busy_device(char *fname, int os_errno)
{
char msg[4096];
struct stat stbuf;
int looks_like_hd= 0, fd, ret;
/* ts A80713 :
check existence of /dev/hdX1 as hint for hard disk rather than CD
Hint by Giulio Orsero: check /proc/ide/hdX/media for "disk"
*/
if (strncmp(fname, "/dev/hd", 7)==0) {
sprintf(msg, "%s1", fname);
if (stat(msg, &stbuf) != -1)
looks_like_hd= 1;
sprintf(msg, "/proc/ide/hd%c/media", fname[7]);
fd = open(msg, O_RDONLY);
if (fd != -1) {
ret = read(fd, msg, 10);
if (ret < 0)
ret = 0;
msg[ret]= 0;
close(fd);
if (strncmp(msg, "disk\n", 5) == 0 ||
strcmp(msg, "disk") == 0)
looks_like_hd= 2;
else if (strncmp(msg, "cdrom\n", 6) == 0 ||
strcmp(msg, "cdrom") == 0)
looks_like_hd= 0;
}
}
/* ts A60814 : i saw no way to do this more nicely */
if (burn_sg_open_abort_busy) {
@ -291,10 +350,26 @@ static int sg_handle_busy_device(char *fname, int os_errno)
}
/* ts A60924 : now reporting to libdax_msgs */
sprintf(msg, "Cannot open busy device '%s'", fname);
libdax_msgs_submit(libdax_messenger, -1, 0x00020001,
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_LOW,
msg, os_errno, 0);
if (looks_like_hd == 2) { /* is surely hard disk */
;
} else if (looks_like_hd) {
sprintf(msg, "Could not examine busy device '%s'", fname);
libdax_msgs_submit(libdax_messenger, -1, 0x0002015a,
LIBDAX_MSGS_SEV_NOTE, LIBDAX_MSGS_PRIO_LOW,
msg, os_errno, 0);
sprintf(msg,
"Busy '%s' seems to be a hard disk, as '%s1' exists. But better check.",
fname, fname);
libdax_msgs_submit(libdax_messenger, -1, 0x0002015b,
LIBDAX_MSGS_SEV_HINT, LIBDAX_MSGS_PRIO_LOW,
msg, 0, 0);
} else {
sprintf(msg, "Cannot open busy device '%s'", fname);
libdax_msgs_submit(libdax_messenger, -1, 0x00020001,
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_LOW,
msg, os_errno, 0);
}
return 1;
}
@ -307,6 +382,28 @@ static int sg_close_drive_fd(char *fname, int driveno, int *fd, int sorry)
if(*fd < 0)
return(0);
#ifdef CDROM_MEDIA_CHANGED_disabled_because_not_helpful
#ifdef CDSL_CURRENT
/* ts A80217 : wondering whether the os knows about our activities */
ret = ioctl(*fd, CDROM_MEDIA_CHANGED, CDSL_CURRENT);
sprintf(msg, "ioctl(CDROM_MEDIA_CHANGED) == %d", ret);
libdax_msgs_submit(libdax_messenger, driveno, 0x00000002,
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH, msg, 0, 0);
#ifdef BLKFLSBUF_disabled_because_not_helpful
ret = ioctl(*fd, BLKFLSBUF, 0);
sprintf(msg, "ioctl(BLKFLSBUF) == %d", ret);
os_errno = 0;
if(ret == -1)
os_errno = errno;
libdax_msgs_submit(libdax_messenger, driveno, 0x00000002,
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH, msg, os_errno,0);
#endif /* BLKFLSBUF */
#endif /* CDSL_CURRENT */
#endif /* CDROM_MEDIA_CHANGED */
ret = close(*fd);
*fd = -1337;
if(ret != -1) {
@ -373,7 +470,7 @@ static int sg_fcntl_lock(int *fd, char *fd_name, int l_type, int verbous)
/* ts A60926 */
static int sg_open_drive_fd(char *fname, int scan_mode)
{
int open_mode = O_RDWR, fd;
int open_mode = O_RDWR, fd, tries= 0;
char msg[81];
/* ts A70409 : DDLP-B */
@ -405,7 +502,8 @@ static int sg_open_drive_fd(char *fname, int scan_mode)
"libburn: experimental: O_EXCL= %d , O_NDELAY= %d\n",
!!(open_mode&O_EXCL),!!(open_mode&O_NDELAY));
*/
try_open:;
fd = open(fname, open_mode);
if (fd == -1) {
/* <<< debugging
@ -414,6 +512,17 @@ static int sg_open_drive_fd(char *fname, int scan_mode)
fname,errno);
*/
if (errno == EBUSY) {
tries++;
/* <<< debugging
fprintf(stderr,
"\nlibburn_DEBUG: EBUSY , tries= %d\n", tries);
*/
if (tries < 4) {
usleep(2000000);
goto try_open;
}
sg_handle_busy_device(fname, errno);
return -1;
@ -547,12 +656,193 @@ failed:;
}
#define Libburn_drive_new_deaL 1
#ifdef Libburn_drive_new_deaL
/* ts A80731 */
static int is_ata_drive(char *fname)
{
int fd;
struct hd_driveid tm;
fd = sg_open_drive_fd(fname, 1);
if (fd == -1) {
if (linux_ata_enumerate_verbous)
fprintf(stderr,"open failed, errno=%d '%s'\n",
errno, strerror(errno));
return 0;
}
memset(&tm, 0, sizeof(tm));
ioctl(fd, HDIO_GET_IDENTITY, &tm);
/* not atapi */
if (!(tm.config & 0x8000) || (tm.config & 0x4000)) {
if (linux_ata_enumerate_verbous)
fprintf(stderr, "not marked as ATAPI\n");
sg_close_drive_fd(fname, -1, &fd, 0);
return 0;
}
/* if SG_IO fails on an atapi device, we should stop trying to
use hd* devices */
if (sgio_test(fd) == -1) {
if (linux_ata_enumerate_verbous)
fprintf(stderr,
"FATAL: sgio_test() failed: errno=%d '%s'\n",
errno, strerror(errno));
sg_close_drive_fd(fname, -1, &fd, 0);
return 0;
}
if (sg_close_drive_fd(fname, -1, &fd, 1) <= 0) {
if (linux_ata_enumerate_verbous)
fprintf(stderr,
"cannot close properly, errno=%d '%s'\n",
errno, strerror(errno));
return 0;
}
return 1;
}
static int is_scsi_drive(char *fname, int *bus_no, int *host_no,
int *channel_no, int *target_no, int *lun_no)
{
int fd, sid_ret = 0, ret;
struct sg_scsi_id sid;
int sibling_fds[BURN_OS_SG_MAX_SIBLINGS], sibling_count= 0;
char sibling_fnames[BURN_OS_SG_MAX_SIBLINGS][BURN_OS_SG_MAX_NAMELEN];
fd = sg_open_drive_fd(fname, 1);
if (fd == -1) {
if (linux_sg_enumerate_debug)
fprintf(stderr, "open failed, errno=%d '%s'\n",
errno, strerror(errno));
return 0;
}
sid_ret = ioctl(fd, SG_GET_SCSI_ID, &sid);
if (sid_ret == -1) {
sid.scsi_id = -1; /* mark SCSI address as invalid */
if(linux_sg_enumerate_debug)
fprintf(stderr,
"ioctl(SG_GET_SCSI_ID) failed, errno=%d '%s' , ",
errno, strerror(errno));
if (sgio_test(fd) == -1) {
if (linux_sg_enumerate_debug)
fprintf(stderr,
"FATAL: sgio_test() failed: errno=%d '%s'",
errno, strerror(errno));
sg_close_drive_fd(fname, -1, &fd, 0);
return 0;
}
#ifdef CDROM_DRIVE_STATUS
/* http://developer.osdl.org/dev/robustmutexes/
src/fusyn.hg/Documentation/ioctl/cdrom.txt */
sid_ret = ioctl(fd, CDROM_DRIVE_STATUS, 0);
if(linux_sg_enumerate_debug)
fprintf(stderr,
"ioctl(CDROM_DRIVE_STATUS) = %d , ",
sid_ret);
if (sid_ret != -1 && sid_ret != CDS_NO_INFO)
sid.scsi_type = TYPE_ROM;
else
sid_ret = -1;
#endif /* CDROM_DRIVE_STATUS */
}
#ifdef SCSI_IOCTL_GET_BUS_NUMBER
/* Hearsay A61005 */
if (ioctl(fd, SCSI_IOCTL_GET_BUS_NUMBER, bus_no) == -1)
*bus_no = -1;
#endif
if (sg_close_drive_fd(fname, -1, &fd,
sid.scsi_type == TYPE_ROM ) <= 0) {
if (linux_sg_enumerate_debug)
fprintf(stderr,
"cannot close properly, errno=%d '%s'\n",
errno, strerror(errno));
return 0;
}
if ( (sid_ret == -1 || sid.scsi_type != TYPE_ROM)
&& !linux_sg_accept_any_type) {
if (linux_sg_enumerate_debug)
fprintf(stderr, "sid.scsi_type = %d (!= TYPE_ROM)\n",
sid.scsi_type);
return 0;
}
if (sid_ret == -1 || sid.scsi_id < 0) {
/* ts A61211 : employ a more general ioctl */
ret = sg_obtain_scsi_adr(fname, bus_no, host_no,
channel_no, target_no, lun_no);
if (ret>0) {
sid.host_no = *host_no;
sid.channel = *channel_no;
sid.scsi_id = *target_no;
sid.lun = *lun_no;
} else {
if (linux_sg_enumerate_debug)
fprintf(stderr,
"sg_obtain_scsi_adr() failed\n");
return 0;
}
}
/* ts A60927 : trying to do locking with growisofs */
if(burn_sg_open_o_excl>1) {
ret = sg_open_scsi_siblings(
fname, -1, sibling_fds, sibling_fnames,
&sibling_count,
sid.host_no, sid.channel,
sid.scsi_id, sid.lun);
if (ret<=0) {
if (linux_sg_enumerate_debug)
fprintf(stderr, "cannot lock siblings\n");
sg_handle_busy_device(fname, 0);
return 0;
}
/* the final occupation will be done in sg_grab() */
sg_release_siblings(sibling_fds, sibling_fnames,
&sibling_count);
}
#ifdef SCSI_IOCTL_GET_BUS_NUMBER
if(*bus_no == -1)
*bus_no = 1000 * (sid.host_no + 1) + sid.channel;
#else
*bus_no = sid.host_no;
#endif
*host_no= sid.host_no;
*channel_no= sid.channel;
*target_no= sid.scsi_id;
*lun_no= sid.lun;
return 1;
}
#endif /* Libburn_drive_new_deaL */
/** Speciality of Linux: detect non-SCSI ATAPI (EIDE) which will from
then on used used via generic SCSI as is done with (emulated) SCSI drives */
static void ata_enumerate(void)
{
#ifdef Libburn_drive_new_deaL
int ret;
#else
struct hd_driveid tm;
int i, fd;
int fd;
#endif
int i;
char fname[10];
if (linux_ata_enumerate_verbous)
@ -573,6 +863,17 @@ static void ata_enumerate(void)
fprintf(stderr, "not in whitelist\n");
continue;
}
#ifdef Libburn_drive_new_deaL
ret = is_ata_drive(fname);
if (ret < 0)
break;
if (ret == 0)
continue;
#else /* Libburn_drive_new_deaL */
fd = sg_open_drive_fd(fname, 1);
if (fd == -1) {
if (linux_ata_enumerate_verbous)
@ -609,6 +910,10 @@ static void ata_enumerate(void)
errno, strerror(errno));
continue;
}
#endif /* Libburn_drive_new_deaL */
if (linux_ata_enumerate_verbous)
fprintf(stderr, "accepting as drive without SCSI address\n");
enumerate_common(fname, -1, -1, -1, -1, -1);
@ -619,12 +924,18 @@ static void ata_enumerate(void)
/** Detects (probably emulated) SCSI drives */
static void sg_enumerate(void)
{
#ifdef Libburn_drive_new_deaL
#else
struct sg_scsi_id sid;
int i, fd, sibling_fds[BURN_OS_SG_MAX_SIBLINGS], sibling_count= 0, ret;
int sid_ret = 0;
int bus_no= -1, host_no= -1, channel_no= -1, target_no= -1, lun_no= -1;
char fname[10];
int fd, sibling_fds[BURN_OS_SG_MAX_SIBLINGS], sibling_count= 0;
char sibling_fnames[BURN_OS_SG_MAX_SIBLINGS][BURN_OS_SG_MAX_NAMELEN];
int sid_ret = 0;
#endif
int i, ret;
int bus_no= -1, host_no= -1, channel_no= -1, target_no= -1, lun_no= -1;
char fname[17];
sg_select_device_family();
@ -638,6 +949,9 @@ static void sg_enumerate(void)
for (i = 0; i < 32; i++) {
sprintf(fname, linux_sg_device_family, i);
/* ts A80702 */
sg_exchange_scd_for_sr(fname, 0);
if (linux_sg_enumerate_debug)
fprintf(stderr, "libburn_debug: %s : ", fname);
@ -648,6 +962,23 @@ static void sg_enumerate(void)
continue;
}
#ifdef Libburn_drive_new_deaL
ret = is_scsi_drive(fname, &bus_no, &host_no, &channel_no,
&target_no, &lun_no);
if (ret < 0)
break;
if (ret == 0)
continue;
if (linux_sg_enumerate_debug)
fprintf(stderr, "accepting as SCSI %d,%d,%d,%d bus=%d\n",
host_no, channel_no, target_no, lun_no, bus_no);
enumerate_common(fname, bus_no, host_no, channel_no,
target_no, lun_no);
#else /* Libburn_drive_new_deaL */
/* ts A60927 */
fd = sg_open_drive_fd(fname, 1);
if (fd == -1) {
@ -757,16 +1088,223 @@ static void sg_enumerate(void)
#else
bus_no = sid.host_no;
#endif
if (linux_sg_enumerate_debug)
fprintf(stderr, "accepting as SCSI %d,%d,%d,%d bus=%d\n",
sid.host_no, sid.channel, sid.scsi_id, sid.lun,
bus_no);
enumerate_common(fname, bus_no, sid.host_no, sid.channel,
sid.scsi_id, sid.lun);
#endif /* Libburn_drive_new_deaL */
}
}
#ifdef Libburn_drive_new_deaL
/* ts A80805 : eventually produce the other official name of a device file */
static int fname_other_name(char *fname, char other_name[80], int flag)
{
if(strncmp(fname, "/dev/sr", 7) == 0 &&
(fname[7] >= '0' && fname[7] <= '9') &&
(fname[8] == 0 ||
(fname[8] >= '0' && fname[8] <= '9' && fname[9] == 0))) {
sprintf(other_name, "/dev/scd%s", fname + 7);
return 1;
}
if(strncmp(fname, "/dev/scd", 8) == 0 &&
(fname[8] >= '0' && fname[8] <= '9') &&
(fname[9] == 0 ||
(fname[9] >= '0' && fname[9] <= '9' && fname[10] == 0))) {
sprintf(other_name, "/dev/sr%s", fname + 8);
return 1;
}
return 0;
}
/* ts A80805 */
static int fname_drive_is_listed(char *fname, int flag)
{
char other_fname[80];
if (burn_drive_is_listed(fname, NULL, 0))
return 1;
if (fname_other_name(fname, other_fname, 0) > 0)
if (burn_drive_is_listed(other_fname, NULL, 0))
return 2;
return 0;
}
/* ts A80731 : Directly open the given address.
@param flag bit0= do not complain about missing file
bit1= do not check whether drive is already listed
*/
static int fname_enumerate(char *fname, int flag)
{
int is_ata= 0, is_scsi= 0;
int bus_no= -1, host_no= -1, channel_no= -1, target_no= -1, lun_no= -1;
char msg[BURN_DRIVE_ADR_LEN + 80];
struct stat stbuf;
if (!(flag & 2))
if (fname_drive_is_listed(fname, 0))
return 2;
if (stat(fname, &stbuf) == -1) {
sprintf(msg, "File object '%s' not found", fname);
if (!(flag & 1))
libdax_msgs_submit(libdax_messenger, -1, 0x0002000b,
LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH,
msg, 0, 0);
return -1;
}
is_ata = is_ata_drive(fname);
if (is_ata < 0)
return -1;
if (!is_ata)
is_scsi = is_scsi_drive(fname, &bus_no, &host_no, &channel_no,
&target_no, &lun_no);
if (is_scsi < 0)
return -1;
if (is_ata == 0 && is_scsi == 0)
return 0;
if (linux_sg_enumerate_debug)
fprintf(stderr,
"(single) accepting as SCSI %d,%d,%d,%d bus=%d\n",
host_no, channel_no, target_no, lun_no, bus_no);
enumerate_common(fname, bus_no, host_no, channel_no,
target_no, lun_no);
return 1;
}
/* ts A80731 : Directly open the given address from a single-item whitlist */
static int single_enumerate(int flag)
{
int ret, wl_count;
char *fname, msg[BURN_DRIVE_ADR_LEN + 80];
wl_count= burn_drive_whitelist_count();
if (wl_count != 1)
return 0;
fname= burn_drive_whitelist_item(0, 0);
if (fname == NULL)
return 0;
ret = fname_enumerate(fname, 2);
if (ret <= 0) {
sprintf(msg, "Cannot access '%s' as SG_IO CDROM drive", fname);
libdax_msgs_submit(libdax_messenger, -1, 0x0002000a,
LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH,
msg, 0, 0);
ret = -1;
}
return ret;
}
/* ts A80801 : looking up drives listed in /proc/sys/dev/cdrom/info line like:
drive name: sr1 hdc hda sr0
@parm flag bit0= release list memory and exit
*/
static int proc_sys_dev_cdrom_info(char ***list, int *count, int flag)
{
FILE *fp;
char line[1024], fname[1024 + 5], *cpt, *retpt, *list_data;
int maxl= 0, pass, i;
if (*list != NULL) {
if ((*list)[0] != NULL)
free((*list)[0]);
free(*list);
*list = NULL;
*count = 0;
}
if (flag & 1)
return 1;
*count = 0;
sg_evaluate_kernel();
if (sg_kernel_age < 2) /* addresses are not suitable for kernel 2.4 */
return 1;
fp = fopen("/proc/sys/dev/cdrom/info", "r");
if (fp == NULL)
return 0;
while (1) {
retpt = fgets(line, sizeof(line), fp);
if (retpt == NULL)
break;
if(strncmp(line, "drive name:", 11) == 0)
break;
}
fclose(fp);
if (retpt == NULL)
return 0;
strcpy(fname, "/dev/");
for(pass = 0; pass < 2; pass++) {
*count = 0;
cpt = line + 11;
while (*cpt != 0) {
for(; *cpt == ' ' || *cpt == '\t'; cpt++);
if (*cpt == 0 || *cpt == '\n')
break;
sscanf(cpt, "%s", fname + 5);
if (strlen(fname) > maxl)
maxl = strlen(fname);
if (pass == 1)
strcpy((*list)[*count], fname);
(*count)++;
for(cpt++; *cpt != ' ' && *cpt != '\t'
&& *cpt != 0 && *cpt != '\n'; cpt++);
}
if (pass == 0) {
list_data = calloc(*count + 1, maxl+1);
*list = calloc(*count + 1, sizeof(char *));
if(list_data == NULL || *list == NULL) {
libdax_msgs_submit(libdax_messenger, -1,
0x00000003,
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
"Out of virtual memory", 0, 0);
if (list_data != NULL)
free(list_data);
if (*list != NULL)
free((char *) *list);
return -1;
}
for (i = 0; i <= *count; i++)
(*list)[i] = list_data + i * (maxl + 1);
}
}
return 1;
}
static int add_proc_info_drives(int flag)
{
int ret, list_count, count = 0, i;
char **list= NULL;
ret = proc_sys_dev_cdrom_info(&list, &list_count, 0);
if (ret <= 0)
return ret;
for (i = 0; i < list_count; i++) {
if (burn_drive_is_banned(list[i]))
continue;
ret = fname_enumerate(list[i], 1);
if (ret == 1)
count++;
}
proc_sys_dev_cdrom_info(&list, &list_count, 1); /* free memory */
return 1 + count;
}
#endif /* Libburn_drive_new_deaL */
/* ts A61115 */
/* ----------------------------------------------------------------------- */
/* PORTING: Private functions which contain publicly needed functionality. */
@ -851,10 +1389,14 @@ int sg_give_next_adr(burn_drive_enumerator_t *idx,
{
/* os-linux.h : typedef int burn_drive_enumerator_t; */
static int sg_limit = 32, ata_limit = 26;
int baseno = 0;
int baseno = 0, i;
char other_name[80];
if (initialize == -1)
if (initialize == -1) {
proc_sys_dev_cdrom_info(&(idx->info_list), &(idx->info_count),
1);
return 0;
}
sg_select_device_family();
if (linux_sg_device_family[0] == 0)
@ -862,26 +1404,56 @@ int sg_give_next_adr(burn_drive_enumerator_t *idx,
if (linux_ata_device_family[0] == 0)
ata_limit = 0;
if (initialize == 1)
*idx = -1;
(*idx)++;
if (*idx >= sg_limit)
if (initialize == 1) {
idx->pos = -1;
idx->info_count= 0;
idx->info_list= NULL;
proc_sys_dev_cdrom_info(&(idx->info_list), &(idx->info_count),
0);
}
(idx->pos)++;
if (idx->pos >= sg_limit)
goto next_ata;
if (adr_size < 10)
if (adr_size < 11)
return -1;
sprintf(adr, linux_sg_device_family, *idx);
return 1;
sprintf(adr, linux_sg_device_family, idx->pos);
sg_exchange_scd_for_sr(adr, 0);
goto return_1_pre_proc;
next_ata:;
baseno += sg_limit;
if (*idx - baseno >= ata_limit)
goto next_nothing;
if (idx->pos - baseno >= ata_limit)
goto next_proc_info;
if (adr_size < 9)
return -1;
sprintf(adr, linux_ata_device_family, 'a' + (*idx - baseno));
return 1;
next_nothing:;
sprintf(adr, linux_ata_device_family, 'a' + (idx->pos - baseno));
goto return_1_pre_proc;
next_proc_info:;
baseno += ata_limit;
for (i = 0; i < idx->info_count; i++) {
if ((idx->info_list)[i][0] == 0)
continue;
if (baseno == idx->pos) {
if (adr_size < strlen((idx->info_list)[i]) + 1)
return -1;
strcpy(adr, (idx->info_list)[i]);
return 1;
}
baseno++;
}
return 0;
return_1_pre_proc:;
for (i = 0; i < idx->info_count; i++) {
if (strcmp((idx->info_list)[i], adr) == 0)
(idx->info_list)[i][0] = 0;
if (fname_other_name(adr, other_name, 0) > 0)
if (strcmp((idx->info_list)[i], other_name) == 0)
(idx->info_list)[i][0] = 0;
}
return 1;
}
@ -903,8 +1475,27 @@ next_nothing:;
/* ts A61115: replacing call to sg-implementation internals from drive.c */
int scsi_enumerate_drives(void)
{
#ifdef Libburn_drive_new_deaL
int ret;
#endif
#ifdef Libburn_drive_new_deaL
/* Direct examination of eventually single whitelisted name */
ret = single_enumerate(0);
if (ret < 0)
return -1;
if (ret > 0)
return 1;
#endif /* Libburn_drive_new_deaL */
sg_enumerate();
ata_enumerate();
#ifdef Libburn_drive_new_deaL
add_proc_info_drives(0);
#endif /* Libburn_drive_new_deaL */
return 1;
}
@ -1355,9 +1946,9 @@ int sg_is_enumerable_adr(char *adr)
sg_give_next_adr(&idx, fname, sizeof(fname), -1);
return 1;
}
}
sg_give_next_adr(&idx, fname, sizeof(fname), -1);
if (first == 0)
sg_give_next_adr(&idx, fname, sizeof(fname), -1);
return(0);
}

View File

@ -1,7 +1,7 @@
/* sg.c
Switcher for operating system dependent transport level modules of libburn.
Copyright (C) 2006 Thomas Schmitt <scdbackup@gmx.net>, provided under GPL
Copyright (C) 2009 Thomas Schmitt <scdbackup@gmx.net>, provided under GPL
*/
@ -10,8 +10,32 @@
#include "sg-freebsd.c"
#else
#ifdef __linux
#include "sg-linux.c"
#endif
#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_Linux_nor_FreeBSD_;
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 Cannot_recognize_Linux_nor_FreeBSD;
int INTENTIONAL_COMPILER_WARNING;
return(0);
}
#include "sg-dummy.c"
#endif /* ! __linux */
#endif /* ! __FreeBSD__ */

View File

@ -18,8 +18,6 @@ void burn_source_free(struct burn_source *src)
enum burn_source_status burn_track_set_source(struct burn_track *t,
struct burn_source *s)
{
if (!s->read)
return BURN_SOURCE_FAILED;
s->refcount++;
t->source = s;
@ -43,3 +41,15 @@ struct burn_source *burn_source_new(void)
out->refcount = 1;
return out;
}
/* ts A71223 */
int burn_source_cancel(struct burn_source *src)
{
if(src->read == NULL)
if(src->version > 0)
if(src->cancel != NULL)
src->cancel(src);
return 1;
}

View File

@ -5,4 +5,6 @@
struct burn_source *burn_source_new(void);
int burn_source_cancel(struct burn_source *src);
#endif /*__SOURCE*/

View File

@ -104,7 +104,9 @@ int spc_wait_unit_attention(struct burn_drive *d, int max_sec, char *cmd_text,
int flag)
{
int i, ret = 1, key = 0, asc = 0, ascq = 0;
char msg[160];
char msg[320];
unsigned char sense[14];
enum response resp;
if (!(flag & 1))
usleep(100000);
@ -117,9 +119,9 @@ int spc_wait_unit_attention(struct burn_drive *d, int max_sec, char *cmd_text,
i, ret, (unsigned) key, (unsigned) asc, (unsigned) ascq);
*/
if(ret > 0) /* ready */
if (ret > 0) /* ready */
break;
if(key!=0x2 || asc!=0x4) {
if (key!=0x2 || asc!=0x4) {
if (key == 0x2 && asc == 0x3A) {
ret = 1; /* medium not present = ok */
/* <<<
@ -138,10 +140,24 @@ int spc_wait_unit_attention(struct burn_drive *d, int max_sec, char *cmd_text,
/* media change notice = try again */
goto slumber;
#ifdef NIX
sprintf(msg,
"Asynchromous SCSI error on %s: key=%X asc=%2.2Xh ascq=%2.2Xh",
cmd_text, (unsigned) key, (unsigned) asc,
(unsigned) ascq);
#else
/* ts A90213 */
sprintf(msg,
"Asynchromous SCSI error on %s: ", cmd_text);
sense[2] = key;
sense[12] = asc;
sense[13] = ascq;
resp = scsi_error_msg(d, sense, 14, msg + strlen(msg),
&key, &asc, &ascq);
#endif /* ! NIX */
libdax_msgs_submit(libdax_messenger, d->global_index,
0x0002014d,
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
@ -275,7 +291,7 @@ void spc_allow(struct burn_drive *d)
}
/*
ts A70518 : Do not call with *alloc_len < 8
ts A70518 - A90603 : Do not call with *alloc_len < 10
*/
/** flag&1= do only inquire alloc_len */
static int spc_sense_caps_al(struct burn_drive *d, int *alloc_len, int flag)
@ -287,13 +303,19 @@ static int spc_sense_caps_al(struct burn_drive *d, int *alloc_len, int flag)
unsigned char *page;
struct command c;
struct burn_speed_descriptor *sd;
char msg[BURN_DRIVE_ADR_LEN + 160];
/* ts A61225 : 1 = report about post-MMC-1 speed descriptors */
static int speed_debug = 0;
if (*alloc_len < 8)
if (*alloc_len < 10)
return 0;
/* ts A90602 : Clearing mdata before command execution */
m = d->mdata;
m->valid = 0;
burn_mdata_free_subs(m);
memset(&buf, 0, sizeof(buf));
scsi_init_command(&c, SPC_MODE_SENSE, sizeof(SPC_MODE_SENSE));
/*
@ -312,12 +334,11 @@ static int spc_sense_caps_al(struct burn_drive *d, int *alloc_len, int flag)
d->issue_command(d, &c);
if (c.error) {
memset(&buf, 0, sizeof(buf));
d->mdata->valid = -1;
m->valid = -1;
was_error = 1;
}
size = c.page->data[0] * 256 + c.page->data[1];
m = d->mdata;
page = c.page->data + 8;
/* ts A61225 :
@ -326,18 +347,28 @@ static int spc_sense_caps_al(struct burn_drive *d, int *alloc_len, int flag)
in MMC-3 6.3.11 there are at least 28 bytes plus a variable length
set of speed descriptors. In MMC-5 E.11 it is declared "legacy".
*/
/* ts A90603 :
SPC-1 8.3.3 enumerates mode page format bytes from 0 to n and
defines Page Length as (n-1).
*/
page_length = page[1];
old_alloc_len = *alloc_len;
*alloc_len = page_length + 8;
*alloc_len = page_length + 10;
if (flag & 1)
return !was_error;
if (page_length + 8 > old_alloc_len)
page_length = old_alloc_len - 8;
if (page_length < 22)
return 0;
if (page_length + 10 > old_alloc_len)
page_length = old_alloc_len - 10;
m->valid = 0;
burn_mdata_free_subs(m);
/* ts A90602 : 20 asserts page[21]. (see SPC-1 8.3.3) */
if (page_length < 20) {
m->valid = -1;
sprintf(msg, "MODE SENSE page 2A too short: %s : %d",
d->devname, page_length);
libdax_msgs_submit(libdax_messenger, d->global_index,
0x0002016e, LIBDAX_MSGS_SEV_DEBUG,
LIBDAX_MSGS_PRIO_LOW, msg, 0, 0);
return 0;
}
m->buffer_size = page[12] * 256 + page[13];
m->dvdram_read = page[2] & 32;
@ -368,12 +399,13 @@ static int spc_sense_caps_al(struct burn_drive *d, int *alloc_len, int flag)
m->min_end_lba = 0x7fffffff;
m->max_end_lba = 0;
m->valid = 1;
if (!was_error)
m->valid = 1;
mmc_get_configuration(d);
/* ts A61225 : end of MMC-1 , begin of MMC-3 */
if (page_length < 32) /* no write speed descriptors ? */
if (page_length < 30) /* no write speed descriptors ? */
goto try_mmc_get_performance;
m->cur_write_speed = page[28] * 256 + page[29];
@ -397,12 +429,12 @@ static int spc_sense_caps_al(struct burn_drive *d, int *alloc_len, int flag)
}
for (i = 0; i < num_write_speeds; i++) {
speed = page[32 + 4*i + 2] * 256 + page[32 + 4*i + 3];
speed = page[32 + 4 * i + 2] * 256 + page[32 + 4 * i + 3];
if (speed_debug)
fprintf(stderr,
"LIBBURN_DEBUG: write speed #%d = %d kB/s (rc %d)\n",
i, speed, page[32 + 4*i +1] & 7);
i, speed, page[32 + 4 * i + 1] & 7);
/* ts A61226 */
ret = burn_speed_descriptor_new(&(d->mdata->speed_descriptors),
@ -415,7 +447,7 @@ static int spc_sense_caps_al(struct burn_drive *d, int *alloc_len, int flag)
strcpy(sd->profile_name,
d->current_profile_text);
}
sd->wrc = (( page[32 + 4*i +1] & 7 ) == 1 );
sd->wrc = (( page[32 + 4 * i + 1] & 7 ) == 1 );
sd->write_speed = speed;
}
@ -431,19 +463,31 @@ static int spc_sense_caps_al(struct burn_drive *d, int *alloc_len, int flag)
m->min_write_speed, m->max_write_speed);
try_mmc_get_performance:;
ret = mmc_get_write_performance(d);
if (ret > 0 && speed_debug)
fprintf(stderr,
if (m->cdrw_write || page_length >= 32) {
/* ts A90823:
One has to avoid U3 enhanced memory sticks here. On my
SuSE 10.2 a SanDisk Cruzer 4GB stalls at the second occasion
of ACh GET PERFORMANCE. (The first one is obviously called
by the OS at plug time.)
This pseudo drive returns no write capabilities and a page
length of 28. MMC-3 describes page length 32. Regrettably
MMC-2 prescribes a page length of 26. Here i have to trust
m->cdrw_write to reliably indicate any MMC-2 burner.
*/
ret = mmc_get_write_performance(d);
if (ret > 0 && speed_debug)
fprintf(stderr,
"LIBBURN_DEBUG: ACh min_write_speed = %d , max_write_speed = %d\n",
m->min_write_speed, m->max_write_speed);
m->min_write_speed, m->max_write_speed);
}
return !was_error;
}
void spc_sense_caps(struct burn_drive *d)
{
int alloc_len, start_len = 22, ret;
int alloc_len, start_len = 30, ret;
if (mmc_function_spy(d, "sense_caps") <= 0)
return;
@ -566,17 +610,21 @@ void spc_sense_write_params(struct burn_drive *d)
c.dir = FROM_DRIVE;
d->issue_command(d, &c);
size = c.page->data[0] * 256 + c.page->data[1];
/* ts A71128 : do not interpret reply if error */
m = d->mdata;
page = c.page->data + 8;
burn_print(1, "write page length 0x%x\n", page[1]);
m->write_page_length = page[1];
m->write_page_valid = 1;
if (!c.error) {
size = c.page->data[0] * 256 + c.page->data[1];
page = c.page->data + 8;
burn_print(1, "write page length 0x%x\n", page[1]);
m->write_page_length = page[1];
m->write_page_valid = 1;
} else
m->write_page_valid = 0;
mmc_read_disc_info(d);
/* ts A70212 : try to setup d->media_capacity_remaining */
if (d->current_profile == 0x1a || d->current_profile == 0x13 ||
d->current_profile == 0x12)
d->current_profile == 0x12 || d->current_profile == 0x43)
d->read_format_capacities(d, -1);
else if (d->status == BURN_DISC_BLANK ||
(d->current_is_cd_profile && d->status == BURN_DISC_APPENDABLE)) {
@ -841,7 +889,7 @@ int burn_scsi_setup_drive(struct burn_drive *d, int bus_no, int host_no,
d->mdata = calloc(1, sizeof(struct scsi_mode_data));
/* ts A61007 : obsolete Assert in drive_getcaps() */
if(d->idata == NULL || d->mdata == NULL) {
if (d->idata == NULL || d->mdata == NULL) {
libdax_msgs_submit(libdax_messenger, -1, 0x00020108,
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
"Could not allocate new drive object", 0, 0);
@ -850,7 +898,7 @@ int burn_scsi_setup_drive(struct burn_drive *d, int bus_no, int host_no,
d->idata->valid = 0;
d->mdata->valid = 0;
d->mdata->speed_descriptors = NULL;
if(!(flag & 1)) {
if (!(flag & 1)) {
ret = spc_setup_drive(d);
if (ret<=0)
return ret;
@ -865,11 +913,14 @@ int burn_scsi_setup_drive(struct burn_drive *d, int bus_no, int host_no,
}
/* ts A61122 */
/* ts A61122 - A80829 */
enum response scsi_error_msg(struct burn_drive *d, unsigned char *sense,
int senselen, char msg[161],
int senselen, char msg_data[161],
int *key, int *asc, int *ascq)
{
char *msg;
msg= msg_data;
*key= *asc= *ascq= -1;
if (senselen<=0 || senselen>2)
@ -879,50 +930,270 @@ enum response scsi_error_msg(struct burn_drive *d, unsigned char *sense,
if (senselen<=0 || senselen>13)
*ascq = sense[13];
sprintf(msg, "[%X %2.2X %2.2X] ", *key, *asc, *ascq);
msg= msg + strlen(msg);
burn_print(12, "CONDITION: 0x%x 0x%x 0x%x on %s %s\n",
*key, *asc, *ascq, d->idata->vendor, d->idata->product);
switch (*asc) {
case 0:
sprintf(msg, "(no error reported by SCSI transaction)");
case 0x00:
sprintf(msg, "(No error reported by SCSI transaction)");
return RETRY;
case 2:
sprintf(msg, "not ready");
case 0x02:
sprintf(msg, "Not ready");
return RETRY;
case 4:
case 0x04:
sprintf(msg,
"logical unit is in the process of becoming ready");
"Logical unit is in the process of becoming ready");
return RETRY;
case 0x08:
if (*key != 4)
break;
if (*ascq == 0)
sprintf(msg, "Logical unit communication failure");
else if (*ascq == 1)
sprintf(msg, "Logical unit communication timeout");
else if (*ascq == 2)
sprintf(msg, "Logical unit communication parity error");
else if (*ascq == 3)
sprintf(msg, "Logical unit communication crc error");
return RETRY;
case 0x09:
if (*key != 4)
break;
if (*ascq == 0)
sprintf(msg, "Track following error");
else if (*ascq == 1)
sprintf(msg, "Tracking servo failure");
else if (*ascq == 2)
sprintf(msg, "Focus servo failure");
else if (*ascq == 3)
sprintf(msg, "Spindle servo failure");
else if (*ascq == 4)
sprintf(msg, "Head select fault");
else
break;
return FAIL;
case 0x0C:
if (*key == 2 && *ascq == 7)
sprintf(msg, "Write error, recovery needed");
else if (*key == 2 && *ascq == 0x0f)
sprintf(msg, "Defects in error window");
else if (*key == 3 && *ascq == 2)
sprintf(msg, "Write error, auto reallocation failed");
else if (*key == 3 && *ascq == 9)
sprintf(msg, "Write error, loss of streaming");
else if (*key == 3)
sprintf(msg, "Write error");
else
break;
return FAIL;
case 0x11:
if (*key != 3)
break;
if (*ascq == 0)
sprintf(msg, "Unrecovered read error");
else if (*ascq == 1)
sprintf(msg, "Read retries exhausted");
else if (*ascq == 2)
sprintf(msg, "Error too long to correct");
else if (*ascq == 5)
sprintf(msg, "L-EC uncorrectable error");
else if (*ascq == 6)
sprintf(msg, "CIRC uncorrectable error");
else
break;
return FAIL;
case 0x15:
if (*key != 3 && *key != 4)
break;
sprintf(msg, "Random positioning error");
return FAIL;
case 0x1a:
if (*key != 5)
break;
sprintf(msg, "Parameter list length error");
return FAIL;
case 0x1b:
if (*key != 4)
break;
sprintf(msg, "Synchronous data transfer error");
return FAIL;
case 0x20:
if (*key == 5)
sprintf(msg, "bad opcode");
if (*key != 5)
break;
sprintf(msg, "Invalid command operation code");
return FAIL;
case 0x21:
sprintf(msg, "invalid address");
if (*key != 5)
break;
if (*ascq == 0)
sprintf(msg, "Lba out of range");
else if (*ascq == 3)
sprintf(msg, "Invalid write crossing layer jump");
else
sprintf(msg, "Invalid address");
return FAIL;
case 0x24:
if (*key == 5)
sprintf(msg, "invalid field in cdb");
else
if (*key != 5)
break;
sprintf(msg, "Invalid field in cdb");
return FAIL;
case 0x26:
if (*key == 5 )
sprintf(msg, "invalid field in parameter list" );
if (*key != 5)
break;
if (*ascq == 1)
sprintf(msg, "Parameter not supported");
else if (*ascq == 2)
sprintf(msg, "Parameter value invalid");
else
sprintf(msg, "Invalid field in parameter list");
return FAIL;
case 0x27:
if (*key != 7)
break;
sprintf(msg, "Write protected");
return FAIL;
case 0x28:
if (*key == 6)
if (*key != 6)
break;
if (*ascq == 0)
sprintf(msg, "Medium may have changed");
else if (*ascq == 2)
sprintf(msg, "Format layer may have changed");
else
break;
return RETRY;
case 0x29:
if (*key != 6)
break;
if (*ascq == 0)
sprintf(msg,
"Power on, reset, or bus device reset occured");
else if (*ascq == 1)
sprintf(msg, "Power on occured");
else if (*ascq == 2)
sprintf(msg, "Bus reset occured");
else if (*ascq == 3)
sprintf(msg, "Bus device reset function occured");
else if (*ascq == 4)
sprintf(msg, "Device internal reset");
else
break;
return RETRY;
case 0x2c:
if (*key != 5)
break;
if (*ascq == 0)
sprintf(msg, "Command sequence error");
else
break;
return FAIL;
case 0x2e:
if (*key != 6)
break;
if (*ascq == 0)
sprintf(msg,
"Insufficient time for operation");
else
break;
return FAIL;
case 0x30:
if (*key != 2 && *key != 5)
break;
if (*ascq == 1)
sprintf(msg, "Cannot read medium, unknown format");
else if (*ascq == 2)
sprintf(msg,
"Cannot read medium, incompatible format");
else if (*ascq == 4)
sprintf(msg, "Cannot write medium, unknown format");
else if (*ascq == 5)
sprintf(msg,
"Cannot write medium, incompatible format");
else if (*ascq == 6)
sprintf(msg,
"Cannot format medium, incompatible medium");
else if (*ascq == 7)
sprintf(msg, "Cleaning failure");
else
sprintf(msg, "Incompatible medium installed");
return FAIL;
case 0x31:
if (*key != 3)
break;
if (*ascq == 0)
sprintf(msg, "Medium unformatted or format corrupted");
else if (*ascq == 1)
sprintf(msg, "Format command failed");
return FAIL;
case 0x3A:
sprintf(msg, "Medium not present");
if (*key != 2)
break;
if (*ascq == 1)
sprintf(msg, "Medium not present, tray closed");
else if (*ascq == 2)
sprintf(msg, "Medium not present, tray open");
else if (*ascq == 3)
sprintf(msg, "Medium not present, loadable");
else
sprintf(msg, "Medium not present");
d->status = BURN_DISC_EMPTY;
return FAIL;
case 0x63:
if (*key != 5)
break;
if (*ascq == 0)
sprintf(msg,
"End of user area encountered on this track");
else if (*ascq == 1)
sprintf(msg, "Packet does not fit in available space");
else
break;
return FAIL;
case 0x64:
if (*key != 5)
break;
if (*ascq == 0)
sprintf(msg, "Illegal mode for this track");
else if (*ascq == 1)
sprintf(msg, "Invalid packet size");
else
break;
return FAIL;
case 0x72:
if (*key == 3)
sprintf(msg, "Session fixation error");
else if (*key == 5 && *ascq == 3)
sprintf(msg,
"Session fixation error, incomplete track in session");
else if (*key == 5 && *ascq == 4)
sprintf(msg,
"Empty or partially written reserved track");
else if (*key == 5 && *ascq == 5)
sprintf(msg,
"No more track reservations allowed");
else
break;
return FAIL;
case 0x73:
if (*key == 3 && *ascq == 0)
sprintf(msg, "CD control error");
else if (*key == 3 && *ascq == 2)
sprintf(msg, "Power calibration area is full");
else if (*key == 3 && *ascq == 3)
sprintf(msg, "Power calibration area error");
else if (*key == 3 && *ascq == 4)
sprintf(msg, "Program memory area update failure");
else if (*key == 3 && *ascq == 5)
sprintf(msg, "Program memory area is full");
else
break;
return FAIL;
}
sprintf(msg,
sprintf(msg_data,
"Failure. See mmc3r10g.pdf: Sense Key %X ASC %2.2X ASCQ %2.2X",
*key, *asc, *ascq);
return FAIL;
@ -947,6 +1218,68 @@ enum response scsi_error(struct burn_drive *d, unsigned char *sense,
}
static char *scsi_command_name(unsigned int c, int flag)
{
switch (c) {
case 0x00:
return "TEST UNIT READY";
case 0x03:
return "REQUEST SENSE";
case 0x04:
return "FORMAT UNIT";
case 0x1b:
return "START/STOP UNIT";
case 0x1e:
return "PREVENT/ALLOW MEDIA REMOVAL";
case 0x23:
return "READ FORMAT CAPACITIES";
case 0x28:
return "READ(10)";
case 0x2a:
return "WRITE(10)";
case 0x35:
return "SYNCHRONIZE CACHE";
case 0x43:
return "READ TOC/PMA/ATIP";
case 0x46:
return "GET CONFIGURATION";
case 0x4a:
return "GET EVENT STATUS NOTIFICATION";
case 0x51:
return "READ DISC INFORMATION";
case 0x52:
return "READ TRACK INFORMATION";
case 0x53:
return "RESERVE TRACK";
case 0x54:
return "SEND OPC INFORMATION";
case 0x55:
return "MODE SELECT";
case 0x5a:
return "SEND OPC INFORMATION";
case 0x5b:
return "CLOSE TRACK/SESSION";
case 0x5c:
return "READ BUFFER CAPACITY";
case 0x5d:
return "SEND CUE SHEET";
case 0xa1:
return "BLANK";
case 0xaa:
return "WRITE(12)";
case 0xac:
return "GET PERFORMANCE";
case 0xb6:
return "SET STREAMING";
case 0xbb:
return "SET CD SPEED";
case 0xbe:
return "READ CD";
}
return "(NOT IN COMMAND LIST)";
}
/* ts A61030 - A61115 */
/* @param flag bit0=do report conditions which are considered not an error */
int scsi_notify_error(struct burn_drive *d, struct command *c,
@ -958,12 +1291,9 @@ int scsi_notify_error(struct burn_drive *d, struct command *c,
if (d->silent_on_scsi_error)
return 1;
strcpy(scsi_msg, " \"");
scsi_error_msg(d, sense, senselen, scsi_msg + strlen(scsi_msg),
&key, &asc, &ascq);
strcat(scsi_msg, "\"");
scsi_error_msg(d, sense, senselen, scsi_msg, &key, &asc, &ascq);
if(!(flag & 1)) {
if (!(flag & 1)) {
/* SPC : TEST UNIT READY command */
if (c->opcode[0] == 0)
return 1;
@ -974,7 +1304,11 @@ int scsi_notify_error(struct burn_drive *d, struct command *c,
return 1;
}
sprintf(msg,"SCSI error condition on command %2.2Xh :", c->opcode[0]);
sprintf(msg, "SCSI error condition on command %2.2Xh %s: ",
c->opcode[0],
scsi_command_name((unsigned int) c->opcode[0], 0));
#ifdef NIX
if (key>=0)
sprintf(msg+strlen(msg), " key=%Xh", key);
if (asc>=0)
@ -988,6 +1322,13 @@ int scsi_notify_error(struct burn_drive *d, struct command *c,
ret = libdax_msgs_submit(libdax_messenger, d->global_index, 0x0002010f,
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH,
scsi_msg,0,0);
#else
strcat(msg, scsi_msg);
ret = libdax_msgs_submit(libdax_messenger, d->global_index, 0x0002010f,
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH, msg,0,0);
#endif /* NIX */
return ret;
}

View File

@ -104,6 +104,30 @@ int burn_disc_add_session(struct burn_disc *d, struct burn_session *s,
return 1;
}
/* ts A81202: this function was in the API but not implemented.
*/
int burn_disc_remove_session(struct burn_disc *d, struct burn_session *s)
{
int i, skip = 0;
if (d->session == NULL)
return 0;
for (i = 0; i < d->sessions; i++) {
if (s == d->session[i]) {
skip++;
continue;
}
d->session[i - skip] = d->session[i];
}
if (!skip)
return 0;
burn_session_free(s);
d->sessions--;
return 1;
}
struct burn_track *burn_track_create(void)
{
struct burn_track *t;
@ -330,11 +354,19 @@ void burn_track_clear_isrc(struct burn_track *t)
int burn_track_get_sectors(struct burn_track *t)
{
/* ts A70125 : was int */
off_t size;
off_t size = 0;
int sectors, seclen;
seclen = burn_sector_length(t->mode);
size = t->offset + t->source->get_size(t->source) + t->tail;
if (t->source != NULL) /* ts A80808 : mending sigsegv */
size = t->offset + t->source->get_size(t->source) + t->tail;
else if(t->entry != NULL) {
/* ts A80808 : all burn_toc_entry of track starts should now
have (extensions_valid & 1), even those from CD.
*/
if (t->entry->extensions_valid & 1)
size = ((off_t) t->entry->track_blocks) * (off_t) 2048;
}
sectors = size / seclen;
if (size % seclen)
sectors++;
@ -468,6 +500,7 @@ int burn_session_get_sectors(struct burn_session *s)
return sectors;
}
int burn_disc_get_sectors(struct burn_disc *d)
{
int sectors = 0, i;
@ -515,3 +548,84 @@ int burn_session_get_hidefirst(struct burn_session *session)
{
return session->hidefirst;
}
/* ts A80808 : Enhance CD toc to DVD toc */
int burn_disc_cd_toc_extensions(struct burn_disc *d, int flag)
{
int sidx= 0, tidx= 0;
struct burn_toc_entry *entry, *prev_entry= NULL;
/* ts A81126 : ticket 146 : There was a SIGSEGV in here */
char msg_data[321], *msg;
strcpy(msg_data,
"Damaged CD table-of-content detected and truncated.");
strcat(msg_data, " In burn_disc_cd_toc_extensions: ");
msg = msg_data + strlen(msg_data);
if (d->session == NULL) {
strcpy(msg, "d->session == NULL");
goto failure;
}
for (sidx = 0; sidx < d->sessions; sidx++) {
if (d->session[sidx] == NULL) {
sprintf(msg, "d->session[%d of %d] == NULL",
sidx, d->sessions);
goto failure;
}
if (d->session[sidx]->track == NULL) {
sprintf(msg, "d->session[%d of %d]->track == NULL",
sidx, d->sessions);
goto failure;
}
if (d->session[sidx]->leadout_entry == NULL) {
sprintf(msg,
" Session %d of %d: Leadout entry missing.",
sidx, d->sessions);
goto failure;
}
for (tidx = 0; tidx < d->session[sidx]->tracks + 1; tidx++) {
if (tidx < d->session[sidx]->tracks) {
if (d->session[sidx]->track[tidx] == NULL) {
sprintf(msg,
"d->session[%d of %d]->track[%d of %d] == NULL",
sidx, d->sessions, tidx, d->session[sidx]->tracks);
goto failure;
}
entry = d->session[sidx]->track[tidx]->entry;
if (entry == NULL) {
sprintf(msg,
"session %d of %d, track %d of %d, entry == NULL",
sidx, d->sessions, tidx,
d->session[sidx]->tracks);
goto failure;
}
} else
entry = d->session[sidx]->leadout_entry;
entry->session_msb = 0;
entry->point_msb = 0;
entry->start_lba = burn_msf_to_lba(entry->pmin,
entry->psec, entry->pframe);
if (tidx > 0) {
prev_entry->track_blocks =
entry->start_lba
- prev_entry->start_lba;
prev_entry->extensions_valid |= 1;
}
if (tidx == d->session[sidx]->tracks) {
entry->session_msb = 0;
entry->point_msb = 0;
entry->track_blocks = 0;
entry->extensions_valid |= 1;
}
prev_entry = entry;
}
}
return 1;
failure:
libdax_msgs_submit(libdax_messenger, -1, 0x0002015f,
LIBDAX_MSGS_SEV_MISHAP, LIBDAX_MSGS_PRIO_HIGH, msg_data, 0, 0);
d->sessions= sidx;
return 0;
}

View File

@ -109,4 +109,8 @@ int burn_track_apply_fillup(struct burn_track *t, off_t max_size, int flag);
off_t burn_track_get_default_size(struct burn_track *t);
/* ts A80808 : Enhance CD toc to DVD toc */
int burn_disc_cd_toc_extensions(struct burn_disc *d, int flag);
#endif /* BURN__STRUCTURE_H */

View File

@ -161,6 +161,11 @@ struct burn_drive
char current_profile_text[80];
int current_is_cd_profile;
int current_is_supported_profile;
/* ts A90603 */
int current_is_guessed_profile;
/* ts A90815 */
unsigned char all_profiles[256];
int num_profiles;
/* ts A70128 : MMC-to-MMC feature info from 46h for DVD-RW.
Quite internal. Regard as opaque :)
@ -171,6 +176,19 @@ struct burn_drive
/* Link Size item number 0 from feature 0021h descriptor */
int current_feat21h_link_size;
/* Flags from feature 0023h for formatting BD mmc5r03c.pdf 5.3.13
Byte 4 BD-RE:
bit0= Cert format 30h sub-type 10b
bit1= QCert format 30h sub-type 11b
bit2= Expand format 01h
bit3= RENoSA format 31h
Byte 8 BD-R:
bit0= RRM format 32h sub-type 10b
*/
int current_feat23h_byte4;
int current_feat23h_byte8;
/* Flags from feature 002Fh feature descriptor mmc5r03c.pdf 5.3.25 :
bit1= DVD-RW supported
bit2= Test Write available
@ -187,6 +205,16 @@ struct burn_drive
synchronize chache has happened yet */
int needs_sync_cache;
/* ts A80412 : whether to use WRITE12 with Streaming bit set
rather than WRITE10. Speeds up DVD-RAM. Might help
with BD-RE */
int do_stream_recording;
/* ts A90227 : the LBA where stream recording shall start.
Writing to lower LBA will be done without streaming.
*/
int stream_recording_start;
/* ts A61218 from 51h READ DISC INFORMATION */
int bg_format_status; /* 0=needs format start, 1=needs format restart*/
@ -218,6 +246,9 @@ struct burn_drive
/* ts A70131 : from 51h READ DISC INFORMATION Number of Sessions (-1)*/
int complete_sessions;
/* ts A90107 */
int state_of_last_session;
/* ts A70129 :
from 51h READ DISC INFORMATION Last Track Number in Last Session */
int last_track_no;
@ -230,6 +261,9 @@ struct burn_drive
/* ts A70215 : if > 0 : first lba on media that is too high for write*/
int media_lba_limit;
/* ts A81210 : Upper limit of readable data size,
0x7fffffff = unknown */
int media_read_capacity;
int toc_temp;
struct burn_disc *disc; /* disc structure */
@ -283,6 +317,11 @@ struct burn_drive
void (*eject) (struct burn_drive *);
void (*load) (struct burn_drive *);
int (*start_unit) (struct burn_drive *);
/* ts A90824 : Calming down noisy drives */
int (*stop_unit) (struct burn_drive *);
int is_stopped;
void (*read_disc_info) (struct burn_drive *);
void (*read_sectors) (struct burn_drive *,
int start,
@ -348,4 +387,9 @@ struct burn_drive
/* end of generic 'drive' data structures */
/* ts A80422 : centralizing this setting for debugging purposes
*/
int burn_drive_set_media_capacity_remaining(struct burn_drive *d, off_t value);
#endif /* __TRANSPORT */

View File

@ -4,7 +4,11 @@
/* #include <a ssert.h> */
#include <stdlib.h>
#include "../version.h"
/* ts A80914 : This is unneeded. Version info comes from libburn.h.
#include "v ersion.h"
*/
#include "util.h"
#include "libburn.h"
@ -47,7 +51,8 @@ char *burn_strndup(char *s, int n)
void burn_version(int *major, int *minor, int *micro)
{
*major = BURN_MAJOR_VERSION;
*minor = BURN_MINOR_VERSION;
*micro = BURN_MICRO_VERSION;
/* ts A80408 : switched from configure.ac versioning to libburn.h versioning */
*major = burn_header_version_major;
*minor = burn_header_version_minor;
*micro = burn_header_version_micro;
}

View File

@ -43,11 +43,30 @@
#include "write.h"
#include "options.h"
#include "structure.h"
#include "source.h"
#include "libdax_msgs.h"
extern struct libdax_msgs *libdax_messenger;
/* The maximum output size to be used with CD media. This is also curbed
by BURN_OS_TRANSPORT_BUFFER_SIZE. The smaller number gets into effect.
*/
#define Libburn_cd_obS (32 * 1024)
/* The size to be used with DVD media.
*/
#define Libburn_dvd_obS (32 * 1024)
/* The size to be used with BD-RE media in normal, not streamed mode.
*/
#define Libburn_bd_re_obS (32 * 1024)
/* The size to be used with BD-RE media in streamed mode.
*/
#define Libburn_bd_re_streamed_obS (64 * 1024)
static int type_to_ctrl(int mode)
{
int ctrl = 0;
@ -836,6 +855,8 @@ int burn_write_track(struct burn_write_opts *o, struct burn_session *s,
/* ts A61103 */
ret = 1;
ex:;
if (d->cancel)
burn_source_cancel(t->source);
if (o->write_type == BURN_WRITE_TAO) {
/* ts A71002 */
@ -964,8 +985,9 @@ int burn_precheck_write(struct burn_write_opts *o, struct burn_disc *disc,
if (d->status == BURN_DISC_UNSUITABLE)
goto unsuitable_profile;
if (d->drive_role == 2 ||
d->current_profile == 0x1a || d->current_profile == 0x12) {
/* DVD+RW , DVD-RAM , emulated drive on stdio file */
d->current_profile == 0x1a || d->current_profile == 0x12 ||
d->current_profile == 0x43) {
/* DVD+RW , DVD-RAM , BD-RE, emulated drive on stdio file */
if (o->start_byte >= 0 && (o->start_byte % 2048))
strcat(reasons,
"write start address not properly aligned to 2048, ");
@ -983,8 +1005,10 @@ int burn_precheck_write(struct burn_write_opts *o, struct burn_disc *disc,
} else if (d->drive_role == 3 ||
d->current_profile == 0x11 || d->current_profile == 0x14 ||
d->current_profile == 0x15 ||
d->current_profile == 0x1b || d->current_profile == 0x2b ) {
/* DVD-R* Sequential , DVD+R[/DL] , sequential stdio "drive" */
d->current_profile == 0x1b || d->current_profile == 0x2b ||
d->current_profile == 0x41) {
/* DVD-R* Sequential , DVD+R[/DL] , BD-R,
sequential stdio "drive" */
if (o->start_byte >= 0)
strcat(reasons, "write start address not supported, ");
} else {
@ -1084,6 +1108,10 @@ int burn_disc_open_track_dvd_plus_r(struct burn_write_opts *o,
if (o->write_type == BURN_WRITE_SAO &&
! burn_track_is_open_ended(s->track[tnum])) {
/* Round track size up to 32 KiB and reserve track */
/* ts A81208 */
/* >>> ??? round to 64 KiB for BD-R ? (It is not mandatory) */
size = ((off_t) burn_track_get_sectors(s->track[tnum]))
* (off_t) 2048;
size = (size + (off_t) 0x7fff) & ~((off_t) 0x7fff);
@ -1131,19 +1159,29 @@ int burn_disc_close_track_dvd_minus_r(struct burn_write_opts *o,
int burn_disc_finalize_dvd_plus_r(struct burn_write_opts *o)
{
struct burn_drive *d = o->drive;
char msg[80];
sprintf(msg, "Finalizing %s ...",
d->current_profile_text);
libdax_msgs_submit(libdax_messenger, d->global_index,
0x00000002,
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_ZERO,
"Finalizing DVD+R ...", 0, 0);
msg, 0, 0);
/* CLOSE SESSION, 101b, Finalize with minimal radius */
d->close_track_session(d, 2, 1); /* (2<<1)|1 = 5 */
if(d->current_profile == 0x41) { /* BD-R */
/* CLOSE SESSION, 110b, Finalize Disc */
d->close_track_session(d, 3, 0); /* (3<<1)|0 = 6 */
} else {
/* CLOSE SESSION, 101b, Finalize with minimal radius */
d->close_track_session(d, 2, 1); /* (2<<1)|1 = 5 */
}
sprintf(msg, "... finalizing %s done ",
d->current_profile_text);
libdax_msgs_submit(libdax_messenger, d->global_index,
0x00000002,
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_ZERO,
"... finalizing DVD+R done ", 0, 0);
msg, 0, 0);
return 1;
}
@ -1178,7 +1216,7 @@ int burn_disc_close_track_dvd_plus_r(struct burn_write_opts *o,
}
/* ts A61218 - A70129 */
/* ts A61218 - A81208 */
int burn_dvd_write_track(struct burn_write_opts *o,
struct burn_session *s, int tnum, int is_last_track)
{
@ -1202,6 +1240,11 @@ int burn_dvd_write_track(struct burn_write_opts *o,
ret = burn_disc_open_track_dvd_plus_r(o, s, tnum);
if (ret <= 0)
goto ex;
} else if (d->current_profile == 0x41) {
/* BD-R SRM */
ret = burn_disc_open_track_dvd_plus_r(o, s, tnum);
if (ret <= 0)
goto ex;
}
sectors = burn_track_get_sectors(t);
@ -1270,9 +1313,17 @@ int burn_dvd_write_track(struct burn_write_opts *o,
is_last_track);
if (ret <= 0)
goto ex;
} else if (d->current_profile == 0x41) {
/* BD-R SRM */
ret = burn_disc_close_track_dvd_plus_r(o, s, tnum,
is_last_track);
if (ret <= 0)
goto ex;
}
ret = 1;
ex:;
if (d->cancel)
burn_source_cancel(t->source);
if (!is_flushed)
d->sync_cache(d); /* burn_write_flush() was not called */
return ret;
@ -1348,10 +1399,70 @@ int burn_disc_close_session_dvd_minus_r(struct burn_write_opts *o,
int burn_dvd_write_session(struct burn_write_opts *o,
struct burn_session *s, int is_last_session)
{
int i,ret;
int i, ret, multi_mem;
struct burn_drive *d = o->drive;
/* >>> open_session ? */
/* ts A90108 */
if (d->current_profile == 0x41 && d->status == BURN_DISC_APPENDABLE &&
d->state_of_last_session == 1) {
/* last session on BD-R is still open */;
/* BR-R were not closed by libburn-0.6.0.pl00 if o->multi==0.
This leads to an unreadable, but recoverable) media state.
Technically they are appendable although the last session
is not readable.
By default the open session gets closed here before the new
session is written. E.g. after writing a small dummy seesion
number 2 one can read session 1 and write session 3 which
points to data of session 1.
For the case that no media with 3 sessions is desired it is
possible to activate the following coarse single-session
closing code:
No new session will be written but calling programs will
report success. Quite misleading.
Activate only if really needed by
# define Libburn_bug_A90108_close_disC yes
*/
#ifdef Libburn_bug_A90108_close_disC
/* Close open session and media.
That was the goal of the failed run which led to the
unreadable (but recoverable) media state.
It is not easy to implement a general close function for
all media types. Therefore this pseudo write code is under
control of #ifdef.
*/
libdax_msgs_submit(libdax_messenger, d->global_index,
0x00020171,
LIBDAX_MSGS_SEV_NOTE, LIBDAX_MSGS_PRIO_HIGH,
"Closing BD-R with accidently open session",
0, 0);
d->close_track_session(d, 3, 0); /* CLOSE SESSION, 110b */
d->state_of_last_session = 3; /* mark as complete session */
d->status = BURN_DISC_FULL;
sleep(3); /* The caller might need time to arrange itself */
return 1;
#else /* Libburn_bug_A90108_close_disC */
/* This is the default mode.
*/
libdax_msgs_submit(libdax_messenger, d->global_index,
0x00020170,
LIBDAX_MSGS_SEV_NOTE, LIBDAX_MSGS_PRIO_HIGH,
"Closing open session before writing new one",
0, 0);
d->close_track_session(d, 1, 0); /* CLOSE SESSION, 010b */
d->state_of_last_session = 3; /* mark as complete session */
#endif /* ! Libburn_bug_A90108_close_disC */
}
for (i = 0; i < s->tracks; i++) {
ret = burn_dvd_write_track(o, s, i,
@ -1362,11 +1473,15 @@ int burn_dvd_write_session(struct burn_write_opts *o,
if (d->current_profile == 0x11 || d->current_profile == 0x14 ||
d->current_profile == 0x15) {
/* DVD-R , DVD-RW Sequential, DVD-R/DL Sequential */
multi_mem = o->multi;
if (!is_last_session)
o->multi = 1;
ret = burn_disc_close_session_dvd_minus_r(o, s);
o->multi = multi_mem;
if (ret <= 0)
return 0;
} else if (d->current_profile == 0x12) {
/* DVD-RAM */
} else if (d->current_profile == 0x12 || d->current_profile == 0x43) {
/* DVD-RAM , BD-RE */
/* ??? any finalization needed ? */;
} else if (d->current_profile == 0x13) {
/* DVD-RW restricted overwrite */
@ -1384,6 +1499,8 @@ int burn_dvd_write_session(struct burn_write_opts *o,
}
} else if (d->current_profile == 0x1b || d->current_profile == 0x2b) {
/* DVD+R , DVD+R/DL do each track as an own session */;
} else if (d->current_profile == 0x41) {
/* BD-R SRM do each track as an own session */;
}
return 1;
}
@ -1395,7 +1512,6 @@ int burn_disc_setup_dvd_plus_rw(struct burn_write_opts *o,
{
struct burn_drive *d = o->drive;
int ret;
char msg[160];
if (d->bg_format_status==0 || d->bg_format_status==1) {
d->busy = BURN_DRIVE_FORMATTING;
@ -1406,16 +1522,6 @@ int burn_disc_setup_dvd_plus_rw(struct burn_write_opts *o,
d->busy = BURN_DRIVE_WRITING;
d->needs_close_session = 1;
}
d->nwa = 0;
if (o->start_byte >= 0) {
d->nwa = o->start_byte / 2048;
sprintf(msg, "Write start address is %d * 2048", d->nwa);
libdax_msgs_submit(libdax_messenger, d->global_index,
0x00020127,
LIBDAX_MSGS_SEV_NOTE, LIBDAX_MSGS_PRIO_HIGH,
msg, 0, 0);
}
/* >>> perform OPC if needed */;
@ -1505,7 +1611,7 @@ int burn_disc_setup_dvd_plus_r(struct burn_write_opts *o,
}
/* ts A61218 - A70129 */
/* ts A61218 - A70415 */
int burn_dvd_write_sync(struct burn_write_opts *o,
struct burn_disc *disc)
{
@ -1517,8 +1623,12 @@ int burn_dvd_write_sync(struct burn_write_opts *o,
d->needs_close_session = 0;
if (d->current_profile == 0x1a || d->current_profile == 0x12) {
/* DVD+RW , DVD-RAM */
/* buffer flush trigger for sector.c:get_sector() */
o->obs = Libburn_dvd_obS;
if (d->current_profile == 0x1a || d->current_profile == 0x12 ||
d->current_profile == 0x43) {
/* DVD+RW , DVD-RAM , BD-RE */
ret = 1;
if (d->current_profile == 0x1a)
ret = burn_disc_setup_dvd_plus_rw(o, disc);
@ -1531,7 +1641,24 @@ int burn_dvd_write_sync(struct burn_write_opts *o,
msg, 0, 0);
goto early_failure;
}
d->nwa = 0;
if (o->start_byte >= 0) {
d->nwa = o->start_byte / 2048;
sprintf(msg, "Write start address is %d * 2048",
d->nwa);
libdax_msgs_submit(libdax_messenger, d->global_index,
0x00020127,
LIBDAX_MSGS_SEV_NOTE, LIBDAX_MSGS_PRIO_HIGH,
msg, 0, 0);
}
o->obs_pad = 0; /* no filling-up of track's last 32k buffer */
if (d->current_profile == 0x43) /* BD-RE */
o->obs = Libburn_bd_re_obS;
if (d->do_stream_recording) {
o->obs_pad = 1;
if (d->current_profile == 0x43) /* BD-RE */
o->obs = Libburn_bd_re_streamed_obS;
}
} else if (d->current_profile == 0x13) {
/* DVD-RW Restricted Overwrite */
@ -1577,8 +1704,12 @@ int burn_dvd_write_sync(struct burn_write_opts *o,
/* ??? padding needed ??? cowardly doing it for now */
o->obs_pad = 1; /* fill-up track's last 32k buffer */
} else if (d->current_profile == 0x1b || d->current_profile == 0x2b) {
/* DVD+R , DVD+R/DL */
} else if (d->current_profile == 0x1b || d->current_profile == 0x2b ||
d->current_profile == 0x41) {
/* DVD+R , DVD+R/DL , BD-R SRM */
/* >>> ts A81208 : with BD-R set o->obs to 64 kB ? */
t = disc->session[0]->track[0];
o_end = ( burn_track_is_open_ended(t) && !o->fill_up_media );
default_size = burn_track_get_default_size(t);
@ -1593,8 +1724,8 @@ int burn_dvd_write_sync(struct burn_write_opts *o,
}
ret = burn_disc_setup_dvd_plus_r(o, disc);
if (ret <= 0) {
sprintf(msg,
"Write preparation setup failed for DVD+R");
sprintf(msg, "Write preparation setup failed for %s",
d->current_profile == 0x41 ? "BD-R" : "DVD+R");
libdax_msgs_submit(libdax_messenger, d->global_index,
0x00020121,
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
@ -1604,7 +1735,19 @@ int burn_dvd_write_sync(struct burn_write_opts *o,
/* ??? padding needed ??? cowardly doing it for now */
o->obs_pad = 1; /* fill-up track's last 32k buffer */
}
o->obs = 32*1024; /* buffer flush trigger for sector.c:get_sector() */
/* <<< test only : Does this increase effective speed with USB ?
ts A90801 : 64kB: speed with 16x DVD-R is 12 rather than 8
>>> next try is 128 kB
o->obs = 128 * 1024;
*/
sprintf(msg, "dvd/bd Profile= %2.2Xh , obs= %d , obs_pad= %d",
d->current_profile, o->obs, o->obs_pad);
libdax_msgs_submit(libdax_messenger, d->global_index, 0x00000002,
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_ZERO, msg, 0, 0);
for (i = 0; i < disc->sessions; i++) {
/* update progress */
@ -1693,7 +1836,11 @@ int burn_stdio_read_source(struct burn_source *source, char *buf, int bufsize,
int count= 0, todo;
for(todo = bufsize; todo > 0; todo -= count) {
count = source->read(source,
if(source->read!=NULL)
count = source->read(source,
(unsigned char *) (buf + (bufsize - todo)), todo);
else
count = source->read_xt(source,
(unsigned char *) (buf + (bufsize - todo)), todo);
if (count <= 0)
break;
@ -1706,6 +1853,13 @@ int burn_stdio_read_source(struct burn_source *source, char *buf, int bufsize,
int burn_stdio_write(int fd, char *buf, int count, struct burn_drive *d,
int flag)
{
if (d->cancel)
return 0;
/*
fprintf(stderr, "libburn_DEBUG: write(%d, %lX, %d)\n",
fd, (unsigned long) buf, count);
*/
if (write(fd, buf, count) != count) {
libdax_msgs_submit(libdax_messenger, d->global_index,
0x00020148,
@ -1718,16 +1872,6 @@ int burn_stdio_write(int fd, char *buf, int count, struct burn_drive *d,
}
/* ts A70911
If defined this makes stdio run on top of sector_data() rather than
own stdio read and write functions. The MMC function pointers d->write()
and d->sync_cache() get replaced by stdio substitutes.
*/
#define Libburn_stdio_track_by_sector_datA 1
#ifdef Libburn_stdio_track_by_sector_datA
/* ts A70910 : to be used as burn_drive.write(), emulating mmc_write() */
int burn_stdio_mmc_write(struct burn_drive *d, int start, struct buffer *buf)
{
@ -1849,9 +1993,6 @@ int burn_stdio_slowdown(struct burn_drive *d, struct timeval *prev_time,
}
#endif /* Libburn_stdio_track_by_sector_datA */
/* ts A70904 */
int burn_stdio_write_track(struct burn_write_opts *o, struct burn_session *s,
int tnum, int flag)
@ -1860,14 +2001,9 @@ int burn_stdio_write_track(struct burn_write_opts *o, struct burn_session *s,
struct burn_track *t = s->track[tnum];
struct burn_drive *d = o->drive;
char buf[16*2048];
#ifdef Libburn_stdio_track_by_sector_datA
int i, prev_sync_sector = 0;
struct buffer *out = d->buffer;
struct timeval prev_time;
#else
int eof_seen = 0;
off_t t_size, w_count;
#endif
bufsize = sizeof(buf);
fd = d->stdio_fd;
@ -1876,8 +2012,6 @@ int burn_stdio_write_track(struct burn_write_opts *o, struct burn_session *s,
burn_disc_init_track_status(o, s, tnum, sectors);
open_ended = burn_track_is_open_ended(t);
#ifdef Libburn_stdio_track_by_sector_datA
/* attach stdio emulators for mmc_*() functions */
if (o->simulate)
d->write = burn_stdio_mmc_dummy_write;
@ -1889,7 +2023,7 @@ int burn_stdio_write_track(struct burn_write_opts *o, struct burn_session *s,
for (i = 0; open_ended || i < sectors; i++) {
/* transact a (CD sized) sector */
if (!sector_data(o, t, 0))
return 0;
{ret= 0; goto ex;}
if (open_ended) {
d->progress.sectors = sectors = d->progress.sector;
if (burn_track_is_data_done(t))
@ -1912,60 +2046,11 @@ int burn_stdio_write_track(struct burn_write_opts *o, struct burn_session *s,
out->bytes = o->obs;
}
ret = burn_write_flush(o, t);
#else /* Libburn_stdio_track_by_sector_datA */
t_size = t->source->get_size(t->source);
/* >>> write t->offset zeros */;
for(w_count = 0; w_count < t_size || open_ended; w_count += ret) {
if (t_size - w_count < bufsize && ! open_ended)
/* >>> what about final sector padding ? */
bufsize = t_size - w_count;
if (eof_seen)
ret = 0;
else
ret = burn_stdio_read_source(t->source, buf,
bufsize, o, 0);
if (ret < 0)
return ret;
if (ret == 0 && open_ended)
break;
if (ret < bufsize && !open_ended) {
memset(buf + ret, 0, bufsize - ret);
eof_seen = 1;
ret = bufsize;
}
t->sourcecount += ret;
if (!o->simulate)
ret = burn_stdio_write(fd, buf, ret, d, 0);
if (ret <= 0)
return ret;
d->progress.sector = (w_count + (off_t) ret) / (off_t) 2048;
if (open_ended)
d->progress.sectors = d->progress.sector;
t->writecount += ret;
t->written_sectors = t->writecount / 2048;
/* Flush to physical device after each full MB */
if (d->progress.sector - prev_sync_sector >= 512) {
prev_sync_sector = d->progress.sector;
if (!o->simulate)
burn_stdio_sync_cache(fd, d, 1);
}
}
/* >>> write t->tail zeros */;
#endif
return 1;
ret= 1;
ex:;
if (d->cancel)
burn_source_cancel(t->source);
return ret;
}
@ -2023,9 +2108,9 @@ void burn_disc_write_sync(struct burn_write_opts *o, struct burn_disc *disc)
{
struct cue_sheet *sheet;
struct burn_drive *d = o->drive;
struct buffer buf;
struct buffer *buffer_mem = o->drive->buffer;
struct burn_track *lt, *t;
int first = 1, i, ret, lba, nwa = 0;
int first = 1, i, ret, lba, nwa = 0, multi_mem;
off_t default_size;
char msg[80];
@ -2036,8 +2121,40 @@ void burn_disc_write_sync(struct burn_write_opts *o, struct burn_disc *disc)
/* ts A61224 */
burn_disc_init_write_status(o, disc); /* must be done very early */
d->buffer = &buf;
/* ts A80412 , A90227 */
d->do_stream_recording = !!o->do_stream_recording;
if (o->do_stream_recording >= 16)
d->stream_recording_start = o->do_stream_recording;
else
d->stream_recording_start = 0;
d->buffer = calloc(sizeof(struct buffer), 1);
if (d->buffer == NULL)
goto fail_wo_sync;
/* >>> ts A90321
memset(d->buffer, 0, sizeof(struct buffer));
fprintf(stderr, "libburn_DEBUG: d->buffer = %lX , size = %d\n",
(unsigned long) d->buffer, (int) sizeof(struct buffer));
calloc() seems not to have the desired effect. valgrind warns:
==18251== Syscall param write(buf) points to uninitialised byte(s)
==18251== at 0x5071DEB: (within /lib64/libpthread-2.5.so)
==18251== by 0x4723FA: burn_stdio_write (write.c:1850)
==18251== by 0x4725DC: burn_stdio_mmc_write (write.c:1894)
==18251== by 0x483B7A: get_sector (sector.c:229)
==18251== by 0x484F11: sector_data (sector.c:639)
==18251== by 0x4729FE: burn_stdio_write_track (write.c:2012)
==18251== by 0x472CF4: burn_stdio_write_sync (write.c:2072)
==18251== by 0x472E8D: burn_disc_write_sync (write.c:2125) <<< we are here
==18251== by 0x460254: write_disc_worker_func (async.c:514)
==18251== by 0x506B09D: start_thread (in /lib64/libpthread-2.5.so)
==18251== by 0x55484CC: clone (in /lib64/libc-2.5.so)
*/
d->rlba = -150;
d->toc_temp = 9;
@ -2046,16 +2163,26 @@ void burn_disc_write_sync(struct burn_write_opts *o, struct burn_disc *disc)
ret = burn_stdio_write_sync(o, disc);
if (ret <= 0)
goto fail_wo_sync;
return;
goto ex;
}
/* ts A61218 */
if (! d->current_is_cd_profile) {
ret = burn_dvd_write_sync(o, disc);
if (ret <= 0)
goto fail_wo_sync;
return;
goto ex;
}
/* ts A70521 : Linux 2.4 USB audio fails with 64 kiB */
/* ts A80414 : might need 64 kiB for BD-RE streaming */
/* buffer flush trigger for sector.c:get_sector() */
o->obs = Libburn_cd_obS;
sprintf(msg, "cd Profile= %2.2Xh , obs= %d , obs_pad= %d",
d->current_profile, o->obs, o->obs_pad);
libdax_msgs_submit(libdax_messenger, d->global_index, 0x00000002,
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_ZERO, msg, 0, 0);
/* ts A70218 */
if (o->write_type == BURN_WRITE_SAO) {
for (i = 0 ; i < disc->session[0]->tracks; i++) {
@ -2162,7 +2289,12 @@ return crap. so we send the command, then ignore the result.
d->alba += 4500;
}
}
if (!burn_write_session(o, disc->session[i]))
multi_mem = o->multi;
if(i < disc->sessions - 1)
o->multi = 1;
ret = burn_write_session(o, disc->session[i]);
o->multi = multi_mem;
if (!ret)
goto fail;
lt = disc->session[i]->track[disc->session[i]->tracks - 1];
@ -2206,7 +2338,7 @@ return crap. so we send the command, then ignore the result.
/* ts A61012 : This return was traditionally missing. I suspect this
to have caused Cdrskin_eject() failures */
return;
goto ex;
fail:
d->sync_cache(d);
@ -2218,6 +2350,12 @@ fail_wo_sync:;
"Burn run failed", 0, 0);
d->cancel = 1;
d->busy = BURN_DRIVE_IDLE;
ex:;
d->do_stream_recording = 0;
if (d->buffer != NULL)
free((char *) d->buffer);
d->buffer = buffer_mem;
return;
}
/* ts A70811 : API function */
@ -2226,7 +2364,7 @@ int burn_random_access_write(struct burn_drive *d, off_t byte_address,
{
int alignment = 0, start, upto, chunksize, err, fd = -1, ret;
char msg[81], *rpt;
struct buffer buf;
struct buffer buf, *buffer_mem = d->buffer;
if (d->released) {
libdax_msgs_submit(libdax_messenger,
@ -2251,6 +2389,8 @@ int burn_random_access_write(struct burn_drive *d, off_t byte_address,
alignment = 32 * 1024;
if (d->current_profile == 0x1a) /* DVD+RW */
alignment = 2 * 1024;
if (d->current_profile == 0x43) /* BD-RE */
alignment = 2 * 1024;
if (alignment == 0) {
sprintf(msg, "Write start address not supported");
libdax_msgs_submit(libdax_messenger, d->global_index,
@ -2335,7 +2475,7 @@ int burn_random_access_write(struct burn_drive *d, off_t byte_address,
if(fd >= 0)
close(fd);
d->buffer = NULL;
d->buffer = buffer_mem;
d->busy = BURN_DRIVE_IDLE;
return 1;
}

View File

@ -1,6 +1,6 @@
/* test/libburner.c , API illustration of burning data or audio tracks to CD */
/* Copyright (C) 2005 - 2007 Thomas Schmitt <scdbackup@gmx.net> */
/* Copyright (C) 2005 - 2009 Thomas Schmitt <scdbackup@gmx.net> */
/* Provided under GPLv2,see also "License and copyright aspects" at file end */
@ -8,8 +8,9 @@
libburner is a minimal demo application for the library libburn as provided
on http://libburnia-project.org . It can list the available devices, can
blank a CD-RW or DVD-RW, can format a DVD-RW, can burn to CD-R, CD-RW, DVD-R,
DVD+R, DVD+RW, DVD-RAM or DVD-RW. Not supported yet: double layer media.
blank a CD-RW or DVD-RW, can format DVD-RW and BD, can burn to CD-R,
CD-RW, DVD-R, DVD+R, DVD+R/DL, DVD+RW, DVD-RW, DVD-RAM, BD-R, BD-RE.
Not supported yet: DVD-R/DL.
It's main purpose, nevertheless, is to show you how to use libburn and also
to serve the libburnia team as reference application. libburner.c does indeed
@ -28,8 +29,9 @@
With that aquired drive you can blank a CD-RW
libburner_blank_disc()
or you can format a DVD-RW to profile "Restricted Overwrite" (needed once)
libburner_format_row()
With the aquired drive you can burn to CD-R, CD-RW, DVD+RW, DVD-RAM, DVD-RW
or an unused BD to default size with spare blocks
libburner_format()
With the aquired drive you can burn to CD, DVD, BD
libburner_payload()
When everything is done, main() releases the drive and shuts down libburn:
burn_drive_release();
@ -104,7 +106,7 @@ int libburner_aquire_drive(char *drive_adr, int *driveno)
ret = libburner_aquire_by_adr(drive_adr);
else
ret = libburner_aquire_by_driveno(driveno);
if (ret <= 0)
if (ret <= 0 || *driveno <= 0)
return ret;
burn_disc_get_profile(drive_list[0].drive, &current_profile,
current_profile_name);
@ -258,7 +260,8 @@ int libburner_aquire_by_driveno(int *driveno)
}
/** Makes a previously used CD-RW ready for thorough re-usal.
/** Makes a previously used CD-RW or unformatted DVD-RW ready for thorough
re-usal.
To our knowledge it is hardly possible to abort an ongoing blank operation
because after start it is entirely handled by the drive.
@ -313,26 +316,56 @@ int libburner_blank_disc(struct burn_drive *drive, int blank_fast)
}
/** Persistently changes DVD-RW profile 0014h "Sequential Recording" to
profile 0013h "Restricted Overwrite" which needs no blanking for re-use
but is not capable of multi-session.
/** Formats unformatted DVD-RW to profile 0013h "Restricted Overwrite"
which needs no blanking for re-use but is not capable of multi-session.
Expect a behavior similar to blanking with unusual noises from the drive.
Formats unformatted BD-RE to default size. This will allocate some
reserve space, test for bad blocks and make the media ready for writing.
Expect a very long run time.
Formats unformatted blank BD-R to hold a default amount of spare blocks
for eventual mishaps during writing. If BD-R get written without being
formatted, then they get no such reserve and will burn at full speed.
*/
int libburner_format_row(struct burn_drive *drive)
int libburner_format(struct burn_drive *drive)
{
struct burn_progress p;
double percent = 1.0;
int ret, status, num_formats, format_flag= 0;
off_t size = 0;
unsigned dummy;
enum burn_disc_status disc_state;
if (current_profile == 0x13) {
fprintf(stderr, "IDLE: DVD-RW media is already formatted\n");
return 2;
} else if (current_profile != 0x14) {
fprintf(stderr, "FATAL: Can only format DVD-RW\n");
} else if (current_profile == 0x41 || current_profile == 0x43) {
disc_state = burn_disc_get_status(drive);
if (disc_state != BURN_DISC_BLANK && current_profile == 0x41) {
fprintf(stderr,
"FATAL: BD-R is not blank. Cannot format.\n");
return 0;
}
ret = burn_disc_get_formats(drive, &status, &size, &dummy,
&num_formats);
if (ret > 0 && status != BURN_FORMAT_IS_UNFORMATTED) {
fprintf(stderr,
"IDLE: BD media is already formatted\n");
return 2;
}
size = 0; /* does not really matter */
format_flag = 3<<1; /* format to default size, no quick */
} else if (current_profile == 0x14) { /* sequential DVD-RW */
size = 128 * 1024 * 1024;
format_flag = 1; /* write initial 128 MiB */
} else {
fprintf(stderr, "FATAL: Can only format DVD-RW or BD\n");
return 0;
}
printf("Beginning to format media.\n");
burn_disc_format(drive, (off_t) 0, 0);
burn_disc_format(drive, size, format_flag);
sleep(1);
while (burn_drive_get_status(drive, &p) != BURN_DRIVE_IDLE) {
@ -344,9 +377,10 @@ int libburner_format_row(struct burn_drive *drive)
}
burn_disc_get_profile(drive_list[0].drive, &current_profile,
current_profile_name);
printf("Media type now: %4.4xh \"%s\"\n",
current_profile, current_profile_name);
if (current_profile != 0x13) {
if (current_profile == 0x14 || current_profile == 0x13)
printf("Media type now: %4.4xh \"%s\"\n",
current_profile, current_profile_name);
if (current_profile == 0x14) {
fprintf(stderr,
"FATAL: Failed to change media profile to desired value\n");
return 0;
@ -443,7 +477,8 @@ int libburner_payload(struct burn_drive *drive,
/* Use the fifo object as data source for the track */
if (burn_track_set_source(track, fifo_src[trackno])
!= BURN_SOURCE_OK) {
printf("FATAL: Cannot attach source object to track object\n");
fprintf(stderr,
"FATAL: Cannot attach source object to track object\n");
return 0;
}
@ -453,7 +488,7 @@ int libburner_payload(struct burn_drive *drive,
/* Give up local reference to the data burn_source object */
burn_source_free(data_src);
} /* trackno loop end */
} /* trackno loop end */
/* Evaluate drive and media */
disc_state = burn_disc_get_status(drive);
@ -533,7 +568,8 @@ int libburner_payload(struct burn_drive *drive,
burn_session_free(session);
burn_disc_free(target_disc);
if (multi && current_profile != 0x1a && current_profile != 0x13 &&
current_profile != 0x12) /* not with DVD+RW, DVD-RW, DVD-RAM */
current_profile != 0x12 && current_profile != 0x43)
/* not with DVD+RW, formatted DVD-RW, DVD-RAM, BD-RE */
printf("NOTE: Media left appendable.\n");
if (simulate_burn)
printf("\n*** Did TRY to SIMULATE burning ***\n\n");
@ -590,7 +626,8 @@ int libburner_setup(int argc, char **argv)
}
strcpy(drive_adr, argv[i]);
}
} else if (!strcmp(argv[i], "--format_overwrite")) {
} else if ((!strcmp(argv[i], "--format_overwrite")) ||
(!strcmp(argv[i], "--format"))) {
do_blank = 101;
} else if (!strcmp(argv[i], "--multi")) {
@ -631,8 +668,7 @@ int libburner_setup(int argc, char **argv)
if (print_help || insuffient_parameters ) {
printf("Usage: %s\n", argv[0]);
printf(" [--drive <address>|<driveno>|\"-\"] [--audio]\n");
printf(" [--blank_fast|--blank_full|--format_overwrite]\n");
printf(" [--try_to_simulate]\n");
printf(" [--blank_fast|--blank_full|--format] [--try_to_simulate]\n");
printf(" [--multi] [<one or more imagefiles>|\"-\"]\n");
printf("Examples\n");
printf("A bus scan (needs rw-permissions to see a drive):\n");
@ -645,8 +681,8 @@ int libburner_setup(int argc, char **argv)
printf(" %s --drive /dev/hdc --blank_fast\n",argv[0]);
printf("Blank a used DVD-RW (is combinable with burning in one run):\n");
printf(" %s --drive /dev/hdc --blank_full\n",argv[0]);
printf("Format a DVD-RW to avoid need for blanking before re-use:\n");
printf(" %s --drive /dev/hdc --format_overwrite\n", argv[0]);
printf("Format a DVD-RW, BD-RE or BD-R:\n");
printf(" %s --drive /dev/hdc --format\n", argv[0]);
printf("Burn two audio tracks (to CD only):\n");
printf(" lame --decode -t /path/to/track1.mp3 track1.cd\n");
printf(" test/dewav /path/to/track2.wav -o track2.cd\n");
@ -696,7 +732,7 @@ int main(int argc, char **argv)
{ ret = 0; goto release_drive; }
if (do_blank) {
if (do_blank > 100)
ret = libburner_format_row(drive_list[driveno].drive);
ret = libburner_format(drive_list[driveno].drive);
else
ret = libburner_blank_disc(drive_list[driveno].drive,
do_blank == 1);

View File

@ -606,7 +606,8 @@ int telltoc_read_and_print(struct burn_drive *drive,
if (start_sector == -1)
start_sector = last_track_start;
if (sector_count == -1) {
sector_count = last_track_size;
sector_count = last_track_start + last_track_size
- start_sector;
if (media_is_cd_profile) /* In case it is a TAO track */
final_cd_try = 0; /* allow it (-1 is denial) */
}