Compare commits

...

138 Commits

Author SHA1 Message Date
ea08843afb Updated change log 2011-11-20 11:17:12 +00:00
d13085ec2d Updated cdrskin tarball generator 2011-11-20 11:15:00 +00:00
ef65e13508 Made number transition to 1.1.8 2011-11-20 11:10:25 +00:00
dd171ebc29 Branching for libburn release 1.1.8 2011-11-20 09:33:50 +00:00
dff3e97daa Bug fix: licdio adapter reacted inconsistently on symbolic links to drives 2011-11-18 15:54:53 +00:00
83e2d20322 Distinguished failure messages about write(2) and fsync(2) 2011-11-16 09:44:59 +00:00
303a2670be Clarified a remark in libburn/libdax_msgs.h 2011-11-16 09:43:03 +00:00
3b96910327 Clarified a remark in libburn/sg-linux.c 2011-11-14 17:07:01 +00:00
6c9b5a4419 Logging of early SCSI commands of Linux system adapter to stderr 2011-11-10 15:37:32 +00:00
cf181bdcd6 Removed remark about SCSI logging being restricted to Linux system adapter 2011-11-10 13:45:23 +00:00
cc65aa9df6 Enabled recognition of CD drive at /dev/vda of Linux guest on qemu virtio 2011-11-09 11:17:19 +00:00
b4ff95c2e7 Bug fix: Misinterpreted mode page 2A if block descriptors are present 2011-11-03 13:08:44 +00:00
a1158a118b Corrected a bug with obtaining Physical Interface Standard information 2011-11-02 13:07:56 +00:00
afe242f920 Avoiding on Linux to list drives from /proc if device family is non-default 2011-11-02 07:43:58 +00:00
854ebd647c Small correction of rev 4416 2011-11-01 22:17:49 +00:00
42b6c22dca Enabled recognition of QEMU DVD-ROM 0.12 as ATAPI drive 2011-10-31 16:43:02 +00:00
a247f7e7e9 Enabled optional reporting of drive replies in Solaris adapter 2011-10-27 16:14:13 +00:00
cad8abef74 Enabled optional reporting of drive replies in libcdio adapter 2011-10-27 09:47:29 +00:00
a504de4b58 Silenced a warnings in libcdio adapter 2011-10-27 09:10:43 +00:00
126e73d19d Added madatory library initialization to test/structest.c 2011-10-12 10:02:29 +00:00
ac4bfb128c Gave up use of burn_print() in libburn 2011-10-12 10:01:28 +00:00
8e97da0078 Avoided release-grab cycles between tasks of a cdrskin run 2011-10-11 16:39:57 +00:00
d6c8792a24 Avoided release-grab cycle in cdrskin -msinfo 2011-10-11 14:58:28 +00:00
dcf6f74e5a Avoided release-grab cycle in cdrskin -msinfo 2011-10-11 14:13:40 +00:00
39df1cdc4e Changed debug message which called "stdio:" addresses enumerable 2011-10-10 13:01:00 +00:00
3862b8d339 Changed term "persistent address" to "device file address" 2011-10-10 13:00:20 +00:00
02255c89be Reacted on nitpicking of cppcheck 2011-10-09 16:24:25 +00:00
3c7e723114 Reacted on warning of cppcheck about burn_disc_get_cd_info() 2011-10-09 15:54:47 +00:00
63c04b8c9b Replaced HTML minus by a flat ASCII minus in HTML man page generator 2011-10-08 12:11:38 +00:00
7d1c712c09 Avoided to release drive prematurely if interrupted while grabbing drive 2011-10-07 07:51:55 +00:00
6b821fcd92 Now unconditional: Cdrskin_libburn_from_pykix_svN 2011-10-06 12:13:46 +00:00
29f202a6fe Removed outdated code and Cdrskin_oldfashioned_api_usE 2011-10-06 12:00:52 +00:00
2cae912040 Removed obsolete macro case 2011-10-06 11:40:40 +00:00
3f7a92cc84 Now unconditional: Cdrskin_all_tracks_with_sector_paD 2011-10-06 11:34:32 +00:00
5faa1c25b0 Now unconditional: Cdrskin_libburn_does_ejecT 2011-10-06 11:32:25 +00:00
f986fe83ff Now unconditional: Cdrskin_libburn_has_drive_get_adR 2011-10-06 11:28:31 +00:00
15192c2bfa Now unconditional: Cdrskin_progress_track_does_worK 2011-10-06 11:25:48 +00:00
9b042009fb Now unconditional: Cdrskin_is_erasable_on_load_does_worK 2011-10-06 11:23:48 +00:00
15c6c539db Now unconditional: Cdrskin_grab_abort_does_worK 2011-10-06 11:21:36 +00:00
824e610824 Now unconditional: Cdrskin_allow_libburn_taO 2011-10-06 11:18:48 +00:00
dbd2e28366 Now unconditional: Cdrskin_libburn_has_is_enumerablE 2011-10-06 11:13:36 +00:00
6cc3012284 Now unconditional: Cdrskin_libburn_has_convert_fs_adR 2011-10-06 11:12:04 +00:00
ff1e0eb54e Now unconditional: Cdrskin_libburn_has_convert_scsi_adR 2011-10-06 11:00:18 +00:00
cbcae473ad Now unconditional: Cdrskin_libburn_has_burn_msgS 2011-10-06 10:59:25 +00:00
fb841a7d08 Now unconditional: Cdrskin_libburn_has_burn_aborT 2011-10-06 10:53:38 +00:00
207a702767 Now unconditional: Cdrskin_libburn_has_cleanup_handleR 2011-10-06 10:45:58 +00:00
4c10e60dae Now unconditional: Cdrskin_libburn_has_audioxtR 2011-10-06 10:43:26 +00:00
7c1666cdce Now unconditional: Cdrskin_libburn_has_get_start_end_lbA 2011-10-06 10:41:12 +00:00
da3aba8ef5 Now unconditional: Cdrskin_libburn_has_burn_disc_unsuitablE 2011-10-06 10:39:05 +00:00
822bdf8b7b Now unconditional: Cdrskin_libburn_has_read_atiP 2011-10-06 10:37:19 +00:00
880c95d9a4 Now unconditional: Cdrskin_libburn_has_buffer_progresS 2011-10-06 10:35:21 +00:00
d12589771b Now unconditional: Cdrskin_libburn_has_pretend_fulL 2011-10-06 10:34:19 +00:00
b7ecdb1014 Now unconditional: Cdrskin_libburn_has_multI 2011-10-06 10:32:03 +00:00
fdb981db72 Now unconditional: Cdrskin_libburn_has_buffer_min_filL 2011-10-06 10:29:10 +00:00
16724f3eef Now unconditional: Cdrskin_atip_speed_is_oK 2011-10-06 10:26:51 +00:00
8cc1fc1ca7 Now unconditional: Cdrskin_libburn_has_get_profilE 2011-10-06 10:22:41 +00:00
421870ae51 Now unconditional: Cdrskin_libburn_has_set_start_bytE 2011-10-06 10:19:53 +00:00
006d1a32fb Now unconditional: Cdrskin_libburn_has_wrote_welL 2011-10-06 10:15:39 +00:00
7ed9f978a8 Now unconditional: Cdrskin_libburn_has_bd_formattinG 2011-10-06 10:14:05 +00:00
b7c07ef18f Now unconditional: Cdrskin_libburn_has_burn_disc_formaT 2011-10-06 10:06:09 +00:00
1c66174a2e Now unconditional: Cdrskin_libburn_has_get_msc1 2011-10-06 09:53:57 +00:00
43b2f73217 Now unconditional: Cdrskin_libburn_has_toc_entry_extensionS 2011-10-06 09:52:26 +00:00
2c282adafb Now unconditional: Cdrskin_libburn_has_get_multi_capS 2011-10-06 09:23:55 +00:00
1d64ff428e Now unconditional: Cdrskin_libburn_has_set_filluP 2011-10-06 09:22:41 +00:00
c813de47c2 Now unconditional: Cdrskin_libburn_has_set_filluP 2011-10-06 09:20:20 +00:00
d39843a974 Now unconditional: Cdrskin_libburn_has_get_spacE 2011-10-06 09:18:01 +00:00
8c25db0148 Now unconditional: Cdrskin_libburn_write_mode_ruleS 2011-10-06 09:14:47 +00:00
46719fbc5c Now unconditional: Cdrskin_libburn_has_allow_untested_profileS 2011-10-06 09:06:56 +00:00
93b65ac4e5 Now unconditional: Cdrskin_libburn_has_set_forcE 2011-10-06 09:05:05 +00:00
3e58712c36 Now unconditional: Cdrskin_libburn_preset_device_familY 2011-10-06 09:02:53 +00:00
f6fc14de13 Now unconditional: Cdrskin_libburn_has_track_set_sizE 2011-10-06 08:59:52 +00:00
4bba05f186 Now unconditional: Cdrskin_libburn_has_set_waitinG 2011-10-06 08:57:50 +00:00
82697b2b8b Now unconditional: Cdrskin_libburn_has_get_best_speeD 2011-10-06 08:55:16 +00:00
ae91e331a7 Now unconditional: Cdrskin_libburn_has_random_access_rW 2011-10-06 08:41:04 +00:00
df41e7b9ff Now unconditional: Cdrskin_libburn_has_get_drive_rolE 2011-10-06 08:33:28 +00:00
49e91d491d Now unconditional: Cdrskin_libburn_has_stream_recordinG 2011-10-06 08:31:00 +00:00
a0a230e38b Now unconditional: Cdrskin_libburn_has_stream_recordinG 2011-10-06 08:27:46 +00:00
e05e813234 New API call burn_drive_re_assess() 2011-10-05 07:56:23 +00:00
c5718b7a4c Avoided one more open()-close() cycles during drive scan and grab on Linux 2011-10-02 17:20:39 +00:00
b81585e082 Avoided open()-close() cycles during drive scan and grab on Linux 2011-10-02 13:41:21 +00:00
91e2256ffb Updated change log 2011-09-27 12:57:21 +00:00
38b30d5e5f Updated cdrskin tarball generator 2011-09-27 12:52:55 +00:00
44b0314449 Made number transition to 1.1.7 2011-09-27 12:50:12 +00:00
3a993efb9f Corrected outdated sentence in documented workaround for udev 2011-09-21 13:42:19 +00:00
d9e6bde437 Improved and documented workaround for udev 2011-09-21 13:34:21 +00:00
71c9dc9f28 Slowing down test cycle while waiting for drive to become ready 2011-09-20 13:25:21 +00:00
35e553a808 Working around collision with udev by closing and re-opening device file 2011-09-20 13:19:47 +00:00
fe812ffde2 Simulation of large disks 2011-09-20 13:17:38 +00:00
a2965e9993 More generous ignoring of failure of fsync() on inappropriate fd 2011-08-29 21:33:43 +00:00
d073709328 Reacted on compiler warning about previous revision 2011-08-17 16:22:14 +00:00
7e6dadeb02 Bug fix: stdio sizes > 4 TB - 32 kB caused integer rollover 2011-08-17 16:09:05 +00:00
fe5efd7b37 Documented changes and release timestamp 2011-08-08 12:25:39 +00:00
7778536f45 Updated cdrskin tarball generator 2011-08-08 12:23:50 +00:00
60dde60ebd Made number transition to 1.1.5 2011-08-08 12:20:01 +00:00
76c4c76722 Forgot to upload the header which defines mmc_get_phys_format_info 2011-08-01 15:34:08 +00:00
2e20a4f888 New API call burn_disc_get_phys_format_info() 2011-08-01 12:54:24 +00:00
62944e3b21 Bug fix: Some drives return -150 as NWA of blank CD, rather than 0 2011-07-31 08:31:11 +00:00
b0a4b7c15c Bug fix: Some drives returned wrong CD sizes after having burnt DVD-R 2011-07-31 08:03:51 +00:00
ecc8bbc71f New option --device_links 2011-07-28 19:16:06 +00:00
b47a0e6884 New API call burn_lookup_device_link() 2011-07-28 19:13:39 +00:00
64f7f5d609 Reacted on warning of cppcheck about libburn/sg-freebsd.c 2011-07-15 08:13:46 +00:00
4e287dbfed Fixed possible uninitialized variable use introduced by rev 4152 2011-07-14 16:22:27 +00:00
13895a6518 Reacted on warning of cppcheck about libburn/sg-solaris.c 2011-07-12 17:38:01 +00:00
f12ce229ae Bug fix: Empty ROM drive was mistaken to hold an unsuitable disc 2011-07-12 15:54:42 +00:00
58d8f3b3c2 Improved -atip and -minfo with empty drive 2011-07-12 15:53:56 +00:00
34c86e88d9 Reacted on warning of cppcheck about libburn/sg-libcdio.c 2011-07-12 14:22:19 +00:00
a2d2ec150b Reacted on warning of cppcheck about libburn/sg-freebsd.c 2011-07-12 14:20:52 +00:00
54325147ee Reacted on warning of cppcheck about libburn/sg-freebsd-port.c 2011-07-12 14:19:55 +00:00
7620840490 Reacted on warning of cppcheck about libburn/sg-dummy.c 2011-07-12 14:19:12 +00:00
0894f7773e Improved intentional compiler warning about lack of suitable system adapter 2011-07-12 14:17:24 +00:00
706f8b937d Reacted on warning of cppcheck about test/poll.c 2011-07-12 11:05:20 +00:00
ec9bc5678b Reacted on warning of cppcheck about libburn/read.c 2011-07-12 11:04:39 +00:00
a751af6caa Reacted on warning of cppcheck about libburn/drive.c 2011-07-12 11:03:34 +00:00
570346b3a5 Reacted on warning of cppcheck about libburn/cleanup.c 2011-07-12 11:02:47 +00:00
f73698c0cb Reacted on warning of cppcheck about libburn/async.c 2011-07-12 11:01:53 +00:00
c11378f1a0 Reacted on warning of cppcheck about cdrskin/cleanup.c 2011-07-12 11:00:27 +00:00
a734e868bd Reacted on warning of cppcheck about cdrskin/cdrfifo.c 2011-07-12 09:59:59 +00:00
653586b97e Implemented macro Libburn_use_sg_freebsd_porT 2011-07-11 14:40:02 +00:00
3cec04dbe3 Reacted on warning of cppcheck 2011-07-07 12:07:43 +00:00
2d8047afcf Silenced warning of cppcheck 2011-07-07 11:50:34 +00:00
781beb3a27 Silenced warning of cppcheck 2011-07-07 11:49:36 +00:00
79e09728ac Reacted on warnings of -Wunused-but-set-variable 2011-07-06 14:39:39 +00:00
3f7210dfff Reacted on warnings of -Wtype-limits and -Wunused-but-set-variable 2011-07-06 14:38:08 +00:00
c03149241d Reacted on warnings of -Wunused-but-set-variable 2011-07-06 14:35:55 +00:00
2433c1f68e Reacted on warnings of -Wunused-but-set-variable 2011-07-06 14:34:58 +00:00
9eb60cd8fc Reacted on warnings of -Wunused-but-set-variable 2011-07-06 14:33:35 +00:00
15e18501d9 Reacted on warnings of -Wunused-but-set-variable 2011-07-06 14:31:32 +00:00
ed8b303d62 Reacted on warnings of -Wunused-but-set-variable 2011-07-06 14:25:57 +00:00
9fbae8df29 Reacted on warnings of -Wunused-but-set-variable 2011-07-04 17:17:40 +00:00
04005adaf4 Avoiding to load speed descriptor list twice 2011-07-04 14:39:47 +00:00
45da5c9934 record stderr of several builds in log files 2011-07-02 14:49:35 +00:00
64b1ab5b3d executable bit, fix text encoding 2011-06-22 13:36:29 +00:00
404717f305 Beginning to create a test suite for libburn and cdrskin 2011-06-22 09:33:23 +00:00
e5ea8f75e6 Silenced compiler warnings about signedness 2011-06-22 09:32:25 +00:00
eb01c9c6c5 Bug fix: libburn-1.1.0 did only compile on Linux, FreeBSD, and Solaris 2011-06-19 20:36:29 +00:00
c1ff7b9812 Documented changes and release timestamp 2011-06-18 16:01:18 +00:00
d6e90bb71f Updated cdrskin tarball generator 2011-06-18 15:58:14 +00:00
ae7f38c15a Made number transition to 1.1.1 2011-06-18 15:56:15 +00:00
46 changed files with 2839 additions and 1942 deletions

View File

@ -1,6 +1,40 @@
SVN trunk (to become libburn-1.0.8.pl00.tar.gz) libburn-1.1.8.tar.gz Mon Nov 21 2011
=============================================================================== ===============================================================================
- no novelties yet * Bug fix: Misinterpreted mode page 2A if block descriptors are present
* Enabled recognition of QEMU DVD-ROM 0.12
* Avoiding to intermediately close and open drive device file
* New API call burn_drive_re_assess()
libburn-1.1.6.tar.gz Tue Sep 27 2011
===============================================================================
* Bug fix: stdio sizes > 4 TB - 32 kB caused integer rollover
* Worked around a collision with Linux udev which lets links vanish
libburn-1.1.4.tar.gz Sun Aug 07 2011
===============================================================================
* Bug fix: Some drives return -150 as NWA of blank CD, rather than 0.
libburn forwarded this misleading information to the application.
* Bug fix: Some drives returned wrong CD sizes after having burned DVD-R
* Bug fix: Empty ROM drive was mistaken to hold an unsuitable disc
* Bug fix: Avoiding to load speed descriptor list twice
* New API call burn_lookup_device_link()
* New API call burn_disc_get_phys_format_info()
* New cdrskin option --device_links
Release 1.1.2 was skipped to get back in sync with libisoburn.
libburn-1.1.0.pl01.tar.gz Mon Jun 20 2011
===============================================================================
* Bug fix: libburn-1.1.0 compiled only on Linux, FreeBSD, and Solaris
libburn-1.1.0.tar.gz Sat Jun 18 2011
===============================================================================
* Bug fix: burn_disc_format() on DVD-RW issued wrong block size with type 00h
* New API call burn_disc_next_track_is_damaged()
* New API call burn_disc_close_damaged()
* Dropped suffix .plXY from tarball name
Release 1.0.8 was skipped to get back in sync with libisofs and libisoburn.
libburn-1.0.6.pl00.tar.gz Sat Apr 9 2011 libburn-1.0.6.pl00.tar.gz Sat Apr 9 2011
=============================================================================== ===============================================================================

View File

@ -118,9 +118,9 @@ test_structest_CPPFLAGS = -Ilibburn
test_structest_LDADD = $(libburn_libburn_la_OBJECTS) $(LIBBURN_EXTRALIBS) test_structest_LDADD = $(libburn_libburn_la_OBJECTS) $(LIBBURN_EXTRALIBS)
test_structest_SOURCES = test/structest.c test_structest_SOURCES = test/structest.c
## cdrskin construction site - ts A60816 - B10409 ## cdrskin construction site - ts A60816 - B10808
cdrskin_cdrskin_CPPFLAGS = -Ilibburn cdrskin_cdrskin_CPPFLAGS = -Ilibburn
cdrskin_cdrskin_CFLAGS = -DCdrskin_libburn_1_0_7 cdrskin_cdrskin_CFLAGS = -DCdrskin_libburn_1_1_8
# cdrskin_cdrskin_LDADD = $(libburn_libburn_la_OBJECTS) $(LIBBURN_EXTRALIBS) # cdrskin_cdrskin_LDADD = $(libburn_libburn_la_OBJECTS) $(LIBBURN_EXTRALIBS)
# ts A80123, change proposed by Simon Huggins to cause dynamic libburn linking # ts A80123, change proposed by Simon Huggins to cause dynamic libburn linking

65
README
View File

@ -11,7 +11,7 @@ Still containing parts of Libburn. By Derek Foreman <derek@signalmarketing.com>
and Ben Jansens <xor@orodu.net> and Ben Jansens <xor@orodu.net>
Copyright (C) 2002-2006 Derek Foreman and Ben Jansens Copyright (C) 2002-2006 Derek Foreman and Ben Jansens
http://files.libburnia-project.org/releases/libburn-1.0.6.pl00.tar.gz http://files.libburnia-project.org/releases/libburn-1.1.8.tar.gz
------------------------------------------------------------------------------ ------------------------------------------------------------------------------
@ -19,10 +19,10 @@ Copyright (C) 2002-2006 Derek Foreman and Ben Jansens
From tarball From tarball
Obtain libburn-1.0.6.pl00.tar.gz, take it to a directory of your choice and do: Obtain libburn-1.1.8.tar.gz, take it to a directory of your choice and do:
tar xzf libburn-1.0.6.pl00.tar.gz tar xzf libburn-1.1.8.tar.gz
cd libburn-1.0.6 cd libburn-1.1.8
./configure --prefix=/usr ./configure --prefix=/usr
make make
@ -92,6 +92,21 @@ Make sure to re-compile all source files after running ./configure
make install make install
Linux only:
libburn tries to avoid a collision with udev's drive examination by waiting
0.1 seconds before opening the device file for a longer time, after udev
might have been alarmed by drive scanning activities.
The waiting time can be set at ./configure time with microsecond granularity.
E.g. 2 seconds:
CFLAGS="$CFLAGS -DLibburn_udev_wait_useC=2000000"
./configure ...options...
Waiting can be disabled by zero waiting time:
CFLAGS="$CFLAGS -DLibburn_udev_wait_useC=0"
Alternatively, libburn can try to be nice by opening the device file,
closing it immediately, waiting, and only then opening it for real:
CFLAGS="$CFLAGS -DLibburn_udev_extra_open_cyclE -DLibburn_udev_wait_useC=500000"
------------------------------------------------------------------------------ ------------------------------------------------------------------------------
An important part of the project, libisofs, is hosted in a bzr repository at An important part of the project, libisofs, is hosted in a bzr repository at
@ -110,7 +125,7 @@ See README files there.
libburnia-project.org is an open-source software project for reading, mastering libburnia-project.org is an open-source software project for reading, mastering
and writing optical discs. and writing optical discs.
For now this means CD media, all DVD media except DVD-R DL, all BD media. For now this means CD media, all DVD media, all BD media.
The project comprises of several more or less interdependent parts which The project comprises of several more or less interdependent parts which
together strive to be a usable foundation for application development. together strive to be a usable foundation for application development.
@ -180,7 +195,8 @@ The project components (list subject to growth, hopefully):
sparse emulation of cdrecord and a more laborate one of mkisofs. sparse emulation of cdrecord and a more laborate one of mkisofs.
All features of xorriso are also available via a C language API All features of xorriso are also available via a C language API
of libisoburn. of libisoburn.
See xorriso/README for more. A static compilation of xorriso and the libraries is dedicated
to the GNU Operating System. See xorriso/README_gnu_xorriso .
- "test" is a collection of application gestures and examples given by the - "test" is a collection of application gestures and examples given by the
authors of the library features. The burn API example of libburn authors of the library features. The burn API example of libburn
@ -613,6 +629,43 @@ Project history as far as known to me:
up to 103 characters. xorriso fixes two bugs and makes use of the library up to 103 characters. xorriso fixes two bugs and makes use of the library
improvements. improvements.
- Thu Apr 14 2011 release libisoburn-1.0.8:
A bug in the mkisofs emulation of xorriso could cause options to be ignored.
The problem was freshly introduced with libisoburn-1.0.6.
- Fri May 13 2011 release libisofs-1.0.8:
Fixes a few rarely occurring bugs that have been found during the last month.
- Sat Jun 18 2011 release 1.1.0:
The consumption of stack memory was reduced. Statical program analysis found
some rarely occuring memory leaks. Several small bugs were fixed.
The suffix .plXY was dropped from tarball names of libburn and libisoburn.
- Mon Jun 20 2011 patch release libburn-1.1.0.pl01:
libburn-1.1.0 compiled only on Linux, FreeBSD, and Solaris, but not on
other X/Open compliant systems.
- Fri Jul 08 2011 release libisofs-1.1.2 and libisoburn-1.1.2:
A severe regression was fixed in libisoburn and xorriso, which was introduced
with version 1.0.6. It caused ISO 9660 images to be unreadable if they were
written to a write-only random-access file. E.g. by: xorrisofs ... >image.iso
- Mon Aug 08 2011 release 1.1.4:
Several bugs were fixed in libburn. The most severe of them prevented xorriso
on some drives from burning mountable ISO 9660 images to CD media.
New means to list drives by their udev symbolic links help to deal with
the non-persistent drive addresses on modern GNU/Linux.
- Tue Sep 27 2011 release 1.1.6:
libisoburn now comes with a test suite. See releng/README. Bugs were fixed
in several rarely used features. Processing of ACL and extattr was enabled
on FreeBSD. Workarounds try to cope with vanishing udev links on GNU/Linux.
- Mon Nov 21 2011 release libburn-1.1.8 and libisoburn-1.1.8:
libburn avoids to close and open drive device files while operating on them.
xorriso emulation mode xorrecord now has an own manual. libburn and xorriso
were prepared to operate on qemu virtio-blk-pci devices.
------------------------------------------------------------------------------ ------------------------------------------------------------------------------

View File

@ -4,7 +4,7 @@
cdrskin. By Thomas Schmitt <scdbackup@gmx.net> cdrskin. By Thomas Schmitt <scdbackup@gmx.net>
Integrated sub project of libburnia-project.org but also published via: Integrated sub project of libburnia-project.org but also published via:
http://scdbackup.sourceforge.net/cdrskin_eng.html http://scdbackup.sourceforge.net/cdrskin_eng.html
http://scdbackup.sourceforge.net/cdrskin-1.0.7.tar.gz http://scdbackup.sourceforge.net/cdrskin-1.1.8.tar.gz
Copyright (C) 2006-2011 Thomas Schmitt, provided under GPL version 2 or later. Copyright (C) 2006-2011 Thomas Schmitt, provided under GPL version 2 or later.
------------------------------------------------------------------------------ ------------------------------------------------------------------------------
@ -26,10 +26,10 @@ By using this software you agree to the disclaimer at the end of this text
Compilation, First Glimpse, Installation Compilation, First Glimpse, Installation
Obtain cdrskin-1.0.7.tar.gz, take it to a directory of your choice and do: Obtain cdrskin-1.1.8.tar.gz, take it to a directory of your choice and do:
tar xzf cdrskin-1.0.7.tar.gz tar xzf cdrskin-1.1.8.tar.gz
cd cdrskin-1.0.7 cd cdrskin-1.1.8
Within that directory execute: Within that directory execute:
@ -438,6 +438,22 @@ It will not read startup files, will abort on option dev_translation= ,
will not have a fifo buffer, and will not be able to put out help texts or will not have a fifo buffer, and will not be able to put out help texts or
debugging messages. debugging messages.
Linux only:
libburn tries to avoid a collision with udev's drive examination by waiting
0.1 seconds before opening the device file for a longer time, after udev
might have been alarmed by drive scanning activities.
The waiting time can be set at ./configure time with microsecond granularity.
E.g. 2 seconds:
CFLAGS="$CFLAGS -DLibburn_udev_wait_useC=2000000"
./configure ...options...
Waiting can be disabled by zero waiting time:
CFLAGS="$CFLAGS -DLibburn_udev_wait_useC=0"
Alternatively, libburn can try to be nice by opening the device file,
closing it immediately, waiting, and only then opening it for real:
CFLAGS="$CFLAGS -DLibburn_udev_extra_open_cyclE -DLibburn_udev_wait_useC=500000"
------------------------------------------------------------------------------ ------------------------------------------------------------------------------
System Dependend Drive Permission Examples System Dependend Drive Permission Examples
@ -560,7 +576,7 @@ contributions in a due way.
Based on and sub project of: Based on and sub project of:
libburnia-project.org libburnia-project.org
By Mario Danic <mario.danic@gmail.com> and Thomas Schmitt <scdbackup@gmx.net> By Mario Danic <mario.danic@gmail.com> and Thomas Schmitt <scdbackup@gmx.net>
Copyright (C) 2006-2010 Mario Danic, Thomas Schmitt Copyright (C) 2006-2011 Mario Danic, Thomas Schmitt
libburnia-project.org is inspired by and in other components still containing libburnia-project.org is inspired by and in other components still containing
parts of parts of

View File

@ -38,8 +38,9 @@ original="./libburn_svn_release.tgz"
# My changes are in $changes , mainly in $changes/cdrskin # My changes are in $changes , mainly in $changes/cdrskin
changes="./libburn-release" changes="./libburn-release"
skin_release="1.0.6" skin_release="1.1.8"
patch_level=".pl00" patch_level=""
# patch_level=".pl00"
skin_rev="$skin_release""$patch_level" skin_rev="$skin_release""$patch_level"
# The result directory and the name of the result tarballs # The result directory and the name of the result tarballs

View File

@ -38,7 +38,7 @@ original="./libburn_svn.tgz"
# My changes are in $changes , mainly in $changes/cdrskin # My changes are in $changes , mainly in $changes/cdrskin
changes="./libburn-develop" changes="./libburn-develop"
skin_release="1.0.7" skin_release="1.1.9"
patch_level="" patch_level=""
skin_rev="$skin_release""$patch_level" skin_rev="$skin_release""$patch_level"

View File

@ -634,7 +634,7 @@ return: <0 = error , 0 = idle , 1 = did some work
*/ */
{ {
double buffer_space; double buffer_space;
int can_read,can_write= 0,ret,did_work= 0,idx,sod,eop_is_near,eop_idx; int can_read,can_write= 0,ret,did_work= 0,idx,sod, eop_idx;
buffer_space= Cdrfifo_tell_buffer_space(o,0); buffer_space= Cdrfifo_tell_buffer_space(o,0);
if(o->dest_fd>=0) if(FD_ISSET((o->dest_fd),wts)) { if(o->dest_fd>=0) if(FD_ISSET((o->dest_fd),wts)) {
@ -644,7 +644,7 @@ return: <0 = error , 0 = idle , 1 = did some work
if(o->read_idx+can_write > o->buffer_size) if(o->read_idx+can_write > o->buffer_size)
can_write= o->buffer_size - o->read_idx; can_write= o->buffer_size - o->read_idx;
if(o->follow_up_fd_idx>=0) { if(o->follow_up_fd_idx>=0) {
eop_is_near= Cdrfifo_eop_adjust(o,&can_write,&eop_idx,0); Cdrfifo_eop_adjust(o,&can_write,&eop_idx,0);
if(can_write<=0) if(can_write<=0)
goto after_write; goto after_write;
} }
@ -1039,9 +1039,9 @@ int Test_mixed_bs(char **paths, int path_count,
bit0= debugging verbousity bit0= debugging verbousity
*/ */
{ {
int fd_in[100],fd_out[100],ret,pipe_fds[100][2],real_out[100]; int fd_in[100],fd_out[100],ret,pipe_fds[100][2];
int i,iv,stall_counter= 0,cycle_counter= 0.0; int i,iv,stall_counter= 0,cycle_counter= 0.0;
char buf[10240], target_path[80]; char target_path[80];
double in_counter, out_counter, prev_in= -1.0, prev_out= -1.0; double in_counter, out_counter, prev_in= -1.0, prev_out= -1.0;
struct CdrfifO *ff_in= NULL, *ff_out= NULL; struct CdrfifO *ff_in= NULL, *ff_out= NULL;
@ -1109,9 +1109,8 @@ int Test_multi(int fs_size, double speed_limit, double interval, int flag)
bit0= debugging verbousity bit0= debugging verbousity
*/ */
{ {
int fd_in[4],fd_out[4],ret,pipe_fds[4][2],real_out[4],pipe_idx; int fd_in[4],fd_out[4],ret,pipe_fds[4][2];
int i,iv; int i,iv;
char buf[10240];
struct CdrfifO *ff1= NULL,*ff2= NULL; struct CdrfifO *ff1= NULL,*ff2= NULL;
/* open four pairs of fds */ /* open four pairs of fds */

View File

@ -2,7 +2,7 @@
.\" First parameter, NAME, should be all caps .\" First parameter, NAME, should be all caps
.\" Second parameter, SECTION, should be 1-8, maybe w/ subsection .\" Second parameter, SECTION, should be 1-8, maybe w/ subsection
.\" other parameters are allowed: see man(7), man(1) .\" other parameters are allowed: see man(7), man(1)
.TH CDRSKIN 1 "Jan 09, 2011" .TH CDRSKIN 1 "Jul 28, 2011"
.\" Please adjust this date whenever revising the manpage. .\" Please adjust this date whenever revising the manpage.
.\" .\"
.\" Some roff macros, for reference: .\" Some roff macros, for reference:
@ -256,7 +256,7 @@ that it has to be formatted again. If in doubt, just give it a try.
.br .br
The drives, CD, DVD, or BD 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 are specific to libburn and the operating system. Those addresses get listed
by a run of \fBcdrskin --devices\fP. by a run of \fBcdrskin --devices\fP or \fBcdrskin --device_links\fP.
.br .br
On Linux, they are device files which traditionally do not offer On Linux, they are device files which traditionally do not offer
w-permissions for normal users. Because libburn needs rw-permission, w-permissions for normal users. Because libburn needs rw-permission,
@ -512,7 +512,7 @@ cdrskin will not write CD-ROM XA but rather strip the header bytes and write as
.TP .TP
.BI dev= target .BI dev= target
Set the address of the drive to use. Valid are at least the Set the address of the drive to use. Valid are at least the
addresses listed with option --devices, addresses listed with options --devices or --device_links,
X,Y,Z addresses listed with option -scanbus, X,Y,Z addresses listed with option -scanbus,
ATA:X,Y,Z addresses listed with options dev=ATA -scanbus, ATA:X,Y,Z addresses listed with options dev=ATA -scanbus,
and volatile libburn drive numbers (numbering starts at "0"). and volatile libburn drive numbers (numbering starts at "0").
@ -881,6 +881,17 @@ Number dev='Devicefile' rw-Permissions : 'Vendor' 'Model'
Number and Devicefile can both be used with option dev=, but number is Number and Devicefile can both be used with option dev=, but number is
volatile (numbering changes if drives become busy). volatile (numbering changes if drives become busy).
.TP .TP
.BI \--device_links
Like --devices, but presenting the drives with addresses of symbolic links
which point to the actual device files.
.br
Modern GNU/Linux systems may shuffle drive addresses from boot to boot.
The udev daemon is supposed to create links which always point to the
same drive, regardless of its system address.
Option --device_links shows the addresses of such links if they begin
by "/dev/dvd" or "/dev/cd".
Precedence is: "dvdrw", "cdrw", "dvd", "cdrom", "cd".
.TP
.BI direct_write_amount= size .BI direct_write_amount= size
Do not write a session with tracks but rather make an appropriate number of Do not write a session with tracks but rather make an appropriate number of
direct write operations with no preparations. Flushing the drive buffer will direct write operations with no preparations. Flushing the drive buffer will
@ -1136,7 +1147,7 @@ Wether this leads to senseful behavior depends on operating system and kernel.
.TP .TP
.BI drive_scsi_dev_family= sr | scd | sg .BI drive_scsi_dev_family= sr | scd | sg
Linux specific: Select a SCSI device file family to be scanned for by Linux specific: Select a SCSI device file family to be scanned for by
options --devices and -scanbus. options --devices, --device_links and -scanbus.
Normally this is /dev/sgN on kernel versions < 2.6 and /dev/srN Normally this is /dev/sgN on kernel versions < 2.6 and /dev/srN
on kernels >= 2.6 . This option allows to explicitly override that default on kernels >= 2.6 . This option allows to explicitly override that default
in order to meet other programs at a common device file for each drive. in order to meet other programs at a common device file for each drive.
@ -1242,7 +1253,7 @@ cdrskin -scanbus
.br .br
cdrskin dev=ATA -scanbus cdrskin dev=ATA -scanbus
.br .br
cdrskin --devices cdrskin --device_links
.SS .SS
.B Get info about a particular drive or loaded media: .B Get info about a particular drive or loaded media:
.br .br

File diff suppressed because it is too large Load Diff

View File

@ -65,7 +65,7 @@ connected via SCSI, PATA (aka IDE, ATA), USB, or SATA.
GPL software included:<BR> GPL software included:<BR>
</H2> </H2>
<DL> <DL>
<DT>libburn-1.0.6</DT> <DT>libburn-1.1.8</DT>
<DD>(founded by Derek Foreman and Ben Jansens, <DD>(founded by Derek Foreman and Ben Jansens,
developed and maintained since August 2006 by developed and maintained since August 2006 by
Thomas Schmitt from team of libburnia-project.org) Thomas Schmitt from team of libburnia-project.org)
@ -200,9 +200,16 @@ Standalone ISO 9660 multi-session CD/DVD/BD tool
<P> <P>
<DL> <DL>
<DT>Download as source code (see README):</DT> <DT>Download as source code (see README):</DT>
<DD><A HREF="cdrskin-1.0.6.pl00.tar.gz">cdrskin-1.0.6.pl00.tar.gz</A> <DD><A HREF="cdrskin-1.1.8.tar.gz">cdrskin-1.1.8.tar.gz</A>
(870 KB). (870 KB).
</DD> </DD>
<DD><A HREF="cdrskin-1.1.8.tar.gz.sig">cdrskin-1.1.8.tar.gz.sig</A></DD>
<DD>
(detached GPG signature for verification by
<KBD>gpg --verify cdrskin-1.1.8.tar.gz.sig cdrskin-1.1.8.tar.gz</KBD>
<BR>
after <KBD>gpg --keyserver keys.gnupg.net --recv-keys ABC0A854</KBD>).
</DD>
<DD> <DD>
The cdrskin tarballs are source code identical with libburn releases The cdrskin tarballs are source code identical with libburn releases
of the same version number. of the same version number.
@ -250,18 +257,24 @@ cdrskin_0.4.2.pl00-x86-suse9_0-static.tar.gz</A>, (310 KB), -static compiled,
<HR> <HR>
<P> <P>
Enhancements towards previous stable version cdrskin-1.0.4.pl00: Enhancements towards previous stable version cdrskin-1.1.6:
<UL> <UL>
<LI>Burning DVD-R DAO with 2 kB size granularity rather than 32 kB</LI> <LI>
Avoiding to intermediately close and open drive device file
</LI>
<LI>
Enabled recognition of QEMU DVD-ROM 0.12
</LI> </LI>
<!-- <!--
<LI>none</LI> <LI>none</LI>
--> -->
</UL> </UL>
Bug fixes towards cdrskin-1.0.4.pl00: Bug fixes towards cdrskin-1.1.6:
<UL> <UL>
<LI>none</LI> <LI>
Misinterpreted mode page 2A if block descriptors are present
</LI>
<!-- <!--
<LI>none</LI> <LI>none</LI>
--> -->
@ -271,8 +284,8 @@ Bug fixes towards cdrskin-1.0.4.pl00:
<P> <P>
<DL> <DL>
<DT><H3>Development snapshot, version 1.0.7 :</H3></DT> <DT><H3>Development snapshot, version 1.1.9 :</H3></DT>
<DD>Enhancements towards current stable version 1.0.6.pl00: <DD>Enhancements towards current stable version 1.1.8:
<UL> <UL>
<LI>none yet</LI> <LI>none yet</LI>
<!-- <!--
@ -282,7 +295,7 @@ Bug fixes towards cdrskin-1.0.4.pl00:
</UL> </UL>
</DD> </DD>
<DD>Bug fixes towards cdrskin-1.0.6.pl00: <DD>Bug fixes towards cdrskin-1.1.8:
<UL> <UL>
<LI>none yet</LI> <LI>none yet</LI>
<!-- <!--
@ -292,10 +305,10 @@ Bug fixes towards cdrskin-1.0.4.pl00:
</DD> </DD>
<DD>&nbsp;</DD> <DD>&nbsp;</DD>
<DD><A HREF="README_cdrskin_devel">README 1.0.7</A> <DD><A HREF="README_cdrskin_devel">README 1.1.9</A>
<DD><A HREF="cdrskin__help_devel">cdrskin-1.0.7 --help</A></DD> <DD><A HREF="cdrskin__help_devel">cdrskin-1.1.9 --help</A></DD>
<DD><A HREF="cdrskin_help_devel">cdrskin-1.0.7 -help</A></DD> <DD><A HREF="cdrskin_help_devel">cdrskin-1.1.9 -help</A></DD>
<DD><A HREF="man_1_cdrskin_devel.html">man cdrskin (as of 1.0.7)</A></DD> <DD><A HREF="man_1_cdrskin_devel.html">man cdrskin (as of 1.1.9)</A></DD>
<DD>&nbsp;</DD> <DD>&nbsp;</DD>
<DT>Maintainers of cdrskin unstable packages please use SVN of <DT>Maintainers of cdrskin unstable packages please use SVN of
<A HREF="http://libburnia-project.org"> libburnia-project.org</A></DT> <A HREF="http://libburnia-project.org"> libburnia-project.org</A></DT>
@ -315,7 +328,7 @@ admins with full system souvereignty.</DT>
<A HREF="README_cdrskin_devel">upcoming README</A> ): <A HREF="README_cdrskin_devel">upcoming README</A> ):
</DD> </DD>
<DD> <DD>
<A HREF="cdrskin-1.0.7.tar.gz">cdrskin-1.0.7.tar.gz</A> <A HREF="cdrskin-1.1.9.tar.gz">cdrskin-1.1.9.tar.gz</A>
(870 KB). (870 KB).
</DD> </DD>
@ -465,10 +478,11 @@ First of all: this relationship is single sided, as cdrskin has to be aware of
cdrecord but not vice versa. cdrecord but not vice versa.
<BR> <BR>
<BR> <BR>
I am a long time user of cdrecord and it works fine for me. I was a long time user of cdrecord and it worked fine for me.
Especially i do appreciate its write mode -tao which allows to pipe arbitrary Especially i do appreciate its write mode -tao which allows to pipe arbitrary
data on CD and CD-RW via stdin. cdrecord is reliable, versatile and well data on CD and CD-RW via stdin. cdrecord is reliable, versatile and well
maintained. So for me - there would be no problem with it. maintained. So for me - there would be no problem with using it for
burning CDs.
<BR> <BR>
But the author of cdrecord and the Linux kernel people foster a very hostile 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). relationship. Ok, that's their business, not mine (or ours if you are with me).

View File

@ -1 +1 @@
#define Cdrskin_timestamP "2011.06.14.152832" #define Cdrskin_timestamP "2011.11.20.100001"

File diff suppressed because it is too large Load Diff

View File

@ -200,9 +200,10 @@ main()
Cleanup_set_handlers(&demoapp,(Cleanup_app_handler_T) Demo_app_handler,0); Cleanup_set_handlers(&demoapp,(Cleanup_app_handler_T) Demo_app_handler,0);
if(1) { /* change to 0 in order to wait for external signals */ if(1) { /* change to 0 in order to wait for external signals */
char *cpt= NULL,c; char *cpt= NULL, c= ' ';
printf("Intentionally provoking SIGSEGV ...\n"); printf("Intentionally provoking SIGSEGV ...\n");
c= *cpt; c= *cpt;
printf("Strange: The system ignored a SIGSEGV: c= %u\n", (unsigned int) c);
} else { } else {
printf("killme: %d\n",getpid()); printf("killme: %d\n",getpid());
sleep(3600); sleep(3600);

View File

@ -8,7 +8,7 @@ debug_opts="-O2"
def_opts= def_opts=
largefile_opts="-D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE=1" largefile_opts="-D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE=1"
fifo_opts="" fifo_opts=""
libvers="-DCdrskin_libburn_1_0_7" libvers="-DCdrskin_libburn_1_1_8"
# To be used if Makefile.am uses libburn_libburn_la_CFLAGS # To be used if Makefile.am uses libburn_libburn_la_CFLAGS
# burn="libburn/libburn_libburn_la-" # burn="libburn/libburn_libburn_la-"
@ -19,7 +19,7 @@ libdax_msgs_o="$burn"libdax_msgs.o
libdax_audioxtr_o="$burn"libdax_audioxtr.o libdax_audioxtr_o="$burn"libdax_audioxtr.o
do_strip=0 do_strip=0
static_opts= static_opts=
warn_opts="-Wall" warn_opts="-Wall -Wextra -Wno-unused-parameter"
libcdio= libcdio=
fifo_source="cdrskin/cdrfifo.c" fifo_source="cdrskin/cdrfifo.c"
compile_cdrskin=1 compile_cdrskin=1
@ -41,31 +41,21 @@ do
elif test "$i" = "-compile_dewav" elif test "$i" = "-compile_dewav"
then then
compile_dewav=1 compile_dewav=1
elif test "$i" = "-cvs_A60220" elif test "$i" = "-libburn_1_1_8"
then then
libvers="-DCdrskin_libburn_cvs_A60220_tS" libvers="-DCdrskin_libburn_1_1_8"
libdax_audioxtr_o=
libdax_msgs_o="$burn"message.o
cleanup_src_or_obj="-DCleanup_has_no_libburn_os_H cdrskin/cleanup.c"
elif test "$i" = "-libburn_1_0_6"
then
libvers="-DCdrskin_libburn_1_0_6"
libdax_audioxtr_o="$burn"libdax_audioxtr.o libdax_audioxtr_o="$burn"libdax_audioxtr.o
libdax_msgs_o="$burn"libdax_msgs.o libdax_msgs_o="$burn"libdax_msgs.o
cleanup_src_or_obj="$burn"cleanup.o cleanup_src_or_obj="$burn"cleanup.o
elif test "$i" = "-libburn_svn" elif test "$i" = "-libburn_svn"
then then
libvers="-DCdrskin_libburn_1_0_7" libvers="-DCdrskin_libburn_1_1_9"
libdax_audioxtr_o="$burn"libdax_audioxtr.o libdax_audioxtr_o="$burn"libdax_audioxtr.o
libdax_msgs_o="$burn"libdax_msgs.o libdax_msgs_o="$burn"libdax_msgs.o
cleanup_src_or_obj="$burn"cleanup.o cleanup_src_or_obj="$burn"cleanup.o
elif test "$i" = "-newapi" -o "$i" = "-experimental" elif test "$i" = "-newapi" -o "$i" = "-experimental"
then then
def_opts="$def_opts -DCdrskin_new_api_tesT" def_opts="$def_opts -DCdrskin_new_api_tesT"
elif test "$i" = "-oldfashioned"
then
def_opts="$def_opts -DCdrskin_oldfashioned_api_usE"
cleanup_src_or_obj="-DCleanup_has_no_libburn_os_H cdrskin/cleanup.c"
elif test "$i" = "-no_largefile" elif test "$i" = "-no_largefile"
then then
largefile_opts= largefile_opts=
@ -109,7 +99,7 @@ do
echo "Options:" echo "Options:"
echo " -compile_cdrfifo compile program cdrskin/cdrfifo." echo " -compile_cdrfifo compile program cdrskin/cdrfifo."
echo " -compile_dewav compile program test/dewav without libburn." echo " -compile_dewav compile program test/dewav without libburn."
echo " -libburn_1_0_6 set macro to match libburn-1.0.6" echo " -libburn_1_1_8 set macro to match libburn-1.1.8"
echo " -libburn_svn set macro to match current libburn-SVN." echo " -libburn_svn set macro to match current libburn-SVN."
echo " -dvd_obs_64k 64 KB default size for DVD/BD writing." echo " -dvd_obs_64k 64 KB default size for DVD/BD writing."
echo " -use_libcdio link with -lcdio because libburn uses it." echo " -use_libcdio link with -lcdio because libburn uses it."
@ -117,7 +107,6 @@ do
echo " -use_no_libburn_fifo use cdrfifo even for single track non-CD" echo " -use_no_libburn_fifo use cdrfifo even for single track non-CD"
echo " -use_no_cdrfifo always use fifo of libburn and never cdrfifo" echo " -use_no_cdrfifo always use fifo of libburn and never cdrfifo"
echo " -experimental use newly introduced libburn features." echo " -experimental use newly introduced libburn features."
echo " -oldfashioned use pre-0.2.2 libburn features only."
echo " -do_diet produce capability reduced lean version." echo " -do_diet produce capability reduced lean version."
echo " -do_strip apply program strip to compiled programs." echo " -do_strip apply program strip to compiled programs."
echo " -g produce debuggable programm." echo " -g produce debuggable programm."

View File

@ -59,6 +59,7 @@ then
-e 's/<\/body>/<BR><HR><FONT SIZE=-1><CENTER>(HTML generated from '"$manpage"'.1 on '"$(date)"' by '$(basename "$0")' )<\/CENTER><\/FONT><\/body>/' \ -e 's/<\/body>/<BR><HR><FONT SIZE=-1><CENTER>(HTML generated from '"$manpage"'.1 on '"$(date)"' by '$(basename "$0")' )<\/CENTER><\/FONT><\/body>/' \
-e 's/See section FILES/See section <A HREF="#FILES">FILES<\/A>/' \ -e 's/See section FILES/See section <A HREF="#FILES">FILES<\/A>/' \
-e 's/See section EXAMPLES/See section <A HREF="#EXAMPLES">EXAMPLES<\/A>/' \ -e 's/See section EXAMPLES/See section <A HREF="#EXAMPLES">EXAMPLES<\/A>/' \
-e 's/&minus;/-/g' \
<"$2" >"$htmlpage" <"$2" >"$htmlpage"
set +x set +x

View File

@ -1,4 +1,4 @@
AC_INIT([libburn], [1.0.7], [http://libburnia-project.org]) AC_INIT([libburn], [1.1.8], [http://libburnia-project.org])
AC_PREREQ([2.50]) AC_PREREQ([2.50])
dnl AC_CONFIG_HEADER([config.h]) dnl AC_CONFIG_HEADER([config.h])
@ -10,7 +10,7 @@ LIBBURNIA_SET_FLAGS
AM_INIT_AUTOMAKE([subdir-objects]) AM_INIT_AUTOMAKE([subdir-objects])
AC_CONFIG_MACRO_DIR([./]) AC_CONFIG_MACRO_DIR([./])
dnl Notes by ts A71207 - B10409 : dnl Notes about version numbers and .so numbers:
dnl dnl
dnl Regrettably the meaning of the various version types was misunderstood dnl Regrettably the meaning of the various version types was misunderstood
dnl before version 0.4.1. dnl before version 0.4.1.
@ -91,6 +91,10 @@ dnl 1.0.0 = libburn.so.4.57.0
dnl 1.0.2 = libburn.so.4.59.0 dnl 1.0.2 = libburn.so.4.59.0
dnl 1.0.4 = libburn.so.4.61.0 dnl 1.0.4 = libburn.so.4.61.0
dnl 1.0.6 = libburn.so.4.63.0 dnl 1.0.6 = libburn.so.4.63.0
dnl 1.1.0 = libburn.so.4.65.0
dnl 1.1.4 = libburn.so.4.67.0
dnl 1.1.6 = libburn.so.4.69.0
dnl 1.1.8 = libburn.so.4.71.0
dnl dnl
dnl So LT_CURRENT, LT_REVISION and LT_AGE get set directly here. dnl So LT_CURRENT, LT_REVISION and LT_AGE get set directly here.
dnl SONAME of the emerging library is LT_CURRENT - LT_AGE. dnl SONAME of the emerging library is LT_CURRENT - LT_AGE.
@ -115,8 +119,8 @@ dnl If BURN_*_VERSION changes, be sure to change AC_INIT above to match.
dnl dnl
dnl As said: Only copies. Original in libburn/libburn.h : burn_header_version_* dnl As said: Only copies. Original in libburn/libburn.h : burn_header_version_*
BURN_MAJOR_VERSION=1 BURN_MAJOR_VERSION=1
BURN_MINOR_VERSION=0 BURN_MINOR_VERSION=1
BURN_MICRO_VERSION=7 BURN_MICRO_VERSION=8
BURN_VERSION=$BURN_MAJOR_VERSION.$BURN_MINOR_VERSION.$BURN_MICRO_VERSION BURN_VERSION=$BURN_MAJOR_VERSION.$BURN_MINOR_VERSION.$BURN_MICRO_VERSION
AC_SUBST(BURN_MAJOR_VERSION) AC_SUBST(BURN_MAJOR_VERSION)
@ -127,14 +131,14 @@ AC_SUBST(BURN_VERSION)
dnl Libtool versioning dnl Libtool versioning
LT_RELEASE=$BURN_MAJOR_VERSION.$BURN_MINOR_VERSION.$BURN_MICRO_VERSION LT_RELEASE=$BURN_MAJOR_VERSION.$BURN_MINOR_VERSION.$BURN_MICRO_VERSION
dnl dnl
dnl ### This is the release version libburn-1.0.6 dnl This is the release version libburn-1.1.8
dnl This is the development version after above release version dnl ### This is the development version after above release version
dnl LT_CURRENT++, LT_AGE++ has not yet happened. dnl LT_CURRENT++, LT_AGE++ has not yet happened.
dnl ### LT_CURRENT++, LT_AGE++ has happened meanwhile. dnl ### LT_CURRENT++, LT_AGE++ has happened meanwhile.
dnl dnl
dnl SONAME = 67 - 63 = 4 . Linux library name = libburn.so.4.63.0 dnl SONAME = 75 - 71 = 4 . Linux library name = libburn.so.4.71.0
LT_CURRENT=67 LT_CURRENT=75
LT_AGE=63 LT_AGE=71
LT_REVISION=0 LT_REVISION=0
LT_CURRENT_MINUS_AGE=`expr $LT_CURRENT - $LT_AGE` LT_CURRENT_MINUS_AGE=`expr $LT_CURRENT - $LT_AGE`

View File

@ -1,7 +1,7 @@
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */ /* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens /* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
Copyright (c) 2006 - 2010 Thomas Schmitt <scdbackup@gmx.net> Copyright (c) 2006 - 2011 Thomas Schmitt <scdbackup@gmx.net>
Provided under GPL version 2 or later. Provided under GPL version 2 or later.
*/ */
@ -183,11 +183,6 @@ static void remove_worker(pthread_t th)
{ {
struct w_list *a, *l = NULL; struct w_list *a, *l = NULL;
#ifdef Libburn_detach_done_workeR
int ret;
char msg[80];
#endif
for (a = workers; a; l = a, a = a->next) for (a = workers; a; l = a, a = a->next)
if (a->thread == th) { if (a->thread == th) {
if (l) if (l)
@ -200,8 +195,12 @@ static void remove_worker(pthread_t th)
/* Alternative : threads get detached and thus should /* Alternative : threads get detached and thus should
dispose themselves. dispose themselves.
*/ */
ret = pthread_detach(th); pthread_detach(th);
/* /*
int ret;
char msg[80];
ret = pthread_detach(th);
sprintf(msg, sprintf(msg,
"remove_workers(): pid= %lu pthread_detach(%lu)= %d", "remove_workers(): pid= %lu pthread_detach(%lu)= %d",
(unsigned long) getpid(), (unsigned long) th, ret); (unsigned long) getpid(), (unsigned long) th, ret);
@ -585,7 +584,6 @@ static void *write_disc_worker_func(struct w_list *w)
void burn_disc_write(struct burn_write_opts *opts, struct burn_disc *disc) void burn_disc_write(struct burn_write_opts *opts, struct burn_disc *disc)
{ {
int ret;
struct write_opts o; struct write_opts o;
char *reasons= NULL; char *reasons= NULL;
struct burn_drive *d; struct burn_drive *d;
@ -648,7 +646,7 @@ void burn_disc_write(struct burn_write_opts *opts, struct burn_disc *disc)
tests in burn_*_write_sync() tests in burn_*_write_sync()
*/ */
BURN_ALLOC_MEM(reasons, char, BURN_REASONS_LEN + 80); BURN_ALLOC_MEM_VOID(reasons, char, BURN_REASONS_LEN + 80);
strcpy(reasons, "Write job parameters are unsuitable:\n"); strcpy(reasons, "Write job parameters are unsuitable:\n");
if (burn_precheck_write(opts, disc, reasons + strlen(reasons), 1) if (burn_precheck_write(opts, disc, reasons + strlen(reasons), 1)
<= 0) { <= 0) {

View File

@ -1,5 +1,5 @@
/* /*
cleanup.c , Copyright 2006 Thomas Schmitt <scdbackup@gmx.net> cleanup.c , Copyright 2006 - 2011 Thomas Schmitt <scdbackup@gmx.net>
A signal handler which cleans up an application and exits. A signal handler which cleans up an application and exits.
@ -205,9 +205,10 @@ main()
Cleanup_set_handlers(&demoapp,(Cleanup_app_handler_T) Demo_app_handler,0); Cleanup_set_handlers(&demoapp,(Cleanup_app_handler_T) Demo_app_handler,0);
if(1) { /* change to 0 in order to wait for external signals */ if(1) { /* change to 0 in order to wait for external signals */
char *cpt= NULL,c; char *cpt= NULL, c= ' ';
printf("Intentionally provoking SIGSEGV ...\n"); printf("Intentionally provoking SIGSEGV ...\n");
c= *cpt; c= *cpt;
printf("Strange: The system ignored a SIGSEGV: c= %u\n", (unsigned int) c);
} else { } else {
printf("killme: %d\n",getpid()); printf("killme: %d\n",getpid());
sleep(3600); sleep(3600);

View File

@ -25,20 +25,4 @@ void burn_set_verbosity(int v)
burn_verbosity = v; burn_verbosity = v;
} }
void burn_print(int level, const char *a, ...)
{
#ifdef WIN32
char debug_string_data[256];
#endif
va_list vl;
if (level <= burn_verbosity) {
va_start(vl, a);
#ifdef WIN32
vsprintf(debug_string_data, a, vl);
OutputDebugString(debug_string_data);
#else
vfprintf(stderr, a, vl);
#endif
}
}

View File

@ -15,6 +15,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <unistd.h> #include <unistd.h>
#include <signal.h> #include <signal.h>
#include <dirent.h>
/* ts A61007 */ /* ts A61007 */
/* #include <a ssert.h> */ /* #include <a ssert.h> */
@ -310,59 +311,197 @@ int burn_drive_inquire_media(struct burn_drive *d)
if (d->current_profile == -1 || d->current_is_cd_profile) if (d->current_profile == -1 || d->current_is_cd_profile)
d->read_toc(d); d->read_toc(d);
/* ts A70314 */ /* ts A70314 , B10712 */
d->status = BURN_DISC_UNSUITABLE; if (d->status != BURN_DISC_EMPTY)
d->status = BURN_DISC_UNSUITABLE;
} }
return 1; return 1;
} }
/* ts B10730 */
/* Send a default mode page 05 to CD and DVD-R-oids */
int burn_drive_send_default_page_05(struct burn_drive *d, int flag)
{
struct burn_write_opts *opts;
if (d->sent_default_page_05)
return 0;
if (!((d->status == BURN_DISC_APPENDABLE ||
d->status == BURN_DISC_BLANK) &&
(d->current_is_cd_profile || d->current_profile == 0x11 ||
d->current_profile == 0x14 || d->current_profile == 0x15)))
return 0;
opts = burn_write_opts_new(d);
if (opts == NULL)
return -1;
if (d->status == BURN_DISC_APPENDABLE)
burn_write_opts_set_write_type(opts,
BURN_WRITE_TAO, BURN_BLOCK_MODE1);
else
burn_write_opts_set_write_type(opts,
BURN_WRITE_SAO, BURN_BLOCK_SAO);
d->send_write_parameters(d, opts);
burn_write_opts_free(opts);
d->sent_default_page_05 = 1;
return 1;
}
/* ts A70924 */
int burn_drive__fd_from_special_adr(char *adr)
{
int fd = -1, i;
if (strcmp(adr, "-") == 0)
fd = 1;
if(strncmp(adr, "/dev/fd/", 8) == 0) {
for (i = 8; adr[i]; i++)
if (!isdigit(adr[i]))
break;
if (i> 8 && adr[i] == 0)
fd = atoi(adr + 8);
}
return fd;
}
/* @param flag bit0= accept read-only files and return 2 in this case
bit1= accept write-only files and return 3 in this case
*/
static int burn_drive__is_rdwr(char *fname, int *stat_ret,
struct stat *stbuf_ret,
off_t *read_size_ret, int flag)
{
int fd, is_rdwr = 1, ret, getfl_ret, st_ret, mask;
struct stat stbuf;
off_t read_size = 0;
memset(&stbuf, 0, sizeof(struct stat));
fd = burn_drive__fd_from_special_adr(fname);
if (fd >= 0)
st_ret = fstat(fd, &stbuf);
else
st_ret = stat(fname, &stbuf);
if (st_ret != -1) {
is_rdwr = burn_os_is_2k_seekrw(fname, 0);
ret = 1;
if (S_ISREG(stbuf.st_mode))
read_size = stbuf.st_size;
else if (is_rdwr)
ret = burn_os_stdio_capacity(fname, &read_size);
if (ret <= 0 ||
read_size / (off_t) 2048 >= (off_t) 0x7ffffff0)
read_size = (off_t) 0x7ffffff0 * (off_t) 2048;
}
if (is_rdwr && fd >= 0) {
getfl_ret = fcntl(fd, F_GETFL);
/*
fprintf(stderr, "LIBBURN_DEBUG: burn_drive__is_rdwr: getfl_ret = %lX , O_RDWR = %lX , & = %lX , O_RDONLY = %lX\n", (unsigned long) getfl_ret, (unsigned long) O_RDWR, (unsigned long) (getfl_ret & O_RDWR), (unsigned long) O_RDONLY);
*/
mask = O_RDWR | O_WRONLY | O_RDONLY;
if (getfl_ret == -1 || (getfl_ret & mask) != O_RDWR)
is_rdwr = 0;
if ((flag & 1) && getfl_ret != -1 &&
(getfl_ret & mask) == O_RDONLY)
is_rdwr = 2;
if ((flag & 2) && getfl_ret != -1 &&
(getfl_ret & mask) == O_WRONLY)
is_rdwr = 3;
}
if (stat_ret != NULL)
*stat_ret = st_ret;
if (stbuf_ret != NULL)
memcpy(stbuf_ret, &stbuf, sizeof(struct stat));
if (read_size_ret != NULL)
*read_size_ret = read_size;
return is_rdwr;
}
int burn_drive_grab_stdio(struct burn_drive *d, int flag)
{
int stat_ret = -1, is_rdwr, ret;
struct stat stbuf;
off_t read_size= 0, size= 0;
char fd_name[40], *name_pt = NULL;
if(d->stdio_fd >= 0) {
sprintf(fd_name, "/dev/fd/%d", d->stdio_fd);
name_pt = fd_name;
} else if (d->devname[0]) {
name_pt = d->devname;
}
if (name_pt != NULL) {
/* re-assess d->media_read_capacity and free space */
is_rdwr = burn_drive__is_rdwr(name_pt, &stat_ret, &stbuf,
&read_size, 1 | 2);
/* despite its name : last valid address, not size */
d->media_read_capacity =
read_size / 2048 - !(read_size % 2048);
if ((stat_ret == -1 || is_rdwr) && d->devname[0]) {
ret = burn_os_stdio_capacity(d->devname, &size);
if (ret > 0)
burn_drive_set_media_capacity_remaining(d,
size);
}
}
d->released = 0;
d->current_profile = 0xffff;
if(d->drive_role == 2 || d->drive_role == 3) {
d->status = BURN_DISC_BLANK;
} else if(d->drive_role == 4) {
if (d->media_read_capacity > 0)
d->status = BURN_DISC_FULL;
else
d->status = BURN_DISC_EMPTY;
} else if(d->drive_role == 5) {
if (stat_ret != -1 && S_ISREG(stbuf.st_mode) &&
stbuf.st_size > 0) {
d->status = BURN_DISC_APPENDABLE;
if (stbuf.st_size / (off_t) 2048
>= 0x7ffffff0) {
d->status = BURN_DISC_FULL;
d->role_5_nwa = 0x7ffffff0;
} else
d->role_5_nwa = stbuf.st_size / 2048 +
!!(stbuf.st_size % 2048);
} else
d->status = BURN_DISC_BLANK;
} else {
d->status = BURN_DISC_EMPTY;
d->current_profile = 0;
}
d->busy = BURN_DRIVE_IDLE;
return 1;
}
int burn_drive_grab(struct burn_drive *d, int le) int burn_drive_grab(struct burn_drive *d, int le)
{ {
int errcode; int errcode;
/* ts A61125 - B10314 */ /* ts A61125 - B10314 */
int ret, sose, stat_ret = -1; int ret, sose;
struct stat stbuf;
if (!d->released) { if (!d->released) {
burn_print(1, "can't grab - already grabbed\n"); libdax_msgs_submit(libdax_messenger, d->global_index,
0x00020189, LIBDAX_MSGS_SEV_FATAL,
LIBDAX_MSGS_PRIO_LOW,
"Drive is already grabbed by libburn", 0, 0);
return 0; return 0;
} }
if(d->drive_role != 1) { if(d->drive_role != 1) {
d->released = 0; ret = burn_drive_grab_stdio(d, 0);
d->current_profile = 0xffff; return ret;
if (d->devname[0])
stat_ret = stat(d->devname, &stbuf);
if(d->drive_role == 2 || d->drive_role == 3) {
d->status = BURN_DISC_BLANK;
} else if(d->drive_role == 4) {
if (d->media_read_capacity > 0)
d->status = BURN_DISC_FULL;
else
d->status = BURN_DISC_EMPTY;
} else if(d->drive_role == 5) {
if (stat_ret != -1 && S_ISREG(stbuf.st_mode) &&
stbuf.st_size > 0) {
d->status = BURN_DISC_APPENDABLE;
d->role_5_nwa = stbuf.st_size / 2048 +
!!(stbuf.st_size % 2048);
} else
d->status = BURN_DISC_BLANK;
} else {
d->status = BURN_DISC_EMPTY;
d->current_profile = 0;
}
d->busy = BURN_DRIVE_IDLE;
return 1;
} }
d->status = BURN_DISC_UNREADY; d->status = BURN_DISC_UNREADY;
errcode = d->grab(d); errcode = d->grab(d);
if (errcode == 0)
if (errcode == 0) {
burn_print(1, "low level drive grab failed\n");
return 0; return 0;
}
d->busy = BURN_DRIVE_GRABBING; d->busy = BURN_DRIVE_GRABBING;
if (le) if (le)
@ -379,6 +518,8 @@ int burn_drive_grab(struct burn_drive *d, int le)
d->silent_on_scsi_error = 1; d->silent_on_scsi_error = 1;
/* ts A61125 : outsourced media state inquiry aspects */ /* ts A61125 : outsourced media state inquiry aspects */
ret = burn_drive_inquire_media(d); ret = burn_drive_inquire_media(d);
burn_drive_send_default_page_05(d, 0);
d->silent_on_scsi_error = sose; d->silent_on_scsi_error = sose;
d->busy = BURN_DRIVE_IDLE; d->busy = BURN_DRIVE_IDLE;
return ret; return ret;
@ -474,7 +615,6 @@ struct burn_drive *burn_drive_finish_enum(struct burn_drive *d)
/* try to get the drive info */ /* try to get the drive info */
ret = t->grab(t); ret = t->grab(t);
if (ret) { if (ret) {
burn_print(2, "getting drive info\n");
t->getcaps(t); t->getcaps(t);
t->unlock(t); t->unlock(t);
t->released = 1; t->released = 1;
@ -499,7 +639,9 @@ ex:
/* ts A61125 : model aspects of burn_drive_release */ /* ts A61125 : model aspects of burn_drive_release */
int burn_drive_mark_unready(struct burn_drive *d) /* @param flag bit3= do not close d->stdio_fd
*/
int burn_drive_mark_unready(struct burn_drive *d, int flag)
{ {
/* ts A61020 : mark media info as invalid */ /* ts A61020 : mark media info as invalid */
d->start_lba= -2000000000; d->start_lba= -2000000000;
@ -519,21 +661,23 @@ int burn_drive_mark_unready(struct burn_drive *d)
burn_disc_free(d->disc); burn_disc_free(d->disc);
d->disc = NULL; d->disc = NULL;
} }
if (d->stdio_fd >= 0) if (!(flag & 8)) {
close (d->stdio_fd); if (d->stdio_fd >= 0)
d->stdio_fd = -1; close (d->stdio_fd);
d->stdio_fd = -1;
}
return 1; return 1;
} }
/* ts A70918 : outsourced from burn_drive_release() and enhanced */ /* ts A70918 : outsourced from burn_drive_release() and enhanced */
/** @param flag bit0-2 = mode : 0=unlock , 1=unlock+eject , 2=leave locked /** @param flag bit0-2 = mode : 0=unlock , 1=unlock+eject , 2=leave locked
bit3= do not call d->release()
*/ */
int burn_drive_release_fl(struct burn_drive *d, int flag) int burn_drive_release_fl(struct burn_drive *d, int flag)
{ {
if (d->released) { if (d->released) {
/* ts A61007 */ /* ts A61007 */
/* burn_print(1, "second release on drive!\n"); */
libdax_msgs_submit(libdax_messenger, libdax_msgs_submit(libdax_messenger,
d->global_index, 0x00020105, d->global_index, 0x00020105,
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH, LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
@ -559,15 +703,17 @@ int burn_drive_release_fl(struct burn_drive *d, int flag)
d->unlock(d); d->unlock(d);
if ((flag & 7) == 1) if ((flag & 7) == 1)
d->eject(d); d->eject(d);
burn_drive_snooze(d, 0); if (!(flag & 8)) {
d->release(d); burn_drive_snooze(d, 0);
d->release(d);
}
} }
d->needs_sync_cache = 0; /* just to be sure */ d->needs_sync_cache = 0; /* just to be sure */
d->released = 1; d->released = 1;
/* ts A61125 : outsourced model aspects */ /* ts A61125 : outsourced model aspects */
burn_drive_mark_unready(d); burn_drive_mark_unready(d, flag & 8);
return 1; return 1;
} }
@ -595,6 +741,36 @@ void burn_drive_release(struct burn_drive *d, int le)
} }
/* ts B11002 */
/* API */
int burn_drive_re_assess(struct burn_drive *d, int flag)
{
int ret;
if (d->released) {
libdax_msgs_submit(libdax_messenger, d->global_index,
0x00020108,
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
"Drive is not grabbed on burn_drive_re_assess()",
0, 0);
return 0;
}
burn_drive_release_fl(d, 2 | 8);
if(d->drive_role != 1) {
ret = burn_drive_grab_stdio(d, 0);
return ret;
}
d->busy = BURN_DRIVE_GRABBING;
ret = burn_drive_inquire_media(d);
burn_drive_send_default_page_05(d, 0);
d->busy = BURN_DRIVE_IDLE;
d->released = 0;
return ret;
}
/* ts A70918 */ /* ts A70918 */
/* API */ /* API */
int burn_drive_leave_locked(struct burn_drive *d, int flag) int burn_drive_leave_locked(struct burn_drive *d, int flag)
@ -650,9 +826,6 @@ void burn_disc_erase_sync(struct burn_drive *d, int fast)
{ {
int ret; int ret;
burn_print(1, "erasing drive %s %s\n", d->idata->vendor,
d->idata->product);
if (d->drive_role == 5) { /* Random access write-only drive */ if (d->drive_role == 5) { /* Random access write-only drive */
ret = truncate(d->devname, (off_t) 0); ret = truncate(d->devname, (off_t) 0);
if (ret == -1) { if (ret == -1) {
@ -699,7 +872,7 @@ void burn_disc_erase_sync(struct burn_drive *d, int fast)
d->progress.sector = 0x10000; d->progress.sector = 0x10000;
/* ts A61125 : update media state records */ /* ts A61125 : update media state records */
burn_drive_mark_unready(d); burn_drive_mark_unready(d, 0);
if (d->drive_role == 1) if (d->drive_role == 1)
burn_drive_inquire_media(d); burn_drive_inquire_media(d);
d->busy = BURN_DRIVE_IDLE; d->busy = BURN_DRIVE_IDLE;
@ -753,7 +926,7 @@ void burn_disc_format_sync(struct burn_drive *d, off_t size, int flag)
goto ex; goto ex;
/* update media state records */ /* update media state records */
burn_drive_mark_unready(d); burn_drive_mark_unready(d, 0);
burn_drive_inquire_media(d); burn_drive_inquire_media(d);
if (flag & 1) { if (flag & 1) {
/* write size in zeros */; /* write size in zeros */;
@ -932,17 +1105,6 @@ void burn_drive_cancel(struct burn_drive *d)
*/ */
} }
/* ts A61007 : defunct because unused */
#if 0
int burn_drive_get_block_types(struct burn_drive *d,
enum burn_write_types write_type)
{
burn_print(12, "write type: %d\n", write_type);
a ssert( /* (write_type >= BURN_WRITE_PACKET) && */
(write_type <= BURN_WRITE_RAW));
return d->block_types[write_type];
}
#endif
static void strip_spaces(char *str) static void strip_spaces(char *str)
{ {
@ -1179,7 +1341,7 @@ int burn_drive_forget(struct burn_drive *d, int force)
if(occup > 0) if(occup > 0)
if(force < 1) if(force < 1)
return 0; return 0;
if(occup > 10) if(occup >= 10)
return 0; return 0;
/* >>> do any drive calming here */; /* >>> do any drive calming here */;
@ -1201,7 +1363,9 @@ int burn_drive_info_forget(struct burn_drive_info *info, int force)
void burn_drive_info_free(struct burn_drive_info drive_infos[]) void burn_drive_info_free(struct burn_drive_info drive_infos[])
{ {
#ifndef Libburn_free_all_drives_on_infO
int i; int i;
#endif
/* ts A60904 : ticket 62, contribution by elmom */ /* ts A60904 : ticket 62, contribution by elmom */
/* clarifying the meaning and the identity of the victim */ /* clarifying the meaning and the identity of the victim */
@ -1394,79 +1558,6 @@ char *burn_drive_whitelist_item(int idx, int flag)
} }
/* ts A70924 */
int burn_drive__fd_from_special_adr(char *adr)
{
int fd = -1, i;
if (strcmp(adr, "-") == 0)
fd = 1;
if(strncmp(adr, "/dev/fd/", 8) == 0) {
for (i = 8; adr[i]; i++)
if (!isdigit(adr[i]))
break;
if (i> 8 && adr[i] == 0)
fd = atoi(adr + 8);
}
return fd;
}
/* @param flag bit0= accept read-only files and return 2 in this case
bit1= accept write-only files and return 3 in this case
*/
static int burn_drive__is_rdwr(char *fname, int *stat_ret,
struct stat *stbuf_ret,
off_t *read_size_ret, int flag)
{
int fd, is_rdwr = 1, ret, getfl_ret, st_ret, mask;
struct stat stbuf;
off_t read_size = 0;
memset(&stbuf, 0, sizeof(struct stat));
fd = burn_drive__fd_from_special_adr(fname);
if (fd >= 0)
st_ret = fstat(fd, &stbuf);
else
st_ret = stat(fname, &stbuf);
if (st_ret != -1) {
is_rdwr = burn_os_is_2k_seekrw(fname, 0);
if (S_ISREG(stbuf.st_mode))
read_size = stbuf.st_size;
else if (is_rdwr) {
ret = burn_os_stdio_capacity(fname, &read_size);
if (ret <= 0)
read_size = (off_t) 0x7ffffff0 * (off_t) 2048;
}
}
if (is_rdwr && fd >= 0) {
getfl_ret = fcntl(fd, F_GETFL);
/*
fprintf(stderr, "LIBBURN_DEBUG: burn_drive__is_rdwr: getfl_ret = %lX , O_RDWR = %lX , & = %lX , O_RDONLY = %lX\n", (unsigned long) getfl_ret, (unsigned long) O_RDWR, (unsigned long) (getfl_ret & O_RDWR), (unsigned long) O_RDONLY);
*/
mask = O_RDWR | O_WRONLY | O_RDONLY;
if (getfl_ret == -1 || (getfl_ret & mask) != O_RDWR)
is_rdwr = 0;
if ((flag & 1) && getfl_ret != -1 &&
(getfl_ret & mask) == O_RDONLY)
is_rdwr = 2;
if ((flag & 2) && getfl_ret != -1 &&
(getfl_ret & mask) == O_WRONLY)
is_rdwr = 3;
}
if (stat_ret != NULL)
*stat_ret = st_ret;
if (stbuf_ret != NULL)
memcpy(stbuf_ret, &stbuf, sizeof(struct stat));
if (read_size_ret != NULL)
*read_size_ret = read_size;
return is_rdwr;
}
static int burn_role_by_access(char *fname, int flag) static int burn_role_by_access(char *fname, int flag)
{ {
/* We normally need _LARGEFILE64_SOURCE defined by the build system. /* We normally need _LARGEFILE64_SOURCE defined by the build system.
@ -1580,8 +1671,13 @@ int burn_drive_grab_dummy(struct burn_drive_info *drive_infos[], char *fname)
(burn_drive_role_4_allowed & 8)) { (burn_drive_role_4_allowed & 8)) {
d->status = BURN_DISC_APPENDABLE; d->status = BURN_DISC_APPENDABLE;
d->block_types[BURN_WRITE_SAO] = 0; d->block_types[BURN_WRITE_SAO] = 0;
d->role_5_nwa = stbuf.st_size / 2048 + if (stbuf.st_size / (off_t) 2048
!!(stbuf.st_size % 2048); >= 0x7ffffff0) {
d->status = BURN_DISC_FULL;
d->role_5_nwa = 0x7ffffff0;
} else
d->role_5_nwa = stbuf.st_size / 2048 +
!!(stbuf.st_size % 2048);
} else { } else {
d->status = BURN_DISC_BLANK; d->status = BURN_DISC_BLANK;
d->block_types[BURN_WRITE_SAO] = d->block_types[BURN_WRITE_SAO] =
@ -1681,7 +1777,7 @@ int burn_drive_scan_and_grab(struct burn_drive_info *drive_infos[], char* adr,
if (ret < 0) if (ret < 0)
return -1; return -1;
if (n_drives <= 0) if (n_drives == 0)
return 0; return 0;
/* /*
fprintf(stderr, "libburn: experimental: n_drives %d , drivetop %d\n", fprintf(stderr, "libburn: experimental: n_drives %d , drivetop %d\n",
@ -2009,8 +2105,9 @@ int burn_drive_convert_fs_adr_sub(char *path, char adr[], int *rec_count)
burn_drive_is_enumerable_adr(path)) { burn_drive_is_enumerable_adr(path)) {
if(strlen(path) >= BURN_DRIVE_ADR_LEN) if(strlen(path) >= BURN_DRIVE_ADR_LEN)
return -1; return -1;
burn_drive_adr_debug_msg( if (strncmp(path, "stdio:", 6) != 0)
"burn_drive_is_enumerable_adr( %s ) is true", path); burn_drive_adr_debug_msg(
"burn_drive_is_enumerable_adr( %s ) is true", path);
strcpy(adr, path); strcpy(adr, path);
return 1; return 1;
} }
@ -2042,6 +2139,7 @@ int burn_drive_convert_fs_adr_sub(char *path, char adr[], int *rec_count)
return 0; return 0;
} }
/* API */
/** Try to convert a given existing filesystem address into a persistent drive /** Try to convert a given existing filesystem address into a persistent drive
address. */ address. */
int burn_drive_convert_fs_adr(char *path, char adr[]) int burn_drive_convert_fs_adr(char *path, char adr[])
@ -2053,6 +2151,88 @@ int burn_drive_convert_fs_adr(char *path, char adr[])
} }
/* API */
int burn_lookup_device_link(char *dev_adr, char link_adr[],
char *dir_adr, char **ranks, int rank_count, int flag)
{
DIR *dirpt= NULL;
struct dirent *entry;
struct stat link_stbuf;
char *adr= NULL, *namept, *sys_adr= NULL;
int ret, name_rank, found_rank= 0x7fffffff, dirlen, i, rec_count = 0;
static char default_ranks_data[][8] =
{"dvdrw", "cdrw", "dvd", "cdrom", "cd"};
char *default_ranks[5];
link_adr[0] = 0;
if (ranks == NULL) {
for (i = 0; i < 5; i++)
default_ranks[i] = default_ranks_data[i];
ranks = default_ranks;
rank_count= 5;
}
dirlen= strlen(dir_adr) + 1;
if (strlen(dir_adr) + 1 >= BURN_DRIVE_ADR_LEN) {
/* >>> Issue warning about oversized directory address */;
{ret = 0; goto ex;}
}
BURN_ALLOC_MEM(adr, char, BURN_DRIVE_ADR_LEN);
BURN_ALLOC_MEM(sys_adr, char, BURN_DRIVE_ADR_LEN);
dirpt = opendir(dir_adr);
if (dirpt == NULL)
{ret = 0; goto ex;}
strcpy(adr, dir_adr);
strcat(adr, "/");
namept = adr + strlen(dir_adr) + 1;
while(1) {
entry = readdir(dirpt);
if(entry == NULL)
break;
if (strlen(entry->d_name) + dirlen >= BURN_DRIVE_ADR_LEN)
continue;
strcpy(namept, entry->d_name);
if(lstat(adr, &link_stbuf) == -1)
continue;
if((link_stbuf.st_mode & S_IFMT) != S_IFLNK)
continue;
/* Determine rank and omit uninteresting ones */
for(name_rank= 0; name_rank < rank_count; name_rank++)
if(strncmp(namept, ranks[name_rank],
strlen(ranks[name_rank])) == 0)
break;
/* we look for lowest rank */
if(name_rank >= rank_count ||
name_rank > found_rank ||
(name_rank == found_rank &&
strcmp(namept, link_adr + dirlen) >= 0))
continue;
/* Does name point to the same device as dev_adr ? */
ret= burn_drive_resolve_link(adr, sys_adr, &rec_count, 2);
if(ret < 0)
goto ex;
if(ret == 0)
continue;
if(strcmp(dev_adr, sys_adr) == 0) {
strcpy(link_adr, adr);
found_rank= name_rank;
}
}
ret= 2;
if(found_rank < 0x7fffffff)
ret= 1;
ex:;
if(dirpt != NULL)
closedir(dirpt);
BURN_FREE_MEM(adr);
BURN_FREE_MEM(sys_adr);
return(ret);
}
/** A pacifier function suitable for burn_abort. /** A pacifier function suitable for burn_abort.
@param handle If not NULL, a pointer to a text suitable for printf("%s") @param handle If not NULL, a pointer to a text suitable for printf("%s")
*/ */
@ -2137,7 +2317,7 @@ int burn_abort_5(int patience,
} }
if(occup <= 10) { if(occup < 10) {
if (drive_array[i].drive_role != 1) if (drive_array[i].drive_role != 1)
/* occup == -1 comes early */ /* occup == -1 comes early */
usleep(1000000); usleep(1000000);
@ -2596,11 +2776,7 @@ int burn_disc_get_multi_caps(struct burn_drive *d, enum burn_write_types wt,
size = d->media_capacity_remaining; size = d->media_capacity_remaining;
burn_os_stdio_capacity(d->devname, &size); burn_os_stdio_capacity(d->devname, &size);
burn_drive_set_media_capacity_remaining(d, size); burn_drive_set_media_capacity_remaining(d, size);
o->start_range_high = d->media_capacity_remaining;
/* >>> This looks wrong ! */
/* >>> should add file size */
o->start_range_high = size;
o->start_alignment = 2048; /* imposting a drive, not a file */ o->start_alignment = 2048; /* imposting a drive, not a file */
o->might_do_sao = 4; o->might_do_sao = 4;
o->might_do_tao = 2; o->might_do_tao = 2;
@ -2615,10 +2791,7 @@ int burn_disc_get_multi_caps(struct burn_drive *d, enum burn_write_types wt,
/* >>> start_range_low = file size rounded to 2048 */; /* >>> start_range_low = file size rounded to 2048 */;
/* >>> This looks wrong ! */ o->start_range_high = d->media_capacity_remaining;
/* >>> should add file size */
o->start_range_high = size;
o->start_alignment = 2048; /* imposting a drive, not a file */ o->start_alignment = 2048; /* imposting a drive, not a file */
if (s == BURN_DISC_APPENDABLE) { if (s == BURN_DISC_APPENDABLE) {
if (wt == BURN_WRITE_SAO || wt == BURN_WRITE_RAW) if (wt == BURN_WRITE_SAO || wt == BURN_WRITE_RAW)
@ -3031,10 +3204,13 @@ int burn_drive_find_by_thread_pid(struct burn_drive **d, pid_t pid,
*/ */
int burn_drive_set_media_capacity_remaining(struct burn_drive *d, off_t value) int burn_drive_set_media_capacity_remaining(struct burn_drive *d, off_t value)
{ {
if (value / (off_t) 2048 > (off_t) 0x7ffffff0)
value = ((off_t) 0x7ffffff0) * (off_t) 2048;
d->media_capacity_remaining = value; d->media_capacity_remaining = value;
return 1; return 1;
} }
/* ts A81215 : API */ /* ts A81215 : API */
int burn_get_read_capacity(struct burn_drive *d, int *capacity, int flag) int burn_get_read_capacity(struct burn_drive *d, int *capacity, int flag)
{ {
@ -3088,7 +3264,7 @@ int burn_disc_get_cd_info(struct burn_drive *d, char disc_type[80],
} }
*disc_id = d->disc_id; *disc_id = d->disc_id;
memcpy(bar_code, d->disc_bar_code, 8); memcpy(bar_code, d->disc_bar_code, 8);
bar_code[9]= 0; bar_code[8]= 0;
*app_code = d->disc_app_code; *app_code = d->disc_app_code;
*valid = d->disc_info_valid; *valid = d->disc_info_valid;
return 1; return 1;
@ -3109,6 +3285,23 @@ int burn_disc_get_bd_spare_info(struct burn_drive *d,
} }
/* ts B10801 : API */
int burn_disc_get_phys_format_info(struct burn_drive *d, int *disk_category,
char **book_name, int *part_version, int *num_layers,
int *num_blocks, int flag)
{
int ret;
if (burn_drive_get_drive_role(d) != 1)
return 0;
*disk_category = *part_version = *num_layers = *num_blocks = 0;
ret = mmc_get_phys_format_info(d, disk_category, book_name,
part_version, num_layers, num_blocks, 0);
return ret;
}
/* ts B10525 : API */ /* ts B10525 : API */
int burn_disc_next_track_is_damaged(struct burn_drive *d, int flag) int burn_disc_next_track_is_damaged(struct burn_drive *d, int flag)
{ {

View File

@ -1,7 +1,7 @@
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */ /* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
/* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens /* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
Copyright (c) 2006 - 2010 Thomas Schmitt <scdbackup@gmx.net> Copyright (c) 2006 - 2011 Thomas Schmitt <scdbackup@gmx.net>
Provided under GPL version 2 or later. Provided under GPL version 2 or later.
*/ */
@ -85,7 +85,7 @@ struct burn_drive *burn_drive_finish_enum(struct burn_drive *d);
int burn_drive_inquire_media(struct burn_drive *d); int burn_drive_inquire_media(struct burn_drive *d);
/* ts A61125 : model aspects of burn_drive_release */ /* ts A61125 : model aspects of burn_drive_release */
int burn_drive_mark_unready(struct burn_drive *d); int burn_drive_mark_unready(struct burn_drive *d, int flag);
/* ts A61226 */ /* ts A61226 */
@ -151,4 +151,8 @@ int burn_abort_5(int patience,
int (*pacifier_func)(void *handle, int patience, int elapsed), int (*pacifier_func)(void *handle, int patience, int elapsed),
void *handle, int elapsed, int flag); void *handle, int elapsed, int flag);
/* ts B10730 */
/* Send a default mode page 05 to CD and DVD-R-oids */
int burn_drive_send_default_page_05(struct burn_drive *d, int flag);
#endif /* __DRIVE */ #endif /* __DRIVE */

View File

@ -625,7 +625,9 @@ void burn_fifo_next_interval(struct burn_source *source,
*interval_min_fill = fs->interval_min_fill; *interval_min_fill = fs->interval_min_fill;
ret = burn_fifo_inquire_status(source, ret = burn_fifo_inquire_status(source,
&size, &free_bytes, &status_text); &size, &free_bytes, &status_text);
if (ret < 0)
return;
fs->interval_min_fill = size - free_bytes - 1; fs->interval_min_fill = size - free_bytes - 1;
} }

View File

@ -36,6 +36,12 @@ void *burn_alloc_mem(size_t size, size_t count, int flag);
ret= -1; goto ex; \ ret= -1; goto ex; \
} } } }
#define BURN_ALLOC_MEM_VOID(pt, typ, count) { \
pt= (typ *) burn_alloc_mem(sizeof(typ), (size_t) (count), 0); \
if(pt == NULL) { \
goto ex; \
} }
#define BURN_FREE_MEM(pt) { \ #define BURN_FREE_MEM(pt) { \
if(pt != NULL) \ if(pt != NULL) \
free((char *) pt); \ free((char *) pt); \

View File

@ -561,9 +561,9 @@ struct burn_drive_info
char revision[5]; char revision[5];
/** Invalid: Was: "Location of the drive in the filesystem." */ /** Invalid: Was: "Location of the drive in the filesystem." */
/** This string has no meaning any more. Once it stored the persistent /** This string has no meaning any more. Once it stored the drive
drive address. Now always use function burn_drive_d_get_adr() to device file address. Now always use function burn_drive_d_get_adr()
inquire a persistent address. ^^^^^^ ALWAYS ^^^^^^^^ */ to inquire a device file address. ^^^^^ ALWAYS ^^^^^^^*/
char location[17]; char location[17];
/** Can the drive read DVD-RAM discs */ /** Can the drive read DVD-RAM discs */
@ -782,7 +782,7 @@ int burn_abort_pacifier(void *handle, int patience, int elapsed);
void burn_set_verbosity(int level); void burn_set_verbosity(int level);
/* ts A91111 */ /* ts A91111 */
/** Enable resp. disable logging of SCSI commands (currently GNU/Linux only). /** Enable resp. disable logging of SCSI commands.
This call can be made at any time - even before burn_initialize(). This call can be made at any time - even before burn_initialize().
It is in effect for all active drives and currently not very thread It is in effect for all active drives and currently not very thread
safe for multiple drives. safe for multiple drives.
@ -840,7 +840,7 @@ void burn_allow_untested_profiles(int yes);
/* ts A60823 */ /* ts A60823 */
/** Aquire a drive with known persistent address. /** Aquire a drive with known device file address.
This is the sysadmin friendly way to open one drive and to leave all This is the sysadmin friendly way to open one drive and to leave all
others untouched. It bundles the following API calls to form a others untouched. It bundles the following API calls to form a
@ -912,7 +912,7 @@ void burn_allow_untested_profiles(int yes);
when it is no longer needed. when it is no longer needed.
This is a result from call burn_drive_scan(). See there. This is a result from call burn_drive_scan(). See there.
Use with driveno 0 only. Use with driveno 0 only.
@param adr The persistent address of the desired drive. Either once @param adr The device file address of the desired drive. Either once
obtained by burn_drive_d_get_adr() or composed skillfully by obtained by burn_drive_d_get_adr() or composed skillfully by
application resp. its user. E.g. "/dev/sr0". application resp. its user. E.g. "/dev/sr0".
Consider to preprocess it by burn_drive_convert_fs_adr(). Consider to preprocess it by burn_drive_convert_fs_adr().
@ -994,25 +994,25 @@ void burn_drive_info_free(struct burn_drive_info drive_infos[]);
/* ts A60823 */ /* ts A60823 */
/* @since 0.2.2 */ /* @since 0.2.2 */
/** Maximum length+1 to expect with a persistent drive address string */ /** Maximum length+1 to expect with a drive device file address string */
#define BURN_DRIVE_ADR_LEN 1024 #define BURN_DRIVE_ADR_LEN 1024
/* ts A70906 */ /* ts A70906 */
/** Inquire the persistent address of the given drive. /** Inquire the device file address of the given drive.
@param drive The drive to inquire. @param drive The drive to inquire.
@param adr An application provided array of at least BURN_DRIVE_ADR_LEN @param adr An application provided array of at least BURN_DRIVE_ADR_LEN
characters size. The persistent address gets copied to it. characters size. The device file address gets copied to it.
@return >0 success , <=0 error (due to libburn internal problem) @return >0 success , <=0 error (due to libburn internal problem)
@since 0.4.0 @since 0.4.0
*/ */
int burn_drive_d_get_adr(struct burn_drive *drive, char adr[]); int burn_drive_d_get_adr(struct burn_drive *drive, char adr[]);
/* A60823 */ /* A60823 */
/** Inquire the persistent address of a drive via a given drive_info object. /** Inquire the device file address of a drive via a given drive_info object.
(Note: This is a legacy call.) (Note: This is a legacy call.)
@param drive_info The drive to inquire.Usually some &(drive_infos[driveno]) @param drive_info The drive to inquire.Usually some &(drive_infos[driveno])
@param adr An application provided array of at least BURN_DRIVE_ADR_LEN @param adr An application provided array of at least BURN_DRIVE_ADR_LEN
characters size. The persistent address gets copied to it. characters size. The device file address gets copied to it.
@return >0 success , <=0 error (due to libburn internal problem) @return >0 success , <=0 error (due to libburn internal problem)
@since 0.2.6 @since 0.2.6
*/ */
@ -1020,21 +1020,23 @@ int burn_drive_get_adr(struct burn_drive_info *drive_info, char adr[]);
/* ts A60922 ticket 33 */ /* ts A60922 ticket 33 */
/** Evaluate whether the given address would be a possible persistent drive /** Evaluate whether the given address would be a drive device file address
address of libburn. which could be listed by a run of burn_drive_scan(). No check is made
whether a device file with this address exists or whether it leads
to a usable MMC drive.
@return 1 means yes, 0 means no @return 1 means yes, 0 means no
@since 0.2.6 @since 0.2.6
*/ */
int burn_drive_is_enumerable_adr(char *adr); int burn_drive_is_enumerable_adr(char *adr);
/* ts A60922 ticket 33 */ /* ts A60922 ticket 33 */
/** Try to convert a given existing filesystem address into a persistent drive /** Try to convert a given existing filesystem address into a drive device file
address. This succeeds with symbolic links or if a hint about the drive's address. This succeeds with symbolic links or if a hint about the drive's
system address can be read from the filesystem object and a matching drive system address can be read from the filesystem object and a matching drive
is found. is found.
@param path The address of an existing file system object @param path The address of an existing file system object
@param adr An application provided array of at least BURN_DRIVE_ADR_LEN @param adr An application provided array of at least BURN_DRIVE_ADR_LEN
characters size. The persistent address gets copied to it. characters size. The device file address gets copied to it.
@return 1 = success , 0 = failure , -1 = severe error @return 1 = success , 0 = failure , -1 = severe error
@since 0.2.6 @since 0.2.6
*/ */
@ -1042,7 +1044,7 @@ int burn_drive_convert_fs_adr(char *path, char adr[]);
/* ts A60923 */ /* ts A60923 */
/** Try to convert a given SCSI address of bus,host,channel,target,lun into /** Try to convert a given SCSI address of bus,host,channel,target,lun into
a persistent drive address. If a SCSI address component parameter is < 0 a drive device file address. If a SCSI address component parameter is < 0
then it is not decisive and the first enumerated address which matches then it is not decisive and the first enumerated address which matches
the >= 0 parameters is taken as result. the >= 0 parameters is taken as result.
Note: bus and (host,channel) are supposed to be redundant. Note: bus and (host,channel) are supposed to be redundant.
@ -1052,17 +1054,50 @@ int burn_drive_convert_fs_adr(char *path, char adr[]);
@param target_no "Target Number" or "SCSI Id" (a device) @param target_no "Target Number" or "SCSI Id" (a device)
@param lun_no "Logical Unit Number" (a sub device) @param lun_no "Logical Unit Number" (a sub device)
@param adr An application provided array of at least BURN_DRIVE_ADR_LEN @param adr An application provided array of at least BURN_DRIVE_ADR_LEN
characters size. The persistent address gets copied to it. characters size. The device file address gets copied to it.
@return 1 = success , 0 = failure , -1 = severe error @return 1 = success , 0 = failure , -1 = severe error
@since 0.2.6 @since 0.2.6
*/ */
int burn_drive_convert_scsi_adr(int bus_no, int host_no, int channel_no, int burn_drive_convert_scsi_adr(int bus_no, int host_no, int channel_no,
int target_no, int lun_no, char adr[]); int target_no, int lun_no, char adr[]);
/* ts B10728 */
/** Try to convert a given drive device file address into the address of a
symbolic link that points to this drive address.
Modern GNU/Linux systems may shuffle drive addresses from boot to boot.
The udev daemon is supposed to create links which always point to the
same drive, regardless of its system address.
This call tries to find such links.
@param dev_adr Should contain a drive address as returned by
burn_drive_scan().
@param link_adr An application provided array of at least
BURN_DRIVE_ADR_LEN characters size. The found link
address gets copied to it.
@param dir_adr The address of the directory where to look for links.
Normally: "/dev"
@param templ An array of pointers to name templates, which
links have to match. A symbolic link in dir_adr matches
a name template if it begins by that text. E.g.
link address "/dev/dvdrw1" matches template "dvdrw".
If templ is NULL, then the default array gets used:
{"dvdrw", "cdrw", "dvd", "cdrom", "cd"}
If several links would match, then a link will win,
which matches the template with the lowest array index.
Among these candidates, the one with the lowest strcmp()
rank will be chosen as link_adr.
@param num_templ Number of array elements in templ.
@param flag Bitfield for control purposes. Unused yet. Submit 0.
@return <0 severe error, 0 failed to search, 2 nothing found
1 success, link_adr is valid
@since 1.1.4
*/
int burn_lookup_device_link(char *dev_adr, char link_adr[],
char *dir_adr, char **templ, int num_templ, int flag);
/* ts A60923 - A61005 */ /* ts A60923 - A61005 */
/** Try to obtain bus,host,channel,target,lun from path. If there is an SCSI /** Try to obtain bus,host,channel,target,lun from path. If there is an SCSI
address at all, then this call should succeed with a persistent address at all, then this call should succeed with a drive device file
drive address obtained via burn_drive_d_get_adr(). It is also supposed to address obtained via burn_drive_d_get_adr(). It is also supposed to
succeed with any device file of a (possibly emulated) SCSI device. succeed with any device file of a (possibly emulated) SCSI device.
@return 1 = success , 0 = failure , -1 = severe error @return 1 = success , 0 = failure , -1 = severe error
@since 0.2.6 @since 0.2.6
@ -1111,6 +1146,17 @@ int burn_drive_probe_cd_write_modes(struct burn_drive_info *drive_info);
int burn_drive_snooze(struct burn_drive *d, int flag); int burn_drive_snooze(struct burn_drive *d, int flag);
/** Re-assess drive and media status. This should be done after a drive
underwent a status change and shall be further used without intermediate
burn_drive_release(), burn_drive_grab(). E.g. after blanking or burning.
@param drive The already grabbed drive to re-assess.
@param flag Unused yet. Submit 0.
@return 1 success , <= 0 could not determine drive and media state
@since 1.1.8
*/
int burn_drive_re_assess(struct burn_drive *d, int flag);
/** Release a drive. This should not be done until the drive is no longer /** Release a drive. This should not be done until the drive is no longer
busy (see burn_drive_get_status). busy (see burn_drive_get_status).
@param drive The drive to release. @param drive The drive to release.
@ -1261,6 +1307,27 @@ int burn_disc_get_cd_info(struct burn_drive *d, char disc_type[80],
int burn_disc_get_bd_spare_info(struct burn_drive *d, int burn_disc_get_bd_spare_info(struct burn_drive *d,
int *alloc_blocks, int *free_blocks, int flag); int *alloc_blocks, int *free_blocks, int flag);
/* ts B10801 */
/** Retrieve some media information which is mainly specific to media of
the DVD-R family: DVD-R , DVD-RW , DVD-R DL , HD DVD-R
Currently the information cannot be retrieved from other media types.
@param d The drive to query.
@param disk_category returns DVD Book to which the media complies
@param book_name returns a pointer to the book name of disk_category.
This memory is static. Do not alter or free it !
@param part_version returns the Media Version in the DVD Book
@param num_layers returns the number of media layers
@param num_blocks returns the number of blocks between pysical start
and physical end of the media
@param flag Bitfield for control purposes (unused yet, submit 0)
@return 1 = reply prarameters are valid,
<=0 = reply is invalid (e.g. because no DVD-R)
@since 1.1.4
*/
int burn_disc_get_phys_format_info(struct burn_drive *d, int *disk_category,
char **book_name, int *part_version, int *num_layers,
int *num_blocks, int flag);
/* ts A61110 */ /* ts A61110 */
/** Read start lba and Next Writeable Address of a track from media. /** Read start lba and Next Writeable Address of a track from media.
Usually a track lba is obtained from the result of burn_track_get_entry(). Usually a track lba is obtained from the result of burn_track_get_entry().
@ -1294,6 +1361,30 @@ int burn_disc_track_lba_nwa(struct burn_drive *d, struct burn_write_opts *o,
*/ */
int burn_disc_next_track_is_damaged(struct burn_drive *d, int flag); int burn_disc_next_track_is_damaged(struct burn_drive *d, int flag);
/* ts B10527 */
/** Try to close the last track and session of media which have bit0 set in
the return value of call burn_disc_next_track_is_damaged().
Whether it helps depends much on the reason why the media is reported
as damaged by the drive.
This call works only for profiles 0x09 CD-R, 0x0a CD-RW, 0x11 DVD-R,
0x14 DVD-RW sequential, 0x1b DVD+R, 0x2b DVD+R DL, 0x41 BD-R sequential.
Note: After writing it is advised to give up the drive and to grab it again
in order to learn about its view on the new media state.
@param o Write options created by burn_write_opts_new() and
manipulated by burn_write_opts_set_multi().
burn_write_opts_set_write_type() should be set to
BURN_WRITE_TAO, burn_write_opts_set_simulate() should be
set to 0.
@param flag Bitfield for control purposes
bit0= force close, even if no damage was seen
@return <=0 media not marked as damaged, or media type not suitable,
or closing attempted but failed
1= attempt finished without error indication
@since 1.1.0
*/
int burn_disc_close_damaged(struct burn_write_opts *o, int flag);
/* ts A70131 */ /* ts A70131 */
/** Read start lba of the first track in the last complete session. /** Read start lba of the first track in the last complete session.
This is the first parameter of mkisofs option -C. The second parameter This is the first parameter of mkisofs option -C. The second parameter
@ -1315,6 +1406,9 @@ int burn_disc_get_msc1(struct burn_drive *d, int *start_lba);
An eventual start address from burn_write_opts_set_start_byte() will be An eventual start address from burn_write_opts_set_start_byte() will be
subtracted from the obtained capacity estimation. Negative results get subtracted from the obtained capacity estimation. Negative results get
defaulted to 0. defaulted to 0.
If the drive is actually a file in a large filesystem or a large block
device, then the capacity is curbed to a maximum of 0x7ffffff0 blocks
= 4 TB - 32 KB.
@param d The drive to query. @param d The drive to query.
@param o If not NULL: write parameters to be set on drive before query @param o If not NULL: write parameters to be set on drive before query
@return number of most probably available free bytes @return number of most probably available free bytes
@ -1608,8 +1702,13 @@ int burn_precheck_write(struct burn_write_opts *o, struct burn_disc *disc,
of data and audio tracks. You must use BURN_WRITE_TAO for such sessions. of data and audio tracks. You must use BURN_WRITE_TAO for such sessions.
To be set by burn_write_opts_set_write_type(). To be set by burn_write_opts_set_write_type().
Note: This function is not suitable for overwriting data in the middle of Note: This function is not suitable for overwriting data in the middle of
a valid data area because it is allowed to append trailing data. a valid data area because it is allowed to append trailing data.
For exact random access overwriting use burn_random_access_write(). For exact random access overwriting use burn_random_access_write().
Note: After writing it is advised to give up the drive and to grab it again
in order to learn about its view on the new media state.
Note: Before mounting the written media it might be necessary to eject
and reload in order to allow the operating system to notice the new
media state.
@param o The options for the writing operation. @param o The options for the writing operation.
@param disc The struct burn_disc * that described the disc to be created @param disc The struct burn_disc * that described the disc to be created
*/ */
@ -2173,7 +2272,11 @@ int burn_drive_set_buffer_waiting(struct burn_drive *d, int enable,
int min_percent, int max_percent); int min_percent, int max_percent);
/* these are for my debugging, they will disappear */ /* these are for my [Derek Foreman's ?] debugging, they will disappear */
/* ts B11012 :
Of course, API symbols will not disappear. But these functions are of
few use, as they only print DEBUG messages.
*/
void burn_structure_print_disc(struct burn_disc *d); void burn_structure_print_disc(struct burn_disc *d);
void burn_structure_print_session(struct burn_session *s); void burn_structure_print_session(struct burn_session *s);
void burn_structure_print_track(struct burn_track *t); void burn_structure_print_track(struct burn_track *t);
@ -2230,7 +2333,7 @@ void burn_write_opts_set_format(struct burn_write_opts *opts, int format);
This corresponds to the Test Write bit in MMC mode page 05h. Several media This corresponds to the Test Write bit in MMC mode page 05h. Several media
types do not support this. See struct burn_multi_caps.might_simulate for types do not support this. See struct burn_multi_caps.might_simulate for
actual availability of this feature. actual availability of this feature.
If the media is suitable, the drive will perform burn_write_disc() as a If the media is suitable, the drive will perform burn_disc_write() as a
simulation instead of effective write operations. This means that the simulation instead of effective write operations. This means that the
media content and burn_disc_get_status() stay unchanged. media content and burn_disc_get_status() stay unchanged.
Note: With stdio-drives, the target file gets eventually created, opened, Note: With stdio-drives, the target file gets eventually created, opened,
@ -2707,8 +2810,8 @@ void burn_version(int *major, int *minor, int *micro);
*/ */
#define burn_header_version_major 1 #define burn_header_version_major 1
#define burn_header_version_minor 0 #define burn_header_version_minor 1
#define burn_header_version_micro 7 #define burn_header_version_micro 8
/** Note: /** Note:
Above version numbers are also recorded in configure.ac because libtool Above version numbers are also recorded in configure.ac because libtool
wants them as parameters at build time. wants them as parameters at build time.
@ -2984,6 +3087,8 @@ int burn_random_access_write(struct burn_drive *d, off_t byte_address,
can be read via burn_read_data() although some of them may never have been can be read via burn_read_data() although some of them may never have been
recorded. If tracks are recognizable then it is better to only read recorded. If tracks are recognizable then it is better to only read
LBAs which are part of some track. LBAs which are part of some track.
If the drive is actually a large file or block device, then the capacity
is curbed to a maximum of 0x7ffffff0 blocks = 4 TB - 32 KB.
@param d The drive from which to read @param d The drive from which to read
@param capacity Will return the result if valid @param capacity Will return the result if valid
@param flag Bitfield for control purposes: Unused yet, submit 0. @param flag Bitfield for control purposes: Unused yet, submit 0.
@ -3035,6 +3140,8 @@ int burn_read_data(struct burn_drive *d, off_t byte_address,
3= stdio-drive, sequential, write-only 3= stdio-drive, sequential, write-only
4= stdio-drive, random access, read-only 4= stdio-drive, random access, read-only
(only if enabled by burn_allow_drive_role_4()) (only if enabled by burn_allow_drive_role_4())
5= stdio-drive, random access, write-only
(only if enabled by burn_allow_drive_role_4())
@since 0.4.0 @since 0.4.0
*/ */
int burn_drive_get_drive_role(struct burn_drive *d); int burn_drive_get_drive_role(struct burn_drive *d);

View File

@ -20,6 +20,7 @@ burn_disc_get_formats;
burn_disc_get_media_id; burn_disc_get_media_id;
burn_disc_get_msc1; burn_disc_get_msc1;
burn_disc_get_multi_caps; burn_disc_get_multi_caps;
burn_disc_get_phys_format_info;
burn_disc_get_profile; burn_disc_get_profile;
burn_disc_get_sectors; burn_disc_get_sectors;
burn_disc_get_sessions; burn_disc_get_sessions;
@ -58,6 +59,7 @@ burn_drive_is_enumerable_adr;
burn_drive_leave_locked; burn_drive_leave_locked;
burn_drive_obtain_scsi_adr; burn_drive_obtain_scsi_adr;
burn_drive_probe_cd_write_modes; burn_drive_probe_cd_write_modes;
burn_drive_re_assess;
burn_drive_release; burn_drive_release;
burn_drive_scan; burn_drive_scan;
burn_drive_scan_and_grab; burn_drive_scan_and_grab;
@ -81,6 +83,7 @@ burn_guess_manufacturer;
burn_initialize; burn_initialize;
burn_is_aborting; burn_is_aborting;
burn_lba_to_msf; burn_lba_to_msf;
burn_lookup_device_link;
burn_msf_to_lba; burn_msf_to_lba;
burn_msf_to_sectors; burn_msf_to_sectors;
burn_msgs_obtain; burn_msgs_obtain;

View File

@ -1,6 +1,6 @@
/* libdax_msgs /* libdax_msgs
Message handling facility of libdax. Message handling facility of libburn and libisofs.
Copyright (C) 2006-2011 Thomas Schmitt <scdbackup@gmx.net>, Copyright (C) 2006-2011 Thomas Schmitt <scdbackup@gmx.net>,
provided under GPL version 2 or later. provided under GPL version 2 or later.
*/ */
@ -574,6 +574,7 @@ Range "scdbackup" : 0x00020000 to 0x0002ffff
0x00020186 (WARNING,HIGH) = Track damaged and not closed 0x00020186 (WARNING,HIGH) = Track damaged and not closed
0x00020187 (NOTE,HIGH) = Track not marked as damaged. No action taken. 0x00020187 (NOTE,HIGH) = Track not marked as damaged. No action taken.
0x00020188 (FAILURE,HIGH) = Cannot close damaged track on given media type 0x00020188 (FAILURE,HIGH) = Cannot close damaged track on given media type
0x00020189 (FATAL,HIGH) = Drive is already grabbed by libburn
libdax_audioxtr: libdax_audioxtr:
0x00020200 (SORRY,HIGH) = Cannot open audio source file 0x00020200 (SORRY,HIGH) = Cannot open audio source file

View File

@ -305,13 +305,12 @@ void mmc_send_cue_sheet(struct burn_drive *d, struct cue_sheet *s)
{ {
struct buffer *buf = NULL; struct buffer *buf = NULL;
struct command *c; struct command *c;
int ret = 1;
c = &(d->casual_command); c = &(d->casual_command);
mmc_start_if_needed(d, 0); mmc_start_if_needed(d, 0);
if (mmc_function_spy(d, "mmc_send_cue_sheet") <= 0) if (mmc_function_spy(d, "mmc_send_cue_sheet") <= 0)
return; return;
BURN_ALLOC_MEM(buf, struct buffer, 1); BURN_ALLOC_MEM_VOID(buf, struct buffer, 1);
scsi_init_command(c, MMC_SEND_CUE_SHEET, sizeof(MMC_SEND_CUE_SHEET)); scsi_init_command(c, MMC_SEND_CUE_SHEET, sizeof(MMC_SEND_CUE_SHEET));
c->retry = 1; c->retry = 1;
c->page = buf; c->page = buf;
@ -445,6 +444,11 @@ int mmc_get_nwa(struct burn_drive *d, int trackno, int *lba, int *nwa)
*nwa = mmc_four_char_to_int(data + 12); *nwa = mmc_four_char_to_int(data + 12);
num = mmc_four_char_to_int(data + 16); num = mmc_four_char_to_int(data + 16);
/* Pioneer BD-RW BDR-205 and LITE-ON LTR-48125S return -150 as *nwa
of blank media */
if (*nwa < *lba && d->status == BURN_DISC_BLANK)
*nwa = *lba;
#ifdef Libburn_pioneer_dvr_216d_load_mode5 #ifdef Libburn_pioneer_dvr_216d_load_mode5
/* >>> memorize track mode : data[6] & 0xf */; /* >>> memorize track mode : data[6] & 0xf */;
#endif #endif
@ -611,10 +615,9 @@ void mmc_get_event(struct burn_drive *d)
struct command *c; struct command *c;
int alloc_len = 8, len, evt_code, loops = 0; int alloc_len = 8, len, evt_code, loops = 0;
unsigned char *evt; unsigned char *evt;
int ret;
c = &(d->casual_command); c = &(d->casual_command);
BURN_ALLOC_MEM(buf, struct buffer, 1); BURN_ALLOC_MEM_VOID(buf, struct buffer, 1);
if (mmc_function_spy(d, "mmc_get_event") <= 0) if (mmc_function_spy(d, "mmc_get_event") <= 0)
goto ex; goto ex;
@ -846,8 +849,6 @@ void mmc_write_12(struct burn_drive *d, int start, struct buffer *buf)
len = buf->sectors; len = buf->sectors;
burn_print(100, "trying to write %d at %d\n", len, start);
scsi_init_command(c, MMC_WRITE_12, sizeof(MMC_WRITE_12)); scsi_init_command(c, MMC_WRITE_12, sizeof(MMC_WRITE_12));
c->retry = 1; c->retry = 1;
mmc_int_to_four_char(c->opcode + 2, start); mmc_int_to_four_char(c->opcode + 2, start);
@ -910,8 +911,6 @@ int mmc_write(struct burn_drive *d, int start, struct buffer *buf)
/* ts A61009 : buffer fill problems are to be handled by caller */ /* ts A61009 : buffer fill problems are to be handled by caller */
/* a ssert(buf->bytes >= buf->sectors);*/ /* can be == at 0... */ /* a ssert(buf->bytes >= buf->sectors);*/ /* can be == at 0... */
burn_print(100, "trying to write %d at %d\n", len, start);
/* ts A70711 */ /* ts A70711 */
if(d->wait_for_buffer_free) if(d->wait_for_buffer_free)
mmc_wait_for_buffer_free(d, buf); mmc_wait_for_buffer_free(d, buf);
@ -1340,7 +1339,7 @@ static int mmc_read_toc_al(struct burn_drive *d, int *alloc_len)
struct buffer *buf = NULL; struct buffer *buf = NULL;
struct command *c = NULL; struct command *c = NULL;
int dlen; int dlen;
int i, bpl= 12, old_alloc_len, t_idx, ret; int i, old_alloc_len, t_idx, ret;
unsigned char *tdata; unsigned char *tdata;
char *msg = NULL; char *msg = NULL;
@ -1435,8 +1434,6 @@ static int mmc_read_toc_al(struct burn_drive *d, int *alloc_len)
{ret = 0; goto ex;} {ret = 0; goto ex;}
tdata = c->page->data + 4; tdata = c->page->data + 4;
burn_print(12, "TOC:\n");
d->disc = burn_disc_create(); d->disc = burn_disc_create();
if (d->disc == NULL) /* ts A70825 */ if (d->disc == NULL) /* ts A70825 */
{ret = 0; goto ex;} {ret = 0; goto ex;}
@ -1450,20 +1447,9 @@ static int mmc_read_toc_al(struct burn_drive *d, int *alloc_len)
} }
/* ts A61022 */ /* ts A61022 */
burn_print(bpl, "-----------------------------------\n");
for (i = 0; i < d->toc_entries; i++, tdata += 11) { for (i = 0; i < d->toc_entries; i++, tdata += 11) {
/* ts A61022: was burn_print level 12 */
burn_print(bpl, "S %d, PT %2.2Xh, TNO %d :", tdata[0],tdata[3],
tdata[2]);
burn_print(bpl, " MSF(%d:%d:%d)", tdata[4],tdata[5],tdata[6]);
burn_print(bpl, " PMSF(%d:%d:%d %d)",
tdata[8], tdata[9], tdata[10],
burn_msf_to_lba(tdata[8], tdata[9], tdata[10]));
burn_print(bpl, " - control %d, adr %d\n", tdata[1] & 0xF,
tdata[1] >> 4);
/* /*
fprintf(stderr, "libburn_experimental: toc entry #%d : %d %d %d\n",i,tdata[8], tdata[9], tdata[10]); fprintf(stderr, "libburn_experimental: toc entry #%d : %d %d %d\n",i,tdata[8], tdata[9], tdata[10]);
*/ */
@ -1515,9 +1501,6 @@ static int mmc_read_toc_al(struct burn_drive *d, int *alloc_len)
&d->toc_entry[i]; &d->toc_entry[i];
} }
/* ts A61022 */
burn_print(bpl, "-----------------------------------\n");
/* ts A70131 : was (d->status != BURN_DISC_BLANK) */ /* ts A70131 : was (d->status != BURN_DISC_BLANK) */
if (d->status == BURN_DISC_UNREADY) if (d->status == BURN_DISC_UNREADY)
d->status = BURN_DISC_FULL; d->status = BURN_DISC_FULL;
@ -1587,6 +1570,8 @@ void mmc_read_toc(struct burn_drive *d)
*/ */
if (alloc_len >= 15) if (alloc_len >= 15)
ret = mmc_read_toc_al(d, &alloc_len); ret = mmc_read_toc_al(d, &alloc_len);
if (ret <= 0)
return;
} }
@ -1750,6 +1735,7 @@ static int mmc_read_disc_info_al(struct burn_drive *d, int *alloc_len)
/* ts A70131 : had to move mmc_read_toc() to end of function */ /* ts A70131 : had to move mmc_read_toc() to end of function */
int do_read_toc = 0, disc_status, len, old_alloc_len; int do_read_toc = 0, disc_status, len, old_alloc_len;
int ret, number_of_sessions = -1; int ret, number_of_sessions = -1;
int key, asc, ascq;
BURN_ALLOC_MEM(buf, struct buffer, 1); BURN_ALLOC_MEM(buf, struct buffer, 1);
BURN_ALLOC_MEM(c, struct command, 1); BURN_ALLOC_MEM(c, struct command, 1);
@ -1759,6 +1745,8 @@ static int mmc_read_disc_info_al(struct burn_drive *d, int *alloc_len)
d->erasable = 0; d->erasable = 0;
d->last_track_no = 1; d->last_track_no = 1;
/* ts B10730 */
d->sent_default_page_05 = 0;
/* ts A70212 - A70215 */ /* ts A70212 - A70215 */
d->media_capacity_remaining = 0; d->media_capacity_remaining = 0;
d->media_lba_limit = 0; d->media_lba_limit = 0;
@ -1785,6 +1773,22 @@ static int mmc_read_disc_info_al(struct burn_drive *d, int *alloc_len)
d->issue_command(d, c); d->issue_command(d, c);
if (c->error) { if (c->error) {
spc_decode_sense(c->sense, 0, &key, &asc, &ascq);
if (key == 5 && asc == 0x20 && ascq == 0) {
/* ts B11031 : qemu -cdrom does not know
051h READ DISC INFORMATION
*/
ret = mmc_read_toc_fmt0(d);
if (ret > 0) {
/* >>> ??? anything more to be set ? */;
mmc_read_capacity(d);
*alloc_len = 0;
goto ex;
}
}
d->busy = BURN_DRIVE_IDLE; d->busy = BURN_DRIVE_IDLE;
{ret = 0; goto ex;} {ret = 0; goto ex;}
} }
@ -2012,6 +2016,9 @@ void mmc_read_disc_info(struct burn_drive *d)
fprintf(stderr,"LIBBURN_DEBUG: 51h alloc_len = %d , ret = %d\n", fprintf(stderr,"LIBBURN_DEBUG: 51h alloc_len = %d , ret = %d\n",
alloc_len, ret); alloc_len, ret);
*/ */
if (ret <= 0)
return;
/* for now there is no need to inquire the variable lenght part */ /* for now there is no need to inquire the variable lenght part */
} }
@ -2020,7 +2027,7 @@ void mmc_read_atip(struct burn_drive *d)
{ {
struct buffer *buf = NULL; struct buffer *buf = NULL;
struct command *c = NULL; struct command *c = NULL;
int alloc_len = 28, ret = 0; int alloc_len = 28;
/* ts A61021 */ /* ts A61021 */
unsigned char *data; unsigned char *data;
@ -2035,8 +2042,8 @@ void mmc_read_atip(struct burn_drive *d)
4234, 5646, 7056, 8468, -12, -13, -14, -15}; 4234, 5646, 7056, 8468, -12, -13, -14, -15};
/* 24, 32, 40, 48, -, -, -, - */ /* 24, 32, 40, 48, -, -, -, - */
BURN_ALLOC_MEM(buf, struct buffer, 1); BURN_ALLOC_MEM_VOID(buf, struct buffer, 1);
BURN_ALLOC_MEM(c, struct command, 1); BURN_ALLOC_MEM_VOID(c, struct command, 1);
mmc_start_if_needed(d, 1); mmc_start_if_needed(d, 1);
if (mmc_function_spy(d, "mmc_read_atip") <= 0) if (mmc_function_spy(d, "mmc_read_atip") <= 0)
goto ex; goto ex;
@ -2087,7 +2094,7 @@ void mmc_read_atip(struct burn_drive *d)
fprintf(stderr,"libburn_experimental: Returned ATIP Data\n"); fprintf(stderr,"libburn_experimental: Returned ATIP Data\n");
for(i= 0; i<28; i++) for(i= 0; i<28; i++)
fprintf(stderr,"%3.3d (0x%2.2x)%s", fprintf(stderr,"%3.3d (0x%2.2x)%s",
data[i],data[i],((i+1)%5 ? " ":"\n")); data[i],data[i],(((i + 1) % 5) ? " " : "\n"));
fprintf(stderr,"\n"); fprintf(stderr,"\n");
fprintf(stderr, fprintf(stderr,
@ -2197,7 +2204,7 @@ void mmc_read_sectors(struct burn_drive *d,
const struct burn_read_opts *o, struct buffer *buf) const struct burn_read_opts *o, struct buffer *buf)
{ {
int temp; int temp;
int errorblock, req; int req;
struct command *c; struct command *c;
c = &(d->casual_command); c = &(d->casual_command);
@ -2212,8 +2219,6 @@ void mmc_read_sectors(struct burn_drive *d,
/* ts A61006 : i second that question */ /* ts A61006 : i second that question */
/* a ssert(d->busy); */ /* a ssert(d->busy); */
burn_print(12, "reading %d from %d\n", len, start);
scsi_init_command(c, MMC_READ_CD, sizeof(MMC_READ_CD)); scsi_init_command(c, MMC_READ_CD, sizeof(MMC_READ_CD));
c->retry = 1; c->retry = 1;
temp = start; temp = start;
@ -2249,19 +2254,6 @@ void mmc_read_sectors(struct burn_drive *d,
c->page = buf; c->page = buf;
c->dir = FROM_DRIVE; c->dir = FROM_DRIVE;
d->issue_command(d, c); d->issue_command(d, c);
if (c->error) {
burn_print(12, "got an error over here\n");
burn_print(12, "%d, %d, %d, %d\n", c->sense[3], c->sense[4],
c->sense[5], c->sense[6]);
errorblock =
(c->sense[3] << 24) + (c->sense[4] << 16) +
(c->sense[5] << 8) + c->sense[6];
c->page->sectors = errorblock - start + 1;
burn_print(1, "error on block %d\n", errorblock);
burn_print(12, "error on block %d\n", errorblock);
burn_print(12, "returning %d sectors\n", c->page->sectors);
}
} }
void mmc_erase(struct burn_drive *d, int fast) void mmc_erase(struct burn_drive *d, int fast)
@ -2378,14 +2370,14 @@ int mmc_set_streaming(struct burn_drive *d,
eff_end_lba = end_lba; eff_end_lba = end_lba;
sprintf(msg, "mmc_set_streaming: end_lba=%d , r=%d , w=%d", sprintf(msg, "mmc_set_streaming: end_lba=%d , r=%d , w=%d",
end_lba, r_speed, w_speed); eff_end_lba, r_speed, w_speed);
libdax_msgs_submit(libdax_messenger, d->global_index, 0x00000002, libdax_msgs_submit(libdax_messenger, d->global_index, 0x00000002,
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_ZERO, LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_ZERO,
msg, 0, 0); msg, 0, 0);
/* start_lba is 0 , 1000 = 1 second as base time for data rate */ /* start_lba is 0 , 1000 = 1 second as base time for data rate */
for (b = 0; b < 4 ; b++) { for (b = 0; b < 4 ; b++) {
pd[8+b] = (end_lba >> (24 - 8 * b)) & 0xff; pd[8+b] = (eff_end_lba >> (24 - 8 * b)) & 0xff;
pd[12+b] = (r_speed >> (24 - 8 * b)) & 0xff; pd[12+b] = (r_speed >> (24 - 8 * b)) & 0xff;
pd[16+b] = (1000 >> (24 - 8 * b)) & 0xff; pd[16+b] = (1000 >> (24 - 8 * b)) & 0xff;
pd[20+b] = (w_speed >> (24 - 8 * b)) & 0xff; pd[20+b] = (w_speed >> (24 - 8 * b)) & 0xff;
@ -2483,12 +2475,15 @@ void mmc_set_speed(struct burn_drive *d, int r, int w)
static int mmc_get_configuration_al(struct burn_drive *d, int *alloc_len) static int mmc_get_configuration_al(struct burn_drive *d, int *alloc_len)
{ {
struct buffer *buf = NULL; struct buffer *buf = NULL;
int len, cp, descr_len = 0, feature_code, prf_number, only_current = 1; int len, cp, descr_len = 0, feature_code, only_current = 1;
int old_alloc_len, only_current_profile = 0, key, asc, ascq, ret; int old_alloc_len, only_current_profile = 0, key, asc, ascq, ret;
unsigned char *descr, *prf, *up_to, *prf_end; unsigned char *descr, *prf, *up_to, *prf_end;
struct command *c = NULL; struct command *c = NULL;
int phys_if_std = 0; int phys_if_std = 0;
char *phys_name = ""; char *phys_name = "";
#ifdef Libburn_print_feature_descriptorS
int prf_number;
#endif
if (*alloc_len < 8) if (*alloc_len < 8)
{ret = 0; goto ex;} {ret = 0; goto ex;}
@ -2655,9 +2650,9 @@ static int mmc_get_configuration_al(struct burn_drive *d, int *alloc_len)
for (prf = descr + 4; prf + 2 < prf_end; prf += 4) { for (prf = descr + 4; prf + 2 < prf_end; prf += 4) {
if (only_current_profile && !(prf[2] & 1)) if (only_current_profile && !(prf[2] & 1))
continue; continue;
prf_number = (prf[0] << 8) | prf[1];
#ifdef Libburn_print_feature_descriptorS #ifdef Libburn_print_feature_descriptorS
prf_number = (prf[0] << 8) | prf[1];
fprintf(stderr, fprintf(stderr,
"LIBBURN_EXPERIMENTAL : %s profile %4.4Xh \"%s\"\n", "LIBBURN_EXPERIMENTAL : %s profile %4.4Xh \"%s\"\n",
prf[2] & 1 ? "+" : "-", prf[2] & 1 ? "+" : "-",
@ -2710,7 +2705,7 @@ static int mmc_get_configuration_al(struct burn_drive *d, int *alloc_len)
} else if (feature_code == 0x01) { } else if (feature_code == 0x01) {
phys_if_std = (descr[4] << 24) | (descr[5] << 16) | phys_if_std = (descr[4] << 24) | (descr[5] << 16) |
(descr[6] << 8) | descr[9]; (descr[6] << 8) | descr[7];
if (phys_if_std == 1) if (phys_if_std == 1)
phys_name = "SCSI Family"; phys_name = "SCSI Family";
else if(phys_if_std == 2) else if(phys_if_std == 2)
@ -2961,13 +2956,13 @@ void mmc_sync_cache(struct burn_drive *d)
{ {
struct command *c = NULL; struct command *c = NULL;
char *msg = NULL; char *msg = NULL;
int key, asc, ascq, ret; int key, asc, ascq;
if (mmc_function_spy(d, "mmc_sync_cache") <= 0) if (mmc_function_spy(d, "mmc_sync_cache") <= 0)
goto ex; goto ex;
BURN_ALLOC_MEM(c, struct command, 1); BURN_ALLOC_MEM_VOID(c, struct command, 1);
BURN_ALLOC_MEM(msg, char, 256); BURN_ALLOC_MEM_VOID(msg, char, 256);
scsi_init_command(c, MMC_SYNC_CACHE, sizeof(MMC_SYNC_CACHE)); scsi_init_command(c, MMC_SYNC_CACHE, sizeof(MMC_SYNC_CACHE));
c->retry = 1; c->retry = 1;
@ -3724,10 +3719,16 @@ static int mmc_get_write_performance_al(struct burn_drive *d,
struct buffer *buf = NULL; struct buffer *buf = NULL;
int len, i, b, num_descr, ret, old_alloc_len; int len, i, b, num_descr, ret, old_alloc_len;
int exact_bit, read_speed, write_speed; int exact_bit, read_speed, write_speed;
/* >>> ts B10702: This rule seems questionable:
TSST SH-203 delivers here for CD only 7040k
whereas mode page 2Ah gives 1412k to 7056k
*/
/* if this call delivers usable data then they should override /* if this call delivers usable data then they should override
previously recorded min/max speed and not compete with them */ previously recorded min/max speed and not compete with them */
int min_write_speed = 0x7fffffff, max_write_speed = 0; int min_write_speed = 0x7fffffff, max_write_speed = 0;
int min_read_speed = 0x7fffffff, max_read_speed = 0; int min_read_speed = 0x7fffffff, max_read_speed = 0;
struct command *c = NULL; struct command *c = NULL;
unsigned long end_lba; unsigned long end_lba;
unsigned char *pd; unsigned char *pd;
@ -3789,6 +3790,10 @@ static int mmc_get_write_performance_al(struct burn_drive *d,
if (len < 12) if (len < 12)
{ret = 0; goto ex;} {ret = 0; goto ex;}
/* ts B10702 : overriding the questionable override rule */
min_write_speed = d->mdata->min_write_speed;
max_write_speed = d->mdata->max_write_speed;
pd = c->page->data; pd = c->page->data;
if (num_descr > *max_descr) if (num_descr > *max_descr)
num_descr = *max_descr; num_descr = *max_descr;
@ -4471,6 +4476,55 @@ ex:;
} }
/* ts B10801
MMC-5, 6.23.3.2.1 Format Code 00h: Physical Format Information
6.23.3.2.16 Format Code 10h: Format Information of
Control Data Zone in the Lead-in
disk_category
*/
int mmc_get_phys_format_info(struct burn_drive *d, int *disk_category,
char **book_name, int *part_version, int *num_layers,
int *num_blocks, int flag)
{
int ret, reply_len, prf;
char *reply = NULL;
static char book_names[][16] = {
"DVD-ROM", "DVD-RAM", "DVD-R", "DVD-RW",
"HD DVD-ROM", "HD DVD-RAM", "HD DVD-R", "unknown",
"unknown", "DVD+RW", "DVD+R", "unknown", "unknown",
"unknown", "DVD+RW DL", "DVD+R DL", "unknown"
};
prf = d->current_profile;
if (!(prf == 0x11 || prf == 0x13 || prf == 0x14 || prf == 0x15 ||
prf == 0x51))
return 0; /* Not a [HD] DVD-R[W] loaded */
ret = mmc_read_disc_structure(d, 0, 0, 0x10, 12, &reply,
&reply_len, 0);
if (ret <= 0)
goto ex;
if(reply_len < 12) {
libdax_msgs_submit(libdax_messenger, -1, 0x00000002,
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_ZERO,
"READ DISC STRUCTURE format 10h: Less than 12 bytes",
0, 0);
{ret = 0; goto ex;}
}
*disk_category = (reply[0] >> 4) & 0xf;
*book_name = book_names[*disk_category];
*part_version = reply[0] & 0xf;
*num_layers = ((reply[2] >> 5) & 0x3) + 1;
*num_blocks = ((reply[9] << 16) | (reply[10] << 8) | reply[11]) -
((reply[5] << 16) | (reply[6] << 8) | reply[7]) + 1;
ret = 1;
ex:;
if (reply != NULL)
free(reply);
return ret;
}
/* ts A61021 : the mmc specific part of sg.c:enumerate_common() /* ts A61021 : the mmc specific part of sg.c:enumerate_common()
*/ */
int mmc_setup_drive(struct burn_drive *d) int mmc_setup_drive(struct burn_drive *d)

View File

@ -110,4 +110,9 @@ int mmc_start_if_needed(struct burn_drive *d, int flag);
int mmc_get_bd_spare_info(struct burn_drive *d, int mmc_get_bd_spare_info(struct burn_drive *d,
int *alloc_blocks, int *free_blocks, int flag); int *alloc_blocks, int *free_blocks, int flag);
/* ts B10801 */
int mmc_get_phys_format_info(struct burn_drive *d, int *disk_category,
char **book_name, int *part_version, int *num_layers,
int *num_blocks, int flag);
#endif /*__MMC*/ #endif /*__MMC*/

View File

@ -115,7 +115,6 @@ drive, or only store a subset of the _opts structs in drives */
while (1) { while (1) {
seclen = burn_sector_length_read(d, o); seclen = burn_sector_length_read(d, o);
burn_print(12, "received %d blocks\n", page.sectors);
for (i = 0; i < page.sectors; i++) { for (i = 0; i < page.sectors; i++) {
burn_packet_process(d, page.data + seclen * i, o); burn_packet_process(d, page.data + seclen * i, o);
d->track_end--; d->track_end--;
@ -123,7 +122,6 @@ drive, or only store a subset of the _opts structs in drives */
} }
if ((d->cancel) || (drive_lba == LAST_SESSION_END(d))) { if ((d->cancel) || (drive_lba == LAST_SESSION_END(d))) {
burn_print(1, "finished or cancelled\n");
d->busy = BURN_DRIVE_IDLE; d->busy = BURN_DRIVE_IDLE;
if (!d->cancel) if (!d->cancel)
d->toc->complete = 1; d->toc->complete = 1;
@ -137,16 +135,14 @@ drive, or only store a subset of the _opts structs in drives */
if (d->currtrack > if (d->currtrack >
d->toc->session[d->currsession].lasttrack) { d->toc->session[d->currsession].lasttrack) {
d->currsession++; d->currsession++;
burn_print(12, "session switch to %d\n", /* session switch to d->currsession */
d->currsession); /* skipping a lead out */
burn_print(12, "skipping a lead out\n");
drive_lba = CURRENT_SESSION_START(d); drive_lba = CURRENT_SESSION_START(d);
burn_print(12, "new lba %d\n", drive_lba);
/* XXX more of the same /* XXX more of the same
end = burn_track_end(d, d->currsession, end = burn_track_end(d, d->currsession,
d->currtrack); d->currtrack);
*/ } */
burn_print(12, "track switch to %d\n", d->currtrack); }
} }
page.sectors = 0; page.sectors = 0;
@ -201,23 +197,21 @@ static int bitcount(unsigned char *data, int n)
return count; return count;
} }
void burn_packet_process(struct burn_drive *d, unsigned char *data, void burn_packet_process(struct burn_drive *d, unsigned char *data,
const struct burn_read_opts *o) const struct burn_read_opts *o)
{ {
unsigned char sub[96]; unsigned char sub[96];
unsigned short crc;
int ptr = 2352, i, j, code, fb; int ptr = 2352, i, j, code, fb;
int audio = 1; int audio = 1;
#ifndef Libburn_no_crc_C
unsigned short crc;
#endif
if (o->c2errors) { if (o->c2errors) {
fb = bitcount(data + ptr, 294); fb = bitcount(data + ptr, 294);
if (fb) { if (fb) {
burn_print(1, "%d damaged bits\n", /* bitcount(data + ptr, 294) damaged bits */;
bitcount(data + ptr, 294));
burn_print(1, "sending error on %s %s\n",
d->idata->vendor, d->idata->product);
/* XXX send a burn_message! burn_message_error(d,
something); */
} }
ptr += 294; ptr += 294;
} }
@ -253,16 +247,17 @@ void burn_packet_process(struct burn_drive *d, unsigned char *data,
} }
} }
} }
crc = (*(sub + 22) << 8) + *(sub + 23);
#ifndef Libburn_no_crc_C #ifndef Libburn_no_crc_C
crc = (*(sub + 22) << 8) + *(sub + 23);
if (crc != crc_ccitt(sub + 12, 10)) { if (crc != crc_ccitt(sub + 12, 10)) {
/*
burn_print(1, "sending error on %s %s\n", burn_print(1, "sending error on %s %s\n",
d->idata->vendor, d->idata->product); d->idata->vendor, d->idata->product);
/* e = burn_error(); e = burn_error();
e->drive = d; e->drive = d;
*/
burn_print(1, "crc mismatch in Q\n"); burn_print(1, "crc mismatch in Q\n");
*/;
} }
#endif #endif

View File

@ -1,7 +1,7 @@
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */ /* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
/* /*
Copyright (c) 2009 - 2010 Thomas Schmitt <scdbackup@gmx.net> Copyright (c) 2009 - 2011 Thomas Schmitt <scdbackup@gmx.net>
Provided under GPL version 2 or later. Provided under GPL version 2 or later.
*/ */
@ -44,6 +44,7 @@ Present implementation: default dummy which enables libburn only to work
#include "debug.h" #include "debug.h"
#include "toc.h" #include "toc.h"
#include "util.h" #include "util.h"
#include "init.h"
#include "libdax_msgs.h" #include "libdax_msgs.h"
extern struct libdax_msgs *libdax_messenger; extern struct libdax_msgs *libdax_messenger;
@ -252,14 +253,12 @@ int burn_os_stdio_capacity(char *path, off_t *bytes)
#endif #endif
char *testpath = NULL, *cpt; char *testpath = NULL, *cpt;
long blocks;
off_t add_size = 0; off_t add_size = 0;
int ret; int ret;
BURN_ALLOC_MEM(testpath, char, 4096); BURN_ALLOC_MEM(testpath, char, 4096);
testpath[0] = 0; testpath[0] = 0;
blocks = *bytes / 512;
if (stat(path, &stbuf) == -1) { if (stat(path, &stbuf) == -1) {
strcpy(testpath, path); strcpy(testpath, path);
cpt = strrchr(testpath, '/'); cpt = strrchr(testpath, '/');
@ -275,6 +274,9 @@ int burn_os_stdio_capacity(char *path, off_t *bytes)
#ifdef Libburn_if_this_was_linuX #ifdef Libburn_if_this_was_linuX
} else if(S_ISBLK(stbuf.st_mode)) { } else if(S_ISBLK(stbuf.st_mode)) {
long blocks;
blocks = *bytes / 512;
fd = open(path, open_mode); fd = open(path, open_mode);
if (fd == -1) if (fd == -1)
{ret = -2; goto ex;} {ret = -2; goto ex;}

View File

@ -1,11 +1,14 @@
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */ /* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
/* /*
Copyright (c) 2006 - 2010 Thomas Schmitt <scdbackup@gmx.net> Copyright (c) 2006 - 2011 Thomas Schmitt <scdbackup@gmx.net>
Provided under GPL version 2 or later. Provided under GPL version 2 or later.
*/ */
/* THIS CODE IS NOT FUNCTIONAL YET !!! */
/* /*
This is the main operating system dependent SCSI part of libburn. It implements This is the main operating system dependent SCSI part of libburn. It implements
@ -490,10 +493,8 @@ int sg_grab(struct burn_drive *d)
*/ */
int sg_release(struct burn_drive *d) int sg_release(struct burn_drive *d)
{ {
if (d->cam == NULL) { if (d->cam == NULL)
burn_print(1, "release an ungrabbed drive. die\n");
return 0; return 0;
}
sg_close_drive(d); sg_close_drive(d);
return 0; return 0;
} }
@ -721,13 +722,11 @@ int burn_os_stdio_capacity(char *path, off_t *bytes)
struct stat stbuf; struct stat stbuf;
struct statvfs vfsbuf; struct statvfs vfsbuf;
char *testpath = NULL, *cpt; char *testpath = NULL, *cpt;
long blocks;
off_t add_size = 0; off_t add_size = 0;
int fd, ret; int fd, ret;
BURN_ALLOC_MEM(testpath, char, 4096); BURN_ALLOC_MEM(testpath, char, 4096);
testpath[0] = 0; testpath[0] = 0;
blocks = *bytes / 512;
if (stat(path, &stbuf) == -1) { if (stat(path, &stbuf) == -1) {
strcpy(testpath, path); strcpy(testpath, path);
cpt = strrchr(testpath, '/'); cpt = strrchr(testpath, '/');
@ -744,7 +743,9 @@ int burn_os_stdio_capacity(char *path, off_t *bytes)
} else if(S_ISBLK(stbuf.st_mode)) { } else if(S_ISBLK(stbuf.st_mode)) {
int open_mode = O_RDWR, fd, ret; int open_mode = O_RDWR, fd, ret;
long blocks;
blocks = *bytes / 512;
if(burn_sg_open_o_excl) if(burn_sg_open_o_excl)
open_mode |= O_EXCL; open_mode |= O_EXCL;
fd = open(path, open_mode); fd = open(path, open_mode);

View File

@ -2,7 +2,8 @@
/* /*
Copyright (c) 2006 - 2011 Thomas Schmitt <scdbackup@gmx.net> Copyright (c) 2006 - 2011 Thomas Schmitt <scdbackup@gmx.net>
Provided under GPL version 2 or later. Provided under GPL version 2 or later
and under FreeBSD license revised, i.e. without advertising clause.
*/ */
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
@ -507,12 +508,9 @@ static void enumerate_common(char *fname, int bus_no, int host_no,
/* try to get the drive info */ /* try to get the drive info */
if (t->grab(t)) { if (t->grab(t)) {
burn_print(2, "getting drive info\n");
t->getcaps(t); t->getcaps(t);
t->unlock(t); t->unlock(t);
t->released = 1; t->released = 1;
} else {
burn_print(2, "unable to grab new located drive\n");
} }
/* ts A60821 /* ts A60821
@ -750,10 +748,8 @@ int sg_release(struct burn_drive *d)
if (mmc_function_spy(d, "sg_release") <= 0) if (mmc_function_spy(d, "sg_release") <= 0)
return 0; return 0;
if (d->cam == NULL) { if (d->cam == NULL)
burn_print(1, "release an ungrabbed drive. die\n");
return 0; return 0;
}
mmc_function_spy(NULL, "sg_release ----------- closing."); mmc_function_spy(NULL, "sg_release ----------- closing.");
@ -764,7 +760,7 @@ int sg_release(struct burn_drive *d)
int sg_issue_command(struct burn_drive *d, struct command *c) int sg_issue_command(struct burn_drive *d, struct command *c)
{ {
int done = 0, err, sense_len = 0, ret, ignore_error, no_retry = 0, i; int done = 0, err, sense_len = 0, ret, ignore_error, i;
int cam_pass_err_recover = 0, key, asc, ascq, timeout_ms; int cam_pass_err_recover = 0, key, asc, ascq, timeout_ms;
union ccb *ccb; union ccb *ccb;
static FILE *fp = NULL; static FILE *fp = NULL;
@ -957,7 +953,7 @@ int sg_issue_command(struct burn_drive *d, struct command *c)
c->sense[2] = 0x02; c->sense[2] = 0x02;
c->sense[12] = 0x04; c->sense[12] = 0x04;
c->sense[13] = 0x00; c->sense[13] = 0x00;
no_retry = 1; done = 1;
} }
/* >>> Need own duration time measurement. /* >>> Need own duration time measurement.
@ -985,12 +981,13 @@ ex:;
int burn_os_is_2k_seekrw(char *path, int flag) int burn_os_is_2k_seekrw(char *path, int flag)
{ {
struct stat stbuf; struct stat stbuf;
#ifdef Libburn_DIOCGMEDIASIZE_ISBLK
int fd, ret;
off_t add_size;
#else
char *spt; char *spt;
int i, e; int i, e;
#ifdef Libburn_DIOCGMEDIASIZE_ISBLK #endif /* ! Libburn_DIOCGMEDIASIZE_ISBLK */
int fd;
off_t add_size;
#endif
if (stat(path, &stbuf) == -1) if (stat(path, &stbuf) == -1)
return 0; return 0;
@ -1010,7 +1007,7 @@ int burn_os_is_2k_seekrw(char *path, int flag)
ret = ioctl(fd, DIOCGMEDIASIZE, &add_size); ret = ioctl(fd, DIOCGMEDIASIZE, &add_size);
close(fd); close(fd);
return 1; return (ret != -1);
#else /* Libburn_DIOCGMEDIASIZE_ISBLK */ #else /* Libburn_DIOCGMEDIASIZE_ISBLK */
@ -1057,13 +1054,11 @@ int burn_os_stdio_capacity(char *path, off_t *bytes)
struct stat stbuf; struct stat stbuf;
struct statvfs vfsbuf; struct statvfs vfsbuf;
char *testpath = NULL, *cpt; char *testpath = NULL, *cpt;
long blocks;
off_t add_size = 0; off_t add_size = 0;
int fd, ret; int fd, ret;
BURN_ALLOC_MEM(testpath, char, 4096); BURN_ALLOC_MEM(testpath, char, 4096);
testpath[0] = 0; testpath[0] = 0;
blocks = *bytes / 512;
if (stat(path, &stbuf) == -1) { if (stat(path, &stbuf) == -1) {
strcpy(testpath, path); strcpy(testpath, path);
cpt = strrchr(testpath, '/'); cpt = strrchr(testpath, '/');
@ -1080,7 +1075,9 @@ int burn_os_stdio_capacity(char *path, off_t *bytes)
} else if(S_ISBLK(stbuf.st_mode)) { } else if(S_ISBLK(stbuf.st_mode)) {
int open_mode = O_RDWR, fd, ret; int open_mode = O_RDWR, fd, ret;
long blocks;
blocks = *bytes / 512;
if(burn_sg_open_o_excl) if(burn_sg_open_o_excl)
open_mode |= O_EXCL; open_mode |= O_EXCL;
fd = open(path, open_mode); fd = open(path, open_mode);

View File

@ -142,6 +142,9 @@ Send feedback to libburn-hackers@pykix.org .
#define Libburn_is_on_solariS 1 #define Libburn_is_on_solariS 1
#endif #endif
/* Proposal by Rocky Bernstein to avoid macro clashes with cdio_config.h */
#define __CDIO_CONFIG_H__ 1
#include <cdio/cdio.h> #include <cdio/cdio.h>
#include <cdio/logging.h> #include <cdio/logging.h>
#include <cdio/mmc.h> #include <cdio/mmc.h>
@ -259,7 +262,7 @@ try_next:;
} }
#endif #endif
if (strlen(*(idx->pos)) >= adr_size) if ((ssize_t) strlen(*(idx->pos)) >= adr_size)
return -1; return -1;
strcpy(adr, *(idx->pos)); strcpy(adr, *(idx->pos));
(idx->pos)++; (idx->pos)++;
@ -440,7 +443,7 @@ int sg_give_next_adr(burn_drive_enumerator_t *idx,
ret = sg_give_next_adr_raw(idx, adr, adr_size, initialize); ret = sg_give_next_adr_raw(idx, adr, adr_size, initialize);
if (ret <= 0) if (ret <= 0)
goto ex; goto ex;
if (strlen(adr) >= path_size) if ((ssize_t) strlen(adr) >= path_size)
goto ex; goto ex;
#ifdef Libburn_is_on_solariS #ifdef Libburn_is_on_solariS
@ -453,8 +456,8 @@ int sg_give_next_adr(burn_drive_enumerator_t *idx,
#endif /* Libburn_is_on_solariS */ #endif /* Libburn_is_on_solariS */
ret = burn_drive_resolve_link(adr, path, &recursion_count, 2); ret = burn_drive_resolve_link(adr, path, &recursion_count, 2);
if(ret > 0 && strlen(path) < adr_size) if(ret > 0 && (ssize_t) strlen(path) < adr_size)
strcpy(path, adr); strcpy(adr, path);
ret = (ret >= 0); ret = (ret >= 0);
ex: ex:
BURN_FREE_MEM(path); BURN_FREE_MEM(path);
@ -594,10 +597,8 @@ ex:;
*/ */
int sg_release(struct burn_drive *d) int sg_release(struct burn_drive *d)
{ {
if (d->p_cdio == NULL) { if (d->p_cdio == NULL)
burn_print(1, "release an ungrabbed drive. die\n");
return 0; return 0;
}
sg_close_drive(d); sg_close_drive(d);
return 0; return 0;
} }
@ -614,7 +615,7 @@ int sg_release(struct burn_drive *d)
*/ */
int sg_issue_command(struct burn_drive *d, struct command *c) int sg_issue_command(struct burn_drive *d, struct command *c)
{ {
int sense_valid = 0, i, timeout_ms, no_retry = 0; int sense_valid = 0, i, timeout_ms, sense_len;
int key = 0, asc = 0, ascq = 0, done = 0; int key = 0, asc = 0, ascq = 0, done = 0;
time_t start_time; time_t start_time;
driver_return_code_t i_status; driver_return_code_t i_status;
@ -623,7 +624,7 @@ int sg_issue_command(struct burn_drive *d, struct command *c)
mmc_cdb_t cdb = {{0, }}; mmc_cdb_t cdb = {{0, }};
cdio_mmc_direction_t e_direction; cdio_mmc_direction_t e_direction;
CdIo_t *p_cdio; CdIo_t *p_cdio;
unsigned char *sense_pt = NULL; cdio_mmc_request_sense_t *sense_pt = NULL;
c->error = 0; c->error = 0;
if (d->p_cdio == NULL) { if (d->p_cdio == NULL) {
@ -666,9 +667,9 @@ int sg_issue_command(struct burn_drive *d, struct command *c)
dxfer_len, c->page->data); dxfer_len, c->page->data);
sense_valid = mmc_last_cmd_sense(p_cdio, &sense_pt); sense_valid = mmc_last_cmd_sense(p_cdio, &sense_pt);
if (sense_valid >= 18) { if (sense_valid >= 18) {
memcpy(c->sense, sense_pt, memcpy(c->sense, (unsigned char *) sense_pt,
sense_valid >= sizeof(c->sense) ? (size_t) sense_valid >= sizeof(c->sense) ?
sizeof(c->sense) : sense_valid ); sizeof(c->sense) : (size_t) sense_valid );
spc_decode_sense(c->sense, 0, &key, &asc, &ascq); spc_decode_sense(c->sense, 0, &key, &asc, &ascq);
} else } else
key = asc = ascq = 0; key = asc = ascq = 0;
@ -701,14 +702,15 @@ int sg_issue_command(struct burn_drive *d, struct command *c)
c->sense[0] = 0x70; /*Fixed format sense data*/ c->sense[0] = 0x70; /*Fixed format sense data*/
c->sense[2] = 0x02; c->sense[2] = 0x02;
c->sense[12] = 0x04; c->sense[12] = 0x04;
no_retry = 1; done = 1;
} }
} }
if (i_status != 0 || (key || asc || ascq)) { if (key || asc || ascq)
done = scsi_eval_cmd_outcome(d, c, fp, c->sense, 18, sense_len = 18;
else
sense_len = 0;
done = scsi_eval_cmd_outcome(d, c, fp, c->sense, sense_len,
0, start_time, timeout_ms, i, 2); 0, start_time, timeout_ms, i, 2);
} else
done = 1;
} /* end of retry-loop */ } /* end of retry-loop */
@ -860,13 +862,11 @@ int burn_os_stdio_capacity(char *path, off_t *bytes)
#endif #endif
char *testpath = NULL, *cpt; char *testpath = NULL, *cpt;
long blocks;
off_t add_size = 0; off_t add_size = 0;
int ret; int ret;
BURN_ALLOC_MEM(testpath, char, 4096); BURN_ALLOC_MEM(testpath, char, 4096);
testpath[0] = 0; testpath[0] = 0;
blocks = *bytes / 512;
if (stat(path, &stbuf) == -1) { if (stat(path, &stbuf) == -1) {
strcpy(testpath, path); strcpy(testpath, path);
cpt = strrchr(testpath, '/'); cpt = strrchr(testpath, '/');
@ -883,8 +883,10 @@ int burn_os_stdio_capacity(char *path, off_t *bytes)
/* GNU/Linux specific determination of block device size */ /* GNU/Linux specific determination of block device size */
} else if(S_ISBLK(stbuf.st_mode)) { } else if(S_ISBLK(stbuf.st_mode)) {
int open_mode = O_RDONLY, fd, ret; int open_mode = O_RDONLY, fd;
long blocks;
blocks = *bytes / 512;
fd = open(path, open_mode); fd = open(path, open_mode);
if (fd == -1) if (fd == -1)
{ret = -2; goto ex;} {ret = -2; goto ex;}
@ -899,7 +901,7 @@ int burn_os_stdio_capacity(char *path, off_t *bytes)
#ifdef Libburn_is_on_freebsD #ifdef Libburn_is_on_freebsD
} else if(S_ISCHR(stbuf.st_mode)) { } else if(S_ISCHR(stbuf.st_mode)) {
int fd, ret; int fd;
fd = open(path, O_RDONLY); fd = open(path, O_RDONLY);
if (fd == -1) if (fd == -1)

View File

@ -185,6 +185,8 @@ static int linux_sg_enumerate_debug = 0;
E.g.: "/dev/sg%d" E.g.: "/dev/sg%d"
sr%d is supposed to map only CD-ROM style devices. Additionally a test sr%d is supposed to map only CD-ROM style devices. Additionally a test
with ioctl(CDROM_DRIVE_STATUS) is made to assert that it is such a drive, with ioctl(CDROM_DRIVE_STATUS) is made to assert that it is such a drive,
If no such assertion is made, then this adapter performs INQUIRE and
looks for first reply byte 0x05.
This initial setting may be overridden in sg_select_device_family() by This initial setting may be overridden in sg_select_device_family() by
settings made via burn_preset_device_open(). settings made via burn_preset_device_open().
@ -252,9 +254,13 @@ int burn_drive_is_banned(char *device_address);
/* ------------------------------------------------------------------------ */ /* ------------------------------------------------------------------------ */
static void enumerate_common(char *fname, int bus_no, int host_no, static void enumerate_common(char *fname, int fd_in, int bus_no, int host_no,
int channel_no, int target_no, int lun_no); int channel_no, int target_no, int lun_no);
static int sg_obtain_scsi_adr_fd(char *path, int fd_in,
int *bus_no, int *host_no, int *channel_no,
int *target_no, int *lun_no);
/* ts A60813 : storage objects are in libburn/init.c /* ts A60813 : storage objects are in libburn/init.c
whether to use O_EXCL with open(2) of devices whether to use O_EXCL with open(2) of devices
@ -372,10 +378,48 @@ static int sg_exchange_scd_for_sr(char *fname, int flag)
} }
/* ts B11110 */
/* This is an early stage version of scsi_log_cmd.
>>> It will become obsolete when the /tmp file handler is moved into
>>> scsi_log_command().
*/
static int sgio_log_cmd(unsigned char *cmd, int cmd_len, FILE *fp_in, int flag)
{
FILE *fp = fp_in;
int ret;
/* >>> ts B11110 : move this into scsi_log_command() */
if (fp == NULL && (burn_sg_log_scsi & 1)) {
fp= fopen("/tmp/libburn_sg_command_log", "a");
fprintf(fp, "\n=========================================\n");
}
ret = scsi_log_command(cmd, cmd_len, NO_TRANSFER, NULL, 0, fp, flag);
if (fp_in == NULL && fp != NULL)
fclose(fp);
return ret;
}
/* ts B11110 */
static int sgio_log_reply(unsigned char *opcode, int data_dir,
unsigned char *data, int dxfer_len,
void *fp_in, unsigned char sense[18],
int sense_len, int duration, int flag)
{
int ret;
ret = scsi_log_reply(opcode, data_dir, data, dxfer_len, fp_in,
sense, sense_len, duration, flag);
return 1;
}
static int sgio_test(int fd) static int sgio_test(int fd)
{ {
unsigned char test_ops[] = { 0, 0, 0, 0, 0, 0 }; unsigned char test_ops[] = { 0, 0, 0, 0, 0, 0 };
sg_io_hdr_t s; sg_io_hdr_t s;
int ret;
memset(&s, 0, sizeof(sg_io_hdr_t)); memset(&s, 0, sizeof(sg_io_hdr_t));
s.interface_id = 'S'; s.interface_id = 'S';
@ -383,7 +427,91 @@ static int sgio_test(int fd)
s.cmd_len = 6; s.cmd_len = 6;
s.cmdp = test_ops; s.cmdp = test_ops;
s.timeout = 12345; s.timeout = 12345;
return ioctl(fd, SG_IO, &s);
sgio_log_cmd(s.cmdp, s.cmd_len, NULL, 0);
ret= ioctl(fd, SG_IO, &s);
sgio_log_reply(s.cmdp, NO_TRANSFER, NULL, 0,
NULL, s.sbp, s.sb_len_wr, s.duration, 0);
return ret;
}
static int sgio_inquiry_cd_drive(int fd, char *fname)
{
unsigned char test_ops[] = { 0x12, 0, 0, 0, 36, 0 };
sg_io_hdr_t s;
struct buffer *buf = NULL;
unsigned char *sense = NULL;
char *msg = NULL, *msg_pt;
int ret = 0, i;
BURN_ALLOC_MEM(buf, struct buffer, 1);
BURN_ALLOC_MEM(sense, unsigned char, 128);
BURN_ALLOC_MEM(msg, char, strlen(fname) + 1024);
memset(&s, 0, sizeof(sg_io_hdr_t));
s.interface_id = 'S';
s.dxfer_direction = SG_DXFER_FROM_DEV;
s.cmd_len = 6;
s.cmdp = test_ops;
s.mx_sb_len = 32;
s.sbp = sense;
s.timeout = 30000;
s.dxferp = buf;
s.dxfer_len = 36;
s.usr_ptr = NULL;
sgio_log_cmd(s.cmdp, s.cmd_len, NULL, 0);
ret = ioctl(fd, SG_IO, &s);
if (ret == -1) {
sprintf(msg,
"INQUIRY on '%s' : ioctl(SG_IO) failed , errno= %d",
fname, errno);
libdax_msgs_submit(libdax_messenger, -1, 0x00000002,
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH,
msg, 0, 0);
goto ex;
}
sgio_log_reply(s.cmdp, FROM_DRIVE, buf->data, s.dxfer_len,
NULL, s.sbp, s.sb_len_wr, s.duration, 0);
if (s.sb_len_wr > 0 || s.host_status != Libburn_sg_host_oK ||
s.driver_status != Libburn_sg_driver_oK) {
sprintf(msg, "INQUIRY failed on '%s' : host_status= %hd , driver_status= %hd", fname, s.host_status, s.driver_status);
if (s.sb_len_wr > 0) {
sprintf(msg + strlen(msg), " , sense data=");
msg_pt = msg + strlen(msg);
for (i = 0 ; i < s.sb_len_wr; i++)
sprintf(msg_pt + i * 3, " %2.2X", s.sbp[i]);
}
libdax_msgs_submit(libdax_messenger, -1, 0x00000002,
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH,
msg, 0, 0);
ret = -1;
goto ex;
}
ret = 0;
if (buf->data[0] == 0x5) {
/* Peripheral qualifier 0, device type 0x5 = CD/DVD device.
SPC-3 tables 82 and 83 */
ret = 1;
} else {
sprintf(msg, "INQUIRY on '%s' : byte 0 = 0x%2.2X",
fname, buf->data[0]);
libdax_msgs_submit(libdax_messenger, -1, 0x00000002,
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH,
msg, 0, 0);
}
ex:;
BURN_FREE_MEM(msg);
BURN_FREE_MEM(sense);
BURN_FREE_MEM(buf);
return ret;
} }
@ -576,6 +704,7 @@ static int sg_open_drive_fd(char *fname, int scan_mode)
O_NONBLOCK was already hardcoded in ata_ but not in sg_. O_NONBLOCK was already hardcoded in ata_ but not in sg_.
There must be some reason for this. So O_NONBLOCK is There must be some reason for this. So O_NONBLOCK is
default mode for both now. Disable on own risk. default mode for both now. Disable on own risk.
ts B10904: O_NONBLOCK is prescribed by <linux/cdrom.h>
ts A70411 ts A70411
Switched to O_NDELAY for LKML statement 2007/4/11/141 by Alan Cox: Switched to O_NDELAY for LKML statement 2007/4/11/141 by Alan Cox:
"open() has side effects. The CD layer allows you to open "open() has side effects. The CD layer allows you to open
@ -756,12 +885,15 @@ failed:;
/* ts A80731 */ /* ts A80731 */
static int is_ata_drive(char *fname) static int is_ata_drive(char *fname, int fd_in)
{ {
int fd; int fd;
struct hd_driveid tm; struct hd_driveid tm;
fd = sg_open_drive_fd(fname, 1); if (fd_in >= 0)
fd = fd_in;
else
fd = sg_open_drive_fd(fname, 1);
if (fd == -1) { if (fd == -1) {
if (linux_ata_enumerate_verbous) if (linux_ata_enumerate_verbous)
fprintf(stderr,"open failed, errno=%d '%s'\n", fprintf(stderr,"open failed, errno=%d '%s'\n",
@ -776,7 +908,8 @@ static int is_ata_drive(char *fname)
if (!(tm.config & 0x8000) || (tm.config & 0x4000)) { if (!(tm.config & 0x8000) || (tm.config & 0x4000)) {
if (linux_ata_enumerate_verbous) if (linux_ata_enumerate_verbous)
fprintf(stderr, "not marked as ATAPI\n"); fprintf(stderr, "not marked as ATAPI\n");
sg_close_drive_fd(fname, -1, &fd, 0); if (fd_in < 0)
sg_close_drive_fd(fname, -1, &fd, 0);
return 0; return 0;
} }
@ -787,9 +920,12 @@ static int is_ata_drive(char *fname)
fprintf(stderr, fprintf(stderr,
"FATAL: sgio_test() failed: errno=%d '%s'\n", "FATAL: sgio_test() failed: errno=%d '%s'\n",
errno, strerror(errno)); errno, strerror(errno));
sg_close_drive_fd(fname, -1, &fd, 0); if (fd_in < 0)
sg_close_drive_fd(fname, -1, &fd, 0);
return 0; return 0;
} }
if (fd_in >= 0)
return 1;
if (sg_close_drive_fd(fname, -1, &fd, 1) <= 0) { if (sg_close_drive_fd(fname, -1, &fd, 1) <= 0) {
if (linux_ata_enumerate_verbous) if (linux_ata_enumerate_verbous)
fprintf(stderr, fprintf(stderr,
@ -801,10 +937,10 @@ static int is_ata_drive(char *fname)
} }
static int is_scsi_drive(char *fname, int *bus_no, int *host_no, static int is_scsi_drive(char *fname, int fd_in, int *bus_no, int *host_no,
int *channel_no, int *target_no, int *lun_no) int *channel_no, int *target_no, int *lun_no)
{ {
int fd, sid_ret = 0, ret; int fd = -1, sid_ret = 0, ret, fail_sev_sorry = 0;
struct sg_scsi_id sid; struct sg_scsi_id sid;
int *sibling_fds = NULL, sibling_count= 0; int *sibling_fds = NULL, sibling_count= 0;
typedef char burn_sg_sibling_fname[BURN_OS_SG_MAX_NAMELEN]; typedef char burn_sg_sibling_fname[BURN_OS_SG_MAX_NAMELEN];
@ -814,14 +950,16 @@ static int is_scsi_drive(char *fname, int *bus_no, int *host_no,
BURN_ALLOC_MEM(sibling_fnames, burn_sg_sibling_fname, BURN_ALLOC_MEM(sibling_fnames, burn_sg_sibling_fname,
BURN_OS_SG_MAX_SIBLINGS); BURN_OS_SG_MAX_SIBLINGS);
fd = sg_open_drive_fd(fname, 1); if (fd_in >= 0)
fd = fd_in;
else
fd = sg_open_drive_fd(fname, 1);
if (fd == -1) { if (fd == -1) {
if (linux_sg_enumerate_debug) if (linux_sg_enumerate_debug)
fprintf(stderr, "open failed, errno=%d '%s'\n", fprintf(stderr, "open failed, errno=%d '%s'\n",
errno, strerror(errno)); errno, strerror(errno));
{ret = 0; goto ex;} {ret = 0; goto ex;}
} }
sid_ret = ioctl(fd, SG_GET_SCSI_ID, &sid); sid_ret = ioctl(fd, SG_GET_SCSI_ID, &sid);
if (sid_ret == -1) { if (sid_ret == -1) {
sid.scsi_id = -1; /* mark SCSI address as invalid */ sid.scsi_id = -1; /* mark SCSI address as invalid */
@ -836,7 +974,6 @@ static int is_scsi_drive(char *fname, int *bus_no, int *host_no,
"FATAL: sgio_test() failed: errno=%d '%s'", "FATAL: sgio_test() failed: errno=%d '%s'",
errno, strerror(errno)); errno, strerror(errno));
sg_close_drive_fd(fname, -1, &fd, 0);
{ret = 0; goto ex;} {ret = 0; goto ex;}
} }
@ -856,20 +993,22 @@ static int is_scsi_drive(char *fname, int *bus_no, int *host_no,
} }
if (sid_ret == -1) {
/* ts B11109 : Try device type from INQUIRY byte 0 */
if (sgio_inquiry_cd_drive(fd, fname) == 1) {
sid_ret = 0;
sid.scsi_type = TYPE_ROM;
}
}
#ifdef SCSI_IOCTL_GET_BUS_NUMBER #ifdef SCSI_IOCTL_GET_BUS_NUMBER
/* Hearsay A61005 */ /* Hearsay A61005 */
if (ioctl(fd, SCSI_IOCTL_GET_BUS_NUMBER, bus_no) == -1) if (ioctl(fd, SCSI_IOCTL_GET_BUS_NUMBER, bus_no) == -1)
*bus_no = -1; *bus_no = -1;
#endif #endif
if (sg_close_drive_fd(fname, -1, &fd, fail_sev_sorry = (sid.scsi_type == TYPE_ROM);
sid.scsi_type == TYPE_ROM ) <= 0) {
if (linux_sg_enumerate_debug)
fprintf(stderr,
"cannot close properly, errno=%d '%s'\n",
errno, strerror(errno));
{ret = 0; goto ex;}
}
if ( (sid_ret == -1 || sid.scsi_type != TYPE_ROM) if ( (sid_ret == -1 || sid.scsi_type != TYPE_ROM)
&& !linux_sg_accept_any_type) { && !linux_sg_accept_any_type) {
if (linux_sg_enumerate_debug) if (linux_sg_enumerate_debug)
@ -880,7 +1019,8 @@ static int is_scsi_drive(char *fname, int *bus_no, int *host_no,
if (sid_ret == -1 || sid.scsi_id < 0) { if (sid_ret == -1 || sid.scsi_id < 0) {
/* ts A61211 : employ a more general ioctl */ /* ts A61211 : employ a more general ioctl */
ret = sg_obtain_scsi_adr(fname, bus_no, host_no, /* ts B11001 : re-use fd */
ret = sg_obtain_scsi_adr_fd(fname, fd, bus_no, host_no,
channel_no, target_no, lun_no); channel_no, target_no, lun_no);
if (ret>0) { if (ret>0) {
sid.host_no = *host_no; sid.host_no = *host_no;
@ -890,7 +1030,7 @@ static int is_scsi_drive(char *fname, int *bus_no, int *host_no,
} else { } else {
if (linux_sg_enumerate_debug) if (linux_sg_enumerate_debug)
fprintf(stderr, fprintf(stderr,
"sg_obtain_scsi_adr() failed\n"); "sg_obtain_scsi_adr_fd() failed\n");
{ret = 0; goto ex;} {ret = 0; goto ex;}
} }
} }
@ -924,18 +1064,42 @@ static int is_scsi_drive(char *fname, int *bus_no, int *host_no,
*lun_no= sid.lun; *lun_no= sid.lun;
ret = 1; ret = 1;
ex:; ex:;
if (fd_in < 0 && fd >= 0) {
if (sg_close_drive_fd(fname, -1, &fd, fail_sev_sorry) <= 0) {
if (linux_sg_enumerate_debug)
fprintf(stderr,
"cannot close properly, errno=%d '%s'\n",
errno, strerror(errno));
if (ret > 0)
ret = 0;
}
}
BURN_FREE_MEM(sibling_fds); BURN_FREE_MEM(sibling_fds);
BURN_FREE_MEM(sibling_fnames); BURN_FREE_MEM(sibling_fnames);
return ret; return ret;
} }
static int sg_open_for_enumeration(char *fname, int flag)
{
int fd;
fd = sg_open_drive_fd(fname, 1);
if (fd < 0) {
if (linux_sg_enumerate_debug || linux_ata_enumerate_verbous)
fprintf(stderr, "open failed, errno=%d '%s'\n",
errno, strerror(errno));
return -1;
}
return fd;
}
/** Speciality of GNU/Linux: detect non-SCSI ATAPI (EIDE) which will from /** Speciality of GNU/Linux: detect non-SCSI ATAPI (EIDE) which will from
then on used used via generic SCSI as is done with (emulated) SCSI drives */ then on used used via generic SCSI as is done with (emulated) SCSI drives */
static void ata_enumerate(void) static void ata_enumerate(void)
{ {
int ret; int ret, i, fd = -1;
int i;
char fname[10]; char fname[10];
if (linux_ata_enumerate_verbous) if (linux_ata_enumerate_verbous)
@ -956,14 +1120,17 @@ static void ata_enumerate(void)
fprintf(stderr, "not in whitelist\n"); fprintf(stderr, "not in whitelist\n");
continue; continue;
} }
ret = is_ata_drive(fname); fd = sg_open_for_enumeration(fname, 0);
if (fd < 0)
continue;
ret = is_ata_drive(fname, fd);
if (ret < 0) if (ret < 0)
break; break;
if (ret == 0) if (ret == 0)
continue; continue;
if (linux_ata_enumerate_verbous) if (linux_ata_enumerate_verbous)
fprintf(stderr, "accepting as drive without SCSI address\n"); fprintf(stderr, "accepting as drive without SCSI address\n");
enumerate_common(fname, -1, -1, -1, -1, -1); enumerate_common(fname, fd, -1, -1, -1, -1, -1);
} }
} }
@ -971,7 +1138,7 @@ static void ata_enumerate(void)
/** Detects (probably emulated) SCSI drives */ /** Detects (probably emulated) SCSI drives */
static void sg_enumerate(void) static void sg_enumerate(void)
{ {
int i, ret; int i, ret, fd = -1;
int bus_no= -1, host_no= -1, channel_no= -1, target_no= -1, lun_no= -1; int bus_no= -1, host_no= -1, channel_no= -1, target_no= -1, lun_no= -1;
char fname[17]; char fname[17];
@ -999,8 +1166,11 @@ static void sg_enumerate(void)
fprintf(stderr, "not in whitelist\n"); fprintf(stderr, "not in whitelist\n");
continue; continue;
} }
fd = sg_open_for_enumeration(fname, 0);
if (fd < 0)
continue;
ret = is_scsi_drive(fname, &bus_no, &host_no, &channel_no, ret = is_scsi_drive(fname, fd, &bus_no, &host_no, &channel_no,
&target_no, &lun_no); &target_no, &lun_no);
if (ret < 0) if (ret < 0)
break; break;
@ -1009,7 +1179,7 @@ static void sg_enumerate(void)
if (linux_sg_enumerate_debug) if (linux_sg_enumerate_debug)
fprintf(stderr, "accepting as SCSI %d,%d,%d,%d bus=%d\n", fprintf(stderr, "accepting as SCSI %d,%d,%d,%d bus=%d\n",
host_no, channel_no, target_no, lun_no, bus_no); host_no, channel_no, target_no, lun_no, bus_no);
enumerate_common(fname, bus_no, host_no, channel_no, enumerate_common(fname, fd, bus_no, host_no, channel_no,
target_no, lun_no); target_no, lun_no);
} }
@ -1058,7 +1228,7 @@ static int fname_drive_is_listed(char *fname, int flag)
*/ */
static int fname_enumerate(char *fname, int flag) static int fname_enumerate(char *fname, int flag)
{ {
int is_ata= 0, is_scsi= 0, ret; int is_ata= 0, is_scsi= 0, ret, fd = -1;
int bus_no= -1, host_no= -1, channel_no= -1, target_no= -1, lun_no= -1; int bus_no= -1, host_no= -1, channel_no= -1, target_no= -1, lun_no= -1;
char *msg = NULL; char *msg = NULL;
struct stat stbuf; struct stat stbuf;
@ -1076,13 +1246,16 @@ static int fname_enumerate(char *fname, int flag)
msg, 0, 0); msg, 0, 0);
{ret = -1; goto ex;} {ret = -1; goto ex;}
} }
is_ata = is_ata_drive(fname); fd = sg_open_for_enumeration(fname, 0);
if (fd < 0)
{ret = 0; goto ex;}
is_ata = is_ata_drive(fname, fd);
if (is_ata < 0) if (is_ata < 0)
{ret = -1; goto ex;} {ret = -1; goto ex;}
if (!is_ata) if (!is_ata)
is_scsi = is_scsi_drive(fname, &bus_no, &host_no, &channel_no, is_scsi = is_scsi_drive(fname, fd, &bus_no, &host_no,
&target_no, &lun_no); &channel_no, &target_no, &lun_no);
if (is_scsi < 0) if (is_scsi < 0)
{ret = -1; goto ex;} {ret = -1; goto ex;}
if (is_ata == 0 && is_scsi == 0) if (is_ata == 0 && is_scsi == 0)
@ -1092,7 +1265,8 @@ static int fname_enumerate(char *fname, int flag)
fprintf(stderr, fprintf(stderr,
"(single) accepting as SCSI %d,%d,%d,%d bus=%d\n", "(single) accepting as SCSI %d,%d,%d,%d bus=%d\n",
host_no, channel_no, target_no, lun_no, bus_no); host_no, channel_no, target_no, lun_no, bus_no);
enumerate_common(fname, bus_no, host_no, channel_no,
enumerate_common(fname, fd, bus_no, host_no, channel_no,
target_no, lun_no); target_no, lun_no);
ret = 1; ret = 1;
ex:; ex:;
@ -1216,6 +1390,9 @@ static int add_proc_info_drives(int flag)
int ret, list_count, count = 0, i; int ret, list_count, count = 0, i;
char **list= NULL; char **list= NULL;
if (burn_sg_use_family != 0)
return(1); /* Looking only for sr resp. scd resp. sg */
ret = proc_sys_dev_cdrom_info(&list, &list_count, 0); ret = proc_sys_dev_cdrom_info(&list, &list_count, 0);
if (ret <= 0) if (ret <= 0)
return ret; return ret;
@ -1245,7 +1422,7 @@ static int add_proc_info_drives(int flag)
*/ */
/* ts A60923 - A61005 : introduced new SCSI parameters */ /* ts A60923 - A61005 : introduced new SCSI parameters */
/* ts A61021 : moved non os-specific code to spc,sbc,mmc,drive */ /* ts A61021 : moved non os-specific code to spc,sbc,mmc,drive */
static void enumerate_common(char *fname, int bus_no, int host_no, static void enumerate_common(char *fname, int fd_in, int bus_no, int host_no,
int channel_no, int target_no, int lun_no) int channel_no, int target_no, int lun_no)
{ {
int ret, i; int ret, i;
@ -1277,8 +1454,12 @@ static void enumerate_common(char *fname, int bus_no, int host_no,
out.release = sg_release; out.release = sg_release;
out.drive_is_open= sg_drive_is_open; out.drive_is_open= sg_drive_is_open;
out.issue_command = sg_issue_command; out.issue_command = sg_issue_command;
if (fd_in >= 0)
out.fd = fd_in;
/* Finally register drive and inquire drive information */ /* Finally register drive and inquire drive information.
out is an invalid copy afterwards. Do not use it for anything.
*/
burn_drive_finish_enum(&out); burn_drive_finish_enum(&out);
} }
@ -1530,6 +1711,39 @@ int sg_grab(struct burn_drive *d)
relase of drive. Unclear why not the official error return relase of drive. Unclear why not the official error return
value -1 of open(2) war used. */ value -1 of open(2) war used. */
if(! burn_drive_is_open(d)) { if(! burn_drive_is_open(d)) {
char msg[120];
/* >>> SINGLE_OPEN : This case should be impossible now, since enumeration
transfers the fd from scanning to drive.
So if close-wait-open is desired, then it has to
be done unconditionally.
*/
#ifndef Libburn_udev_wait_useC
#define Libburn_udev_wait_useC 100000
#endif
#ifndef Libburn_udev_extra_open_cyclE
if (Libburn_udev_wait_useC > 0) {
/* ts B10921 : workaround for udev which might get
a kernel event from open() and might
remove links if it cannot inspect the
drive. This waiting period shall allow udev
to act after it was woken up by the drive scan
activities.
*/
sprintf(msg,
"To avoid collision with udev: Waiting %lu usec before grabbing",
(unsigned long) Libburn_udev_wait_useC);
libdax_msgs_submit(libdax_messenger, -1, 0x00000002,
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH,
msg, 0, 0);
usleep(Libburn_udev_wait_useC);
}
#endif /* Libburn_udev_extra_open_cyclE */
try_open:; try_open:;
/* ts A60821 /* ts A60821
@ -1549,9 +1763,36 @@ try_open:;
if(ret <= 0) if(ret <= 0)
goto drive_is_in_use; goto drive_is_in_use;
} }
fd = open(d->devname, open_mode); fd = open(d->devname, open_mode);
os_errno = errno; os_errno = errno;
#ifdef Libburn_udev_extra_open_cyclE
/* ts B10920 : workaround for udev which might get
a kernel event from open() and might
remove links if it cannot inspect the
drive.
ts B10921 : this is more obtrusive than above waiting
before open(). The drive scan already has
opened and closed the drive several times.
So it seems to be merely about giving an
opportunity to udev, before long term grabbing
happens.
*/
if (fd >= 0 && Libburn_udev_wait_useC > 0) {
close(fd);
sprintf(msg,
"To avoid collision with udev: Waiting %lu usec before re-opening",
(unsigned long) Libburn_udev_wait_useC);
libdax_msgs_submit(libdax_messenger, -1, 0x00000002,
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH,
msg, 0, 0);
usleep(Libburn_udev_wait_useC);
fd = open(d->devname, open_mode);
os_errno = errno;
}
#endif /* Libburn_udev_extra_open_cyclE */
if (fd >= 0) { if (fd >= 0) {
sg_fcntl_lock(&fd, d->devname, F_WRLCK, 1); sg_fcntl_lock(&fd, d->devname, F_WRLCK, 1);
if (fd < 0) if (fd < 0)
@ -1575,6 +1816,10 @@ try_open:;
drive_is_in_use:; drive_is_in_use:;
tries++; tries++;
if (tries < max_tries) { if (tries < max_tries) {
libdax_msgs_submit(libdax_messenger, -1, 0x00000002,
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH,
"Drive is in use. Waiting 2 seconds before re-try",
0, 0);
usleep(2000000); usleep(2000000);
goto try_open; goto try_open;
} }
@ -1601,10 +1846,8 @@ int sg_release(struct burn_drive *d)
if (mmc_function_spy(d, "sg_release") <= 0) if (mmc_function_spy(d, "sg_release") <= 0)
return 0; return 0;
if (d->fd < 1) { if (d->fd < 1)
burn_print(1, "release an ungrabbed drive. die\n");
return 0; return 0;
}
/* ts A60821 /* ts A60821
<<< debug: for tracing calls which might use open drive fds */ <<< debug: for tracing calls which might use open drive fds */
@ -1640,6 +1883,8 @@ int sg_issue_command(struct burn_drive *d, struct command *c)
d->fd, d->released); d->fd, d->released);
mmc_function_spy(NULL, msg); mmc_function_spy(NULL, msg);
/* >>> ts B11110 : move this into scsi_log_cmd() together with the
static fp */
/* ts A61030 */ /* ts A61030 */
if (burn_sg_log_scsi & 1) { if (burn_sg_log_scsi & 1) {
if (fp == NULL) { if (fp == NULL) {
@ -1760,12 +2005,13 @@ ex:;
} }
/* ts A60922 */ /* ts B11001 : outsourced from non-static sg_obtain_scsi_adr() */
/** Tries to obtain SCSI address parameters. /** Tries to obtain SCSI address parameters.
@return 1 is success , 0 is failure @return 1 is success , 0 is failure
*/ */
int sg_obtain_scsi_adr(char *path, int *bus_no, int *host_no, int *channel_no, static int sg_obtain_scsi_adr_fd(char *path, int fd_in,
int *target_no, int *lun_no) int *bus_no, int *host_no, int *channel_no,
int *target_no, int *lun_no)
{ {
int fd, ret, l, open_mode = O_RDONLY; int fd, ret, l, open_mode = O_RDONLY;
struct my_scsi_idlun { struct my_scsi_idlun {
@ -1775,7 +2021,8 @@ int sg_obtain_scsi_adr(char *path, int *bus_no, int *host_no, int *channel_no,
struct my_scsi_idlun idlun; struct my_scsi_idlun idlun;
/* valgrind called idlun unitialized because it is blind for ioctl */ /* valgrind called idlun unitialized because it is blind for ioctl */
memset(&idlun, 0, sizeof(struct my_scsi_idlun)); idlun.x = 0;
idlun.host_unique_id = 0;
l = strlen(linux_ata_device_family) - 2; l = strlen(linux_ata_device_family) - 2;
if (l > 0 && strncmp(path, linux_ata_device_family, l) == 0 if (l > 0 && strncmp(path, linux_ata_device_family, l) == 0
@ -1792,7 +2039,10 @@ int sg_obtain_scsi_adr(char *path, int *bus_no, int *host_no, int *channel_no,
SuSE 9.0 (kernel 2.4) and SuSE 9.3 (kernel 2.6) */ SuSE 9.0 (kernel 2.4) and SuSE 9.3 (kernel 2.6) */
/* so skip it for now */; /* so skip it for now */;
} }
fd = open(path, open_mode); if (fd_in >= 0)
fd = fd_in;
else
fd = open(path, open_mode);
if(fd < 0) if(fd < 0)
return 0; return 0;
sg_fcntl_lock(&fd, path, F_RDLCK, 0); sg_fcntl_lock(&fd, path, F_RDLCK, 0);
@ -1808,7 +2058,8 @@ int sg_obtain_scsi_adr(char *path, int *bus_no, int *host_no, int *channel_no,
/* http://www.tldp.org/HOWTO/SCSI-Generic-HOWTO/scsi_g_idlun.html */ /* http://www.tldp.org/HOWTO/SCSI-Generic-HOWTO/scsi_g_idlun.html */
ret = ioctl(fd, SCSI_IOCTL_GET_IDLUN, &idlun); ret = ioctl(fd, SCSI_IOCTL_GET_IDLUN, &idlun);
sg_close_drive_fd(path, -1, &fd, 0); if (fd_in < 0)
sg_close_drive_fd(path, -1, &fd, 0);
if (ret == -1) if (ret == -1)
return(0); return(0);
*host_no= (idlun.x>>24)&255; *host_no= (idlun.x>>24)&255;
@ -1825,6 +2076,18 @@ int sg_obtain_scsi_adr(char *path, int *bus_no, int *host_no, int *channel_no,
} }
/* ts A60922 */
/** 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)
{
return sg_obtain_scsi_adr_fd(path, -1, bus_no, host_no, channel_no,
target_no, lun_no);
}
/* ts A60922 ticket 33 : called from drive.c */ /* ts A60922 ticket 33 : called from drive.c */
/** Tells wether a text is a persistent address as listed by the enumeration /** Tells wether a text is a persistent address as listed by the enumeration
functions. functions.
@ -1928,6 +2191,19 @@ int burn_os_stdio_capacity(char *path, off_t *bytes)
*bytes = add_size + ((off_t) vfsbuf.f_frsize) * *bytes = add_size + ((off_t) vfsbuf.f_frsize) *
(off_t) vfsbuf.f_bavail; (off_t) vfsbuf.f_bavail;
} }
#ifdef NIX
/* <<< */
fprintf(stderr, "libburn_DEBUG: Faking 4.5 TB of disk space\n");
*bytes = ((off_t) 2415919104) * (off_t) 2048;
if (*bytes / (off_t) 2048 > (off_t) 0x7ffffff0) {
*bytes = ((off_t) 0x7ffffff0) * (off_t) 2048;
fprintf(stderr, "libburn_DEBUG: Reducing disk space to 4 TB - 2 kB\n");
}
/* <<< */
#endif
ret = 1; ret = 1;
ex:; ex:;
BURN_FREE_MEM(testpath); BURN_FREE_MEM(testpath);

View File

@ -561,10 +561,8 @@ ex:;
*/ */
int sg_release(struct burn_drive *d) int sg_release(struct burn_drive *d)
{ {
if (d->fd < 0) { if (d->fd < 0)
burn_print(1, "release an ungrabbed drive. die\n");
return 0; return 0;
}
sg_close_drive(d); sg_close_drive(d);
return 0; return 0;
} }
@ -581,7 +579,7 @@ int sg_release(struct burn_drive *d)
*/ */
int sg_issue_command(struct burn_drive *d, struct command *c) int sg_issue_command(struct burn_drive *d, struct command *c)
{ {
int i, timeout_ms, ret, key, asc, ascq, done = 0; int i, timeout_ms, ret, key, asc, ascq, done = 0, sense_len;
time_t start_time; time_t start_time;
struct uscsi_cmd cgc; struct uscsi_cmd cgc;
char msg[80]; char msg[80];
@ -662,11 +660,12 @@ int sg_issue_command(struct burn_drive *d, struct command *c)
/* >>> valid sense: cgc.uscsi_rqlen - cgc.uscsi_rqresid */; /* >>> valid sense: cgc.uscsi_rqlen - cgc.uscsi_rqresid */;
spc_decode_sense(c->sense, 0, &key, &asc, &ascq); spc_decode_sense(c->sense, 0, &key, &asc, &ascq);
if (key || asc || ascq) { if (key || asc || ascq)
done = scsi_eval_cmd_outcome(d, c, fp, c->sense, 18, 0, sense_len = 18;
else
sense_len = 0;
done = scsi_eval_cmd_outcome(d, c, fp, c->sense, sense_len, 0,
start_time, timeout_ms, i, 2); start_time, timeout_ms, i, 2);
} else
done = 1;
} /* end of retry-loop */ } /* end of retry-loop */
@ -785,13 +784,11 @@ int burn_os_stdio_capacity(char *path, off_t *bytes)
#endif #endif
char *testpath = NULL, *cpt; char *testpath = NULL, *cpt;
long blocks;
off_t add_size = 0; off_t add_size = 0;
BURN_ALLOC_MEM(testpath, char, 4096); BURN_ALLOC_MEM(testpath, char, 4096);
testpath[0] = 0; testpath[0] = 0;
blocks = *bytes / 512;
if (stat(path, &stbuf) == -1) { if (stat(path, &stbuf) == -1) {
strcpy(testpath, path); strcpy(testpath, path);
cpt = strrchr(testpath, '/'); cpt = strrchr(testpath, '/');

View File

@ -23,12 +23,20 @@
#else #else
#ifdef __FreeBSD__ #ifdef __FreeBSD__
#ifdef Libburn_use_sg_freebsd_porT
#include "sg-freebsd-port.c"
#else
#include "sg-freebsd.c" #include "sg-freebsd.c"
#endif
#else #else
#ifdef __FreeBSD_kernel__ #ifdef __FreeBSD_kernel__
#ifdef Libburn_use_sg_freebsd_porT
#include "sg-freebsd-port.c"
#else
#include "sg-freebsd.c" #include "sg-freebsd.c"
#endif
#else #else
#ifdef __linux #ifdef __linux
@ -50,11 +58,11 @@
static int intentional_compiler_warning(void) static int intentional_compiler_warning(void)
{ {
int INTENTIONAL_COMPILER_WARNING_; int INTENTIONAL_COMPILER_WARNING_;
int Cannot_recognize_GNU_Linux_nor_FreeBSD_; int Cannot_recognize_GNU_Linux_nor_FreeBSD_nor_Solaris_;
int Have_to_use_dummy_MMC_transport_adapter_; int Have_to_use_dummy_MMC_transport_adapter_;
int This_libburn_will_not_be_able_to_operate_on_real_CD_drives; int This_libburn_will_not_be_able_to_operate_on_real_CD_drives;
int Have_to_use_dummy_MMC_transport_adapter; int Have_to_use_dummy_MMC_transport_adapter;
int Cannot_recognize_GNU_Linux_nor_FreeBSD; int Cannot_recognize_GNU_Linux_nor_FreeBSD_nor_Solaris;
int INTENTIONAL_COMPILER_WARNING; int INTENTIONAL_COMPILER_WARNING;
return(0); return(0);

View File

@ -113,6 +113,7 @@ int spc_test_unit_ready_r(struct burn_drive *d, int *key, int *asc, int *ascq)
c->retry = 0; c->retry = 0;
c->dir = NO_TRANSFER; c->dir = NO_TRANSFER;
d->issue_command(d, c); d->issue_command(d, c);
*key = *asc = *ascq = 0;
if (c->error) { if (c->error) {
spc_decode_sense(c->sense, 0, key, asc, ascq); spc_decode_sense(c->sense, 0, key, asc, ascq);
return (key == 0); return (key == 0);
@ -138,15 +139,20 @@ int spc_wait_unit_attention(struct burn_drive *d, int max_sec, char *cmd_text,
int flag) int flag)
{ {
int i, ret = 1, key = 0, asc = 0, ascq = 0, clueless_start = 0; int i, ret = 1, key = 0, asc = 0, ascq = 0, clueless_start = 0;
static int clueless_timeout = 5 * 10; static double tests_per_second = 2.0;
int sleep_usecs, loop_limit, clueless_timeout;
char *msg = NULL; char *msg = NULL;
unsigned char sense[14]; unsigned char sense[14];
enum response resp;
BURN_ALLOC_MEM(msg, char, 320); BURN_ALLOC_MEM(msg, char, 320);
clueless_timeout = 5 * tests_per_second + 1;
loop_limit = max_sec * tests_per_second + 1;
sleep_usecs = 1000000 / tests_per_second;
if (!(flag & 1)) if (!(flag & 1))
usleep(100000); usleep(sleep_usecs);
for(i = !(flag & 1); i < max_sec * 10; i++) {
for(i = !(flag & 1); i < loop_limit; i++) {
ret = spc_test_unit_ready_r(d, &key, &asc, &ascq); ret = spc_test_unit_ready_r(d, &key, &asc, &ascq);
if (ret > 0) /* ready */ if (ret > 0) /* ready */
break; break;
@ -177,7 +183,7 @@ handle_error:;
sense[2] = key; sense[2] = key;
sense[12] = asc; sense[12] = asc;
sense[13] = ascq; sense[13] = ascq;
resp = scsi_error_msg(d, sense, 14, msg + strlen(msg), scsi_error_msg(d, sense, 14, msg + strlen(msg),
&key, &asc, &ascq); &key, &asc, &ascq);
libdax_msgs_submit(libdax_messenger, d->global_index, libdax_msgs_submit(libdax_messenger, d->global_index,
0x0002014d, 0x0002014d,
@ -203,7 +209,7 @@ handle_error:;
goto handle_error; goto handle_error;
slumber:; slumber:;
usleep(100000); usleep(sleep_usecs);
} }
if (ret <= 0 || !(flag & 2)) { if (ret <= 0 || !(flag & 2)) {
sprintf(msg, "Async %s %s after %d.%d seconds", sprintf(msg, "Async %s %s after %d.%d seconds",
@ -268,13 +274,12 @@ void spc_inquiry(struct burn_drive *d)
struct buffer *buf = NULL; struct buffer *buf = NULL;
struct burn_scsi_inquiry_data *id; struct burn_scsi_inquiry_data *id;
struct command *c = NULL; struct command *c = NULL;
int ret;
if (mmc_function_spy(d, "inquiry") <= 0) if (mmc_function_spy(d, "inquiry") <= 0)
return; return;
BURN_ALLOC_MEM(buf, struct buffer, 1); BURN_ALLOC_MEM_VOID(buf, struct buffer, 1);
BURN_ALLOC_MEM(c, struct command, 1); BURN_ALLOC_MEM_VOID(c, struct command, 1);
scsi_init_command(c, SPC_INQUIRY, sizeof(SPC_INQUIRY)); scsi_init_command(c, SPC_INQUIRY, sizeof(SPC_INQUIRY));
c->dxfer_len = (c->opcode[3] << 8) | c->opcode[4]; c->dxfer_len = (c->opcode[3] << 8) | c->opcode[4];
c->retry = 1; c->retry = 1;
@ -342,8 +347,8 @@ static int spc_sense_caps_al(struct burn_drive *d, int *alloc_len, int flag)
{ {
struct buffer *buf = NULL; struct buffer *buf = NULL;
struct scsi_mode_data *m; struct scsi_mode_data *m;
int size, page_length, num_write_speeds = 0, i, speed, ret; int page_length, num_write_speeds = 0, i, speed, ret;
int old_alloc_len, was_error = 0; int old_alloc_len, was_error = 0, block_descr_len;
unsigned char *page; unsigned char *page;
struct command *c = NULL; struct command *c = NULL;
struct burn_speed_descriptor *sd; struct burn_speed_descriptor *sd;
@ -366,10 +371,6 @@ static int spc_sense_caps_al(struct burn_drive *d, int *alloc_len, int flag)
memset(buf, 0, sizeof(struct buffer)); memset(buf, 0, sizeof(struct buffer));
scsi_init_command(c, SPC_MODE_SENSE, sizeof(SPC_MODE_SENSE)); scsi_init_command(c, SPC_MODE_SENSE, sizeof(SPC_MODE_SENSE));
/*
memcpy(c->opcode, SPC_MODE_SENSE, sizeof(SPC_MODE_SENSE));
c->oplen = sizeof(SPC_MODE_SENSE);
*/
c->dxfer_len = *alloc_len; c->dxfer_len = *alloc_len;
c->opcode[7] = (c->dxfer_len >> 8) & 0xff; c->opcode[7] = (c->dxfer_len >> 8) & 0xff;
c->opcode[8] = c->dxfer_len & 0xff; c->opcode[8] = c->dxfer_len & 0xff;
@ -386,14 +387,22 @@ static int spc_sense_caps_al(struct burn_drive *d, int *alloc_len, int flag)
was_error = 1; was_error = 1;
} }
size = c->page->data[0] * 256 + c->page->data[1] + 2; /* ts B11103 : qemu SCSI CD-ROM has Block Descriptor Length > 0.
page = c->page->data + 8; The descriptors come between header and page.
*/
block_descr_len = c->page->data[6] * 256 + c->page->data[7];
/* Skip over Mode Data Header and block descriptors */
page = c->page->data + 8 + block_descr_len;
/* ts A61225 : /* ts A61225 :
Although MODE SENSE indeed belongs to SPC, the returned code page Although MODE SENSE indeed belongs to SPC, the returned code page
2Ah is part of MMC-1 to MMC-3. In MMC-1 5.2.3.4. it has 22 bytes, 2Ah is part of MMC-1 to MMC-3. In MMC-1 5.2.3.4. it has 22 bytes,
in MMC-3 6.3.11 there are at least 28 bytes plus a variable length 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". set of speed descriptors. In MMC-5 E.11 it is declared "legacy".
ts B11031 :
qemu emulates an ATAPI DVD-ROM, which delivers only a page length
of 18. This is now tolerated.
*/ */
/* ts A90603 : /* ts A90603 :
SPC-1 8.3.3 enumerates mode page format bytes from 0 to n and SPC-1 8.3.3 enumerates mode page format bytes from 0 to n and
@ -407,8 +416,9 @@ static int spc_sense_caps_al(struct burn_drive *d, int *alloc_len, int flag)
if (page_length + 10 > old_alloc_len) if (page_length + 10 > old_alloc_len)
page_length = old_alloc_len - 10; page_length = old_alloc_len - 10;
/* ts A90602 : 20 asserts page[21]. (see SPC-1 8.3.3) */ /* ts A90602 : page_length N asserts page[N+1]. (see SPC-1 8.3.3) */
if (page_length < 20) { /* ts B11031 : qemu drive has a page_length of 18 */
if (page_length < 18) {
m->valid = -1; m->valid = -1;
sprintf(msg, "MODE SENSE page 2A too short: %s : %d", sprintf(msg, "MODE SENSE page 2A too short: %s : %d",
d->devname, page_length); d->devname, page_length);
@ -437,8 +447,11 @@ static int spc_sense_caps_al(struct burn_drive *d, int *alloc_len, int flag)
m->max_read_speed = page[8] * 256 + page[9]; m->max_read_speed = page[8] * 256 + page[9];
m->cur_read_speed = page[14] * 256 + page[15]; m->cur_read_speed = page[14] * 256 + page[15];
m->max_write_speed = page[18] * 256 + page[19]; m->max_write_speed = m->cur_write_speed = 0;
m->cur_write_speed = page[20] * 256 + page[21]; if (page_length >= 18) /* note: page length is page size - 2 */
m->max_write_speed = page[18] * 256 + page[19];
if (page_length >= 20)
m->cur_write_speed = page[20] * 256 + page[21];
/* ts A61021 : New field to be set by atip (or following MMC-3 info) */ /* ts A61021 : New field to be set by atip (or following MMC-3 info) */
m->min_write_speed = m->max_write_speed; m->min_write_speed = m->max_write_speed;
@ -538,7 +551,7 @@ ex:
void spc_sense_caps(struct burn_drive *d) void spc_sense_caps(struct burn_drive *d)
{ {
int alloc_len, start_len = 30, ret; int alloc_len, start_len = 30, minimum_len = 28, ret;
mmc_start_if_needed(d, 1); mmc_start_if_needed(d, 1);
if (mmc_function_spy(d, "sense_caps") <= 0) if (mmc_function_spy(d, "sense_caps") <= 0)
@ -551,7 +564,12 @@ void spc_sense_caps(struct burn_drive *d)
fprintf(stderr,"LIBBURN_DEBUG: 5Ah alloc_len = %d , ret = %d\n", fprintf(stderr,"LIBBURN_DEBUG: 5Ah alloc_len = %d , ret = %d\n",
alloc_len, ret); alloc_len, ret);
*/ */
if (alloc_len >= start_len && ret > 0) /* ts B11103:
qemu ATAPI DVD-ROM delivers only 28.
SanDisk Cruzer U3 memory stick throws error on alloc_len < 30.
MMC-1 prescribes that 30 are available. qemu tolerates 30.
*/
if (alloc_len >= minimum_len && ret > 0)
/* second execution with announced length */ /* second execution with announced length */
spc_sense_caps_al(d, &alloc_len, 0); spc_sense_caps_al(d, &alloc_len, 0);
} }
@ -561,17 +579,16 @@ void spc_sense_error_params(struct burn_drive *d)
{ {
struct buffer *buf = NULL; struct buffer *buf = NULL;
struct scsi_mode_data *m; struct scsi_mode_data *m;
int size, alloc_len = 12 ; int alloc_len = 12 ;
unsigned char *page; unsigned char *page;
struct command *c = NULL; struct command *c = NULL;
int ret;
mmc_start_if_needed(d, 1); mmc_start_if_needed(d, 1);
if (mmc_function_spy(d, "sense_error_params") <= 0) if (mmc_function_spy(d, "sense_error_params") <= 0)
goto ex; goto ex;
BURN_ALLOC_MEM(buf, struct buffer, 1); BURN_ALLOC_MEM_VOID(buf, struct buffer, 1);
BURN_ALLOC_MEM(c, struct command, 1); BURN_ALLOC_MEM_VOID(c, struct command, 1);
scsi_init_command(c, SPC_MODE_SENSE, sizeof(SPC_MODE_SENSE)); scsi_init_command(c, SPC_MODE_SENSE, sizeof(SPC_MODE_SENSE));
c->dxfer_len = alloc_len; c->dxfer_len = alloc_len;
@ -585,7 +602,6 @@ void spc_sense_error_params(struct burn_drive *d)
c->dir = FROM_DRIVE; c->dir = FROM_DRIVE;
d->issue_command(d, c); d->issue_command(d, c);
size = c->page->data[0] * 256 + c->page->data[1] + 2;
m = d->mdata; m = d->mdata;
page = c->page->data + 8; page = c->page->data + 8;
d->params.retries = page[3]; d->params.retries = page[3];
@ -601,14 +617,13 @@ void spc_select_error_params(struct burn_drive *d,
{ {
struct buffer *buf = NULL; struct buffer *buf = NULL;
struct command *c = NULL; struct command *c = NULL;
int ret;
mmc_start_if_needed(d, 1); mmc_start_if_needed(d, 1);
if (mmc_function_spy(d, "select_error_params") <= 0) if (mmc_function_spy(d, "select_error_params") <= 0)
goto ex; goto ex;
BURN_ALLOC_MEM(buf, struct buffer, 1); BURN_ALLOC_MEM_VOID(buf, struct buffer, 1);
BURN_ALLOC_MEM(c, struct command, 1); BURN_ALLOC_MEM_VOID(c, struct command, 1);
scsi_init_command(c, SPC_MODE_SELECT, sizeof(SPC_MODE_SELECT)); scsi_init_command(c, SPC_MODE_SELECT, sizeof(SPC_MODE_SELECT));
c->retry = 1; c->retry = 1;
@ -627,7 +642,6 @@ void spc_select_error_params(struct burn_drive *d,
c->page->data[10] |= 4; c->page->data[10] |= 4;
if (!o->hardware_error_recovery) if (!o->hardware_error_recovery)
c->page->data[10] |= 1; c->page->data[10] |= 1;
/*burn_print(1, "error parameter 0x%x\n", c->page->data[10]);*/
c->page->data[11] = d->params.retries; c->page->data[11] = d->params.retries;
c->dir = TO_DRIVE; c->dir = TO_DRIVE;
d->issue_command(d, c); d->issue_command(d, c);
@ -640,7 +654,7 @@ void spc_sense_write_params(struct burn_drive *d)
{ {
struct buffer *buf = NULL; struct buffer *buf = NULL;
struct scsi_mode_data *m; struct scsi_mode_data *m;
int size, dummy, alloc_len = 10, ret; int dummy1, dummy2, alloc_len = 10;
unsigned char *page; unsigned char *page;
struct command *c = NULL; struct command *c = NULL;
@ -648,8 +662,8 @@ void spc_sense_write_params(struct burn_drive *d)
if (mmc_function_spy(d, "sense_write_params") <= 0) if (mmc_function_spy(d, "sense_write_params") <= 0)
goto ex; goto ex;
BURN_ALLOC_MEM(buf, struct buffer, 1); BURN_ALLOC_MEM_VOID(buf, struct buffer, 1);
BURN_ALLOC_MEM(c, struct command, 1); BURN_ALLOC_MEM_VOID(c, struct command, 1);
/* ts A61007 : Done in soft at only caller burn_drive_grab() */ /* ts A61007 : Done in soft at only caller burn_drive_grab() */
/* a ssert(d->mdata->cdr_write || d->mdata->cdrw_write || /* a ssert(d->mdata->cdr_write || d->mdata->cdrw_write ||
@ -670,9 +684,7 @@ void spc_sense_write_params(struct burn_drive *d)
/* ts A71128 : do not interpret reply if error */ /* ts A71128 : do not interpret reply if error */
m = d->mdata; m = d->mdata;
if (!c->error) { if (!c->error) {
size = c->page->data[0] * 256 + c->page->data[1] + 2;
page = c->page->data + 8; 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_length = page[1];
m->write_page_valid = 1; m->write_page_valid = 1;
} else } else
@ -685,7 +697,8 @@ void spc_sense_write_params(struct burn_drive *d)
d->read_format_capacities(d, -1); d->read_format_capacities(d, -1);
else if (d->status == BURN_DISC_BLANK || else if (d->status == BURN_DISC_BLANK ||
(d->current_is_cd_profile && d->status == BURN_DISC_APPENDABLE)) { (d->current_is_cd_profile && d->status == BURN_DISC_APPENDABLE)) {
d->get_nwa(d, -1, &dummy, &dummy); burn_drive_send_default_page_05(d, 0);
d->get_nwa(d, -1, &dummy1, &dummy2);
} }
/* others are hopefully up to date from mmc_read_disc_info() */ /* others are hopefully up to date from mmc_read_disc_info() */
@ -710,14 +723,14 @@ void spc_select_write_params(struct burn_drive *d,
{ {
struct buffer *buf = NULL; struct buffer *buf = NULL;
struct command *c = NULL; struct command *c = NULL;
int alloc_len, ret; int alloc_len;
mmc_start_if_needed(d, 1); mmc_start_if_needed(d, 1);
if (mmc_function_spy(d, "select_write_params") <= 0) if (mmc_function_spy(d, "select_write_params") <= 0)
goto ex; goto ex;
BURN_ALLOC_MEM(buf, struct buffer, 1); BURN_ALLOC_MEM_VOID(buf, struct buffer, 1);
BURN_ALLOC_MEM(c, struct command, 1); BURN_ALLOC_MEM_VOID(c, struct command, 1);
/* ts A61007 : All current callers are safe. */ /* ts A61007 : All current callers are safe. */
/* a ssert(o->drive == d); */ /* a ssert(o->drive == d); */
@ -762,9 +775,6 @@ void spc_select_write_params(struct burn_drive *d,
c->page->bytes = alloc_len; c->page->bytes = alloc_len;
burn_print(12, "using write page length %d (valid %d)\n",
d->mdata->write_page_length, d->mdata->write_page_valid);
/* ts A61229 */ /* ts A61229 */
if (mmc_compose_mode_page_5(d, o, c->page->data + 8) <= 0) if (mmc_compose_mode_page_5(d, o, c->page->data + 8) <= 0)
goto ex; goto ex;
@ -781,6 +791,7 @@ void spc_getcaps(struct burn_drive *d)
if (mmc_function_spy(d, "getcaps") <= 0) if (mmc_function_spy(d, "getcaps") <= 0)
return; return;
burn_speed_descriptor_destroy(&(d->mdata->speed_descriptors), 1);
spc_inquiry(d); spc_inquiry(d);
spc_sense_caps(d); spc_sense_caps(d);
spc_sense_error_params(d); spc_sense_error_params(d);
@ -797,21 +808,18 @@ void spc_probe_write_modes(struct burn_drive *d)
int try_write_type = 1; int try_write_type = 1;
int try_block_type = 0; int try_block_type = 0;
int key, asc, ascq, useable_write_type = -1, useable_block_type = -1; int key, asc, ascq, useable_write_type = -1, useable_block_type = -1;
int last_try = 0, ret; int last_try = 0;
struct command *c = NULL; struct command *c = NULL;
mmc_start_if_needed(d, 1); mmc_start_if_needed(d, 1);
if (mmc_function_spy(d, "spc_probe_write_modes") <= 0) if (mmc_function_spy(d, "spc_probe_write_modes") <= 0)
goto ex; goto ex;
BURN_ALLOC_MEM(buf, struct buffer, 1); BURN_ALLOC_MEM_VOID(buf, struct buffer, 1);
BURN_ALLOC_MEM(c, struct command, 1); BURN_ALLOC_MEM_VOID(c, struct command, 1);
/* ts A70213 : added pseudo try_write_type 4 to set a suitable mode */ /* ts A70213 : added pseudo try_write_type 4 to set a suitable mode */
while (try_write_type != 5) { while (try_write_type != 5) {
burn_print(9, "trying %d, %d\n", try_write_type,
try_block_type);
/* ts A70213 */ /* ts A70213 */
if (try_write_type == 4) { if (try_write_type == 4) {
/* Pseudo write type NONE . Set a useable write mode */ /* Pseudo write type NONE . Set a useable write mode */
@ -850,10 +858,9 @@ void spc_probe_write_modes(struct burn_drive *d)
spc_decode_sense(c->sense, 0, &key, &asc, &ascq); spc_decode_sense(c->sense, 0, &key, &asc, &ascq);
if (key) if (key)
burn_print(7, "%d not supported\n", try_block_type); /* try_block_type not supported */;
else { else {
burn_print(7, "%d:%d SUPPORTED MODE!\n", /* try_write_type, try_block_type is supported mode */
try_write_type, try_block_type);
if (try_write_type == 2) /* sao */ if (try_write_type == 2) /* sao */
d->block_types[try_write_type] = d->block_types[try_write_type] =
BURN_BLOCK_SAO; BURN_BLOCK_SAO;
@ -1034,9 +1041,6 @@ enum response scsi_error_msg(struct burn_drive *d, unsigned char *sense,
sprintf(msg, "[%X %2.2X %2.2X] ", *key, *asc, *ascq); sprintf(msg, "[%X %2.2X %2.2X] ", *key, *asc, *ascq);
msg= msg + strlen(msg); 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) { switch (*asc) {
case 0x00: case 0x00:
if (*key > 0 || *ascq > 0) if (*key > 0 || *ascq > 0)
@ -1332,10 +1336,6 @@ enum response scsi_error(struct burn_drive *d, unsigned char *sense,
BURN_ALLOC_MEM(msg, char, 160); BURN_ALLOC_MEM(msg, char, 160);
resp = scsi_error_msg(d, sense, senselen, msg, &key, &asc, &ascq); resp = scsi_error_msg(d, sense, senselen, msg, &key, &asc, &ascq);
if (asc == 0 || asc == 0x3A)
burn_print(12, "%s\n", msg);
else
burn_print(1, "%s\n", msg);
ex:; ex:;
if (ret == -1) if (ret == -1)
resp = FAIL; resp = FAIL;
@ -1408,7 +1408,7 @@ static char *scsi_command_name(unsigned int c, int flag)
case 0xbe: case 0xbe:
return "READ CD"; return "READ CD";
} }
return "(NOT IN COMMAND LIST)"; return "(NOT IN LIBBURN COMMAND LIST)";
} }
@ -1456,38 +1456,39 @@ ex:;
} }
/* ts A91106 */ /* ts B11110 */
/* @param flag bit0= do not show eventual data payload sent to the drive /* @param flag bit0= do not show eventual data payload sent to the drive
(never with WRITE commands) (never with WRITE commands)
bit1= show write length and target LBA in decimal
*/ */
int scsi_show_cmd_text(struct command *c, void *fp_in, int flag) int scsi_show_command(unsigned char *opcode, int oplen, int dir,
unsigned char *data, int bytes,
void *fp_in, int flag)
{ {
int i; int i;
FILE *fp = fp_in; FILE *fp = fp_in;
fprintf(fp, "\n%s\n", fprintf(fp, "\n%s\n",
scsi_command_name((unsigned int) c->opcode[0], 0)); scsi_command_name((unsigned int) opcode[0], 0));
for(i = 0; i < 16 && i < c->oplen; i++) for(i = 0; i < 16 && i < oplen; i++)
fprintf(fp, "%2.2x ", c->opcode[i]); fprintf(fp, "%2.2x ", opcode[i]);
if (i > 0) if (i > 0)
fprintf(fp, "\n"); fprintf(fp, "\n");
if (flag & 1) if (flag & 1)
return 1; return 1;
if (c->opcode[0] == 0x2A) { /* WRITE 10 */ if (opcode[0] == 0x2A) { /* WRITE 10 */
if (flag & 2) if (flag & 2)
fprintf(fp, "%d -> %d\n", fprintf(fp, "%d -> %d\n",
(c->opcode[7] << 8) | c->opcode[8], (opcode[7] << 8) | opcode[8],
mmc_four_char_to_int(c->opcode + 2)); mmc_four_char_to_int(opcode + 2));
} else if (c->opcode[0] == 0xAA) { /* WRITE 12 */ } else if (opcode[0] == 0xAA) { /* WRITE 12 */
if (flag & 2) if (flag & 2)
fprintf(fp, "%d -> %d\n", fprintf(fp, "%d -> %d\n",
mmc_four_char_to_int(c->opcode + 6), mmc_four_char_to_int(opcode + 6),
mmc_four_char_to_int(c->opcode + 2)); mmc_four_char_to_int(opcode + 2));
} else if (c->dir == TO_DRIVE) { } else if (dir == TO_DRIVE && !(flag & 1)) {
fprintf(fp, "To drive: %db\n", c->page->bytes); fprintf(fp, "To drive: %db\n", bytes);
for (i = 0; i < c->page->bytes; i++) for (i = 0; i < bytes; i++)
fprintf(fp, "%2.2x%c", c->page->data[i], fprintf(fp, "%2.2x%c", data[i],
((i % 20) == 19 ? '\n' : ' ')); ((i % 20) == 19 ? '\n' : ' '));
if (i % 20) if (i % 20)
fprintf(fp, "\n"); fprintf(fp, "\n");
@ -1495,24 +1496,39 @@ int scsi_show_cmd_text(struct command *c, void *fp_in, int flag)
return 1; return 1;
} }
/* ts A91106 */ /* ts A91106 */
int scsi_show_cmd_reply(struct command *c, void *fp_in, int flag) /* @param flag bit0= do not show eventual data payload sent to the drive
(never with WRITE commands)
*/
int scsi_show_cmd_text(struct command *c, void *fp_in, int flag)
{
return scsi_show_command(c->opcode, c->oplen, c->dir, c->page->data,
c->page->bytes, fp_in, flag);
}
/* ts A91106 */ /* ts B11110 */
int scsi_show_command_reply(unsigned char *opcode, int data_dir,
unsigned char *data, int dxfer_len,
void *fp_in, int flag)
{ {
int i; int i;
FILE *fp = fp_in; FILE *fp = fp_in;
if (c->dir != FROM_DRIVE) if (data_dir != FROM_DRIVE)
return 2; return 2;
if (c->opcode[0] == 0x28 || c->opcode[0] == 0x3C || if (opcode[0] == 0x28 || opcode[0] == 0x3C ||
c->opcode[0] == 0xA8 || c->opcode[0] == 0xBE) { opcode[0] == 0xA8 || opcode[0] == 0xBE) {
/* READ commands */ /* READ commands */
/* >>> report amount of data */; /* >>> report amount of data */;
return 2; return 2;
} }
fprintf(fp, "From drive: %db\n", c->dxfer_len); fprintf(fp, "From drive: %db\n", dxfer_len);
for (i = 0; i < c->dxfer_len; i++) for (i = 0; i < dxfer_len; i++)
fprintf(fp, "%2.2x%c", c->page->data[i], fprintf(fp, "%2.2x%c", data[i],
((i % 20) == 19 ? '\n' : ' ')); ((i % 20) == 19 ? '\n' : ' '));
if (i % 20) if (i % 20)
fprintf(fp, "\n"); fprintf(fp, "\n");
@ -1520,31 +1536,51 @@ int scsi_show_cmd_reply(struct command *c, void *fp_in, int flag)
} }
/* ts B11110 */
/** Logs command (before execution) */
int scsi_log_command(unsigned char *opcode, int oplen, int data_dir,
unsigned char *data, int bytes,
void *fp_in, int flag)
{
FILE *fp = fp_in;
if (fp != NULL && (fp == stderr || (burn_sg_log_scsi & 1))) {
scsi_show_command(opcode, oplen, data_dir, data, bytes, fp, 0);
if (burn_sg_log_scsi & 4)
fflush(fp);
}
if (fp == stderr || !(burn_sg_log_scsi & 2))
return 1;
scsi_log_command(opcode, oplen, data_dir, data, bytes, stderr, 0);
return 1;
}
/* ts A91218 (former sg_log_cmd ts A70518) */ /* ts A91218 (former sg_log_cmd ts A70518) */
/** Logs command (before execution) */ /** Logs command (before execution) */
int scsi_log_cmd(struct command *c, void *fp_in, int flag) int scsi_log_cmd(struct command *c, void *fp_in, int flag)
{ {
FILE *fp = fp_in; int ret, bytes = 0;
unsigned char *data = NULL;
if (fp != NULL && (fp == stderr || (burn_sg_log_scsi & 1))) { if (c->page != NULL) {
scsi_show_cmd_text(c, fp, 0); data = c->page->data;
if (burn_sg_log_scsi & 4) bytes = c->page->bytes;
fflush(fp);
} }
if (fp == stderr || !(burn_sg_log_scsi & 2)) ret = scsi_log_command(c->opcode, c->oplen, c->dir, data, bytes,
return 1; fp_in, flag);
scsi_log_cmd(c, stderr, flag); return ret;
return 1;
} }
/* ts A91221 (former sg_log_err ts A91108) */ /* ts B11110 */
/** Logs outcome of a sg command. /** Logs outcome of a sg command.
@param flag bit0 causes an error message @param flag bit0 causes an error message
bit1 do not print duration bit1 do not print duration
*/ */
int scsi_log_err(struct command *c, void *fp_in, unsigned char sense[18], int scsi_log_reply(unsigned char *opcode, int data_dir, unsigned char *data,
int sense_len, int duration, int flag) int dxfer_len, void *fp_in, unsigned char sense[18],
int sense_len, int duration, int flag)
{ {
char durtxt[20]; char durtxt[20];
FILE *fp = fp_in; FILE *fp = fp_in;
@ -1570,7 +1606,9 @@ int scsi_log_err(struct command *c, void *fp_in, unsigned char sense[18],
(unsigned int) key, (unsigned int) asc, (unsigned int) key, (unsigned int) asc,
(unsigned int) ascq, durtxt); (unsigned int) ascq, durtxt);
} else { } else {
scsi_show_cmd_reply(c, fp, 0); scsi_show_command_reply(opcode, data_dir, data,
dxfer_len, fp, 0);
if (!(flag & 2)) if (!(flag & 2))
fprintf(fp,"%6d ms\n", duration); fprintf(fp,"%6d ms\n", duration);
} }
@ -1579,11 +1617,32 @@ int scsi_log_err(struct command *c, void *fp_in, unsigned char sense[18],
} }
if (fp == stderr || !(burn_sg_log_scsi & 2)) if (fp == stderr || !(burn_sg_log_scsi & 2))
return 1; return 1;
scsi_log_err(c, stderr, sense, sense_len, duration, flag); scsi_log_reply(opcode, data_dir, data, dxfer_len,
stderr, sense, sense_len, duration, flag);
return 1; return 1;
} }
/* ts A91221 (former sg_log_err ts A91108) */
/** Legacy frontend to scsi_log_reply().
@param flag bit0 causes an error message
bit1 do not print duration
*/
int scsi_log_err(struct command *c, void *fp_in, unsigned char sense[18],
int sense_len, int duration, int flag)
{
int ret;
unsigned char *data = NULL;
if (c->page != NULL)
data = c->page->data;
ret= scsi_log_reply(c->opcode, c->dir, data, c->dxfer_len ,
fp_in, sense, sense_len, duration, flag);
return ret;
}
/* ts B00808 */ /* ts B00808 */
/* /*
@param flag bit0 = do not retry @param flag bit0 = do not retry

View File

@ -68,15 +68,30 @@ int scsi_init_command(struct command *c, unsigned char *opcode, int oplen);
/* ts A91106 */ /* ts A91106 */
int scsi_show_cmd_text(struct command *c, void *fp, int flag); int scsi_show_cmd_text(struct command *c, void *fp, int flag);
/* ts A91106 */ /* ts B11110 */
int scsi_show_cmd_reply(struct command *c, void *fp, int flag); /** Logs command (before execution). */
int scsi_log_command(unsigned char *opcode, int oplen, int data_dir,
unsigned char *data, int bytes,
void *fp_in, int flag);
/* ts A91218 (former sg_log_cmd ts A70518) */ /* ts A91218 (former sg_log_cmd ts A70518) */
/** Logs command (before execution) */ /** Legacy frontend to scsi_log_command() */
int scsi_log_cmd(struct command *c, void *fp, int flag); int scsi_log_cmd(struct command *c, void *fp, int flag);
/* ts B11110 */
/** Logs outcome of a sg command.
@param flag bit0 causes an error message
bit1 do not print duration
*/
int scsi_log_reply(unsigned char *opcode, int data_dir, unsigned char *data,
int dxfer_len, void *fp_in, unsigned char sense[18],
int sense_len, int duration, int flag);
/* ts A91221 (former sg_log_err ts A91108) */ /* ts A91221 (former sg_log_err ts A91108) */
/** Logs outcome of a sg command. */ /** Legacy frontend to scsi_log_reply().
@param flag bit0 causes an error message
bit1 do not print duration
*/
int scsi_log_err(struct command *c, void *fp, unsigned char sense[18], int scsi_log_err(struct command *c, void *fp, unsigned char sense[18],
int sense_len, int duration, int flag); int sense_len, int duration, int flag);

View File

@ -242,8 +242,12 @@ int burn_session_remove_track(struct burn_session *s, struct burn_track *t)
void burn_structure_print_disc(struct burn_disc *d) void burn_structure_print_disc(struct burn_disc *d)
{ {
int i; int i;
char msg[40];
burn_print(12, "This disc has %d sessions\n", d->sessions); sprintf(msg, "This disc has %d sessions", d->sessions);
libdax_msgs_submit(libdax_messenger, -1, 0x00000002,
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH,
msg, 0, 0);
for (i = 0; i < d->sessions; i++) { for (i = 0; i < d->sessions; i++) {
burn_structure_print_session(d->session[i]); burn_structure_print_session(d->session[i]);
} }
@ -251,16 +255,25 @@ void burn_structure_print_disc(struct burn_disc *d)
void burn_structure_print_session(struct burn_session *s) void burn_structure_print_session(struct burn_session *s)
{ {
int i; int i;
char msg[40];
burn_print(12, " Session has %d tracks\n", s->tracks); sprintf(msg, " Session has %d tracks", s->tracks);
libdax_msgs_submit(libdax_messenger, -1, 0x00000002,
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH,
msg, 0, 0);
for (i = 0; i < s->tracks; i++) { for (i = 0; i < s->tracks; i++) {
burn_structure_print_track(s->track[i]); burn_structure_print_track(s->track[i]);
} }
} }
void burn_structure_print_track(struct burn_track *t) void burn_structure_print_track(struct burn_track *t)
{ {
burn_print(12, "(%p) track size %d sectors\n", t, char msg[80];
burn_track_get_sectors(t));
sprintf(msg, " track size %d sectors",
burn_track_get_sectors(t));
libdax_msgs_submit(libdax_messenger, -1, 0x00000002,
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH,
msg, 0, 0);
} }
void burn_track_define_data(struct burn_track *t, int offset, int tail, void burn_track_define_data(struct burn_track *t, int offset, int tail,
@ -398,7 +411,6 @@ int burn_track_get_sectors(struct burn_track *t)
sectors = size / seclen; sectors = size / seclen;
if (size % seclen) if (size % seclen)
sectors++; sectors++;
burn_print(1, "%d sectors of %d length\n", sectors, seclen);
return sectors; return sectors;
} }

View File

@ -105,16 +105,14 @@ static void write_clonecd2(volatile struct toc *toc, int f)
void toc_find_modes(struct burn_drive *d) void toc_find_modes(struct burn_drive *d)
{ {
struct burn_read_opts o; int i, j;
int lba;
int i, j, ret;
struct buffer *mem = NULL; struct buffer *mem = NULL;
struct burn_toc_entry *e; struct burn_toc_entry *e;
BURN_ALLOC_MEM(mem, struct buffer, 1); /* ts A70519 : the code which needs this does not work with GNU/Linux 2.4 USB
int lba;
struct burn_read_opts o;
mem->bytes = 0;
mem->sectors = 1;
o.raw = 1; o.raw = 1;
o.c2errors = 0; o.c2errors = 0;
o.subcodes_audio = 1; o.subcodes_audio = 1;
@ -123,17 +121,18 @@ void toc_find_modes(struct burn_drive *d)
o.report_recovered_errors = 0; o.report_recovered_errors = 0;
o.transfer_damaged_blocks = 1; o.transfer_damaged_blocks = 1;
o.hardware_error_retries = 1; o.hardware_error_retries = 1;
*/
BURN_ALLOC_MEM_VOID(mem, struct buffer, 1);
mem->bytes = 0;
mem->sectors = 1;
for (i = 0; i < d->disc->sessions; i++) for (i = 0; i < d->disc->sessions; i++)
for (j = 0; j < d->disc->session[i]->tracks; j++) { for (j = 0; j < d->disc->session[i]->tracks; j++) {
struct burn_track *t = d->disc->session[i]->track[j]; struct burn_track *t = d->disc->session[i]->track[j];
e = t->entry; e = t->entry;
if (!e)
lba = 0;
else
lba = burn_msf_to_lba(e->pmin, e->psec,
e->pframe);
/* XXX | in the subcodes if appropriate! */ /* XXX | in the subcodes if appropriate! */
if (e && !(e->control & 4)) { if (e && !(e->control & 4)) {
t->mode = BURN_AUDIO; t->mode = BURN_AUDIO;
@ -142,6 +141,11 @@ void toc_find_modes(struct burn_drive *d)
t->mode = BURN_MODE1; t->mode = BURN_MODE1;
/* ts A70519 : this does not work with GNU/Linux 2.4 USB because one cannot /* ts A70519 : this does not work with GNU/Linux 2.4 USB because one cannot
predict the exact dxfer_size without knowing the sector type. predict the exact dxfer_size without knowing the sector type.
if (!e)
lba = 0;
else
lba = burn_msf_to_lba(e->pmin, e->psec,
e->pframe);
mem->sectors = 1; mem->sectors = 1;
d->read_sectors(d, lba, mem.sectors, &o, mem); d->read_sectors(d, lba, mem.sectors, &o, mem);
t->mode = sector_identify(mem->data); t->mode = sector_identify(mem->data);

View File

@ -279,6 +279,10 @@ struct burn_drive
/* ts A70129 : /* ts A70129 :
from 51h READ DISC INFORMATION Last Track Number in Last Session */ from 51h READ DISC INFORMATION Last Track Number in Last Session */
int last_track_no; int last_track_no;
/* ts B10730 : whether a default mode page 05 was already sent.
*/
int sent_default_page_05;
/* ts A70212 : from various sources : free space on media (in bytes) /* ts A70212 : from various sources : free space on media (in bytes)
With CD this might change after particular write With CD this might change after particular write
parameters have been set and nwa has been inquired. parameters have been set and nwa has been inquired.
@ -289,7 +293,9 @@ struct burn_drive
int media_lba_limit; int media_lba_limit;
/* ts A81210 : Upper limit of readable data size, /* ts A81210 : Upper limit of readable data size,
0x7fffffff = unknown */ 0x7fffffff = unknown
0x7ffffff0 = 32 bit overflow, or unknown stdio size
*/
int media_read_capacity; int media_read_capacity;
/* ts B10314 : Next Writeable Adress for drive_role == 5 */ /* ts B10314 : Next Writeable Adress for drive_role == 5 */

View File

@ -74,9 +74,6 @@ struct cd_mid_record {
int m_li; int m_li;
int s_li; int s_li;
int f_li; int f_li;
int m_lo;
int s_lo;
int f_lo;
char *other_brands; char *other_brands;
}; };
typedef struct cd_mid_record cd_mid_record_t; typedef struct cd_mid_record cd_mid_record_t;
@ -91,51 +88,51 @@ char *burn_guess_cd_manufacturer(int m_li, int s_li, int f_li,
int m_lo, int s_lo, int f_lo, int flag) int m_lo, int s_lo, int f_lo, int flag)
{ {
static cd_mid_record_t mid_list[]= { static cd_mid_record_t mid_list[]= {
{"SKC", 96, 40, 0, 0, 0, 0, ""}, {"SKC", 96, 40, 0, ""},
{"Ritek Corp" , 96, 43, 30, 0, 0, 0, ""}, {"Ritek Corp" , 96, 43, 30, ""},
{"TDK / Ritek" , 97, 10, 0, 0, 0, 0, "TRAXDATA"}, {"TDK / Ritek" , 97, 10, 0, "TRAXDATA"},
{"TDK Corporation" , 97, 15, 0, 0, 0, 0, ""}, {"TDK Corporation" , 97, 15, 0, ""},
{"Ritek Corp" , 97, 15, 10, 0, 0, 0, "7-plus, Aopen, PONY, Power Source, TDK, TRAXDATA, HiCO, PHILIPS, Primdisc, Victor.JVC, OPTI STORAGE, Samsung"}, {"Ritek Corp" , 97, 15, 10, "7-plus, Aopen, PONY, Power Source, TDK, TRAXDATA, HiCO, PHILIPS, Primdisc, Victor.JVC, OPTI STORAGE, Samsung"},
{"Mitsubishi Chemical Corporation" , 97, 15, 20, 0, 0, 0, ""}, {"Mitsubishi Chemical Corporation" , 97, 15, 20, ""},
{"Nan-Ya Plastics Corporation" , 97, 15, 30, 0, 0, 0, "Hatron, MMore, Acer, LITEON"}, {"Nan-Ya Plastics Corporation" , 97, 15, 30, "Hatron, MMore, Acer, LITEON"},
{"Delphi" , 97, 15, 50, 0, 0, 0, ""}, {"Delphi" , 97, 15, 50, ""},
{"Shenzhen SG&SAST" , 97, 16, 20, 0, 0, 0, ""}, {"Shenzhen SG&SAST" , 97, 16, 20, ""},
{"Moser Baer India Limited" , 97, 17, 0, 0, 0, 0, "EMTEC, Intenso, YAKUMO, PLATINUM, Silver Circle"}, {"Moser Baer India Limited" , 97, 17, 0, "EMTEC, Intenso, YAKUMO, PLATINUM, Silver Circle"},
{"SKY media Manufacturing SA" , 97, 17, 10, 0, 0, 0, ""}, {"SKY media Manufacturing SA" , 97, 17, 10, ""},
{"Wing" , 97, 18, 10, 0, 0, 0, ""}, {"Wing" , 97, 18, 10, ""},
{"DDT" , 97, 18, 20, 0, 0, 0, ""}, {"DDT" , 97, 18, 20, ""},
{"Daxon Technology Inc. / Acer" , 97, 22, 60, 0, 0, 0, "Maxmax, Diamond Data, BenQ, gold, SONY"}, {"Daxon Technology Inc. / Acer" , 97, 22, 60, "Maxmax, Diamond Data, BenQ, gold, SONY"},
{"Taiyo Yuden Company Limited" , 97, 24, 0, 0, 0, 0, "Maxell, FUJIFILM, SONY"}, {"Taiyo Yuden Company Limited" , 97, 24, 0, "Maxell, FUJIFILM, SONY"},
{"Sony Corporation" , 97, 24, 10, 0, 0, 0, "LeadData, Imation"}, {"Sony Corporation" , 97, 24, 10, "LeadData, Imation"},
{"Computer Support Italcard s.r.l" , 97, 24, 20, 0, 0, 0, ""}, {"Computer Support Italcard s.r.l" , 97, 24, 20, ""},
{"Unitech Japan Inc." , 97, 24, 30, 0, 0, 0, ""}, {"Unitech Japan Inc." , 97, 24, 30, ""},
{"MPO, France" , 97, 25, 0, 0, 0, 0, "TDK"}, {"MPO, France" , 97, 25, 0, "TDK"},
{"Hitachi Maxell Ltd." , 97, 25, 20, 0, 0, 0, ""}, {"Hitachi Maxell Ltd." , 97, 25, 20, ""},
{"Infodisc Technology Co,Ltd." , 97, 25, 30, 0, 0, 0, "MEMOREX, SPEEDA, Lead data"}, {"Infodisc Technology Co,Ltd." , 97, 25, 30, "MEMOREX, SPEEDA, Lead data"},
{"Xcitec" , 97, 25, 60, 0, 0, 0, ""}, {"Xcitec" , 97, 25, 60, ""},
{"Fornet International Pte Ltd" , 97, 26, 0, 0, 0, 0, "COMPUSA, Cdhouse"}, {"Fornet International Pte Ltd" , 97, 26, 0, "COMPUSA, Cdhouse"},
{"Postech Corporation" , 97, 26, 10, 0, 0, 0, "Mr.Platinum"}, {"Postech Corporation" , 97, 26, 10, "Mr.Platinum"},
{"SKC Co Ltd." , 97, 26, 20, 0, 0, 0, "Infinite"}, {"SKC Co Ltd." , 97, 26, 20, "Infinite"},
{"Fuji Photo Film Co,Ltd." , 97, 26, 40, 0, 0, 0, ""}, {"Fuji Photo Film Co,Ltd." , 97, 26, 40, ""},
{"Lead Data Inc." , 97, 26, 50, 0, 0, 0, "SONY, Gigastorage, MIRAGE"}, {"Lead Data Inc." , 97, 26, 50, "SONY, Gigastorage, MIRAGE"},
{"CMC Magnetics Corporation" , 97, 26, 60, 0, 0, 0, "Daxon, Verbatim, Memorex, Bi-Winner, PLEXTOR, YAMAHA, Melody, Office DEPOT, Philips, eMARK, imation, HyperMedia, Samsung, Shintaro, Techworks"}, {"CMC Magnetics Corporation" , 97, 26, 60, "Daxon, Verbatim, Memorex, Bi-Winner, PLEXTOR, YAMAHA, Melody, Office DEPOT, Philips, eMARK, imation, HyperMedia, Samsung, Shintaro, Techworks"},
{"Ricoh Company Limited" , 97, 27, 0, 0, 0, 0, "Sony, Digital Storage, Csita"}, {"Ricoh Company Limited" , 97, 27, 0, "Sony, Digital Storage, Csita"},
{"Plasmon Data Systems Ltd" , 97, 27, 10, 0, 0, 0, "Ritek, TDK, EMTEC, ALPHAPET, MANIA"}, {"Plasmon Data Systems Ltd" , 97, 27, 10, "Ritek, TDK, EMTEC, ALPHAPET, MANIA"},
{"Princo Corporation" , 97, 27, 20, 0, 0, 0, ""}, {"Princo Corporation" , 97, 27, 20, ""},
{"Pioneer" , 97, 27, 30, 0, 0, 0, ""}, {"Pioneer" , 97, 27, 30, ""},
{"Eastman Kodak Company" , 97, 27, 40, 0, 0, 0, ""}, {"Eastman Kodak Company" , 97, 27, 40, ""},
{"Mitsui Chemicals Inc." , 97, 27, 50, 0, 0, 0, "MAM-A, TDK"}, {"Mitsui Chemicals Inc." , 97, 27, 50, "MAM-A, TDK"},
{"Ricoh Company Limited" , 97, 27, 60, 0, 0, 0, "Ritek"}, {"Ricoh Company Limited" , 97, 27, 60, "Ritek"},
{"Gigastorage Corporation" , 97, 28, 10, 0, 0, 0, "MaxMax, Nan-Ya"}, {"Gigastorage Corporation" , 97, 28, 10, "MaxMax, Nan-Ya"},
{"Multi Media Masters&Machinary SA" , 97, 28, 20, 0, 0, 0, "King, Mmirex"}, {"Multi Media Masters&Machinary SA" , 97, 28, 20, "King, Mmirex"},
{"Ritek Corp" , 97, 31, 0, 0, 0, 0, "TDK"}, {"Ritek Corp" , 97, 31, 0, "TDK"},
{"Grand Advance Technology Sdn. Bhd." , 97, 31, 30, 0, 0, 0, ""}, {"Grand Advance Technology Sdn. Bhd." , 97, 31, 30, ""},
{"TDK Corporation" , 97, 32, 00, 0, 0, 0, ""}, {"TDK Corporation" , 97, 32, 00, ""},
{"Prodisc Technology Inc." , 97, 32, 10, 0, 0, 0, "Smartbuy, Mitsubishi, Digmaster, LG, Media Market"}, {"Prodisc Technology Inc." , 97, 32, 10, "Smartbuy, Mitsubishi, Digmaster, LG, Media Market"},
{"Mitsubishi Chemical Corporation" , 97, 34, 20, 0, 0, 0, "YAMAHA, Verbatim"}, {"Mitsubishi Chemical Corporation" , 97, 34, 20, "YAMAHA, Verbatim"},
{"Mitsui Chemicals Inc." , 97, 48, 50, 0, 0, 0, ""}, {"Mitsui Chemicals Inc." , 97, 48, 50, ""},
{"TDK Corporation" , 97, 49, 0, 0, 0, 0, ""}, {"TDK Corporation" , 97, 49, 0, ""},
{"", 0, 0, 0, 0, 0, 0, ""} {"", 0, 0, 0, ""}
}; };
int i, f_li_0; int i, f_li_0;
@ -173,7 +170,6 @@ char *burn_guess_cd_manufacturer(int m_li, int s_li, int f_li,
/* ts A90904 */ /* ts A90904 */
struct dvd_mid_record { struct dvd_mid_record {
char *mc1; char *mc1;
char *mc2;
int mc1_sig_len; int mc1_sig_len;
char *manufacturer; char *manufacturer;
}; };
@ -192,49 +188,49 @@ char *burn_guess_manufacturer(int prf,
Especially: ' ' -> '_' , {"_%/" unprintables -> %XY) Especially: ' ' -> '_' , {"_%/" unprintables -> %XY)
*/ */
static dvd_mid_record_t mid_list[]= { static dvd_mid_record_t mid_list[]= {
{"AML", "", 8, "UML"}, {"AML", 8, "UML"},
{"BeAll", "", 5, "BeAll Developers, Inc."}, {"BeAll", 5, "BeAll Developers, Inc."},
{"CMC", "", 3, "CMC Magnetics Corporation"}, {"CMC", 3, "CMC Magnetics Corporation"},
{"DAXON", "", 5, "Daxon Technology Inc. / Acer"}, {"DAXON", 5, "Daxon Technology Inc. / Acer"},
{"Daxon", "", 5, "Daxon Technology Inc. / Acer"}, {"Daxon", 5, "Daxon Technology Inc. / Acer"},
{"FUJI", "", 4, "Fujifilm Holdings Corporation"}, {"FUJI", 4, "Fujifilm Holdings Corporation"},
{"INFODISC", "", 8, "New Star Digital Co., Ltd."}, {"INFODISC", 8, "New Star Digital Co., Ltd."},
{"INFOME", "", 6, "InfoMedia Inc."}, {"INFOME", 6, "InfoMedia Inc."},
{"ISMMBD", "", 6, "Info Source Multi Media Ltd."}, {"ISMMBD", 6, "Info Source Multi Media Ltd."},
{"JVC", "", 3, "JVC Limited"}, {"JVC", 3, "JVC Limited"},
{"KIC01RG", "", 7, "AMC"}, {"KIC01RG", 7, "AMC"},
{"LD", "", 8, "Lead Data Inc."}, {"LD", 8, "Lead Data Inc."},
{"LGE", "", 3, "LG Electronics"}, {"LGE", 3, "LG Electronics"},
{"MAM", "", 8, "Mitsui Advanced Media, Inc. Europe"}, {"MAM", 8, "Mitsui Advanced Media, Inc. Europe"},
{"MAXELL", "", 6, "Hitachi Maxell Ltd."}, {"MAXELL", 6, "Hitachi Maxell Ltd."},
{"MBI", "", 3, "Moser Baer India Limited"}, {"MBI", 3, "Moser Baer India Limited"},
{"MCC", "", 8, "Mitsubishi Chemical Corporation"}, {"MCC", 8, "Mitsubishi Chemical Corporation"},
{"MCI", "", 8, "Mitsui Chemicals Inc."}, {"MCI", 8, "Mitsui Chemicals Inc."},
{"MEI", "", 3, "Panasonic Corporation"}, {"MEI", 3, "Panasonic Corporation"},
{"MKM", "", 3, "Mitsubishi Kagaku Media Co."}, {"MKM", 3, "Mitsubishi Kagaku Media Co."},
{"MMC", "", 8, "Mitsubishi Kagaku Media Co."}, {"MMC", 8, "Mitsubishi Kagaku Media Co."},
{"MXL", "", 8, "Hitachi Maxell Ltd."}, {"MXL", 8, "Hitachi Maxell Ltd."},
{"NANYA", "", 5, "Nan-Ya Plastics Corporation"}, {"NANYA", 5, "Nan-Ya Plastics Corporation"},
{"NSD", "", 8, "NESA International Inc."}, {"NSD", 8, "NESA International Inc."},
{"OPTODISC", "", 8, "Optodisc Technology Corporation"}, {"OPTODISC", 8, "Optodisc Technology Corporation"},
{"OTCBDR", "", 8, "Optodisc Technology Corporation"}, {"OTCBDR", 8, "Optodisc Technology Corporation"},
{"PHILIP", "", 8, "Moser Baer India Limited"}, {"PHILIP", 8, "Moser Baer India Limited"},
{"PHILIPS", "", 8, "Philips"}, {"PHILIPS", 8, "Philips"},
{"PRINCO", "", 6, "Princo Corporation"}, {"PRINCO", 6, "Princo Corporation"},
{"PRODISC", "", 7, "Prodisc Technology Inc."}, {"PRODISC", 7, "Prodisc Technology Inc."},
{"Prodisc", "", 7, "Prodisc Technology Inc."}, {"Prodisc", 7, "Prodisc Technology Inc."},
{"PVC", "", 3, "Pioneer"}, {"PVC", 3, "Pioneer"},
{"RICOHJPN", "", 8, "Ricoh Company Limited"}, {"RICOHJPN", 8, "Ricoh Company Limited"},
{"RITEK", "", 5, "Ritek Corp"}, {"RITEK", 5, "Ritek Corp"},
{"SONY", "", 4, "Sony Corporation"}, {"SONY", 4, "Sony Corporation"},
{"TDK", "", 3, "TDK Corporation"}, {"TDK", 3, "TDK Corporation"},
{"TT", "", 8, "TDK Corporation"}, {"TT", 8, "TDK Corporation"},
{"TY", "", 8, "Taiyo Yuden Company Limited"}, {"TY", 8, "Taiyo Yuden Company Limited"},
{"TYG", "", 3, "Taiyo Yuden Company Limited"}, {"TYG", 3, "Taiyo Yuden Company Limited"},
{"UTJR001", "", 7, "Unifino Inc."}, {"UTJR001", 7, "Unifino Inc."},
{"VERBAT", "", 5, "Mitsubishi Kagaku Media Co."}, {"VERBAT", 5, "Mitsubishi Kagaku Media Co."},
{"YUDEN", "", 5, "Taiyo Yuden Company Limited"}, {"YUDEN", 5, "Taiyo Yuden Company Limited"},
{"", "", 0, ""} {"", 0, ""}
}; };
if (media_code2 != NULL && if (media_code2 != NULL &&

View File

@ -244,7 +244,6 @@ int burn_write_close_track(struct burn_write_opts *o, struct burn_session *s,
{ {
char msg[81]; char msg[81];
struct burn_drive *d; struct burn_drive *d;
struct burn_track *t;
/* ts A61106 */ /* ts A61106 */
#ifdef Libburn_experimental_no_close_tracK #ifdef Libburn_experimental_no_close_tracK
@ -252,7 +251,6 @@ int burn_write_close_track(struct burn_write_opts *o, struct burn_session *s,
#endif #endif
d = o->drive; d = o->drive;
t = s->track[tnum];
d->busy = BURN_DRIVE_CLOSING_TRACK; d->busy = BURN_DRIVE_CLOSING_TRACK;
@ -414,7 +412,6 @@ struct cue_sheet *burn_create_toc_entries(struct burn_write_opts *o,
goto failed; goto failed;
runtime += 150; runtime += 150;
burn_print(1, "toc for %d tracks:\n", ntr);
d->toc_entries = ntr + 3; d->toc_entries = ntr + 3;
/* ts A61009 */ /* ts A61009 */
@ -515,8 +512,6 @@ struct cue_sheet *burn_create_toc_entries(struct burn_write_opts *o,
e[3 + i].pframe = f; e[3 + i].pframe = f;
e[3 + i].adr = 1; e[3 + i].adr = 1;
e[3 + i].control = type_to_ctrl(tar[i]->mode); e[3 + i].control = type_to_ctrl(tar[i]->mode);
burn_print(1, "track %d control %d\n", tar[i]->mode,
e[3 + i].control);
ret = add_cue(sheet, ctladr | 1, i + 1, 1, form, 0, runtime); ret = add_cue(sheet, ctladr | 1, i + 1, 1, form, 0, runtime);
if (ret <= 0) if (ret <= 0)
@ -568,11 +563,6 @@ XXX this is untested :)
e[2].pmin = m; e[2].pmin = m;
e[2].psec = s; e[2].psec = s;
e[2].pframe = f; e[2].pframe = f;
burn_print(1, "run time is %d (%d:%d:%d)\n", runtime, m, s, f);
for (i = 0; i < d->toc_entries; i++)
burn_print(1, "point %d (%02d:%02d:%02d)\n",
d->toc_entry[i].point, d->toc_entry[i].pmin,
d->toc_entry[i].psec, d->toc_entry[i].pframe);
ret = add_cue(sheet, ctladr | 1, 0xAA, 1, 1, 0, runtime); ret = add_cue(sheet, ctladr | 1, 0xAA, 1, 1, 0, runtime);
if (ret <= 0) if (ret <= 0)
goto failed; goto failed;
@ -614,8 +604,6 @@ int burn_write_leadin(struct burn_write_opts *o,
d->busy = BURN_DRIVE_WRITING_LEADIN; d->busy = BURN_DRIVE_WRITING_LEADIN;
burn_print(5, first ? " first leadin\n" : " leadin\n");
if (first) if (first)
count = 0 - d->alba - 150; count = 0 - d->alba - 150;
else else
@ -644,7 +632,6 @@ int burn_write_leadout(struct burn_write_opts *o,
d->busy = BURN_DRIVE_WRITING_LEADOUT; d->busy = BURN_DRIVE_WRITING_LEADOUT;
d->rlba = -150; d->rlba = -150;
burn_print(5, first ? " first leadout\n" : " leadout\n");
if (first) if (first)
count = 6750; count = 6750;
else else
@ -666,19 +653,10 @@ int burn_write_leadout(struct burn_write_opts *o,
int burn_write_session(struct burn_write_opts *o, struct burn_session *s) int burn_write_session(struct burn_write_opts *o, struct burn_session *s)
{ {
struct burn_drive *d = o->drive; struct burn_drive *d = o->drive;
struct burn_track *prev = NULL, *next = NULL;
int i, ret; int i, ret;
d->rlba = 0; d->rlba = 0;
burn_print(1, " writing a session\n");
for (i = 0; i < s->tracks; i++) { for (i = 0; i < s->tracks; i++) {
if (i > 0)
prev = s->track[i - 1];
if (i + 1 < s->tracks)
next = s->track[i + 1];
else
next = NULL;
if (!burn_write_track(o, s, i)) if (!burn_write_track(o, s, i))
{ ret = 0; goto ex; } { ret = 0; goto ex; }
} }
@ -808,8 +786,6 @@ int burn_write_track(struct burn_write_opts *o, struct burn_session *s,
burn_disc_init_track_status(o, s, tnum, sectors); burn_disc_init_track_status(o, s, tnum, sectors);
burn_print(12, "track %d is %d sectors long\n", tnum, sectors);
/* ts A61030 : this cannot happen. tnum is always < s->tracks */ /* ts A61030 : this cannot happen. tnum is always < s->tracks */
if (tnum == s->tracks) if (tnum == s->tracks)
tmp = sectors > 150 ? 150 : sectors; tmp = sectors > 150 ? 150 : sectors;
@ -840,8 +816,6 @@ int burn_write_track(struct burn_write_opts *o, struct burn_session *s,
fprintf(stderr,"LIBBURN_DEBUG: TNUM=%d TRACKS=%d TMP=%d\n", fprintf(stderr,"LIBBURN_DEBUG: TNUM=%d TRACKS=%d TMP=%d\n",
tnum, s->tracks, tmp); tnum, s->tracks, tmp);
burn_print(1, "last track, leadout prep\n");
/* ts A61023 */ /* ts A61023 */
if ((i%64)==0) if ((i%64)==0)
d->read_buffer_capacity(d); d->read_buffer_capacity(d);
@ -1158,7 +1132,7 @@ int burn_disc_open_track_dvd_plus_r(struct burn_write_opts *o,
struct burn_session *s, int tnum) struct burn_session *s, int tnum)
{ {
struct burn_drive *d = o->drive; struct burn_drive *d = o->drive;
char *msg; char *msg = NULL;
int ret, lba, nwa; int ret, lba, nwa;
off_t size; off_t size;
@ -2010,7 +1984,7 @@ ex:;
/* >>> eventual emergency finalization measures */ /* >>> eventual emergency finalization measures */
/* update media state records */ /* update media state records */
burn_drive_mark_unready(d); burn_drive_mark_unready(d, 0);
burn_drive_inquire_media(d); burn_drive_inquire_media(d);
if (d->current_profile == 0x41 && d->complete_sessions >= 300) { if (d->current_profile == 0x41 && d->complete_sessions >= 300) {
@ -2115,6 +2089,9 @@ 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 burn_stdio_write(int fd, char *buf, int count, struct burn_drive *d,
int flag) int flag)
{ {
int ret;
char *msg = NULL;
if (d->cancel) if (d->cancel)
return 0; return 0;
/* /*
@ -2122,15 +2099,23 @@ fprintf(stderr, "libburn_DEBUG: write(%d, %lX, %d)\n",
fd, (unsigned long) buf, count); fd, (unsigned long) buf, count);
*/ */
if (write(fd, buf, count) != count) { ret = write(fd, buf, count);
if (ret != count) {
BURN_ALLOC_MEM(msg, char, 160);
sprintf(msg,
"Cannot write desired amount of data. write(2) returned %d.",
ret);
libdax_msgs_submit(libdax_messenger, d->global_index, libdax_msgs_submit(libdax_messenger, d->global_index,
0x00020148, 0x00020148,
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH, LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
"Cannot write desired amount of data", errno, 0); msg, errno, 0);
d->cancel = 1; d->cancel = 1;
return 0; return 0;
} }
return count; ex:;
BURN_FREE_MEM(msg);
return ret;
} }
@ -2194,6 +2179,9 @@ int burn_stdio_mmc_dummy_write(struct burn_drive *d, int start,
*/ */
int burn_stdio_sync_cache(int fd, struct burn_drive *d, int flag) int burn_stdio_sync_cache(int fd, struct burn_drive *d, int flag)
{ {
int ret;
char *msg = NULL;
if (fd < 0) { if (fd < 0) {
libdax_msgs_submit(libdax_messenger, d->global_index, libdax_msgs_submit(libdax_messenger, d->global_index,
0x0002017d, 0x0002017d,
@ -2208,17 +2196,24 @@ int burn_stdio_sync_cache(int fd, struct burn_drive *d, int flag)
libdax_msgs_submit(libdax_messenger, -1, 0x00000002, libdax_msgs_submit(libdax_messenger, -1, 0x00000002,
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_ZERO, LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_ZERO,
"syncing cache (stdio fsync)", 0, 0); "syncing cache (stdio fsync)", 0, 0);
if (fsync(fd) != 0) { ret = fsync(fd);
if (errno == EINVAL) /* E.g. /dev/null cannot fsync */ if (ret != 0 && errno == EIO) {
return 1; BURN_ALLOC_MEM(msg, char, 160);
sprintf(msg,
"Cannot write desired amount of data. fsync(2) returned %d.",
ret);
libdax_msgs_submit(libdax_messenger, d->global_index, libdax_msgs_submit(libdax_messenger, d->global_index,
0x00020148, 0x00020148,
LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH, LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
"Cannot write desired amount of data", errno, 0); msg, errno, 0);
d->cancel = 1; d->cancel = 1;
return 0; return 0;
} }
return 1; ret = 1;
ex:;
BURN_FREE_MEM(msg);
return ret;
} }
@ -2263,7 +2258,7 @@ int burn_stdio_slowdown(struct burn_drive *d, struct timeval *prev_time,
int burn_stdio_write_track(struct burn_write_opts *o, struct burn_session *s, int burn_stdio_write_track(struct burn_write_opts *o, struct burn_session *s,
int tnum, int flag) int tnum, int flag)
{ {
int open_ended, bufsize = 16 * 2048, ret, sectors, fd; int open_ended, bufsize = 16 * 2048, ret, sectors;
struct burn_track *t = s->track[tnum]; struct burn_track *t = s->track[tnum];
struct burn_drive *d = o->drive; struct burn_drive *d = o->drive;
char *buf = NULL; char *buf = NULL;
@ -2272,7 +2267,6 @@ int burn_stdio_write_track(struct burn_write_opts *o, struct burn_session *s,
struct timeval prev_time; struct timeval prev_time;
BURN_ALLOC_MEM(buf, char, bufsize); BURN_ALLOC_MEM(buf, char, bufsize);
fd = d->stdio_fd;
sectors = burn_track_get_sectors(t); sectors = burn_track_get_sectors(t);
burn_disc_init_track_status(o, s, tnum, sectors); burn_disc_init_track_status(o, s, tnum, sectors);
@ -2349,6 +2343,9 @@ int burn_stdio_write_sync(struct burn_write_opts *o,
d->progress.tracks = 1; d->progress.tracks = 1;
/* >>> adjust sector size (2048) to eventual audio or even raw */ /* >>> adjust sector size (2048) to eventual audio or even raw */
/* >>> ??? ts B11004 : Why this eagerness to close and open ? */
/* open target file */ /* open target file */
if (d->stdio_fd >= 0) if (d->stdio_fd >= 0)
close(d->stdio_fd); close(d->stdio_fd);
@ -2369,12 +2366,15 @@ int burn_stdio_write_sync(struct burn_write_opts *o,
d->progress.sectors = 0; d->progress.sectors = 0;
ret = 1; ret = 1;
ex:; ex:;
/* >>> ??? ts B11004 : Why this eagerness to close ? */
if (d->stdio_fd >= 0) if (d->stdio_fd >= 0)
close(d->stdio_fd); close(d->stdio_fd);
d->stdio_fd = -1; d->stdio_fd = -1;
/* update media state records */ /* update media state records */
burn_drive_mark_unready(d); burn_drive_mark_unready(d, 8);
/* <<< d->busy = BURN_DRIVE_IDLE; */ /* <<< d->busy = BURN_DRIVE_IDLE; */
return ret; return ret;
@ -2488,8 +2488,6 @@ calloc() seems not to have the desired effect. valgrind warns:
} }
} }
burn_print(1, "sync write of %d CD sessions\n", disc->sessions);
/* Apparently some drives require this command to be sent, and a few drives /* Apparently some drives require this command to be sent, and a few drives
return crap. so we send the command, then ignore the result. return crap. so we send the command, then ignore the result.
*/ */
@ -2619,12 +2617,9 @@ return crap. so we send the command, then ignore the result.
sleep(1); sleep(1);
/* ts A61125 : update media state records */ /* ts A61125 : update media state records */
burn_drive_mark_unready(d); burn_drive_mark_unready(d, 0);
burn_drive_inquire_media(d); burn_drive_inquire_media(d);
burn_print(1, "done\n");
/* <<< d->busy = BURN_DRIVE_IDLE; */
/* ts A61012 : This return was traditionally missing. I suspect this /* ts A61012 : This return was traditionally missing. I suspect this
to have caused Cdrskin_eject() failures */ to have caused Cdrskin_eject() failures */
goto ex; goto ex;
@ -2633,7 +2628,6 @@ fail:
d->sync_cache(d); d->sync_cache(d);
fail_wo_sync:; fail_wo_sync:;
usleep(500001); /* ts A61222: to avoid a warning from remove_worker()*/ usleep(500001); /* ts A61222: to avoid a warning from remove_worker()*/
burn_print(1, "done - failed\n");
libdax_msgs_submit(libdax_messenger, d->global_index, 0x0002010b, libdax_msgs_submit(libdax_messenger, d->global_index, 0x0002010b,
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH, LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
"Burn run failed", 0, 0); "Burn run failed", 0, 0);

41
releng/releng_build_os Executable file
View File

@ -0,0 +1,41 @@
#!/bin/sh
set -e
cd ..
if [ ! -x configure ]; then
printf "\n*** please run ./bootstrap first.\n"
exit 1
fi
build()
{
for F in ${1}
do
make clean
clear
printf "\n *** building with: %s\n" CPPFLAGS=-D${F}
sleep 1
# libcdio is not autodetected by default; should be available everywhere
CPPFLAGS=-D${F} ./configure --enable-libcdio; make 2> releng/libburn.${F}.log
make clean
done
}
OS=`uname -o`
case ${OS} in
GNU/Linux)
printf "OS: %s\n" ${OS}
sleep 1
build "__linux Libburn_use_sg_dummY Libburn_use_libcdiO"
;;
*)
printf "Unknown OS: %s\n" ${OS}
exit 1
;;
esac
# just in case
unset CPPFLAGS

View File

@ -20,8 +20,6 @@ static void catch_int ()
static void poll_drive(int d) static void poll_drive(int d)
{ {
enum burn_disc_status s;
fprintf(stderr, "polling disc in %s - %s:\n", fprintf(stderr, "polling disc in %s - %s:\n",
drives[d].vendor, drives[d].product); drives[d].vendor, drives[d].product);
@ -33,8 +31,7 @@ static void poll_drive(int d)
while (burn_drive_get_status(drives[d].drive, NULL)) while (burn_drive_get_status(drives[d].drive, NULL))
usleep(1000); usleep(1000);
while ((s = burn_disc_get_status(drives[d].drive)) while (burn_disc_get_status(drives[d].drive) == BURN_DISC_UNREADY)
== BURN_DISC_UNREADY)
usleep(1000); usleep(1000);
while (NEXT == 0) { while (NEXT == 0) {

View File

@ -12,6 +12,9 @@ int main(int argc, char **argv)
struct burn_session *session; struct burn_session *session;
struct burn_source *src; struct burn_source *src;
burn_initialize();
burn_msgs_set_severities("NEVER", "ALL", "structest: ");
disc = burn_disc_create(); disc = burn_disc_create();
session = burn_session_create(); session = burn_session_create();
burn_disc_add_session(disc, session, BURN_POS_END); burn_disc_add_session(disc, session, BURN_POS_END);