libburn-1.4.2/0000755000175700017510000000000012652650103010164 500000000000000libburn-1.4.2/README0000644000175700017510000011261412652645544011006 00000000000000------------------------------------------------------------------------------ libburnia-project.org ------------------------------------------------------------------------------ This all is under GPL. (See GPL reference, our clarification and commitment at the end of this text) ------------------------------------------------------------------------------ libburnia-project.org By Mario Danic and Thomas Schmitt Copyright (C) 2006-2016 Mario Danic, Thomas Schmitt Still containing parts of Libburn. By Derek Foreman and Ben Jansens Copyright (C) 2002-2006 Derek Foreman and Ben Jansens http://files.libburnia-project.org/releases/libburn-1.4.2.pl01.tar.gz ------------------------------------------------------------------------------ Build and Installation From tarball Obtain libburn-1.4.2.pl01.tar.gz, take it to a directory of your choice and do: tar xzf libburn-1.4.2.pl01.tar.gz cd libburn-1.4.2 ./configure --prefix=/usr make To make libburn accessible for running and application development, and to install the cdrecord compatibility binary cdrskin, do (as Superuser): make install This procedure installs libburn.so.4 and cdrskin depending on it. For a standalone cdrskin binary, see cdrskin/README. A behavioral conflict is known between any burn software and demons like hald which probe CD drives. This can spoil burn runs for CD-R or CD-RW. You may have to keep your hald away from the drive. See for example http://www.freebsd.org/gnome/docs/halfaq.html From SVN Our build system is based on autotools. For preparing the build of a SVN snapshot you will need autotools of at least version 1.7. Do in a directory of your choice: svn co http://svn.libburnia-project.org/libburn/trunk libburn-svn cd libburn-svn ./bootstrap ./configure --prefix=/usr make make install Warning: The trunk might contain experimental features which might not persist until next release. Special ./configure options make install on GNU/Linux will try to run program ldconfig with the library installation directory as only argument. Failure to do so will not abort installation. One may disable ldconfig by ./configure option: --disable-ldconfig-at-install In some situations Linux may deliver a better write performance to drives if the track input is read with O_DIRECT (see man 2 open). The API call burn_os_open_track_src() and the input readers of cdrskin and libburn fifo can be told to use this peculiar read mode by: --enable-track-src-odirect But often libburn call burn_write_opts_set_dvd_obs(opts, 64*1024) will yield even better performance in such a situation. 64k can be made default at configure time by: --enable-dvd-obs-64k This may be combined with above --enable-track-src-odirect . If it is desired that DVD DAO writing and stdio: writing get padded up to a full write chunk of 32k or 64k, then use ./configure option: --enable-dvd-obs-pad Alternatively the transport of SCSI commands can be done via libcdio-0.83. You may install it and re-run libburn's ./configure with option --enable-libcdio By use of a version script, the libburn.so library exposes no other function names but those of the API definition in libburn/libburn.h. If -Wl,--version-script=... makes problems with the local compiler, then disable this encapsulation feature by --disable-versioned-libs Make sure to re-compile all source files after running ./configure make clean ; make make install Linux only: libburn tries to avoid a collision with udev's drive examination by waiting 0.1 seconds before opening the device file for a longer time, after udev might have been alarmed by drive scanning activities. The waiting time can be set at ./configure time with microsecond granularity. E.g. 2 seconds: CFLAGS="$CFLAGS -DLibburn_udev_wait_useC=2000000" ./configure ...options... Waiting can be disabled by zero waiting time: CFLAGS="$CFLAGS -DLibburn_udev_wait_useC=0" Alternatively, libburn can try to be nice by opening the device file, closing it immediately, waiting, and only then opening it for real: CFLAGS="$CFLAGS -DLibburn_udev_extra_open_cyclE -DLibburn_udev_wait_useC=500000" ------------------------------------------------------------------------------ An important part of the project, libisofs, is hosted in a bzr repository at launchpad.net : bzr branch lp:libisofs Another part the project, libisoburn, is hosted in the libburnia SVN, too: svn co http://svn.libburnia-project.org/libisoburn/trunk libisoburn See README files there. ------------------------------------------------------------------------------ Overview of libburnia-project.org libburnia-project.org is an open-source software project for reading, mastering and writing optical discs. For now this means CD media, all DVD media, all BD media. The project comprises of several more or less interdependent parts which together strive to be a usable foundation for application development. These are libraries, language bindings, and middleware binaries which emulate classical (and valuable) Linux tools. Currently it is supported on GNU/Linux with kernels >= 2.4, on FreeBSD with ATAPI/CAM enabled in the kernel (see man atapicam), on OpenSolaris (tested with kernel 5.11), on NetBSD (tested with 6.1.3). On other X/Open compliant systems there will only be pseudo drives, but no direct MMC operation on real CD/DVD/BD drives. For full ports to other systems we would need : login on a development machine or a live OS on CD or DVD, advise from a system person about the equivalent of Linux sg or FreeBSD CAM, volunteers for testing of realistic use cases. We have a well tested code base for burning data and audio CDs, DVDs and BDs. The burn API is quite comprehensively documented and can be used to build a presentable application. We have a functional application which emulates the core use cases of cdrecord in order to prove that usability, and in order to allow you to explore libburn's scope by help of existing cdrecord frontends. ISO 9660 filesystems with Rock Ridge and Joliet extensions can be created and manipulated quite freely. This capability together with our burn capability makes possible a single binary application which covers all steps of image composition, updating and writing. Quite unique in the Linux world. The project components (list subject to growth, hopefully): - libburn is the library by which preformatted data get onto optical media. It uses either /dev/sgN (e.g. on kernel 2.4 with ide-scsi) or /dev/srM or /dev/hdX (e.g. on kernel 2.6). libburn is the foundation of our cdrecord emulation. Its code is independent of cdrecord. Its DVD capabilities are learned from studying the code of dvd+rw-tools and MMC-5 specs. No code but only the pure SCSI knowledge has been taken from dvd+rw-tools, though. - libisofs is the library to pack up hard disk files and directories into a ISO 9660 disk image. This may then be brought to CD via libburn. An own ISO 9660 extension stores ACLs, xattr, and MD5 of file content. - libisoburn is an add-on to libburn and libisofs which coordinates both and also can grow ISO-9660 filesystem images on multi-session media as well as on overwriteable media via the same API. All media peculiarities are handled automatically. It also contains the methods of command oriented application xorriso and offers them via a C language API. - cdrskin is a limited cdrecord compatibility wrapper for libburn. cdrecord is a powerful GPL'ed burn program included in Joerg Schilling's cdrtools. cdrskin strives to be a second source for the services traditionally provided by cdrecord. Additionally it provides libburn's DVD capabilities, where only -sao is compatible with cdrecord. cdrskin does not contain any bytes copied from cdrecord's sources. Many bytes have been copied from the message output of cdrecord runs, though. See cdrskin/README for more. - xorriso is an application of all three libraries which creates, loads, manipulates and writes ISO 9660 filesystem images with Rock Ridge extensions. Manipulation is not only adding or overwriting of files but also deleting, renaming, attribute changing, incremental backups, activating boot images, and extracting of files from ISO images to disk. There is also a sparse emulation of cdrecord and a more laborate one of mkisofs. All features of xorriso are also available via a C language API of libisoburn. A static compilation of xorriso and the libraries is dedicated to the GNU Operating System. See xorriso/README_gnu_xorriso . - "test" is a collection of application gestures and examples given by the authors of the library features. The burn API example of libburn is named test/libburner.c . The API for media information inquiry is demonstrated in test/telltoc.c . Explore these examples if you look for inspiration. We strive to be a responsive upstream. Our libraries are committed to maintain older feature sets in newer versions. This applies to source code headers (API) as well as to linkable objects (ABI). The only exception from this rule is about non-release versions x.y.*[13579] which are allowed to introduce new features, change those new features in any way and even may revoke such new features before the next release of x.y.*[02468]. As soon as it is released, a feature is promised to persist. SONAMES: libburn.so.4 (since 0.3.4, March 2007), libisofs.so.6 (since 0.6.2, February 2008), libisoburn.so.1 (since 0.1.0, February 2008). Applications must use 64 bit off_t. E.g. by defining #define _LARGEFILE_SOURCE #define _FILE_OFFSET_BITS 64 or take special precautions to interface with the libraries by 64 bit integers where the .h files prescribe off_t. To reduce libburn's off_t size to 32 bit will keep it from processing tracks of more than 2 GB size. ------------------------------------------------------------------------------ Project history as far as known to me: - Founded in 2002 as it seems. See mailing list archives http://lists.freedesktop.org/archives/libburn/ The site of this founder team is reachable and offers download of a (somewhat outdated) tarball and from CVS : http://icculus.org/burn/ Copyright holders and most probably founders: Derek Foreman and Ben Jansens. - I came to using libburn in 2005. Founded the cdrskin project and submitted necessary patches which were accepted or implemented better. Except one remaining patch which prevented cdrskin from using vanilla libburn from CVS. The cdrskin project site is reachable and offers download of the heavily patched (elsewise outdated) tarball under the name cdrskin-0.1.2 : http://scdbackup.sourceforge.net/cdrskin_eng.html It has meanwhile moved to use vanilla libburn.pykix.org , though. Version 0.1.4 constitutes the first release of this kind. - In July 2006 our team mate Mario Danic announced a revival of libburn which by about nearly everybody else was perceived as unfriendly fork. Derek Foreman four days later posted a message which expressed his discontent. The situation first caused me to publically regret it and then - after i got the opportunity to move in with cdrskin - gave me true reason to personally apologize to Derek Foreman, Ben Jansens and the contributors at icculus.org/burn. Posted to both projects: http://lists.freedesktop.org/archives/libburn/2006-August/000446.html http://mailman-mail1.webfaction.com/pipermail/libburn-hackers/2006-August/000024.html - Mid August 2006 project cdrskin established a branch office in libburn.pykix.org so that all maintainers of our tools have one single place to get the current (at least slightely) usable coordinated versions of everything. Project cdrskin will live forth independendly for a while but it is committed to stay in sync with libburn.pykix.org (or some successor, if ever). cdrskin is also committed to support icculus.org/burn if the pending fork is made reality by content changes in that project. It will cease to maintain a patched version of icculus.org/burn though. Precondition for a new release of cdrskin on base of icculus.org/burn would be the pending "whitelist patch" therefore. I would rather prefer if both projects find consense and merge, or at least cooperate. I have not given up hope totally, yet. I, personally, will honor any approach. - 2nd September 2006 the decision is made to strive for a consolidation of copyright and a commitment to GPL in a reasonable and open minded way. This is to avoid long term problems with code of unknown origin and with finding consense among the not so clearly defined group of copyright claimers and -holders. libisofs is already claimed sole copyright Mario Danic. cdrskin and libburner are already claimed sole copyright Thomas Schmitt. Rewrites of other components will follow and concluded by claiming full copyright within the group of libburn.pykix.org-copyright holders. - 16th September 2006 feature freeze for release of libburn-0.2.2 . - 20th September 2006 release of libburn-0.2.2 . - 26th October 2006 feature freeze for cdrskin-0.2.4 based on libburn-0.2.3 . This version of cdrskin is much more cdrecord compatible in repect to drive addressing and audio features. - 30th October 2006 release of cdrskin-0.2.4 . - 13th November 2006 splitting releases of libburn+cdrskin from libisofs. - 24th November 2006 release of libburn-0.2.6 and cdrskin-0.2.6 . cdrskin has become suitable for unaware frontends as long as they perform only the core of cdrecord use cases (including open-ended input streams, audio, and multi-session). - 28th November 2006 the umbrella project which encloses both, libisofs and libburn, is now called libburnia. For the origin of this name, see http://en.wikipedia.org/wiki/Liburnians . - 16th January 2007 release of libburn-0.3.0 and cdrskin-0.3.0 . Now the scope is widened to a first class of DVD media: overwriteable single layer types DVD-RAM, DVD+RW, DVD-RW. This is not a cdrecord emulation but rather inspired by dvd+rw-tools' "poor man" writing facility for this class of media. Taking a bow towards Andy Polyakov. - 11th February 2007 version 0.3.2 covers sequential DVD-RW and DVD-R with multi-session and with DAO. - 12th March 2007 version 0.3.4 supports DVD+R and thus covers all single layer DVD media. Code for double layer DVD+/-R is implemented but awaits a tester yet. - 23th April 2007 version 0.3.6 follows the unanimous opinion of Linux kernel people that one should not use /dev/sg on kernel 2.6. - 31st July 2007 version 0.3.8 marks the first anniversary of libburn revival. We look back on improved stability, a substantially extended list of media and write modes, and better protection against typical user mishaps. - 24th October 2007 version 0.4.0 is the foundation of new library libisoburn and an upcomming integrated application for manipulating and writing ISO 9660 + Rock Ridge images. cdrskin-0.4.0 got capabilities like growisofs by these enhancements: growing of overwriteable media and disk files. Taking again a bow towards Andy Polyakov. - 26th Januar 2008 version 0.4.2 rectifies the version numbering so that we reliably release libburn.so.4 as should have been done since libburn-0.3.2. cdrskin now is by default linked dynamically and does a runtime check to ensure not to be started with a libburn which is older than itself. - 3rd Feb 2008 libisofs-0.2.x (.so.5) has been deprecated. - 14th Feb 2008 libisofs-0.6.2 permanently replaces the old libisofs-0.2.x. It is the first release of new libisofs.so.6 which will guarantee future API/ABI compatibility for its whole feature set. - 15th Feb 2008 libisoburn-0.1.0 (.so.1) coordinates libisofs and libburn for the purpose of ISO image reading and writing. It emulates multi-session on overwriteable media. Application xorriso makes use of all three libraries. - 8th Apr 2008 libburn-0.4.4 has proven to be capable of burning to DVD+R/DL and read performance on disk file pseudo-drives has been improved. - 27th Apr 2008 libisofs-0.6.4 can now read data file content from images and can map pieces of disk files onto image files. Image directory iteration has been enhanced. Input data streams and extended information have been exposed in the API to enable future development. - 29th Apr 2008 libisoburn-0.1.4 was made more efficient with reading of image tree nodes. It now depends on libisofs-0.6.4 and libburn-0.4.4. xorriso makes use of new libisofs features by performing incremental updates of directory trees and by cutting oversized data files into pieces. A primitive single session emulation of cdrecord and mkisofs is provided. - 10th May 2008 libburn-0.4.6 supports formatting and writing of BD-RE, full nominal speed for DVD-RAM and BD-RE. cdrskin has a unified blank type with automatic media state recognition. - 17th May 2008 an old bug with DVD-RAM and now with BD-RE is fixed by libburn-0.4.8. So libisoburn can now perform emulation of multisession on those media. - 19th May 2008 libisoburn-0.1.6 brings better table-of-content emulation on overwriteble media and disk files. - 1st Jun 2008 libisofs-0.6.6 fixes some problems around device files. - 3rd Jun 2008 libisoburn-0.1.8 fixes a bug with overwriteable media. - 23rd Jun 2008 libisoburn-0.2.0 introduces extraction of files from ISO images. - 16th Jul 2008 libburn-0.5.0 handles systems with no /dev/sr* but only /dev/scd*. - 19th Jul 2008 libisoburn/xorriso-0.2.2 can do multi-session in mkisofs and cdrecord style. xorriso now can serve underneath growisofs. - 20th Aug 2008 libburn-0.5.2 revokes the necessity that a drive must be enumerable in order to be adressable. Enumeration is enhanced by examining /proc/sys/dev/cdrom/info. - 24th Aug 2008 libisoburn/xorriso-0.2.4 introduces a media readability check with data retrieval option. - 18th Sep 2008 libisofs-0.6.8 supports ISO 9660 Level 3 which can represent very large data files in the image. - 20th Sep 2008 libisoburn/xorriso-0.2.6 takes into respect the new Level 3 capabilities of libisofs. - 6th Oct 2008 libburn-0.5.4 adjusts the changes of 0.5.2 to the needs of Linux kernel 2.4 and introduces human readable SCSI error messages. - 6th Oct 2008 libisofs-0.6.10 fixes two bugs which prevented adding and manipulation of ISOLINUX boot images. - 15th Oct 2008 libisoburn/xorriso-0.2.8 can activate and maintain an ISOLINUX boot image by an EL Torito boot record. - 12th Nov 2008 libburn-0.5.6 fixes usage of freed memory by the fifo thread of an aborted burn run. - 26th Nov 2008 libisofs-0.6.12 can produce a ISOLINUX isohybrid MBR on the fly and can produce ISO images which resemble old mkisofs images. - 2nd Dec 2008 libisoburn-0.3.0. xorriso now is ready for exotic character sets, for legacy FreeBSD systems which expect an outdated Rock Ridge signature, and for producing ISO images with MBR which boot from hard disk or USB stick. Three minor bugs were fixed. - 7th Dec 2008 libburn-0.5.8 prevents a SIGSEGV with wierd CD table-of-content and improves BD-RE formatting. - 9th Dec 2008 Our project received a donation from Thomas Weber. - 2nd Jan 2009 libburn-0.6.0 learned to format BD-R and write to either formatted or unformatted BD-R. - 6th Jan 2009 libisoburn-0.3.2. xorriso can produce and execute commands for mounting older sessions from all kinds of media. Pseudo-drives outside the /dev/ tree can be addressed without prefix "stdio:". - 20th Feb 2009 libburn-0.6.2 source release now compiles out of the box on FreeBSD. - 28 Feb 2009 libisofs-0.6.14 can record ACLs and Extended Attributes xattr in its ISO images. - 01 Mar 2009 libisoburn-0.3.4. xorriso makes use of the ACL and xattr capabilities provided by libisofs for xorriso backup features. - 11 Mar 2009 libisofs-0.6.16 of libisofs fixes two bugs which on Solaris prevented to navigate the ISO images by ".." and to recognize the Rock Ridge extensions of ISO images. The ban to build libisofs on operating systems other than Linux and FreeBSD has been lifted. - 13 Mar 2009 libburn-0.6.4 got a dummy adapter for SCSI/MMC command transport. It will show no drives and thus libburn will only be able to perform operations on "stdio:" pseudo drives. Nevertheless this was precondition to lift the ban to build libburn on operating systems other than Linux and FreeBSD. - 16 Mar 2009 libisoburn-0.3.6: xorriso uses RRIP version 1.10 as default in order to be mountable where mkisofs images are mountable. - 17 Apr 2009 libisofs-0.6.18 introduces content filtering of data files. Built-in filters implement compression to formats gzip and zisofs. External filter processes can perform arbitrary data conversions like encryption. - 19 Apr 2009 libisoburn-0.3.8 makes use of the new libisofs capability to perform content filtering of data files. - 08 May 2009 libburn-0.6.6 fixes a bug with aborting on broken output pipe and a bug with device scan on FreeBSD. - 31 May 2009 libisofs-0.6.20 can record hard link relations in ISO images and offers support with restoring them to disk. Current Linux kernels will mount images with such hard links but will attribute a unique inode number to each file. - 28 Jun 2009 libisoburn-0.4.0: xorriso can record and restore hard link relations of files. Performance of data reading has been improved. Option -find now supports logical operators with its tests. - 14 Jul 2009 libburn-0.6.8 fixes bugs and shortcommings with old MMC-1 drives and with large SCSI bus numbers as handed out by Linux for USB drives. - 20 Jul 2009 libisoburn-0.4.0.pl01 fixes a regression in xorriso which caused data loss in older sessions if xorriso was used underneath growisofs. Affected are releases since libisoburn-0.3.2 in january 2009. - 25 Aug 2009 libisofs-0.6.22 can record MD5 checksums for the whole session and for each single data file. Checksum tags can be used to verify superblock and directory tree before importing them. - 27 Aug 2009 libburn-0.7.0 learned to calm down a drive and to inquire its supported profiles. It works around some pitfalls with U3 enhanced memory sticks which emulate a CD-ROM. - 27 Aug 2009 libisoburn-0.4.0.pl00 can record MD5 checksums by which one may verify the session or single data files in the image. When comparing image files with files in the local filesystem, the MD5 sums avoid the need for reading file content from the image. - 22 Sep 2009 libisoburn-0.4.0.pl01 fixes a bug in xorriso option -cut_out. - 08 Oct 2009 libisofs-0.6.24 fixes a bug which could cause the loss of blanks in file names when a new session got added to an ISO image. With names shorter than 251 characters this happened only to trailing blanks. - 08 Oct 2009 libisoburn-0.4.0.pl02 fixes bugs with xorriso option -for_backup, with xorrisofs -help, and with xorrecord -help. - 12 Oct 2009 libburn-0.7.2 fixes a bug with CD TAO multi-track dummy sessions. It can retrieve media product info and can process track input which was prepared for CD-ROM XA Mode 2 Form 1. cdrskin now performs option -minfo. - 28 Oct 2009 libisoburn-0.4.4 fixes a bug with cdrecord emulation and introduces new information options about media type and ISO image id strings. On Linux it helps with mounting two sessions of the same media simultaneously. - 12 Nov 2009 libburn-0.7.2.pl01 works around problems with Pioneer DVR-216D. DVD-R runs made the drive stuck. Ejecting the tray did not work properly. - 06 Dec 2009 libburn-0.7.4 works around problems with newer DVD burners, provides throughput enhancements with hampered busses on Linux, and new API calls to log SCSI commands and to control the libburn fifo. - 09 Dec 2009 libisoburn-0.4.6 now offers performance tuning of output to DVD drives or disk files. - 26 Dec 2009 libburn-0.7.4.pl01 fixes the release tarball which was lacking the files of the generic system adapter for X/Open. - 29 Dec 2009 Our project received a donation for purchasing a fine small computer which shall serve as OS farm for development and support. - 20 Jan 2010 Version 0.6.26 of libisofs fixes minor bugs and shall enhance portability. - 22 Jan 2010 libburn-0.7.6 has an improved system adapter for FreeBSD, fixes bugs about the generic X/Open system adapter, and can use libcdio >= 0.83 as SCSI transport facility. - 10 Feb 2010 libisofs-0.6.28 fixes a regression about bootable images which was introduced by version 0.6.22 in August 2009. - 23 Feb 2010 libisoburn-0.5.0 marks the transition of the xorriso standalone version to an official GNU project. The name changed to "GNU xorriso" and its license is now GPLv3+. The licenses of libburnia libraries and applications are not affected by this change. - 10 Mar 2010 libburn-0.7.8 fixes bugs and improves the built-in abort handler on FreeBSD. - 30 Mar 2010 Release 0.5.2 of libisoburn provides xorriso documentation in GNU Texinfo format with embedded extra data to derive a full man page. - 09 Apr 2010 libburn-0.8.0 now works with ahci driver on FreeBSD 8-STABLE. - 03 May 2010 Version 0.6.32 of libisofs is able to create ISO images with multiple boot images. All boot catalog parameters described in El-Torito specs can be set and inquired. This was needed to use GRUB boot images for EFI. - 04 May 2010 Release 0.5.6.pl00 of libisoburn makes use of the new libisofs capabilities about boot images. - 11 Jun 2010 libburn-0.8.2 now works on Solaris. - 14 Jun 2010 By release 0.5.8.pl00 of libisoburn, xorriso becomes a public C language API of libisoburn. The emulations of mkisofs and cdrecord have been enhanced. - Tue Jun 29 2010 Version 0.6.34 of libisofs provides new features about hiding file names from directory trees. - Wed Jun 30 2010 libburn-0.8.4 removes some restrictions on operating systems other than Linux and FreeBSD. - Fri Jul 02 2010 Release 0.6.0.pl00 of libisoburn adds more options to the mkisofs emulation of xorriso. It also fixes minor bugs and shortcommings. - Wed Sep 15 2010 Version 0.6.36 of libisofs can produce ISO images which bear a partiton 1 with non-zero start address. They can be mounted from USB stick via the main device file (e.g. /dev/sdb) as well as via the partition device file (e.g. /dev/sdb1). - Fri Sep 17 2010 libburn-0.8.6 lifts the test reservation on DVD-R DL media. - Sat Sep 18 2010 Release 0.6.2.pl00 of libisoburn introduces a partition with non-zero offset for ISO 9660 images on USB sticks, improves mkisofs emulation, and fixes a regression which existed since version 0.4.2. - Wed Oct 20 2010 libburn-0.8.8 can report the used amount of BD spare blocks. - Sat Oct 23 2010 Version 0.6.38 of libisofs can use libjte to produce jigdo files along with the ISO image. Further filesystem images may be appended as MBR partitions 1 to 4. The capability was added to produce boot blocks for computers with MIPS CPU. - Tue Oct 26 2010 Release 0.6.4.pl00 of libisoburn and xorriso makes use of the new libisofs capabilities. - Wed Dec 08 2010 libburn-0.9.0 fixes a regression with SCSI command logging. - Fri Dec 10 2010 Version 0.6.40 of libisofs makes the prediction of the emerging image size less expensive and is able to make images bootable for SUN SPARC systems. - Sun Dec 12 2010 Release 0.6.6.pl00 of libisoburn and xorriso can read ISO images which were copied to a different start address than they were prepared for. - Mon Jan 17 2011 we go for release 1.0.0. This does not indicate a technological overhaul but shall emphasize the maturity of the software. libisofs-1.0.0 fixes a bug about the length of ECMA-119 directory names and is ready to store untranslated ECMA-119 names (violating the specs). libburn-1.0.0.pl00 is now willing to create stdio-drive files with rw-permissions for all, if umask really asks for it. cdrskin now refuses to burn if the foreseeable size exceeds media capacity libisoburn-1.0.0.pl00 can now create an ISO 9660:1999 directory tree, improved the emulation fidelity of command -as mkisofs, lowered the default abort threshold for xorriso batch mode, and increased that threshold for xorriso dialog mode. - Wed Feb 23 2011 release 1.0.2: libisofs fixes several bugs and introduces the capability to copy files inside the ISO filesystem. libburn removed a compilation obstacle on Solaris 9 and improved recognition of stdio pseudo-drives. libisoburn and xorriso fix bugs and make use of the new libisofs capability. xorriso improves its mkisofs emulation. - Thu Mar 10 2011 release 1.0.4: Several bugs were fixed in the libraries and in the mkisofs emulation of xorriso. This emulation xorrisofs has now an own man page and info document. - Sat Apr 09 2011 release 1.0.6: libburn refined its representation of emulated drives. The size alignment of DVD DAO is now 2 kB rather than 32 kB. libisofs produces Joliet names of up to 103 characters. xorriso fixes two bugs and makes use of the library improvements. - Thu Apr 14 2011 release libisoburn-1.0.8: A bug in the mkisofs emulation of xorriso could cause options to be ignored. The problem was freshly introduced with libisoburn-1.0.6. - Fri May 13 2011 release libisofs-1.0.8: Fixes a few rarely occurring bugs that have been found during the last month. - Sat Jun 18 2011 release 1.1.0: The consumption of stack memory was reduced. Statical program analysis found some rarely 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. - Sat Jan 28 2012 release 1.2.0: libburn has learned to read and write CD-TEXT with CD SAO audio sessions. It can now read CDRWIN .cue files which define pure audio or pure data sessions. libisofs and libisoburn improved timestamp handling. Several minor bugs were fixed. - Mon Apr 02 2012 release 1.2.2: The handling of intentional deviations from ECMA-119 specifications has been improved in libisofs. libisoburn and xorriso now make use of these improvements. Some rarely occuring bugs have been fixed. - Fri Jul 20 2012 release 1.2.4: libburn and libisofs got some rarely occuring bugs fixed. libisofs learned to produce HFS+ metadata and Apple Partition Map. The capabilities of isohybrid options --efi and --mac have been implemented (GPT and APM). - Tue Jan 08 2013 release 1.2.6: Small improvements were made in libburn. Minor bugs were fixed in the libraries. xorriso improved its capabilities to serve the needs of frontend programs. A proof of concept for a GUI frontend has been implemented: xorriso-tcltk - Mon Mar 18 2013 release 1.2.8: Some rarely occuring bugs were fixed in libisofs and libburn. libburn's handling of incomplete sessions has been improved. xorriso's mkisofs emulation learned to set El Torito section id strings. - Fri May 17 2013 release 1.3.0: Several bugs were fixed in the libraries and in xorriso. The recently introduced new boot preparation capabilities have been tested. New boot preparation options for GRUB2 were added. - Fri May 31 2013 patch release libburn-1.3.0.pl01: cdrskin -msinfo on DVD and BD reported as old session start the same number as the next writable address. Regression introduced by version 1.2.8. - Fri Aug 07 2013 release 1.3.2: cdrskin has aquired the capability to copy audio tracks to .wav files. It can extract CD-TEXT in a form that is readable for humans and for cdrskin itself. Several small bugs were fixed in xorriso. Its capabilities to serve frontend programs in dialog mode have been improved. - Thu Dec 12 2013 release 1.3.4: A long standing hidden bug was fixed, which affected inspection of unformatted DVD+RW. xorriso now by default puts EL Torito boot images to low block addresses. It can report and set read speeds. Several rarely occuring bugs were fixed. - Tue Mar 04 2014 release 1.3.6 libburn learned to operate optical drives and media on NetBSD. libisofs got a bug fix about HFS+ and enhancements about character set conversion. Minor bugs were fixed in libisoburn. xorriso can now find files with names which cannot be represented unchanged in ECMA-119, Joliet, or HFS+. - Sat Jun 28 2014 release 1.3.8 libburn got several bugs fixed. libisofs offers new API calls for inspection of boot sectors in ISO 9660 filesystems. xorriso improved its support for NetBSD, offers new features with command -find, and a command to extract ISO 9660 file content onto standard output or into filter processes. - Sun May 17 2015 release 1.4.0 This release is mainly about bug fixes and a new feature of xorriso to propose commands or as_mkisofs options which can reproduce the boot equipment of the loaded ISO filesystem. - Sat Nov 28 2015 release 1.4.2 libburn got some bugs fixed and learned to inquire the drive serial number. libisofs now sorts data file content by ECMA-119 file names for better reproducability of ISO content. Rock Ridge filenames may be restricted to lengths between 64 and 255 bytes. If needed, a qualified truncation happens. xorriso now can replay boot settings when modifying ISO filesystems. In order to avoid clogging of concurrent Linux SG_IO, xorriso got command -modesty_on_drive to enable an old workaround from IDE master/slave days. The source code underwent a scan by Coverity. About 150 code changes resulted, but no easy-to-trigger bugs were found. - Fri Jan 29 2016 patch release libburn-1.4.2.pl01: cdrskin did not work with "-" (stdin) as input. Regression introduced by version 1.4.2. ------------------------------------------------------------------------------ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 or later as published by the Free Software Foundation. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ------------------------------------------------------------------------------ Clarification in my name and in the name of Mario Danic, upcoming copyright holders on toplevel of libburnia. To be fully in effect after the remaining other copyrighted code has been replaced by ours and by copyright-free contributions of our friends: ------------------------------------------------------------------------------ We, the copyright holders, agree on the interpretation that dynamical linking of our libraries constitutes "use of" and not "derivation from" our work in the sense of GPL, provided those libraries are compiled from our unaltered code or from altered code published under GPL. So we will not raise legal protest if you link our libraries dynamically with applications which are not under GPL, or if you distribute our libraries and application tools in binary form, as long as you fulfill the usual condition of GPL to offer a copy of their source code -altered or unaltered- under GPL. We ask you politely to use our work in open source spirit and with the due reference to the entire open source community. If there should really arise the case where above clarification does not suffice to fulfill a clear and neat request in open source spirit that would otherwise be declined for mere formal reasons, only in that case we will duely consider to issue a special license covering only that special case. It is the open source idea of responsible freedom which will be decisive and you will have to prove that you exhausted all own means to qualify for GPL. For now we are firmly committed to maintain one single license: GPL. signed: Mario Danic, Thomas Schmitt Agreement joined later by: Vreixo Formoso libburn-1.4.2/COPYING0000644000175700017510000003542712652644224011161 00000000000000 GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS libburn-1.4.2/test/0000755000175700017510000000000012652650103011143 500000000000000libburn-1.4.2/test/libburner.c0000644000175700017510000007227612652644222013236 00000000000000 /* test/libburner.c , API illustration of burning data or audio tracks to CD */ /* Copyright (C) 2005 - 2015 Thomas Schmitt */ /* Provided under GPL, see also "License and copyright aspects" at file end */ /** Overview libburner is a minimal demo application for the library libburn as provided on http://libburnia-project.org . It can list the available devices, can blank a CD-RW or DVD-RW, can format DVD-RW and BD, can burn to CD-R, CD-RW, DVD-R, DVD+R, DVD+R/DL, DVD+RW, DVD-RW, DVD-RAM, BD-R, BD-RE. Not supported yet: DVD-R/DL. It's main purpose, nevertheless, is to show you how to use libburn and also to serve the libburnia team as reference application. libburner.c does indeed define the standard way how above three gestures can be implemented and stay upward compatible for a good while. There is another demo program, test/telltoc.c, which inspects drive, media state, and media contents. Before you can do anything, you have to initialize libburn by burn_initialize() and provide some signal and abort handling, e.g. by the builtin handler, by burn_set_signal_handling("libburner : ", NULL, 0x0) as it is done in main() at the end of this file. Then you aquire a drive in an appropriate way conforming to the API. The twoi main approaches are shown here in application functions: libburner_aquire_by_adr() demonstrates usage as of cdrecord traditions libburner_aquire_by_driveno() demonstrates a scan-and-choose approach With that aquired drive you can blank a CD-RW or DVD-RW as shown in libburner_blank_disc() or you can format a DVD-RW to profile "Restricted Overwrite" (needed once) or an unused BD to default size with spare blocks libburner_format() With the aquired drive you can burn to CD, DVD, BD. See libburner_payload() These three functions switch temporarily to a non-fatal signal handler while they are waiting for the drive to become idle again: burn_set_signal_handling("libburner : ", NULL, 0x30) After the waiting loop ended, they check for eventual abort events by burn_is_aborting(0) The 0x30 handler will eventually execute burn_abort() but not wait for the drive to become idle and not call exit(). This is needed because the worker threads might block as long as the signal handler has not returned. The 0x0 handler would wait for them to finish. Take this into respect when implementing own signal handlers. When everything is done, main() releases the drive and shuts down libburn: burn_drive_release(); burn_finish() Applications must use 64 bit off_t. E.g. by defining #define _LARGEFILE_SOURCE #define _FILE_OFFSET_BITS 64 or take special precautions to interface with the library by 64 bit integers where libburn/libburn.h prescribes off_t. This program gets fed with appropriate settings externally by libburn's autotools generated build system. */ /** See this for the decisive API specs . libburn.h is The Original */ /* For using the installed header file : #include */ /* This program insists in the own headerfile. */ #include "../libburn/libburn.h" /* libburn works on Linux systems with kernel 2.4 or 2.6, FreeBSD, Solaris */ #include #include #include #include #include #include #include #include #include #include /** For simplicity i use global variables to represent the drives. Drives are systemwide global, so we do not give away much of good style. */ /** This list will hold the drives known to libburn. This might be all CD drives of the system and thus might impose severe impact on the system. */ static struct burn_drive_info *drive_list; /** If you start a long lasting operation with drive_count > 1 then you are not friendly to the users of other drives on those systems. Beware. */ static unsigned int drive_count; /** This variable indicates wether the drive is grabbed and must be finally released */ static int drive_is_grabbed = 0; /** A number and a text describing the type of media in aquired drive */ static int current_profile= -1; static char current_profile_name[80]= {""}; /* Some in-advance definitions make possible a more comprehensive ordering of the functions and their explanations in here */ int libburner_aquire_by_adr(char *drive_adr); int libburner_aquire_by_driveno(int *drive_no); /* ------------------------------- API gestures ---------------------------- */ /** You need to aquire a drive before burning. The API offers this as one compact call and alternatively as application controllable gestures of whitelisting, scanning for drives and finally grabbing one of them. If you have a persistent address of the drive, then the compact call is to prefer because it only touches one drive. On modern Linux kernels, there should be no fatal disturbance of ongoing burns of other libburn instances with any of our approaches. We use open(O_EXCL) by default. On /dev/hdX it should cooperate with growisofs and some cdrecord variants. On /dev/sgN versus /dev/scdM expect it not to respect other programs. */ int libburner_aquire_drive(char *drive_adr, int *driveno) { int ret; if(drive_adr != NULL && drive_adr[0] != 0) ret = libburner_aquire_by_adr(drive_adr); else ret = libburner_aquire_by_driveno(driveno); if (ret <= 0 || *driveno <= 0) return ret; burn_disc_get_profile(drive_list[0].drive, ¤t_profile, current_profile_name); if (current_profile_name[0]) printf("Detected media type: %s\n", current_profile_name); return 1; } /** If the persistent drive address is known, then this approach is much more un-obtrusive to the systemwide livestock of drives. Only the given drive device will be opened during this procedure. */ int libburner_aquire_by_adr(char *drive_adr) { int ret; char libburn_drive_adr[BURN_DRIVE_ADR_LEN]; /* Some not-so-harmless drive addresses get blocked in this demo */ if (strncmp(drive_adr, "stdio:/dev/fd/", 14) == 0 || strcmp(drive_adr, "stdio:-") == 0) { fprintf(stderr, "Will not work with pseudo-drive '%s'\n", drive_adr); return 0; } /* This tries to resolve links or alternative device files */ ret = burn_drive_convert_fs_adr(drive_adr, libburn_drive_adr); if (ret<=0) { fprintf(stderr, "Address does not lead to a CD burner: '%s'\n", drive_adr); return 0; } fprintf(stderr,"Aquiring drive '%s' ...\n", libburn_drive_adr); ret = burn_drive_scan_and_grab(&drive_list, libburn_drive_adr, 1); if (ret <= 0) { fprintf(stderr,"FAILURE with persistent drive address '%s'\n", libburn_drive_adr); } else { fprintf(stderr,"Done\n"); drive_is_grabbed = 1; } return ret; } /** This method demonstrates how to use libburn without knowing a persistent drive address in advance. It has to make sure that after assessing the list of available drives, all unwanted drives get closed again. As long as they are open, no other libburn instance can see them. This is an intended locking feature. The application is responsible for giving up the locks by either burn_drive_release() (only after burn_drive_grab() !), burn_drive_info_forget(), burn_drive_info_free(), or burn_finish(). @param driveno the index number in libburn's drive list. This will get set to 0 on success and will then be the drive index to use in the further dourse of processing. @return 1 success , <= 0 failure */ int libburner_aquire_by_driveno(int *driveno) { char adr[BURN_DRIVE_ADR_LEN]; int ret, i; printf("Beginning to scan for devices ...\n"); while (!burn_drive_scan(&drive_list, &drive_count)) usleep(100002); if (drive_count <= 0 && *driveno >= 0) { printf("FAILED (no drives found)\n"); return 0; } printf("Done\n"); /* Interactive programs may choose the drive number at this moment. drive[0] to drive[drive_count-1] are struct burn_drive_info as defined in libburn/libburn.h . This structure is part of API and thus will strive for future compatibility on source level. Have a look at the info offered. Caution: do not take .location for drive address. Always use burn_drive_get_adr() or you might become incompatible in future. Note: bugs with struct burn_drive_info - if any - will not be easy to fix. Please report them but also strive for workarounds on application level. */ printf("\nOverview of accessible drives (%d found) :\n", drive_count); printf("-----------------------------------------------------------------------------\n"); for (i = 0; i < (int) drive_count; i++) { if (burn_drive_get_adr(&(drive_list[i]), adr) <=0) strcpy(adr, "-get_adr_failed-"); printf("%d --drive '%s' : '%s' '%s'\n", i,adr,drive_list[i].vendor,drive_list[i].product); } printf("-----------------------------------------------------------------------------\n\n"); /* On multi-drive systems save yourself from sysadmins' revenge. Be aware that you hold reserved all available drives at this point. So either make your choice quick enough not to annoy other system users, or set free the drives for a while. The tested way of setting free all drives is to shutdown the library and to restart when the choice has been made. The list of selectable drives should also hold persistent drive addresses as obtained above by burn_drive_get_adr(). By such an address one may use burn_drive_scan_and_grab() to finally aquire exactly one drive. A not yet tested shortcut should be to call burn_drive_info_free() and to call either burn_drive_scan() or burn_drive_scan_and_grab() before accessing any drives again. In both cases you have to be aware that the desired drive might get aquired in the meantime by another user or libburn process. */ /* We already made our choice via command line. (default is 0) So we just have to keep our desired drive and drop all others. No other libburn instance will have a chance to steal our drive. */ if (*driveno < 0) { printf("Pseudo-drive \"-\" given : bus scanning done.\n"); return 2; /* the program will end after this */ } if ((int) drive_count <= *driveno) { fprintf(stderr, "Found only %d drives. Number %d not available.\n", drive_count, *driveno); return 0; /* the program will end after this */ } /* Drop all drives which we do not want to use */ for (i = 0; i < (int) drive_count; i++) { if (i == *driveno) /* the one drive we want to keep */ continue; ret = burn_drive_info_forget(&(drive_list[i]),0); if (ret != 1) fprintf(stderr, "Cannot drop drive %d. Please report \"ret=%d\" to libburn-hackers@pykix.org\n", i, ret); else printf("Dropped unwanted drive %d\n",i); } /* Make the one we want ready for blanking or burning */ ret= burn_drive_grab(drive_list[*driveno].drive, 1); if (ret != 1) return 0; drive_is_grabbed = 1; return 1; } /** Makes a previously used CD-RW or unformatted DVD-RW ready for thorough re-usal. To our knowledge it is hardly possible to abort an ongoing blank operation because after start it is entirely handled by the drive. So expect signal handling to wait the normal blanking timespan until it can allow the process to end. External kill -9 will not help the drive. */ int libburner_blank_disc(struct burn_drive *drive, int blank_fast) { enum burn_disc_status disc_state; struct burn_progress p; double percent = 1.0; disc_state = burn_disc_get_status(drive); printf( "Drive media status: %d (see libburn/libburn.h BURN_DISC_*)\n", disc_state); if (current_profile == 0x13) { ; /* formatted DVD-RW will get blanked to sequential state */ } else if (disc_state == BURN_DISC_BLANK) { fprintf(stderr, "IDLE: Blank media detected. Will leave it untouched\n"); return 2; } else if (disc_state == BURN_DISC_FULL || disc_state == BURN_DISC_APPENDABLE) { ; /* this is what libburner is willing to blank */ } else if (disc_state == BURN_DISC_EMPTY) { fprintf(stderr,"FATAL: No media detected in drive\n"); return 0; } else { fprintf(stderr, "FATAL: Unsuitable drive and media state\n"); return 0; } if(!burn_disc_erasable(drive)) { fprintf(stderr, "FATAL : Media is not of erasable type\n"); return 0; } /* Switch to asynchronous signal handling for the time of waiting */ burn_set_signal_handling("libburner : ", NULL, 0x30); printf("Beginning to %s-blank media.\n", (blank_fast?"fast":"full")); burn_disc_erase(drive, blank_fast); sleep(1); while (burn_drive_get_status(drive, &p) != BURN_DRIVE_IDLE) { if(p.sectors>0 && p.sector>=0) /* display 1 to 99 percent */ percent = 1.0 + ((double) p.sector+1.0) / ((double) p.sectors) * 98.0; printf("Blanking ( %.1f%% done )\n", percent); sleep(1); } if (burn_is_aborting(0) > 0) return -1; /* Back to synchronous handling */ burn_set_signal_handling("libburner : ", NULL, 0x0); printf("Done\n"); return 1; } /** Formats unformatted DVD-RW to profile 0013h "Restricted Overwrite" which needs no blanking for re-use but is not capable of multi-session. Expect a behavior similar to blanking with unusual noises from the drive. Formats unformatted BD-RE to default size. This will allocate some reserve space, test for bad blocks and make the media ready for writing. Expect a very long run time. Formats unformatted blank BD-R to hold a default amount of spare blocks for eventual mishaps during writing. If BD-R get written without being formatted, then they get no such reserve and will burn at full speed. */ int libburner_format(struct burn_drive *drive) { struct burn_progress p; double percent = 1.0; int ret, status, num_formats, format_flag= 0; off_t size = 0; unsigned dummy; enum burn_disc_status disc_state; if (current_profile == 0x13) { fprintf(stderr, "IDLE: DVD-RW media is already formatted\n"); return 2; } else if (current_profile == 0x41 || current_profile == 0x43) { disc_state = burn_disc_get_status(drive); if (disc_state != BURN_DISC_BLANK && current_profile == 0x41) { fprintf(stderr, "FATAL: BD-R is not blank. Cannot format.\n"); return 0; } ret = burn_disc_get_formats(drive, &status, &size, &dummy, &num_formats); if (ret > 0 && status != BURN_FORMAT_IS_UNFORMATTED) { fprintf(stderr, "IDLE: BD media is already formatted\n"); return 2; } size = 0; /* does not really matter */ format_flag = 3<<1; /* format to default size, no quick */ } else if (current_profile == 0x14) { /* sequential DVD-RW */ size = 128 * 1024 * 1024; format_flag = 1; /* write initial 128 MiB */ } else { fprintf(stderr, "FATAL: Can only format DVD-RW or BD\n"); return 0; } burn_set_signal_handling("libburner : ", NULL, 0x30); printf("Beginning to format media.\n"); burn_disc_format(drive, size, format_flag); sleep(1); while (burn_drive_get_status(drive, &p) != BURN_DRIVE_IDLE) { if(p.sectors>0 && p.sector>=0) /* display 1 to 99 percent */ percent = 1.0 + ((double) p.sector+1.0) / ((double) p.sectors) * 98.0; printf("Formatting ( %.1f%% done )\n", percent); sleep(1); } if (burn_is_aborting(0) > 0) return -1; burn_set_signal_handling("libburner : ", NULL, 0x0); burn_disc_get_profile(drive_list[0].drive, ¤t_profile, current_profile_name); if (current_profile == 0x14 || current_profile == 0x13) printf("Media type now: %4.4xh \"%s\"\n", current_profile, current_profile_name); if (current_profile == 0x14) { fprintf(stderr, "FATAL: Failed to change media profile to desired value\n"); return 0; } return 1; } /** Brings preformatted track images (ISO 9660, audio, ...) onto media. To make sure a data image is fully readable on any Linux machine, this function adds 300 kiB of padding to the (usualy single) track. Audio tracks get padded to complete their last sector. A fifo of 4 MB is installed between each track and its data source. Each of the 4 MB buffers gets allocated automatically as soon as a track begins to be processed and it gets freed as soon as the track is done. The fifos do not wait for buffer fill but writing starts immediately. In case of external signals expect abort handling of an ongoing burn to last up to a minute. Wait the normal burning timespan before any kill -9. */ int libburner_payload(struct burn_drive *drive, char source_adr[][4096], int source_adr_count, int multi, int simulate_burn, int all_tracks_type) { struct burn_source *data_src = NULL, *fifo_src[99]; struct burn_disc *target_disc = NULL; struct burn_session *session = NULL; struct burn_write_opts *burn_options = NULL; enum burn_disc_status disc_state; struct burn_track *track, *tracklist[99]; struct burn_progress progress; time_t start_time; int last_sector = 0, padding = 0, trackno, unpredicted_size = 0, fd; int fifo_chunksize = 2352, fifo_chunks = 1783; /* ~ 4 MB fifo */ int ret; off_t fixed_size; char *adr, reasons[BURN_REASONS_LEN]; struct stat stbuf; for (trackno = 0 ; trackno < source_adr_count; trackno++) { fifo_src[trackno] = NULL; tracklist[trackno] = NULL; } if (all_tracks_type != BURN_AUDIO) { all_tracks_type = BURN_MODE1; /* a padding of 300 kiB helps to avoid the read-ahead bug */ padding = 300*1024; fifo_chunksize = 2048; fifo_chunks = 2048; /* 4 MB fifo */ } target_disc = burn_disc_create(); session = burn_session_create(); burn_disc_add_session(target_disc, session, BURN_POS_END); for (trackno = 0 ; trackno < source_adr_count; trackno++) { tracklist[trackno] = track = burn_track_create(); burn_track_define_data(track, 0, padding, 1, all_tracks_type); /* Open file descriptor to source of track data */ adr = source_adr[trackno]; fixed_size = 0; if (adr[0] == '-' && adr[1] == 0) { fd = 0; } else { fd = open(adr, O_RDONLY); if (fd>=0) if (fstat(fd,&stbuf)!=-1) if((stbuf.st_mode&S_IFMT)==S_IFREG) fixed_size = stbuf.st_size; } if (fixed_size==0) unpredicted_size = 1; /* Convert this filedescriptor into a burn_source object */ data_src = NULL; if (fd >= 0) data_src = burn_fd_source_new(fd, -1, fixed_size); if (data_src == NULL) { fprintf(stderr, "FATAL: Could not open data source '%s'.\n",adr); if(errno!=0) fprintf(stderr,"(Most recent system error: %s )\n", strerror(errno)); {ret = 0; goto ex;} } /* Install a fifo object on top of that data source object */ fifo_src[trackno] = burn_fifo_source_new(data_src, fifo_chunksize, fifo_chunks, 0); if (fifo_src[trackno] == NULL) { fprintf(stderr, "FATAL: Could not create fifo object of 4 MB\n"); {ret = 0; goto ex;} } /* Use the fifo object as data source for the track */ if (burn_track_set_source(track, fifo_src[trackno]) != BURN_SOURCE_OK) { fprintf(stderr, "FATAL: Cannot attach source object to track object\n"); {ret = 0; goto ex;} } burn_session_add_track(session, track, BURN_POS_END); printf("Track %d : source is '%s'\n", trackno+1, adr); /* Give up local reference to the data burn_source object */ burn_source_free(data_src); data_src = NULL; } /* trackno loop end */ /* Evaluate drive and media */ disc_state = burn_disc_get_status(drive); if (disc_state != BURN_DISC_BLANK && disc_state != BURN_DISC_APPENDABLE) { if (disc_state == BURN_DISC_FULL) { fprintf(stderr, "FATAL: Closed media with data detected. Need blank or appendable media.\n"); if (burn_disc_erasable(drive)) fprintf(stderr, "HINT: Try --blank_fast\n\n"); } else if (disc_state == BURN_DISC_EMPTY) fprintf(stderr,"FATAL: No media detected in drive\n"); else fprintf(stderr, "FATAL: Cannot recognize state of drive and media\n"); {ret = 0; goto ex;} } burn_options = burn_write_opts_new(drive); burn_write_opts_set_perform_opc(burn_options, 0); burn_write_opts_set_multi(burn_options, !!multi); if(simulate_burn) printf("\n*** Will TRY to SIMULATE burning ***\n\n"); burn_write_opts_set_simulate(burn_options, simulate_burn); burn_drive_set_speed(drive, 0, 0); burn_write_opts_set_underrun_proof(burn_options, 1); if (burn_write_opts_auto_write_type(burn_options, target_disc, reasons, 0) == BURN_WRITE_NONE) { fprintf(stderr, "FATAL: Failed to find a suitable write mode with this media.\n"); fprintf(stderr, "Reasons given:\n%s\n", reasons); {ret = 0; goto ex;} } burn_set_signal_handling("libburner : ", NULL, 0x30); printf("Burning starts. With e.g. 4x media expect up to a minute of zero progress.\n"); start_time = time(0); burn_disc_write(burn_options, target_disc); while (burn_drive_get_status(drive, NULL) == BURN_DRIVE_SPAWNING) usleep(100002); while (burn_drive_get_status(drive, &progress) != BURN_DRIVE_IDLE) { if (progress.sectors <= 0 || (progress.sector >= progress.sectors - 1 && !unpredicted_size) || (unpredicted_size && progress.sector == last_sector)) printf( "Thank you for being patient since %d seconds.", (int) (time(0) - start_time)); else if(unpredicted_size) printf("Track %d : sector %d", progress.track+1, progress.sector); else printf("Track %d : sector %d of %d",progress.track+1, progress.sector, progress.sectors); last_sector = progress.sector; if (progress.track >= 0 && progress.track < source_adr_count) { int size, free_bytes, ret; char *status_text; ret = burn_fifo_inquire_status( fifo_src[progress.track], &size, &free_bytes, &status_text); if (ret >= 0 ) printf(" [fifo %s, %2d%% fill]", status_text, (int) (100.0 - 100.0 * ((double) free_bytes) / (double) size)); } printf("\n"); sleep(1); } printf("\n"); if (burn_is_aborting(0) > 0) {ret = -1; goto ex;} if (multi && current_profile != 0x1a && current_profile != 0x13 && current_profile != 0x12 && current_profile != 0x43) /* not with DVD+RW, formatted DVD-RW, DVD-RAM, BD-RE */ printf("NOTE: Media left appendable.\n"); if (simulate_burn) printf("\n*** Did TRY to SIMULATE burning ***\n\n"); ret = 1; ex:; /* Dispose objects */ if (burn_options != NULL) burn_write_opts_free(burn_options); for (trackno = 0 ; trackno < source_adr_count; trackno++) { if (fifo_src[trackno] != NULL) burn_source_free(fifo_src[trackno]); if (tracklist[trackno]) burn_track_free(tracklist[trackno]); } if (data_src != NULL) burn_source_free(data_src); if (session != NULL) burn_session_free(session); if (target_disc != NULL) burn_disc_free(target_disc); return ret; } /** The setup parameters of libburner */ static char drive_adr[BURN_DRIVE_ADR_LEN] = {""}; static int driveno = 0; static int do_blank = 0; static char source_adr[99][4096]; static int source_adr_count = 0; static int do_multi = 0; static int simulate_burn = 0; static int all_tracks_type = BURN_MODE1; /** Converts command line arguments into above setup parameters. */ int libburner_setup(int argc, char **argv) { int i, insuffient_parameters = 0, print_help = 0; for (i = 1; i < argc; ++i) { if (!strcmp(argv[i], "--audio")) { all_tracks_type = BURN_AUDIO; } else if (!strcmp(argv[i], "--blank_fast")) { do_blank = 1; } else if (!strcmp(argv[i], "--blank_full")) { do_blank = 2; } else if (!strcmp(argv[i], "--burn_for_real")) { simulate_burn = 0; } else if (!strcmp(argv[i], "--drive")) { ++i; if (i >= argc) { fprintf(stderr,"--drive requires an argument\n"); return 1; } else if (strcmp(argv[i], "-") == 0) { drive_adr[0] = 0; driveno = -1; } else if (isdigit(argv[i][0])) { drive_adr[0] = 0; driveno = atoi(argv[i]); } else { if(strlen(argv[i]) >= BURN_DRIVE_ADR_LEN) { fprintf(stderr,"--drive address too long (max. %d)\n", BURN_DRIVE_ADR_LEN-1); return 2; } strcpy(drive_adr, argv[i]); } } else if ((!strcmp(argv[i], "--format_overwrite")) || (!strcmp(argv[i], "--format"))) { do_blank = 101; } else if (!strcmp(argv[i], "--multi")) { do_multi = 1; } else if (!strcmp(argv[i], "--stdin_size")) { /* obsoleted */ i++; } else if (!strcmp(argv[i], "--try_to_simulate")) { simulate_burn = 1; } else if (!strcmp(argv[i], "--help")) { print_help = 1; } else if (!strncmp(argv[i], "--",2)) { fprintf(stderr, "Unidentified option: %s\n", argv[i]); return 7; } else { if(strlen(argv[i]) >= 4096) { fprintf(stderr, "Source address too long (max. %d)\n", 4096-1); return 5; } if(source_adr_count >= 99) { fprintf(stderr, "Too many tracks (max. 99)\n"); return 6; } strcpy(source_adr[source_adr_count], argv[i]); source_adr_count++; } } insuffient_parameters = 1; if (driveno < 0) insuffient_parameters = 0; if (source_adr_count > 0) insuffient_parameters = 0; if (do_blank) insuffient_parameters = 0; if (print_help || insuffient_parameters ) { printf("Usage: %s\n", argv[0]); printf(" [--drive
||\"-\"] [--audio]\n"); printf(" [--blank_fast|--blank_full|--format] [--try_to_simulate]\n"); printf(" [--multi] [|\"-\"]\n"); printf("Examples\n"); printf("A bus scan (needs rw-permissions to see a drive):\n"); printf(" %s --drive -\n",argv[0]); printf("Burn a file to drive chosen by number, leave appendable:\n"); printf(" %s --drive 0 --multi my_image_file\n", argv[0]); printf("Burn a file to drive chosen by persistent address, close:\n"); printf(" %s --drive /dev/hdc my_image_file\n", argv[0]); printf("Blank a used CD-RW (is combinable with burning in one run):\n"); printf(" %s --drive /dev/hdc --blank_fast\n",argv[0]); printf("Blank a used DVD-RW (is combinable with burning in one run):\n"); printf(" %s --drive /dev/hdc --blank_full\n",argv[0]); printf("Format a DVD-RW, BD-RE or BD-R:\n"); printf(" %s --drive /dev/hdc --format\n", argv[0]); printf("Burn two audio tracks (to CD only):\n"); printf(" lame --decode -t /path/to/track1.mp3 track1.cd\n"); printf(" test/dewav /path/to/track2.wav -o track2.cd\n"); printf(" %s --drive /dev/hdc --audio track1.cd track2.cd\n", argv[0]); printf("Burn a compressed afio archive on-the-fly:\n"); printf(" ( cd my_directory ; find . -print | afio -oZ - ) | \\\n"); printf(" %s --drive /dev/hdc -\n", argv[0]); printf("To be read from *not mounted* media via: afio -tvZ /dev/hdc\n"); if (insuffient_parameters) return 6; } return 0; } int main(int argc, char **argv) { int ret; /* A warning to programmers who start their own projekt from here. */ if (sizeof(off_t) != 8) { fprintf(stderr, "\nFATAL: Compile time misconfiguration. off_t is not 64 bit.\n\n"); exit(39); } ret = libburner_setup(argc, argv); if (ret) exit(ret); printf("Initializing libburnia-project.org ...\n"); if (burn_initialize()) printf("Done\n"); else { printf("FAILED\n"); fprintf(stderr,"\nFATAL: Failed to initialize.\n"); exit(33); } /* Print messages of severity SORRY or more directly to stderr */ burn_msgs_set_severities("NEVER", "SORRY", "libburner : "); /* Activate the synchronous signal handler which eventually will try to properly shutdown drive and library on aborting events. */ burn_set_signal_handling("libburner : ", NULL, 0x0); /** Note: driveno might change its value in this call */ ret = libburner_aquire_drive(drive_adr, &driveno); if (ret<=0) { fprintf(stderr,"\nFATAL: Failed to aquire drive.\n"); { ret = 34; goto finish_libburn; } } if (ret == 2) { ret = 0; goto release_drive; } if (do_blank) { if (do_blank > 100) ret = libburner_format(drive_list[driveno].drive); else ret = libburner_blank_disc(drive_list[driveno].drive, do_blank == 1); if (ret<=0) { ret = 36; goto release_drive; } } if (source_adr_count > 0) { ret = libburner_payload(drive_list[driveno].drive, source_adr, source_adr_count, do_multi, simulate_burn, all_tracks_type); if (ret<=0) { ret = 38; goto release_drive; } } ret = 0; release_drive:; if (drive_is_grabbed) burn_drive_release(drive_list[driveno].drive, 0); finish_libburn:; if (burn_is_aborting(0) > 0) { burn_abort(4400, burn_abort_pacifier, "libburner : "); fprintf(stderr,"\nlibburner run aborted\n"); exit(1); } /* This app does not bother to know about exact scan state. Better to accept a memory leak here. We are done anyway. */ /* burn_drive_info_free(drive_list); */ burn_finish(); exit(ret); } /* License and copyright aspects: This all is provided under GPL. Read. Try. Think. Play. Write yourself some code. Be free of my copyright. Be also invited to study the code of cdrskin/cdrskin.c et al. History: libburner is a compilation of my own contributions to test/burniso.c and fresh code which replaced the remaining parts under copyright of Derek Foreman. My respect and my thanks to Derek for providing me a start back in 2005. */ libburn-1.4.2/test/telltoc.c0000644000175700017510000007576412652644222012725 00000000000000 /* test/telltoc.c , API illustration of obtaining media status info */ /* Copyright (C) 2006 - 2015 Thomas Schmitt Provided under GPL */ /** Overview telltoc is a minimal demo application for the library libburn as provided on http://libburnia-project.org . It can list the available devices, can display some drive properties, the type of media, eventual table of content, multisession info for mkisofs option -C, and can read audio or data tracks. It's main purpose, nevertheless, is to show you how to use libburn and also to serve the libburn team as reference application. telltoc.c does indeed define the standard way how above gestures can be implemented and stay upward compatible for a good while. The burn aspects of libburn are demonstrated by program test/libburner.c . Before you can do anything, you have to initialize libburn by burn_initialize() as it is done in main() at the end of this file. Then you aquire a drive in an appropriate way conforming to the API. The two main approaches are shown here in application functions: telltoc_aquire_by_adr() demonstrates usage as of cdrecord traditions telltoc_aquire_by_driveno() demonstrates a scan-and-choose approach With that aquired drive you can call telltoc_media() prints some information about the media in a drive telltoc_toc() prints a table of content (if there is content) telltoc_msinfo() prints parameters for mkisofs option -C telltoc_read_and_print() reads from audio or data CD or from DVD or BD and prints 7-bit to stdout (encodings 0,2) or 8-bit to file (encoding 1) When everything is done, main() releases the drive and shuts down libburn: burn_drive_release(); burn_finish() */ /** See this for the decisive API specs . libburn.h is The Original */ /* For using the installed header file : #include */ /* This program insists in the own headerfile. */ #include "../libburn/libburn.h" /* libburn is intended for Linux systems with kernel 2.4 or 2.6 for now */ #include #include #include #include #include #include #include #include #include #include /** For simplicity i use global variables to represent the drives. Drives are systemwide global, so we do not give away much of good style. */ /** This list will hold the drives known to libburn. This might be all CD drives of the system and thus might impose severe impact on the system. */ static struct burn_drive_info *drive_list; /** If you start a long lasting operation with drive_count > 1 then you are not friendly to the users of other drives on those systems. Beware. */ static unsigned int drive_count; /** This variable indicates wether the drive is grabbed and must be finally released */ static int drive_is_grabbed = 0; /* Some in-advance definitions to make possible a more comprehensive ordering of the functions and their explanations in here */ int telltoc_aquire_by_adr(char *drive_adr); int telltoc_aquire_by_driveno(int *drive_no, int silent); /* Messages from --toc to --read_and_print (CD tracksize is a bit tricky) */ static int last_track_start = 0, last_track_size = -1; static int medium_is_cd_profile = 0; /* 0 = undecided , -1 = no , 1 = yes */ static int cd_is_audio = 0; /* 0 = undecided , -1 = no , 1 = yes */ /* ------------------------------- API gestures ---------------------------- */ /** You need to aquire a drive before burning. The API offers this as one compact call and alternatively as application controllable gestures of whitelisting, scanning for drives and finally grabbing one of them. If you have a persistent address of the drive, then the compact call is to prefer because it only touches one drive. On modern Linux kernels, there should be no fatal disturbance of ongoing burns of other libburn instances with any of our approaches. We use open(O_EXCL) by default. On /dev/hdX it should cooperate with growisofs and some cdrecord variants. On /dev/sgN versus /dev/scdM expect it not to respect other programs. */ int telltoc_aquire_drive(char *drive_adr, int *driveno, int silent_drive) { int ret; if(drive_adr != NULL && drive_adr[0] != 0) ret = telltoc_aquire_by_adr(drive_adr); else ret = telltoc_aquire_by_driveno(driveno, silent_drive); return ret; } /** If the persistent drive address is known, then this approach is much more un-obtrusive to the systemwide livestock of drives. Only the given drive device will be opened during this procedure. Special drive addresses stdio: direct output to a hard disk file which will behave much like a DVD-RAM. */ int telltoc_aquire_by_adr(char *drive_adr) { int ret; char libburn_drive_adr[BURN_DRIVE_ADR_LEN]; /* This tries to resolve links or alternative device files */ ret = burn_drive_convert_fs_adr(drive_adr, libburn_drive_adr); if (ret<=0) { fprintf(stderr, "Address does not lead to a CD burner: '%s'\n", drive_adr); return 0; } fprintf(stderr,"Aquiring drive '%s' ...\n", libburn_drive_adr); ret = burn_drive_scan_and_grab(&drive_list, libburn_drive_adr, 1); if (ret <= 0) { fprintf(stderr,"FAILURE with persistent drive address '%s'\n", libburn_drive_adr); } else { fprintf(stderr,"Done\n"); drive_is_grabbed = 1; } return ret; } /** This method demonstrates how to use libburn without knowing a persistent drive address in advance. It has to make sure that after assessing the list of available drives, all unwanted drives get closed again. As long as they are open, no other libburn instance can see them. This is an intended locking feature. The application is responsible for giving up the locks by either burn_drive_release() (only after burn_drive_grab() !), burn_drive_info_forget(), burn_drive_info_free(), or burn_finish(). @param driveno the index number in libburn's drive list. This will get set to 0 on success and will then be the drive index to use in the further dourse of processing. @param silent_drive 1=do not print "Drive found :" line with *driveno >= 0 @return 1 success , <= 0 failure */ int telltoc_aquire_by_driveno(int *driveno, int silent_drive) { char adr[BURN_DRIVE_ADR_LEN]; int ret, i; fprintf(stderr, "Beginning to scan for devices ...\n"); while (!burn_drive_scan(&drive_list, &drive_count)) usleep(100002); if (drive_count <= 0 && *driveno >= 0) { fprintf(stderr, "FAILED (no drives found)\n"); return 0; } fprintf(stderr, "Done\n"); for (i = 0; i < (int) drive_count; i++) { if (*driveno >= 0 && (silent_drive || *driveno != i)) continue; if (burn_drive_get_adr(&(drive_list[i]), adr) <=0) strcpy(adr, "-get_adr_failed-"); printf("Drive found : %d --drive '%s' : ", i,adr); printf("%-8s %-16s (%4s)\n", drive_list[i].vendor,drive_list[i].product, drive_list[i].revision); } if (*driveno < 0) { fprintf(stderr, "Pseudo-drive \"-\" given : bus scanning done.\n"); return 2; /* the program will end after this */ } /* We already made our choice via command line. (default is 0) So we just have to keep our desired drive and drop all others. */ if ((int) drive_count <= *driveno) { fprintf(stderr, "Found only %d drives. Number %d not available.\n", drive_count, *driveno); return 0; /* the program will end after this */ } /* Drop all drives which we do not want to use */ for (i = 0; i < (int) drive_count; i++) { if (i == *driveno) /* the one drive we want to keep */ continue; ret = burn_drive_info_forget(&(drive_list[i]),0); if (ret != 1) fprintf(stderr, "Cannot drop drive %d. Please report \"ret=%d\" to libburn-hackers@pykix.org\n", i, ret); else fprintf(stderr, "Dropped unwanted drive %d\n",i); } /* Make the one we want ready for inquiry */ ret= burn_drive_grab(drive_list[*driveno].drive, 1); if (ret != 1) return 0; drive_is_grabbed = 1; return 1; } /** This gesture is necessary to get my NEC DVD_RW ND-4570A out of a state of noisy overexcitement after its tray was loaded and it then was inquired for Next Writeable Address. The noise then still lasts 20 seconds. Same with cdrecord -toc, btw. This opens a small gap for losing the drive to another libburn instance. Not a problem in telltoc. This is done as very last drive operation. Eventually the other libburn instance will have the same sanitizing effect. */ int telltoc_regrab(struct burn_drive *drive) { int ret; if (drive_is_grabbed) burn_drive_release(drive, 0); drive_is_grabbed = 0; ret = burn_drive_grab(drive, 0); if (ret != 0) { drive_is_grabbed = 1; } return !!ret; } int telltoc_media(struct burn_drive *drive) { int ret, media_found = 0, profile_no = -1, num_profiles = 0, i; int profiles[64]; char is_current_profile[64]; double max_speed = 0.0, min_speed = 0.0, speed_conv; off_t available = 0; enum burn_disc_status s; char profile_name[80], speed_unit[40]; struct burn_multi_caps *caps = NULL; struct burn_write_opts *o = NULL; printf("Media current: "); ret = burn_disc_get_profile(drive, &profile_no, profile_name); if (profile_no > 0 && ret > 0) { if (profile_name[0]) printf("%s\n", profile_name); else printf("%4.4Xh\n", profile_no); } else printf("is not recognizable\n"); /* Determine speed unit before profile_name gets reused */ speed_conv = 176.4; strcpy(speed_unit,"176.4 kB/s (CD, data speed 150 KiB/s)"); if (strstr(profile_name, "DVD") == profile_name) { speed_conv = 1385.0; strcpy(speed_unit,"1385.0 kB/s (DVD)"); } else if (strstr(profile_name, "BD") == profile_name) { speed_conv = 4495.625; strcpy(speed_unit,"4495.625 kB/s (BD)"); } ret = burn_drive_get_all_profiles(drive, &num_profiles, profiles, is_current_profile); if (ret > 0) { for (i = 0; i < num_profiles; i++) { ret = burn_obtain_profile_name(profiles[i], profile_name); if (ret <= 0) sprintf(profile_name, "Unknown media type 0x%4.4X", (unsigned int) profiles[i]); printf("Drive can do : %s%s\n", profile_name, is_current_profile[i] ? " (current)" : ""); } } printf("Media status : "); s = burn_disc_get_status(drive); if (s == BURN_DISC_FULL) { printf("is written , is closed\n"); media_found = 1; } else if (s == BURN_DISC_APPENDABLE) { printf("is written , is appendable\n"); media_found = 1; } else if (s == BURN_DISC_BLANK) { printf("is blank\n"); media_found = 1; } else if (s == BURN_DISC_EMPTY) printf("is not present\n"); else printf("is not recognizable\n"); printf("Media reuse : "); if (media_found) { if (burn_disc_erasable(drive)) printf("is erasable\n"); else printf("is not erasable\n"); } else printf("is not recognizable\n"); ret = burn_disc_get_multi_caps(drive, BURN_WRITE_NONE, &caps, 0); if (ret > 0) { /* Media appears writeable */ printf("Write multi : "); printf("%s multi-session , ", caps->multi_session == 1 ? "offers" : "cannot do"); if (caps->multi_track) printf("offers multiple tracks\n"); else printf("offers only single track\n"); printf("Write start : "); if (caps->start_adr == 1) printf( "offers addresses [%.f , %.f]s , alignment=%.fs\n", (double) caps->start_range_low / 2048 , (double) caps->start_range_high / 2048 , (double) caps->start_alignment / 2048 ); else printf("prohibits write start addressing\n"); printf("Write modes : "); if (caps->might_do_tao) printf("TAO%s", caps->advised_write_mode == BURN_WRITE_TAO ? " (advised)" : ""); if (caps->might_do_sao) printf("%sSAO%s", caps->might_do_tao ? " , " : "", caps->advised_write_mode == BURN_WRITE_SAO ? " (advised)" : ""); if (caps->might_do_raw) printf("%sRAW%s", caps->might_do_tao | caps->might_do_sao ? " , " : "", caps->advised_write_mode == BURN_WRITE_RAW ? " (advised)" : ""); printf("\n"); printf("Write dummy : "); if (caps->might_simulate) printf("supposed to work with non-RAW modes\n"); else printf("will not work\n"); o= burn_write_opts_new(drive); if (o != NULL) { burn_write_opts_set_perform_opc(o, 0); if(caps->advised_write_mode == BURN_WRITE_TAO) burn_write_opts_set_write_type(o, BURN_WRITE_TAO, BURN_BLOCK_MODE1); else if (caps->advised_write_mode == BURN_WRITE_SAO) burn_write_opts_set_write_type(o, BURN_WRITE_SAO, BURN_BLOCK_SAO); else { burn_write_opts_free(o); o = NULL; } } available = burn_disc_available_space(drive, o); printf("Write space : %.1f MiB (%.fs)\n", ((double) available) / 1024.0 / 1024.0, ((double) available) / 2048.0); burn_disc_free_multi_caps(&caps); if (o != NULL) burn_write_opts_free(o); } ret = burn_drive_get_write_speed(drive); max_speed = ((double ) ret) / speed_conv; ret = burn_drive_get_min_write_speed(drive); min_speed = ((double ) ret) / speed_conv; if (!media_found) printf("Drive speed : max=%.1f , min=%.1f\n", max_speed, min_speed); else printf("Avail. speed : max=%.1f , min=%.1f\n", max_speed, min_speed); ret = 0; if (media_found) ret = burn_disc_read_atip(drive); if(ret>0) { ret = burn_drive_get_min_write_speed(drive); min_speed = ((double ) ret) / speed_conv; ret = burn_drive_get_write_speed(drive); max_speed = ((double ) ret) / speed_conv; printf("Media speed : max=%.1f , min=%.1f\n", max_speed, min_speed); } printf("Speed unit 1x: %s\n", speed_unit); if (caps != NULL) burn_disc_free_multi_caps(&caps); return 1; } int telltoc_speedlist(struct burn_drive *drive) { int ret, has_modern_entries = 0; struct burn_speed_descriptor *speed_list, *sd; ret = burn_drive_get_speedlist(drive, &speed_list); if (ret <= 0) { fprintf(stderr, "SORRY: Cannot obtain speed list info\n"); return 2; } for (sd = speed_list; sd != NULL; sd = sd->next) if (sd->source == 2) has_modern_entries = 1; for (sd = speed_list; sd != NULL; sd = sd->next) { if (has_modern_entries && sd->source < 2) continue; if (sd->write_speed <= 0) continue; printf("Speed descr. : %d kB/s", sd->write_speed); if (sd->end_lba >= 0) printf(", %.1f MiB", ((double) sd->end_lba) / 512.0); if (sd->profile_name[0]) printf(", %s", sd->profile_name); printf("\n"); } burn_drive_free_speedlist(&speed_list); return 1; } int telltoc_formatlist(struct burn_drive *drive) { int ret, i, status, num_formats, profile_no, type; off_t size; unsigned dummy; char status_text[80], profile_name[90]; ret = burn_disc_get_formats(drive, &status, &size, &dummy, &num_formats); if (ret <= 0) { fprintf(stderr, "SORRY: Cannot obtain format list info\n"); return 2; } if (status == BURN_FORMAT_IS_UNFORMATTED) sprintf(status_text, "unformatted, up to %.1f MiB", ((double) size) / 1024.0 / 1024.0); else if(status == BURN_FORMAT_IS_FORMATTED) sprintf(status_text, "formatted, with %.1f MiB", ((double) size) / 1024.0 / 1024.0); else if(status == BURN_FORMAT_IS_UNKNOWN) { burn_disc_get_profile(drive, &profile_no, profile_name); if (profile_no > 0) sprintf(status_text, "intermediate or unknown"); else sprintf(status_text, "no media or unknown media"); } else sprintf(status_text, "illegal status according to MMC-5"); printf("Format status: %s\n", status_text); for (i = 0; i < num_formats; i++) { ret = burn_disc_get_format_descr(drive, i, &type, &size, &dummy); if (ret <= 0) continue; printf("Format descr.: %2.2Xh , %.1f MiB (%.fs)\n", type, ((double) size) / 1024.0 / 1024.0, ((double) size) / 2048.0); } return 1; } void telltoc_detect_cd(struct burn_drive *drive) { int pno; char profile_name[80]; if (burn_disc_get_profile(drive, &pno, profile_name) > 0) { if (pno >= 0x08 && pno <= 0x0a) medium_is_cd_profile = 1; else medium_is_cd_profile = -1; } } int telltoc_toc(struct burn_drive *drive) { int num_sessions = 0 , num_tracks = 0 , lba = 0, pmin, psec, pframe; int track_count = 0, track_is_audio; int session_no, track_no; struct burn_disc *disc= NULL; struct burn_session **sessions; struct burn_track **tracks; struct burn_toc_entry toc_entry; disc = burn_drive_get_disc(drive); if (disc==NULL) { fprintf(stderr, "SORRY: Cannot obtain Table Of Content\n"); return 2; } sessions = burn_disc_get_sessions(disc, &num_sessions); for (session_no = 0; session_no 0) /* In case it is a TAO track */ final_cd_try = 0; /* allow it (-1 is denial) */ } if (sector_count <= 0) sector_count = 2147483632; if (encoding == 1) { if (stat(raw_file,&stbuf) != -1) { if (!(S_ISCHR(stbuf.st_mode) || S_ISFIFO(stbuf.st_mode) || (stbuf.st_mode & S_IFMT) == S_IFSOCK )) { fprintf(stderr, "SORRY: target file '%s' already existing\n", raw_file); return 1; } } raw_fp = fopen(raw_file,"w"); if (raw_fp == NULL) { fprintf(stderr,"SORRY: cannot open target file '%s' (%s)\n", raw_file, strerror(errno)); return 1; } printf( "Data : start=%ds , count=%ds , read=0s , encoding=%d:'%s'\n", start_sector, sector_count, encoding, raw_file); } else printf( "Data : start=%ds , count=%ds , read=0 , encoding=%d\n", start_sector, sector_count, encoding); /* Whether to read audio or data */ if (cd_is_audio > 0) { read_audio = 1; } else if (medium_is_cd_profile > 0 && cd_is_audio == 0) { /* Try whether the start sector is audio */ ret = burn_read_audio(drive, start_sector, buf, (off_t) 2352, &data_count, 2 | 4); if (ret > 0) read_audio = 1; } if (read_audio) { sector_size = 2352; chunk_size = 12; } else { sector_size = 2048; chunk_size = 16; if (start_sector < 0) start_sector = 0; } todo = sector_count - 2*(final_cd_try > -1); for (done = 0; done < todo && final_cd_try != 1; done += request) { if (todo - done > chunk_size) request = chunk_size; else request = todo - done; if (read_audio) { ret = burn_read_audio(drive, start_sector + done, buf, (off_t) (request * sector_size), &data_count, 0); } else { ret = burn_read_data(drive, ((off_t) start_sector + done) * (off_t) sector_size, buf, (off_t) (request * sector_size), &data_count, 1); } print_result:; total_count += data_count; if (encoding == 1) { if (data_count > 0) { ret = fwrite(buf, data_count, 1, raw_fp); if (ret < 1) { fprintf(stderr, "FAILURE: writing to '%s' : %s\n", raw_file, strerror(errno)); fclose(raw_fp); return 1; } } } else for (i = 0; i < data_count; i += 16) { if (encoding == 0) { sprintf(line, "%8ds + %4d : ", start_sector + done + i / sector_size, i % sector_size); lbas = strlen(line); } for (j = 0; j < 16 && i + j < data_count; j++) { if (buf[i + j] >= ' ' && buf[i + j] <= 126 && encoding != 2) sprintf(line + lbas + 3 * j, " %c ", (int) buf[i + j]); else sprintf(line + lbas + 3 * j, "%2.2X ", (unsigned char) buf[i + j]); } line[lbas + 3 * (j - 1) + 2] = 0; printf("%s\n",line); } if (encoding == 1 && total_count - last_reported_count >= 1000 * sector_size) { fprintf(stderr, "\rReading data : start=%ds , count=%ds , read=%ds ", start_sector, sector_count, (int) (total_count / (off_t) sector_size)); last_reported_count = total_count; } if (ret <= 0) { fprintf(stderr, "SORRY : Reading failed.\n"); break; } } if (ret > 0 && medium_is_cd_profile > 0 && final_cd_try == 0) { /* In a SAO track the last 2 frames should be data too */ final_cd_try = 1; if (read_audio) { ret = burn_read_audio(drive, start_sector + todo, buf, (off_t) (2 * sector_size), &data_count, 2); } else { burn_read_data(drive, ((off_t) start_sector + todo) * (off_t) sector_size, buf, (off_t) (2 * sector_size), &data_count, 2); } if (data_count < 2 * sector_size) fprintf(stderr, "\rNOTE : Last two frames of CD track unreadable. This is normal if TAO track.\n"); if (data_count > 0) goto print_result; } if (last_reported_count > 0) fprintf(stderr, "\r \r"); printf("End Of Data : start=%ds , count=%ds , read=%ds\n", start_sector, sector_count, (int) (total_count / (off_t) sector_size)); if (raw_fp != NULL) fclose(raw_fp); return ret; } /** The setup parameters of telltoc */ static char drive_adr[BURN_DRIVE_ADR_LEN] = {""}; static int driveno = 0; static int do_media = 0; static int do_toc = 0; static int do_msinfo = 0; static int print_help = 0; static int do_capacities = 0; static int read_start = -2, read_count = -2, print_encoding = 0; static char print_raw_file[4096] = {""}; /** Converts command line arguments into above setup parameters. drive_adr[] must provide at least BURN_DRIVE_ADR_LEN bytes. source_adr[] must provide at least 4096 bytes. */ int telltoc_setup(int argc, char **argv) { int i; for (i = 1; i < argc; ++i) { if (strlen(argv[i]) >= 4096) { fprintf(stderr, "Argument at position %d is much too long. (Max 4095)\n", i); return 2; } } for (i = 1; i < argc; ++i) { if (!strcmp(argv[i], "--drive")) { ++i; if (i >= argc) { fprintf(stderr,"--drive requires an argument\n"); return 1; } else if (strcmp(argv[i], "-") == 0) { drive_adr[0] = 0; driveno = -1; } else if (isdigit(argv[i][0])) { drive_adr[0] = 0; driveno = atoi(argv[i]); } else { if(strlen(argv[i]) >= BURN_DRIVE_ADR_LEN) { fprintf(stderr,"--drive address too long (max. %d)\n", BURN_DRIVE_ADR_LEN-1); return 2; } strcpy(drive_adr, argv[i]); } } else if (strcmp(argv[i],"--media")==0) { do_media = 1; } else if (!strcmp(argv[i], "--msinfo")) { do_msinfo = 1; } else if (!strcmp(argv[i], "--capacities")) { do_capacities = 1; } else if (!strcmp(argv[i], "--toc")) { do_toc = 1; } else if (!strcmp(argv[i], "--read_and_print")) { i+= 3; if (i >= argc) { fprintf(stderr,"--read_and_print requires three arguments: start count encoding(try 0, not 1)\n"); return 1; } sscanf(argv[i-2], "%d", &read_start); sscanf(argv[i-1], "%d", &read_count); print_encoding = 0; if(strncmp(argv[i], "raw:", 4) == 0 || strncmp(argv[i], "1:", 2) == 0) { print_encoding = 1; strcpy(print_raw_file, strchr(argv[i], ':') + 1); if (strcmp(print_raw_file, "-") == 0) { fprintf(stderr, "--read_and_print does not write to \"-\" as stdout.\n"); return 1; } } else if(strcmp(argv[i], "hex") == 0 || strcmp(argv[i], "2") == 0) print_encoding = 2; } else if (!strcmp(argv[i], "--help")) { print_help = 1; } else { fprintf(stderr, "Unidentified option: %s\n", argv[i]); return 7; } } if (argc==1) print_help = 1; if (print_help) { printf("Usage: %s\n", argv[0]); printf(" [--drive
||\"-\"]\n"); printf(" [--media] [--capacities] [--toc] [--msinfo]\n"); printf(" [--read_and_print \"0\"|\"hex\"|\"raw\":]\n"); printf("Examples\n"); printf("A bus scan (needs rw-permissions to see a drive):\n"); printf(" %s --drive -\n",argv[0]); printf("Obtain info about the type of loaded media:\n"); printf(" %s --drive /dev/hdc --media\n",argv[0]); printf("Obtain table of content:\n"); printf(" %s --drive /dev/hdc --toc\n",argv[0]); printf("Obtain parameters for option -C of program mkisofs:\n"); printf(" msinfo=$(%s --drive /dev/hdc --msinfo 2>/dev/null)\n", argv[0]); printf(" mkisofs ... -C \"$msinfo\" ...\n"); printf("Obtain what is available about drive 0 and its media\n"); printf(" %s --drive 0\n",argv[0]); printf("View blocks 16 to 19 of audio or data CD or DVD or BD in human readable form\n"); printf(" %s --drive /dev/sr1 --read_and_print 16 4 0 | less\n", argv[0]); printf("Copy last track from CD to file /tmp/data\n"); printf(" %s --drive /dev/sr1 --toc --read_and_print -1 -1 raw:/tmp/data\n", argv[0]); } return 0; } int main(int argc, char **argv) { int ret, toc_failed = 0, msinfo_alone = 0, msinfo_explicit = 0; int full_default = 0; ret = telltoc_setup(argc, argv); if (ret) exit(ret); /* Behavior shall be different if --msinfo is only option */ if (do_msinfo) { msinfo_explicit = 1; if (!(do_media || do_toc)) msinfo_alone = 1; } /* Default option is to do everything if possible */ if (do_media==0 && do_msinfo==0 && do_capacities==0 && do_toc==0 && (read_start < 0 || read_count <= 0) && driveno!=-1) { if(print_help) exit(0); full_default = do_media = do_msinfo = do_capacities= do_toc= 1; } fprintf(stderr, "Initializing libburnia-project.org ...\n"); if (burn_initialize()) fprintf(stderr, "Done\n"); else { fprintf(stderr,"\nFATAL: Failed to initialize.\n"); exit(33); } /* Print messages of severity WARNING or more directly to stderr */ burn_msgs_set_severities("NEVER", "WARNING", "telltoc : "); /* Activate the default signal handler */ burn_set_signal_handling("telltoc : ", NULL, 0); /** Note: driveno might change its value in this call */ ret = telltoc_aquire_drive(drive_adr, &driveno, !full_default); if (ret<=0) { fprintf(stderr,"\nFATAL: Failed to aquire drive.\n"); { ret = 34; goto finish_libburn; } } if (ret == 2) { ret = 0; goto release_drive; } if (do_media) { ret = telltoc_media(drive_list[driveno].drive); if (ret<=0) {ret = 36; goto release_drive; } } if (do_capacities) { ret = telltoc_speedlist(drive_list[driveno].drive); if (ret<=0) {ret = 39; goto release_drive; } ret = telltoc_formatlist(drive_list[driveno].drive); if (ret<=0) {ret = 39; goto release_drive; } } if (do_toc) { ret = telltoc_toc(drive_list[driveno].drive); if (ret<=0) {ret = 37; goto release_drive; } if (ret==2) toc_failed = 1; } if (do_msinfo) { ret = telltoc_msinfo(drive_list[driveno].drive, msinfo_explicit, msinfo_alone); if (ret<=0) {ret = 38; goto release_drive; } } if (read_start != -2 && (read_count > 0 || read_count == -1)) { ret = telltoc_read_and_print(drive_list[driveno].drive, read_start, read_count, print_raw_file, print_encoding); if (ret<=0) {ret = 40; goto release_drive; } } ret = 0; if (toc_failed) ret = 37; release_drive:; if (drive_is_grabbed) burn_drive_release(drive_list[driveno].drive, 0); finish_libburn:; /* This app does not bother to know about exact scan state. Better to accept a memory leak here. We are done anyway. */ /* burn_drive_info_free(drive_list); */ burn_finish(); exit(ret); } /* License and copyright aspects: See test/libburner.c */ libburn-1.4.2/test/fake_au.c0000644000175700017510000001057012652644222012632 00000000000000 /* fake_au Fakes a file in SUN .au format from a raw little-endian PCM audio file (e.g. a file extracted from .wav by test/dewav). The input data are assumed to be 16 bit, stereo, 44100 Hz. Copyright (C) 2006 - 2015 Thomas Schmitt Provided under GPL version 2 or later. Info used: http://www.opengroup.org/public/pubs/external/auformat.html */ #include #include #include #include #include #include #include #include #include int fake_write(unsigned char *buf, size_t size, FILE *fp) { int ret; ret= fwrite(buf,size,1,fp); if(ret==1) return(1); fprintf(stderr,"Error %d while writing: '%s'\n",errno,strerror(errno)); return(0); } int main(int argc, char **argv) { int ret, i; unsigned data_size= 0,byte_count,exit_value= 0; FILE *fp_out= stdout,*fp_in= stdin; unsigned char buf[4]; char out_path[4096],in_path[4096]; struct stat stbuf; strcpy(out_path,"-"); strcpy(in_path,""); if(argc < 2) { exit_value= 1; goto help; } for(i= 1; i= 4096) { fprintf(stderr,"%s: argument at position %d is much too long.\n", argv[0], i); exit(1); } } for(i= 1; i=argc-1) { fprintf(stderr,"%s: option -o needs a file address as argument.\n", argv[0]); exit(1); } i++; strcpy(out_path, argv[i]); } else if(strcmp(argv[i],"--stdin_size")==0) { if(i>=argc-1) { fprintf(stderr,"%s: option --stdin_size needs a number as argument.\n", argv[0]); exit(1); } i++; sscanf(argv[i],"%u",&data_size); } else if(strcmp(argv[i],"--help")==0) { exit_value= 0; help:; fprintf(stderr,"usage: %s \\\n", argv[0]); fprintf(stderr," [-o output_path|\"-\"] [source_path | --stdin_size size]\n"); fprintf(stderr, "Disguises an extracted .wav stream as .au stereo, 16bit, 44100Hz\n"); fprintf(stderr, "stdin gets byte-swapped and appended up to the announced data_size.\n"); exit(exit_value); } else { if(in_path[0]!=0) { fprintf(stderr,"%s: only one input file is allowed.\n", argv[0]); exit(1); } strcpy(in_path, argv[i]); } } if(strcmp(in_path,"-")==0 || in_path[0]==0) { if(data_size==0) { fprintf(stderr,"%s: input from stdin needs option --stdin_size.\n", argv[0]); exit(6); } fp_in= stdin; } else { fp_in= fopen(in_path,"r"); if(stat(in_path,&stbuf)!=-1) data_size= stbuf.st_size; } if(fp_in==NULL) { fprintf(stderr,"Error %d while fopen(\"%s\",\"r\") : '%s'\n", errno,in_path,strerror(errno)); exit(2); } if(strcmp(out_path,"-")==0) { fp_out= stdout; } else { if(stat(out_path,&stbuf)!=-1) { fprintf(stderr,"%s: file '%s' already existing\n",argv[0],out_path); exit(4); } fp_out= fopen(out_path,"w"); } if(fp_out==NULL) { fprintf(stderr,"Error %d while fopen(\"%s\",\"w\") : '%s'\n", errno,out_path,strerror(errno)); exit(2); } fake_write((unsigned char *) ".snd",4,fp_out); /* magic number */ buf[0]= buf[1]= buf[2]= 0; buf[3]= 32; fake_write(buf,4,fp_out); /* data_location */ buf[0]= (data_size>>24)&0xff; buf[1]= (data_size>>16)&0xff; buf[2]= (data_size>>8)&0xff; buf[3]= (data_size)&0xff; fake_write(buf,4,fp_out); /* data_size */ buf[0]= buf[1]= buf[2]= 0; buf[3]= 3; fake_write(buf,4,fp_out); /* encoding 16 Bit PCM */ buf[0]= buf[1]= 0; buf[2]= 172; buf[3]= 68; fake_write(buf,4,fp_out); /* sample rate 44100 Hz */ buf[0]= buf[1]= buf[2]= 0; buf[3]= 2; fake_write(buf,4,fp_out); /* number of channels */ buf[0]= buf[1]= buf[2]= buf[3]= 0; fake_write(buf,4,fp_out); /* padding */ fake_write(buf,4,fp_out); /* padding */ for(byte_count= 0; byte_count #include #include #include #include #include #include #include #include #include static int create_original(struct burn_source **original, char *path, int flag) { printf("create_original: path='%s'\n", path); *original = burn_file_source_new(path, NULL); if (*original == NULL) return 0; return 1; } static int set_up_offst_sources(struct burn_source *original, struct burn_source *offsetters[], int count, int flag) { int i; off_t start = 3, size = 10, gap = 7; for (i = 0; i < count; i++) { offsetters[i] = burn_offst_source_new(original, i > 0 ? offsetters[i - 1] : NULL, start, size, 0); if (offsetters[i] == NULL) return 0; printf("set_up_offst_sources: idx=%d, start=%d\n", i, (int) start); start += size + gap; } return 1; } static int consume_source(struct burn_source *src, int flag) { int ret, count = 0; unsigned char buf[1]; while (1) { ret = src->read_xt(src, buf, 1); if (ret < 0) { printf("\n"); fprintf(stderr, "consume_source: count=%d, ret=%d\n", count, ret); return 0; } if (ret == 0) break; printf("%u ", buf[0]); count++; } printf(" count=%d\n", count); return 1; } static int consume_all_sources(struct burn_source *offsetters[], int count, int flag) { int i, ret; for (i = 0; i < count; i++) { printf("consume_source: idx=%d\n", i); ret = consume_source(offsetters[i], 0); if (ret <= 0) return ret; } return 1; } static int free_all_sources(struct burn_source *original, struct burn_source *offsetters[], int count, int flag) { int i; for (i = 0; i < count; i++) burn_source_free(offsetters[i]); burn_source_free(original); return 1; } int main(int argc, char **argv) { int ret; char *path = "./COPYRIGHT"; struct burn_source *original = NULL, *offsetters[4]; if (argc > 1) path = argv[1]; if (burn_initialize() == 0) exit(1); ret = create_original(&original, path, 0); if (ret <= 0) exit(2); ret = set_up_offst_sources(original, offsetters, 4, 0); if (ret <= 0) exit(3); ret = consume_all_sources(offsetters, 4, 0); if (ret <= 0) exit(4); ret = free_all_sources(original, offsetters, 4, 0); if (ret <= 0) exit(5); burn_finish(); exit(0); } libburn-1.4.2/test/dewav.c0000644000175700017510000001376312652644222012354 00000000000000 /* dewav Demo of libburn extension libdax_audioxtr Audio track data extraction facility of libdax and libburn. Copyright (C) 2006 Thomas Schmitt , provided under GPL */ #include #include #include #include #include #include #include #include #include /* libdax_audioxtr is quite independent of libburn. It only needs the messaging facility libdax_msgs. So we got two build variations: */ #ifdef Dewav_without_libburN /* This build environment is standalone relying only on libdax components */ #include "../libburn/libdax_msgs.h" struct libdax_msgs *libdax_messenger= NULL; /* The API for .wav extraction */ #define LIBDAX_AUDIOXTR_H_PUBLIC 1 #include "../libburn/libdax_audioxtr.h" #else /* Dewav_without_libburN */ /* This build environment uses libdax_msgs and libdax_audioxtr via libburn */ /* Thus the API header of libburn */ #include "../libburn/libburn.h" #endif /* ! Dewav_without_libburN */ int main(int argc, char **argv) { /* This program acts as filter from in_path to out_path */ char *in_path= "", *out_path= "-"; /* The read-and-extract object for use with in_path */ struct libdax_audioxtr *xtr= NULL; /* The file descriptor eventually detached from xtr */ int xtr_fd= -2; /* Default output is stdout */ int out_fd= 1; /* Inquired source parameters */ char *fmt, *fmt_info; int num_channels, sample_rate, bits_per_sample, msb_first; off_t data_size; /* Auxiliary variables */ int ret, i, be_strict= 1, buf_count, detach_fd= 0, extract_all= 0; char buf[2048]; if(argc < 2) goto help; for(i= 1; i=argc-1) { fprintf(stderr,"%s: option -o needs a file address as argument.\n", argv[0]); exit(1); } i++; out_path= argv[i]; } else if(strcmp(argv[i],"--lax")==0) { be_strict= 0; } else if(strcmp(argv[i],"--strict")==0) { be_strict= 1; } else if(strcmp(argv[i],"--detach_fd")==0) { /* Test the dirty detach method. Always --extract_all */ detach_fd= 1; } else if(strcmp(argv[i],"--extract_all")==0) { /* Dirty : read all available bytes regardless of data_size */ extract_all= 1; } else if(strcmp(argv[i],"--help")==0) { help:; fprintf(stderr, "usage: %s [-o output_path|\"-\"] [--lax|--strict] [source_path|\"-\"]\n", argv[0]); exit(0); } else { if(in_path[0]!=0) { fprintf(stderr,"%s: only one input file is allowed.\n", argv[0]); exit(2); } in_path= argv[i]; } } if(in_path[0] == 0) in_path= "-"; /* Depending on wether this was built standalone or with full libburn : */ #ifdef Dewav_without_libburN /* Initialize and set up libdax messaging system */ ret= libdax_msgs_new(&libdax_messenger,0); if(ret<=0) { fprintf(stderr,"Failed to create libdax_messenger object.\n"); exit(3); } libdax_msgs_set_severities(libdax_messenger, LIBDAX_MSGS_SEV_NEVER, LIBDAX_MSGS_SEV_NOTE, "", 0); fprintf(stderr, "dewav on libdax\n"); #else /* Dewav_without_libburN */ /* Initialize libburn and set up its messaging system */ if(burn_initialize() == 0) { fprintf(stderr,"Failed to initialize libburn.\n"); exit(3); } /* Print messages of severity NOTE or more directly to stderr */ burn_msgs_set_severities("NEVER", "NOTE", ""); fprintf(stderr, "dewav on libburn\n"); #endif /* ! Dewav_without_libburN */ /* Open audio source and create extractor object */ ret= libdax_audioxtr_new(&xtr, in_path, 0); if(ret<=0) exit(4); if(strcmp(out_path,"-")!=0) { out_fd= open(out_path, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH); if(out_fd == -1) { fprintf(stderr, "Cannot open file: %s\n", out_path); fprintf(stderr, "Error reported: '%s' (%d)\n",strerror(errno), errno); exit(5); } } /* Obtain and print parameters of audio source */ libdax_audioxtr_get_id(xtr, &fmt, &fmt_info, &num_channels, &sample_rate, &bits_per_sample, &msb_first, 0); fprintf(stderr, "Detected format: %s\n", fmt_info); libdax_audioxtr_get_size(xtr, &data_size, 0); fprintf(stderr, "Data size : %.f bytes\n", (double) data_size); if((strcmp(fmt,".wav")!=0 && strcmp(fmt,".au")!=0) || num_channels!=2 || sample_rate!=44100 || bits_per_sample!=16) { fprintf(stderr, "%sAudio source parameters do not comply to cdrskin/README specs\n", (be_strict ? "" : "WARNING: ")); if(be_strict) exit(6); } if(msb_first==0) fprintf(stderr, "NOTE: Extracted data to be written with cdrskin option -swab\n"); if(detach_fd) { /* Take over fd from xtr */; ret= libdax_audioxtr_detach_fd(xtr, &xtr_fd, 0); if(ret<=0) { fprintf(stderr, "Cannot detach file descriptor from extractor\n"); exit(8); } /* not needed any more */ libdax_audioxtr_destroy(&xtr, 0); fprintf(stderr, "Note: detached fd and freed extractor object.\n"); } /* Extract and put out raw audio data */; while(1) { if(detach_fd) { buf_count= read(xtr_fd, buf, sizeof(buf)); if(buf_count==-1) fprintf(stderr,"Error while reading from detached fd\n(%d) '%s'\n", errno, strerror(errno)); } else { buf_count= libdax_audioxtr_read(xtr, buf, sizeof(buf), !!extract_all); } if(buf_count < 0) exit(7); if(buf_count == 0) break; ret= write(out_fd, buf, buf_count); if(ret == -1) { fprintf(stderr, "Failed to write buffer of %d bytes to: %s\n", buf_count, out_path); fprintf(stderr, "Error reported: '%s' (%d)\n", strerror(errno), errno); exit(5); } } /* Shutdown */ if(out_fd>2) close(out_fd); /* ( It is permissible to do this with xtr==NULL ) */ libdax_audioxtr_destroy(&xtr, 0); #ifdef Dewav_without_libburN libdax_msgs_destroy(&libdax_messenger,0); #else /* Dewav_without_libburN */ burn_finish(); #endif /* ! Dewav_without_libburN */ exit(0); } libburn-1.4.2/test/poll.c0000644000175700017510000000303112652644222012177 00000000000000/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */ #include "libburn/libburn.h" #include "libburn/toc.h" #include "libburn/mmc.h" #include #include #include #include #include static struct burn_drive_info *drives; static unsigned int n_drives; int NEXT; static void catch_int () { NEXT = 1; } static void poll_drive(int d) { fprintf(stderr, "polling disc in %s - %s:\n", drives[d].vendor, drives[d].product); if (!burn_drive_grab(drives[d].drive, 1)) { fprintf(stderr, "Unable to open the drive!\n"); return; } while (burn_drive_get_status(drives[d].drive, NULL)) usleep(1000); while (burn_disc_get_status(drives[d].drive) == BURN_DISC_UNREADY) usleep(1000); while (NEXT == 0) { sleep(2); mmc_get_event(drives[d].drive); } burn_drive_release(drives[d].drive, 0); } int main() { int i; struct sigaction newact; struct sigaction oldact; fprintf(stderr, "Initializing library..."); if (burn_initialize()) fprintf(stderr, "Success\n"); else { printf("Failed\n"); return 1; } fprintf(stderr, "Scanning for devices..."); while (!burn_drive_scan(&drives, &n_drives)) ; fprintf(stderr, "Done\n"); if (!drives) { printf("No burner found\n"); return 1; } memset(&newact, 0, sizeof(newact)); newact.sa_handler = catch_int; sigaction(SIGINT, &newact, &oldact); for (i = 0; i < (int) n_drives; i++) { NEXT=0; poll_drive(i); } sigaction(SIGINT, &oldact, NULL); burn_drive_info_free(drives); burn_finish(); return 0; } libburn-1.4.2/Makefile.in0000644000175700017510000020253112652650102012153 00000000000000# Makefile.in generated by automake 1.14.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ noinst_PROGRAMS = test/libburner$(EXEEXT) test/offst_source$(EXEEXT) \ test/telltoc$(EXEEXT) test/dewav$(EXEEXT) \ test/fake_au$(EXEEXT) test/poll$(EXEEXT) bin_PROGRAMS = cdrskin/cdrskin$(EXEEXT) subdir = . DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ $(top_srcdir)/configure $(am__configure_deps) \ $(top_srcdir)/doc/doxygen.conf.in $(srcdir)/version.h.in \ $(srcdir)/libburn-1.pc.in depcomp $(libinclude_HEADERS) \ AUTHORS COPYING ChangeLog INSTALL NEWS README compile \ config.guess config.sub install-sh missing ltmain.sh ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ configure.lineno config.status.lineno mkinstalldirs = $(install_sh) -d CONFIG_CLEAN_FILES = doc/doxygen.conf version.h libburn-1.pc CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(bindir)" \ "$(DESTDIR)$(man1dir)" "$(DESTDIR)$(pkgconfigdir)" \ "$(DESTDIR)$(libincludedir)" LTLIBRARIES = $(lib_LTLIBRARIES) am__DEPENDENCIES_1 = libburn_libburn_la_DEPENDENCIES = $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) am__dirstamp = $(am__leading_dot)dirstamp am_libburn_libburn_la_OBJECTS = libburn/async.lo libburn/cdtext.lo \ libburn/cleanup.lo libburn/crc.lo libburn/debug.lo \ libburn/drive.lo libburn/ecma130ab.lo libburn/file.lo \ libburn/init.lo libburn/libdax_audioxtr.lo \ libburn/libdax_msgs.lo libburn/mmc.lo libburn/null.lo \ libburn/options.lo libburn/read.lo libburn/sbc.lo \ libburn/sector.lo libburn/sg.lo libburn/source.lo \ libburn/spc.lo libburn/structure.lo libburn/toc.lo \ libburn/util.lo libburn/write.lo libburn_libburn_la_OBJECTS = $(am_libburn_libburn_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = libburn_libburn_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(AM_CFLAGS) $(CFLAGS) $(libburn_libburn_la_LDFLAGS) \ $(LDFLAGS) -o $@ PROGRAMS = $(bin_PROGRAMS) $(noinst_PROGRAMS) am_cdrskin_cdrskin_OBJECTS = \ cdrskin/cdrskin_cdrskin-cdrskin.$(OBJEXT) \ cdrskin/cdrskin_cdrskin-cdrfifo.$(OBJEXT) cdrskin_cdrskin_OBJECTS = $(am_cdrskin_cdrskin_OBJECTS) am__DEPENDENCIES_2 = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) cdrskin_cdrskin_DEPENDENCIES = libburn/libburn.la \ $(am__DEPENDENCIES_2) cdrskin_cdrskin_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(cdrskin_cdrskin_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ -o $@ am_test_dewav_OBJECTS = test/test_dewav-dewav.$(OBJEXT) test_dewav_OBJECTS = $(am_test_dewav_OBJECTS) test_dewav_DEPENDENCIES = $(libburn_libburn_la_OBJECTS) \ $(am__DEPENDENCIES_2) am_test_fake_au_OBJECTS = test/test_fake_au-fake_au.$(OBJEXT) test_fake_au_OBJECTS = $(am_test_fake_au_OBJECTS) test_fake_au_DEPENDENCIES = am_test_libburner_OBJECTS = test/test_libburner-libburner.$(OBJEXT) test_libburner_OBJECTS = $(am_test_libburner_OBJECTS) test_libburner_DEPENDENCIES = $(libburn_libburn_la_OBJECTS) \ $(am__DEPENDENCIES_2) am_test_offst_source_OBJECTS = \ test/test_offst_source-offst_source.$(OBJEXT) test_offst_source_OBJECTS = $(am_test_offst_source_OBJECTS) test_offst_source_DEPENDENCIES = $(libburn_libburn_la_OBJECTS) \ $(am__DEPENDENCIES_2) am_test_poll_OBJECTS = test/test_poll-poll.$(OBJEXT) test_poll_OBJECTS = $(am_test_poll_OBJECTS) test_poll_DEPENDENCIES = $(libburn_libburn_la_OBJECTS) \ $(am__DEPENDENCIES_2) am_test_telltoc_OBJECTS = test/test_telltoc-telltoc.$(OBJEXT) test_telltoc_OBJECTS = $(am_test_telltoc_OBJECTS) test_telltoc_DEPENDENCIES = $(libburn_libburn_la_OBJECTS) \ $(am__DEPENDENCIES_2) AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libburn_libburn_la_SOURCES) $(cdrskin_cdrskin_SOURCES) \ $(test_dewav_SOURCES) $(test_fake_au_SOURCES) \ $(test_libburner_SOURCES) $(test_offst_source_SOURCES) \ $(test_poll_SOURCES) $(test_telltoc_SOURCES) DIST_SOURCES = $(libburn_libburn_la_SOURCES) \ $(cdrskin_cdrskin_SOURCES) $(test_dewav_SOURCES) \ $(test_fake_au_SOURCES) $(test_libburner_SOURCES) \ $(test_offst_source_SOURCES) $(test_poll_SOURCES) \ $(test_telltoc_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac man1dir = $(mandir)/man1 NROFF = nroff MANS = $(man_MANS) DATA = $(nodist_pkgconfig_DATA) HEADERS = $(libinclude_HEADERS) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags CSCOPE = cscope AM_RECURSIVE_TARGETS = cscope DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) distdir = $(PACKAGE)-$(VERSION) top_distdir = $(distdir) am__remove_distdir = \ if test -d "$(distdir)"; then \ find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \ && rm -rf "$(distdir)" \ || { sleep 5 && rm -rf "$(distdir)"; }; \ else :; fi am__post_remove_distdir = $(am__remove_distdir) DIST_ARCHIVES = $(distdir).tar.gz GZIP_ENV = --best DIST_TARGETS = dist-gzip distuninstallcheck_listfiles = find . -type f -print am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \ | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$' distcleancheck_listfiles = find . -type f -print ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ ARCH = @ARCH@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BURN_BINARY_AGE = @BURN_BINARY_AGE@ BURN_INTERFACE_AGE = @BURN_INTERFACE_AGE@ BURN_MAJOR_VERSION = @BURN_MAJOR_VERSION@ BURN_MICRO_VERSION = @BURN_MICRO_VERSION@ BURN_MINOR_VERSION = @BURN_MINOR_VERSION@ BURN_VERSION = @BURN_VERSION@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBBURNIA_LDCONFIG_CMD = @LIBBURNIA_LDCONFIG_CMD@ LIBBURNIA_PKGCONFDIR = @LIBBURNIA_PKGCONFDIR@ LIBBURN_ARCH_LIBS = @LIBBURN_ARCH_LIBS@ LIBCDIO_CFLAGS = @LIBCDIO_CFLAGS@ LIBCDIO_LIBS = @LIBCDIO_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIBTOOL_DEPS = @LIBTOOL_DEPS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_AGE = @LT_AGE@ LT_CURRENT = @LT_CURRENT@ LT_CURRENT_MINUS_AGE = @LT_CURRENT_MINUS_AGE@ LT_RELEASE = @LT_RELEASE@ LT_REVISION = @LT_REVISION@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ THREAD_LIBS = @THREAD_LIBS@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = $(DESTDIR)$(prefix)/share/doc/$(PACKAGE)-$(VERSION) dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ # ts A90315 : LIBBURNIA_PKGCONFDIR is defined OS specific in acinclude.m4 # was: pkgconfigdir=$(libdir)/pkgconfig pkgconfigdir = $(LIBBURNIA_PKGCONFDIR) libincludedir = $(includedir)/libburn lib_LTLIBRARIES = libburn/libburn.la ACLOCAL_AMFLAGS = -I ./ # Build libraries libburn_libburn_la_LDFLAGS = \ -version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE) # This causes undesired .o names # configure.ac appends -D options to variable CFLAG ### libburn_libburn_la_CFLAGS = $(LIBBURN_DVD_OBS_64K) libburn_libburn_la_LIBADD = $(LIBBURN_ARCH_LIBS) $(THREAD_LIBS) libburn_libburn_la_SOURCES = \ libburn/async.c \ libburn/async.h \ libburn/back_hacks.h \ libburn/cdtext.c \ libburn/cleanup.c \ libburn/cleanup.h \ libburn/crc.c \ libburn/crc.h \ libburn/debug.c \ libburn/debug.h \ libburn/drive.c \ libburn/drive.h \ libburn/ecma130ab.c \ libburn/ecma130ab.h \ libburn/error.h \ libburn/file.c \ libburn/file.h \ libburn/init.c \ libburn/init.h \ libburn/libburn.h \ libburn/libdax_audioxtr.h \ libburn/libdax_audioxtr.c \ libburn/libdax_msgs.h \ libburn/libdax_msgs.c \ libburn/mmc.c \ libburn/mmc.h \ libburn/null.c \ libburn/null.h \ libburn/options.c \ libburn/options.h \ libburn/os.h \ libburn/read.c \ libburn/read.h \ libburn/sbc.c \ libburn/sbc.h \ libburn/sector.c \ libburn/sector.h \ libburn/sg.c \ libburn/sg.h \ libburn/source.h \ libburn/source.c \ libburn/spc.c \ libburn/spc.h \ libburn/structure.c \ libburn/structure.h \ libburn/toc.c \ libburn/toc.h \ libburn/transport.h \ libburn/util.c \ libburn/util.h \ libburn/write.c \ libburn/write.h libinclude_HEADERS = \ libburn/libburn.h LIBBURN_EXTRALIBS = $(LIBBURN_ARCH_LIBS) $(THREAD_LIBS) test_libburner_CPPFLAGS = -Ilibburn test_libburner_LDADD = $(libburn_libburn_la_OBJECTS) $(LIBBURN_EXTRALIBS) test_libburner_SOURCES = test/libburner.c test_offst_source_CPPFLAGS = -Ilibburn test_offst_source_LDADD = $(libburn_libburn_la_OBJECTS) $(LIBBURN_EXTRALIBS) test_offst_source_SOURCES = test/offst_source.c test_telltoc_CPPFLAGS = -Ilibburn test_telltoc_LDADD = $(libburn_libburn_la_OBJECTS) $(LIBBURN_EXTRALIBS) test_telltoc_SOURCES = test/telltoc.c test_dewav_CPPFLAGS = -Ilibburn test_dewav_LDADD = $(libburn_libburn_la_OBJECTS) $(LIBBURN_EXTRALIBS) test_dewav_SOURCES = test/dewav.c test_fake_au_CPPFLAGS = test_fake_au_LDADD = test_fake_au_SOURCES = test/fake_au.c test_poll_CPPFLAGS = -Ilibburn test_poll_LDADD = $(libburn_libburn_la_OBJECTS) $(LIBBURN_EXTRALIBS) test_poll_SOURCES = test/poll.c cdrskin_cdrskin_CPPFLAGS = -Ilibburn cdrskin_cdrskin_CFLAGS = -DCdrskin_libburn_1_4_2 # cdrskin_cdrskin_LDADD = $(libburn_libburn_la_OBJECTS) $(LIBBURN_EXTRALIBS) # ts A80123, change proposed by Simon Huggins to cause dynamic libburn linking cdrskin_cdrskin_LDADD = libburn/libburn.la $(LIBBURN_EXTRALIBS) cdrskin_cdrskin_SOURCES = cdrskin/cdrskin.c cdrskin/cdrfifo.c cdrskin/cdrfifo.h cdrskin/cdrskin_timestamp.h webhost = http://libburn-api.pykix.org webpath = / # Indent source files indent_files = \ $(libburn_libburn_la_SOURCES) \ $(test_poll_SOURCES) # Extra things nodist_pkgconfig_DATA = \ libburn-1.pc # http://www.nada.kth.se/cgi-bin/info?(automake.info)Man%20pages man_MANS = cdrskin/cdrskin.1 EXTRA_DIST = \ bootstrap \ libburn-1.pc.in \ version.h.in \ doc/comments \ doc/doxygen.conf.in \ doc/cookbook.txt \ doc/mediainfo.txt \ doc/cdtext.txt \ README \ AUTHORS \ CONTRIBUTORS \ COPYRIGHT \ cdrskin/README \ cdrskin/cdrecord_spy.sh \ cdrskin/compile_cdrskin.sh \ cdrskin/convert_man_to_html.sh \ cdrskin/changelog.txt \ cdrskin/cdrskin_eng.html \ cdrskin/wiki_plain.txt \ cdrskin/cleanup.h \ cdrskin/cleanup.c \ libburn/libburn.ver \ libburn/os-dummy.h \ libburn/os-freebsd.h \ libburn/os-linux.h \ libburn/os-libcdio.h \ libburn/os-solaris.h \ libburn/os-netbsd.h \ libburn/sg-dummy.c \ libburn/sg-freebsd.c \ libburn/sg-linux.c \ libburn/sg-libcdio.c \ libburn/sg-solaris.c \ libburn/sg-netbsd.c \ COPYING \ NEWS \ ChangeLog \ INSTALL \ $(man_MANS) all: all-am .SUFFIXES: .SUFFIXES: .c .lo .o .obj am--refresh: Makefile @: $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ echo ' cd $(srcdir) && $(AUTOMAKE) --foreign'; \ $(am__cd) $(srcdir) && $(AUTOMAKE) --foreign \ && exit 0; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ echo ' $(SHELL) ./config.status'; \ $(SHELL) ./config.status;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) $(SHELL) ./config.status --recheck $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) $(am__cd) $(srcdir) && $(AUTOCONF) $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) $(am__aclocal_m4_deps): doc/doxygen.conf: $(top_builddir)/config.status $(top_srcdir)/doc/doxygen.conf.in cd $(top_builddir) && $(SHELL) ./config.status $@ version.h: $(top_builddir)/config.status $(srcdir)/version.h.in cd $(top_builddir) && $(SHELL) ./config.status $@ libburn-1.pc: $(top_builddir)/config.status $(srcdir)/libburn-1.pc.in cd $(top_builddir) && $(SHELL) ./config.status $@ install-libLTLIBRARIES: $(lib_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \ } uninstall-libLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \ done clean-libLTLIBRARIES: -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) @list='$(lib_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libburn/$(am__dirstamp): @$(MKDIR_P) libburn @: > libburn/$(am__dirstamp) libburn/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) libburn/$(DEPDIR) @: > libburn/$(DEPDIR)/$(am__dirstamp) libburn/async.lo: libburn/$(am__dirstamp) \ libburn/$(DEPDIR)/$(am__dirstamp) libburn/cdtext.lo: libburn/$(am__dirstamp) \ libburn/$(DEPDIR)/$(am__dirstamp) libburn/cleanup.lo: libburn/$(am__dirstamp) \ libburn/$(DEPDIR)/$(am__dirstamp) libburn/crc.lo: libburn/$(am__dirstamp) \ libburn/$(DEPDIR)/$(am__dirstamp) libburn/debug.lo: libburn/$(am__dirstamp) \ libburn/$(DEPDIR)/$(am__dirstamp) libburn/drive.lo: libburn/$(am__dirstamp) \ libburn/$(DEPDIR)/$(am__dirstamp) libburn/ecma130ab.lo: libburn/$(am__dirstamp) \ libburn/$(DEPDIR)/$(am__dirstamp) libburn/file.lo: libburn/$(am__dirstamp) \ libburn/$(DEPDIR)/$(am__dirstamp) libburn/init.lo: libburn/$(am__dirstamp) \ libburn/$(DEPDIR)/$(am__dirstamp) libburn/libdax_audioxtr.lo: libburn/$(am__dirstamp) \ libburn/$(DEPDIR)/$(am__dirstamp) libburn/libdax_msgs.lo: libburn/$(am__dirstamp) \ libburn/$(DEPDIR)/$(am__dirstamp) libburn/mmc.lo: libburn/$(am__dirstamp) \ libburn/$(DEPDIR)/$(am__dirstamp) libburn/null.lo: libburn/$(am__dirstamp) \ libburn/$(DEPDIR)/$(am__dirstamp) libburn/options.lo: libburn/$(am__dirstamp) \ libburn/$(DEPDIR)/$(am__dirstamp) libburn/read.lo: libburn/$(am__dirstamp) \ libburn/$(DEPDIR)/$(am__dirstamp) libburn/sbc.lo: libburn/$(am__dirstamp) \ libburn/$(DEPDIR)/$(am__dirstamp) libburn/sector.lo: libburn/$(am__dirstamp) \ libburn/$(DEPDIR)/$(am__dirstamp) libburn/sg.lo: libburn/$(am__dirstamp) \ libburn/$(DEPDIR)/$(am__dirstamp) libburn/source.lo: libburn/$(am__dirstamp) \ libburn/$(DEPDIR)/$(am__dirstamp) libburn/spc.lo: libburn/$(am__dirstamp) \ libburn/$(DEPDIR)/$(am__dirstamp) libburn/structure.lo: libburn/$(am__dirstamp) \ libburn/$(DEPDIR)/$(am__dirstamp) libburn/toc.lo: libburn/$(am__dirstamp) \ libburn/$(DEPDIR)/$(am__dirstamp) libburn/util.lo: libburn/$(am__dirstamp) \ libburn/$(DEPDIR)/$(am__dirstamp) libburn/write.lo: libburn/$(am__dirstamp) \ libburn/$(DEPDIR)/$(am__dirstamp) libburn/libburn.la: $(libburn_libburn_la_OBJECTS) $(libburn_libburn_la_DEPENDENCIES) $(EXTRA_libburn_libburn_la_DEPENDENCIES) libburn/$(am__dirstamp) $(AM_V_CCLD)$(libburn_libburn_la_LINK) -rpath $(libdir) $(libburn_libburn_la_OBJECTS) $(libburn_libburn_la_LIBADD) $(LIBS) install-binPROGRAMS: $(bin_PROGRAMS) @$(NORMAL_INSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ fi; \ for p in $$list; do echo "$$p $$p"; done | \ sed 's/$(EXEEXT)$$//' | \ while read p p1; do if test -f $$p \ || test -f $$p1 \ ; then echo "$$p"; echo "$$p"; else :; fi; \ done | \ sed -e 'p;s,.*/,,;n;h' \ -e 's|.*|.|' \ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ sed 'N;N;N;s,\n, ,g' | \ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ if ($$2 == $$4) files[d] = files[d] " " $$1; \ else { print "f", $$3 "/" $$4, $$1; } } \ END { for (d in files) print "f", d, files[d] }' | \ while read type dir files; do \ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ test -z "$$files" || { \ echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ } \ ; done uninstall-binPROGRAMS: @$(NORMAL_UNINSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ files=`for p in $$list; do echo "$$p"; done | \ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ -e 's/$$/$(EXEEXT)/' \ `; \ test -n "$$list" || exit 0; \ echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(bindir)" && rm -f $$files clean-binPROGRAMS: @list='$(bin_PROGRAMS)'; test -n "$$list" || exit 0; \ echo " rm -f" $$list; \ rm -f $$list || exit $$?; \ test -n "$(EXEEXT)" || exit 0; \ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ echo " rm -f" $$list; \ rm -f $$list clean-noinstPROGRAMS: @list='$(noinst_PROGRAMS)'; test -n "$$list" || exit 0; \ echo " rm -f" $$list; \ rm -f $$list || exit $$?; \ test -n "$(EXEEXT)" || exit 0; \ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ echo " rm -f" $$list; \ rm -f $$list cdrskin/$(am__dirstamp): @$(MKDIR_P) cdrskin @: > cdrskin/$(am__dirstamp) cdrskin/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) cdrskin/$(DEPDIR) @: > cdrskin/$(DEPDIR)/$(am__dirstamp) cdrskin/cdrskin_cdrskin-cdrskin.$(OBJEXT): cdrskin/$(am__dirstamp) \ cdrskin/$(DEPDIR)/$(am__dirstamp) cdrskin/cdrskin_cdrskin-cdrfifo.$(OBJEXT): cdrskin/$(am__dirstamp) \ cdrskin/$(DEPDIR)/$(am__dirstamp) cdrskin/cdrskin$(EXEEXT): $(cdrskin_cdrskin_OBJECTS) $(cdrskin_cdrskin_DEPENDENCIES) $(EXTRA_cdrskin_cdrskin_DEPENDENCIES) cdrskin/$(am__dirstamp) @rm -f cdrskin/cdrskin$(EXEEXT) $(AM_V_CCLD)$(cdrskin_cdrskin_LINK) $(cdrskin_cdrskin_OBJECTS) $(cdrskin_cdrskin_LDADD) $(LIBS) test/$(am__dirstamp): @$(MKDIR_P) test @: > test/$(am__dirstamp) test/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) test/$(DEPDIR) @: > test/$(DEPDIR)/$(am__dirstamp) test/test_dewav-dewav.$(OBJEXT): test/$(am__dirstamp) \ test/$(DEPDIR)/$(am__dirstamp) test/dewav$(EXEEXT): $(test_dewav_OBJECTS) $(test_dewav_DEPENDENCIES) $(EXTRA_test_dewav_DEPENDENCIES) test/$(am__dirstamp) @rm -f test/dewav$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_dewav_OBJECTS) $(test_dewav_LDADD) $(LIBS) test/test_fake_au-fake_au.$(OBJEXT): test/$(am__dirstamp) \ test/$(DEPDIR)/$(am__dirstamp) test/fake_au$(EXEEXT): $(test_fake_au_OBJECTS) $(test_fake_au_DEPENDENCIES) $(EXTRA_test_fake_au_DEPENDENCIES) test/$(am__dirstamp) @rm -f test/fake_au$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_fake_au_OBJECTS) $(test_fake_au_LDADD) $(LIBS) test/test_libburner-libburner.$(OBJEXT): test/$(am__dirstamp) \ test/$(DEPDIR)/$(am__dirstamp) test/libburner$(EXEEXT): $(test_libburner_OBJECTS) $(test_libburner_DEPENDENCIES) $(EXTRA_test_libburner_DEPENDENCIES) test/$(am__dirstamp) @rm -f test/libburner$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_libburner_OBJECTS) $(test_libburner_LDADD) $(LIBS) test/test_offst_source-offst_source.$(OBJEXT): test/$(am__dirstamp) \ test/$(DEPDIR)/$(am__dirstamp) test/offst_source$(EXEEXT): $(test_offst_source_OBJECTS) $(test_offst_source_DEPENDENCIES) $(EXTRA_test_offst_source_DEPENDENCIES) test/$(am__dirstamp) @rm -f test/offst_source$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_offst_source_OBJECTS) $(test_offst_source_LDADD) $(LIBS) test/test_poll-poll.$(OBJEXT): test/$(am__dirstamp) \ test/$(DEPDIR)/$(am__dirstamp) test/poll$(EXEEXT): $(test_poll_OBJECTS) $(test_poll_DEPENDENCIES) $(EXTRA_test_poll_DEPENDENCIES) test/$(am__dirstamp) @rm -f test/poll$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_poll_OBJECTS) $(test_poll_LDADD) $(LIBS) test/test_telltoc-telltoc.$(OBJEXT): test/$(am__dirstamp) \ test/$(DEPDIR)/$(am__dirstamp) test/telltoc$(EXEEXT): $(test_telltoc_OBJECTS) $(test_telltoc_DEPENDENCIES) $(EXTRA_test_telltoc_DEPENDENCIES) test/$(am__dirstamp) @rm -f test/telltoc$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_telltoc_OBJECTS) $(test_telltoc_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) -rm -f cdrskin/*.$(OBJEXT) -rm -f libburn/*.$(OBJEXT) -rm -f libburn/*.lo -rm -f test/*.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@cdrskin/$(DEPDIR)/cdrskin_cdrskin-cdrfifo.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@cdrskin/$(DEPDIR)/cdrskin_cdrskin-cdrskin.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@libburn/$(DEPDIR)/async.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@libburn/$(DEPDIR)/cdtext.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@libburn/$(DEPDIR)/cleanup.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@libburn/$(DEPDIR)/crc.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@libburn/$(DEPDIR)/debug.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@libburn/$(DEPDIR)/drive.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@libburn/$(DEPDIR)/ecma130ab.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@libburn/$(DEPDIR)/file.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@libburn/$(DEPDIR)/init.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@libburn/$(DEPDIR)/libdax_audioxtr.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@libburn/$(DEPDIR)/libdax_msgs.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@libburn/$(DEPDIR)/mmc.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@libburn/$(DEPDIR)/null.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@libburn/$(DEPDIR)/options.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@libburn/$(DEPDIR)/read.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@libburn/$(DEPDIR)/sbc.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@libburn/$(DEPDIR)/sector.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@libburn/$(DEPDIR)/sg.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@libburn/$(DEPDIR)/source.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@libburn/$(DEPDIR)/spc.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@libburn/$(DEPDIR)/structure.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@libburn/$(DEPDIR)/toc.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@libburn/$(DEPDIR)/util.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@libburn/$(DEPDIR)/write.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@test/$(DEPDIR)/test_dewav-dewav.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@test/$(DEPDIR)/test_fake_au-fake_au.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@test/$(DEPDIR)/test_libburner-libburner.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@test/$(DEPDIR)/test_offst_source-offst_source.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@test/$(DEPDIR)/test_poll-poll.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@test/$(DEPDIR)/test_telltoc-telltoc.Po@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< cdrskin/cdrskin_cdrskin-cdrskin.o: cdrskin/cdrskin.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdrskin_cdrskin_CPPFLAGS) $(CPPFLAGS) $(cdrskin_cdrskin_CFLAGS) $(CFLAGS) -MT cdrskin/cdrskin_cdrskin-cdrskin.o -MD -MP -MF cdrskin/$(DEPDIR)/cdrskin_cdrskin-cdrskin.Tpo -c -o cdrskin/cdrskin_cdrskin-cdrskin.o `test -f 'cdrskin/cdrskin.c' || echo '$(srcdir)/'`cdrskin/cdrskin.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cdrskin/$(DEPDIR)/cdrskin_cdrskin-cdrskin.Tpo cdrskin/$(DEPDIR)/cdrskin_cdrskin-cdrskin.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cdrskin/cdrskin.c' object='cdrskin/cdrskin_cdrskin-cdrskin.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdrskin_cdrskin_CPPFLAGS) $(CPPFLAGS) $(cdrskin_cdrskin_CFLAGS) $(CFLAGS) -c -o cdrskin/cdrskin_cdrskin-cdrskin.o `test -f 'cdrskin/cdrskin.c' || echo '$(srcdir)/'`cdrskin/cdrskin.c cdrskin/cdrskin_cdrskin-cdrskin.obj: cdrskin/cdrskin.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdrskin_cdrskin_CPPFLAGS) $(CPPFLAGS) $(cdrskin_cdrskin_CFLAGS) $(CFLAGS) -MT cdrskin/cdrskin_cdrskin-cdrskin.obj -MD -MP -MF cdrskin/$(DEPDIR)/cdrskin_cdrskin-cdrskin.Tpo -c -o cdrskin/cdrskin_cdrskin-cdrskin.obj `if test -f 'cdrskin/cdrskin.c'; then $(CYGPATH_W) 'cdrskin/cdrskin.c'; else $(CYGPATH_W) '$(srcdir)/cdrskin/cdrskin.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cdrskin/$(DEPDIR)/cdrskin_cdrskin-cdrskin.Tpo cdrskin/$(DEPDIR)/cdrskin_cdrskin-cdrskin.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cdrskin/cdrskin.c' object='cdrskin/cdrskin_cdrskin-cdrskin.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdrskin_cdrskin_CPPFLAGS) $(CPPFLAGS) $(cdrskin_cdrskin_CFLAGS) $(CFLAGS) -c -o cdrskin/cdrskin_cdrskin-cdrskin.obj `if test -f 'cdrskin/cdrskin.c'; then $(CYGPATH_W) 'cdrskin/cdrskin.c'; else $(CYGPATH_W) '$(srcdir)/cdrskin/cdrskin.c'; fi` cdrskin/cdrskin_cdrskin-cdrfifo.o: cdrskin/cdrfifo.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdrskin_cdrskin_CPPFLAGS) $(CPPFLAGS) $(cdrskin_cdrskin_CFLAGS) $(CFLAGS) -MT cdrskin/cdrskin_cdrskin-cdrfifo.o -MD -MP -MF cdrskin/$(DEPDIR)/cdrskin_cdrskin-cdrfifo.Tpo -c -o cdrskin/cdrskin_cdrskin-cdrfifo.o `test -f 'cdrskin/cdrfifo.c' || echo '$(srcdir)/'`cdrskin/cdrfifo.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cdrskin/$(DEPDIR)/cdrskin_cdrskin-cdrfifo.Tpo cdrskin/$(DEPDIR)/cdrskin_cdrskin-cdrfifo.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cdrskin/cdrfifo.c' object='cdrskin/cdrskin_cdrskin-cdrfifo.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdrskin_cdrskin_CPPFLAGS) $(CPPFLAGS) $(cdrskin_cdrskin_CFLAGS) $(CFLAGS) -c -o cdrskin/cdrskin_cdrskin-cdrfifo.o `test -f 'cdrskin/cdrfifo.c' || echo '$(srcdir)/'`cdrskin/cdrfifo.c cdrskin/cdrskin_cdrskin-cdrfifo.obj: cdrskin/cdrfifo.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdrskin_cdrskin_CPPFLAGS) $(CPPFLAGS) $(cdrskin_cdrskin_CFLAGS) $(CFLAGS) -MT cdrskin/cdrskin_cdrskin-cdrfifo.obj -MD -MP -MF cdrskin/$(DEPDIR)/cdrskin_cdrskin-cdrfifo.Tpo -c -o cdrskin/cdrskin_cdrskin-cdrfifo.obj `if test -f 'cdrskin/cdrfifo.c'; then $(CYGPATH_W) 'cdrskin/cdrfifo.c'; else $(CYGPATH_W) '$(srcdir)/cdrskin/cdrfifo.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) cdrskin/$(DEPDIR)/cdrskin_cdrskin-cdrfifo.Tpo cdrskin/$(DEPDIR)/cdrskin_cdrskin-cdrfifo.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cdrskin/cdrfifo.c' object='cdrskin/cdrskin_cdrskin-cdrfifo.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdrskin_cdrskin_CPPFLAGS) $(CPPFLAGS) $(cdrskin_cdrskin_CFLAGS) $(CFLAGS) -c -o cdrskin/cdrskin_cdrskin-cdrfifo.obj `if test -f 'cdrskin/cdrfifo.c'; then $(CYGPATH_W) 'cdrskin/cdrfifo.c'; else $(CYGPATH_W) '$(srcdir)/cdrskin/cdrfifo.c'; fi` test/test_dewav-dewav.o: test/dewav.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_dewav_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT test/test_dewav-dewav.o -MD -MP -MF test/$(DEPDIR)/test_dewav-dewav.Tpo -c -o test/test_dewav-dewav.o `test -f 'test/dewav.c' || echo '$(srcdir)/'`test/dewav.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) test/$(DEPDIR)/test_dewav-dewav.Tpo test/$(DEPDIR)/test_dewav-dewav.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='test/dewav.c' object='test/test_dewav-dewav.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_dewav_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o test/test_dewav-dewav.o `test -f 'test/dewav.c' || echo '$(srcdir)/'`test/dewav.c test/test_dewav-dewav.obj: test/dewav.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_dewav_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT test/test_dewav-dewav.obj -MD -MP -MF test/$(DEPDIR)/test_dewav-dewav.Tpo -c -o test/test_dewav-dewav.obj `if test -f 'test/dewav.c'; then $(CYGPATH_W) 'test/dewav.c'; else $(CYGPATH_W) '$(srcdir)/test/dewav.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) test/$(DEPDIR)/test_dewav-dewav.Tpo test/$(DEPDIR)/test_dewav-dewav.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='test/dewav.c' object='test/test_dewav-dewav.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_dewav_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o test/test_dewav-dewav.obj `if test -f 'test/dewav.c'; then $(CYGPATH_W) 'test/dewav.c'; else $(CYGPATH_W) '$(srcdir)/test/dewav.c'; fi` test/test_fake_au-fake_au.o: test/fake_au.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_fake_au_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT test/test_fake_au-fake_au.o -MD -MP -MF test/$(DEPDIR)/test_fake_au-fake_au.Tpo -c -o test/test_fake_au-fake_au.o `test -f 'test/fake_au.c' || echo '$(srcdir)/'`test/fake_au.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) test/$(DEPDIR)/test_fake_au-fake_au.Tpo test/$(DEPDIR)/test_fake_au-fake_au.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='test/fake_au.c' object='test/test_fake_au-fake_au.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_fake_au_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o test/test_fake_au-fake_au.o `test -f 'test/fake_au.c' || echo '$(srcdir)/'`test/fake_au.c test/test_fake_au-fake_au.obj: test/fake_au.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_fake_au_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT test/test_fake_au-fake_au.obj -MD -MP -MF test/$(DEPDIR)/test_fake_au-fake_au.Tpo -c -o test/test_fake_au-fake_au.obj `if test -f 'test/fake_au.c'; then $(CYGPATH_W) 'test/fake_au.c'; else $(CYGPATH_W) '$(srcdir)/test/fake_au.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) test/$(DEPDIR)/test_fake_au-fake_au.Tpo test/$(DEPDIR)/test_fake_au-fake_au.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='test/fake_au.c' object='test/test_fake_au-fake_au.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_fake_au_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o test/test_fake_au-fake_au.obj `if test -f 'test/fake_au.c'; then $(CYGPATH_W) 'test/fake_au.c'; else $(CYGPATH_W) '$(srcdir)/test/fake_au.c'; fi` test/test_libburner-libburner.o: test/libburner.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_libburner_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT test/test_libburner-libburner.o -MD -MP -MF test/$(DEPDIR)/test_libburner-libburner.Tpo -c -o test/test_libburner-libburner.o `test -f 'test/libburner.c' || echo '$(srcdir)/'`test/libburner.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) test/$(DEPDIR)/test_libburner-libburner.Tpo test/$(DEPDIR)/test_libburner-libburner.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='test/libburner.c' object='test/test_libburner-libburner.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_libburner_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o test/test_libburner-libburner.o `test -f 'test/libburner.c' || echo '$(srcdir)/'`test/libburner.c test/test_libburner-libburner.obj: test/libburner.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_libburner_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT test/test_libburner-libburner.obj -MD -MP -MF test/$(DEPDIR)/test_libburner-libburner.Tpo -c -o test/test_libburner-libburner.obj `if test -f 'test/libburner.c'; then $(CYGPATH_W) 'test/libburner.c'; else $(CYGPATH_W) '$(srcdir)/test/libburner.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) test/$(DEPDIR)/test_libburner-libburner.Tpo test/$(DEPDIR)/test_libburner-libburner.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='test/libburner.c' object='test/test_libburner-libburner.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_libburner_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o test/test_libburner-libburner.obj `if test -f 'test/libburner.c'; then $(CYGPATH_W) 'test/libburner.c'; else $(CYGPATH_W) '$(srcdir)/test/libburner.c'; fi` test/test_offst_source-offst_source.o: test/offst_source.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_offst_source_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT test/test_offst_source-offst_source.o -MD -MP -MF test/$(DEPDIR)/test_offst_source-offst_source.Tpo -c -o test/test_offst_source-offst_source.o `test -f 'test/offst_source.c' || echo '$(srcdir)/'`test/offst_source.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) test/$(DEPDIR)/test_offst_source-offst_source.Tpo test/$(DEPDIR)/test_offst_source-offst_source.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='test/offst_source.c' object='test/test_offst_source-offst_source.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_offst_source_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o test/test_offst_source-offst_source.o `test -f 'test/offst_source.c' || echo '$(srcdir)/'`test/offst_source.c test/test_offst_source-offst_source.obj: test/offst_source.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_offst_source_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT test/test_offst_source-offst_source.obj -MD -MP -MF test/$(DEPDIR)/test_offst_source-offst_source.Tpo -c -o test/test_offst_source-offst_source.obj `if test -f 'test/offst_source.c'; then $(CYGPATH_W) 'test/offst_source.c'; else $(CYGPATH_W) '$(srcdir)/test/offst_source.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) test/$(DEPDIR)/test_offst_source-offst_source.Tpo test/$(DEPDIR)/test_offst_source-offst_source.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='test/offst_source.c' object='test/test_offst_source-offst_source.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_offst_source_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o test/test_offst_source-offst_source.obj `if test -f 'test/offst_source.c'; then $(CYGPATH_W) 'test/offst_source.c'; else $(CYGPATH_W) '$(srcdir)/test/offst_source.c'; fi` test/test_poll-poll.o: test/poll.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_poll_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT test/test_poll-poll.o -MD -MP -MF test/$(DEPDIR)/test_poll-poll.Tpo -c -o test/test_poll-poll.o `test -f 'test/poll.c' || echo '$(srcdir)/'`test/poll.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) test/$(DEPDIR)/test_poll-poll.Tpo test/$(DEPDIR)/test_poll-poll.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='test/poll.c' object='test/test_poll-poll.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_poll_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o test/test_poll-poll.o `test -f 'test/poll.c' || echo '$(srcdir)/'`test/poll.c test/test_poll-poll.obj: test/poll.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_poll_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT test/test_poll-poll.obj -MD -MP -MF test/$(DEPDIR)/test_poll-poll.Tpo -c -o test/test_poll-poll.obj `if test -f 'test/poll.c'; then $(CYGPATH_W) 'test/poll.c'; else $(CYGPATH_W) '$(srcdir)/test/poll.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) test/$(DEPDIR)/test_poll-poll.Tpo test/$(DEPDIR)/test_poll-poll.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='test/poll.c' object='test/test_poll-poll.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_poll_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o test/test_poll-poll.obj `if test -f 'test/poll.c'; then $(CYGPATH_W) 'test/poll.c'; else $(CYGPATH_W) '$(srcdir)/test/poll.c'; fi` test/test_telltoc-telltoc.o: test/telltoc.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_telltoc_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT test/test_telltoc-telltoc.o -MD -MP -MF test/$(DEPDIR)/test_telltoc-telltoc.Tpo -c -o test/test_telltoc-telltoc.o `test -f 'test/telltoc.c' || echo '$(srcdir)/'`test/telltoc.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) test/$(DEPDIR)/test_telltoc-telltoc.Tpo test/$(DEPDIR)/test_telltoc-telltoc.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='test/telltoc.c' object='test/test_telltoc-telltoc.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_telltoc_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o test/test_telltoc-telltoc.o `test -f 'test/telltoc.c' || echo '$(srcdir)/'`test/telltoc.c test/test_telltoc-telltoc.obj: test/telltoc.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_telltoc_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT test/test_telltoc-telltoc.obj -MD -MP -MF test/$(DEPDIR)/test_telltoc-telltoc.Tpo -c -o test/test_telltoc-telltoc.obj `if test -f 'test/telltoc.c'; then $(CYGPATH_W) 'test/telltoc.c'; else $(CYGPATH_W) '$(srcdir)/test/telltoc.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) test/$(DEPDIR)/test_telltoc-telltoc.Tpo test/$(DEPDIR)/test_telltoc-telltoc.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='test/telltoc.c' object='test/test_telltoc-telltoc.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_telltoc_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o test/test_telltoc-telltoc.obj `if test -f 'test/telltoc.c'; then $(CYGPATH_W) 'test/telltoc.c'; else $(CYGPATH_W) '$(srcdir)/test/telltoc.c'; fi` mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs -rm -rf cdrskin/.libs cdrskin/_libs -rm -rf libburn/.libs libburn/_libs -rm -rf test/.libs test/_libs distclean-libtool: -rm -f libtool config.lt install-man1: $(man_MANS) @$(NORMAL_INSTALL) @list1=''; \ list2='$(man_MANS)'; \ test -n "$(man1dir)" \ && test -n "`echo $$list1$$list2`" \ || exit 0; \ echo " $(MKDIR_P) '$(DESTDIR)$(man1dir)'"; \ $(MKDIR_P) "$(DESTDIR)$(man1dir)" || exit 1; \ { for i in $$list1; do echo "$$i"; done; \ if test -n "$$list2"; then \ for i in $$list2; do echo "$$i"; done \ | sed -n '/\.1[a-z]*$$/p'; \ fi; \ } | while read p; do \ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; echo "$$p"; \ done | \ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \ sed 'N;N;s,\n, ,g' | { \ list=; while read file base inst; do \ if test "$$base" = "$$inst"; then list="$$list $$file"; else \ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man1dir)/$$inst'"; \ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man1dir)/$$inst" || exit $$?; \ fi; \ done; \ for i in $$list; do echo "$$i"; done | $(am__base_list) | \ while read files; do \ test -z "$$files" || { \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man1dir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(man1dir)" || exit $$?; }; \ done; } uninstall-man1: @$(NORMAL_UNINSTALL) @list=''; test -n "$(man1dir)" || exit 0; \ files=`{ for i in $$list; do echo "$$i"; done; \ l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \ sed -n '/\.1[a-z]*$$/p'; \ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ dir='$(DESTDIR)$(man1dir)'; $(am__uninstall_files_from_dir) install-nodist_pkgconfigDATA: $(nodist_pkgconfig_DATA) @$(NORMAL_INSTALL) @list='$(nodist_pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(pkgconfigdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(pkgconfigdir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pkgconfigdir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(pkgconfigdir)" || exit $$?; \ done uninstall-nodist_pkgconfigDATA: @$(NORMAL_UNINSTALL) @list='$(nodist_pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(pkgconfigdir)'; $(am__uninstall_files_from_dir) install-libincludeHEADERS: $(libinclude_HEADERS) @$(NORMAL_INSTALL) @list='$(libinclude_HEADERS)'; test -n "$(libincludedir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(libincludedir)'"; \ $(MKDIR_P) "$(DESTDIR)$(libincludedir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(libincludedir)'"; \ $(INSTALL_HEADER) $$files "$(DESTDIR)$(libincludedir)" || exit $$?; \ done uninstall-libincludeHEADERS: @$(NORMAL_UNINSTALL) @list='$(libinclude_HEADERS)'; test -n "$(libincludedir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(libincludedir)'; $(am__uninstall_files_from_dir) ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscope: cscope.files test ! -s cscope.files \ || $(CSCOPE) -b -q $(AM_CSCOPEFLAGS) $(CSCOPEFLAGS) -i cscope.files $(CSCOPE_ARGS) clean-cscope: -rm -f cscope.files cscope.files: clean-cscope cscopelist cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags -rm -f cscope.out cscope.in.out cscope.po.out cscope.files distdir: $(DISTFILES) $(am__remove_distdir) test -d "$(distdir)" || mkdir "$(distdir)" @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done -test -n "$(am__skip_mode_fix)" \ || find "$(distdir)" -type d ! -perm -755 \ -exec chmod u+rwx,go+rx {} \; -o \ ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \ || chmod -R a+r "$(distdir)" dist-gzip: distdir tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz $(am__post_remove_distdir) dist-bzip2: distdir tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2 $(am__post_remove_distdir) dist-lzip: distdir tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz $(am__post_remove_distdir) dist-xz: distdir tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz $(am__post_remove_distdir) dist-tarZ: distdir @echo WARNING: "Support for shar distribution archives is" \ "deprecated." >&2 @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z $(am__post_remove_distdir) dist-shar: distdir @echo WARNING: "Support for distribution archives compressed with" \ "legacy program 'compress' is deprecated." >&2 @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz $(am__post_remove_distdir) dist-zip: distdir -rm -f $(distdir).zip zip -rq $(distdir).zip $(distdir) $(am__post_remove_distdir) dist dist-all: $(MAKE) $(AM_MAKEFLAGS) $(DIST_TARGETS) am__post_remove_distdir='@:' $(am__post_remove_distdir) # This target untars the dist file and tries a VPATH configuration. Then # it guarantees that the distribution is self-contained by making another # tarfile. distcheck: dist case '$(DIST_ARCHIVES)' in \ *.tar.gz*) \ GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\ *.tar.bz2*) \ bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\ *.tar.lz*) \ lzip -dc $(distdir).tar.lz | $(am__untar) ;;\ *.tar.xz*) \ xz -dc $(distdir).tar.xz | $(am__untar) ;;\ *.tar.Z*) \ uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ *.shar.gz*) \ GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\ *.zip*) \ unzip $(distdir).zip ;;\ esac chmod -R a-w $(distdir) chmod u+w $(distdir) mkdir $(distdir)/_build $(distdir)/_inst chmod a-w $(distdir) test -d $(distdir)/_build || exit 0; \ dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ && am__cwd=`pwd` \ && $(am__cd) $(distdir)/_build \ && ../configure \ $(AM_DISTCHECK_CONFIGURE_FLAGS) \ $(DISTCHECK_CONFIGURE_FLAGS) \ --srcdir=.. --prefix="$$dc_install_base" \ && $(MAKE) $(AM_MAKEFLAGS) \ && $(MAKE) $(AM_MAKEFLAGS) dvi \ && $(MAKE) $(AM_MAKEFLAGS) check \ && $(MAKE) $(AM_MAKEFLAGS) install \ && $(MAKE) $(AM_MAKEFLAGS) installcheck \ && $(MAKE) $(AM_MAKEFLAGS) uninstall \ && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \ distuninstallcheck \ && chmod -R a-w "$$dc_install_base" \ && ({ \ (cd ../.. && umask 077 && mkdir "$$dc_destdir") \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \ distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \ } || { rm -rf "$$dc_destdir"; exit 1; }) \ && rm -rf "$$dc_destdir" \ && $(MAKE) $(AM_MAKEFLAGS) dist \ && rm -rf $(DIST_ARCHIVES) \ && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \ && cd "$$am__cwd" \ || exit 1 $(am__post_remove_distdir) @(echo "$(distdir) archives ready for distribution: "; \ list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x' distuninstallcheck: @test -n '$(distuninstallcheck_dir)' || { \ echo 'ERROR: trying to run $@ with an empty' \ '$$(distuninstallcheck_dir)' >&2; \ exit 1; \ }; \ $(am__cd) '$(distuninstallcheck_dir)' || { \ echo 'ERROR: cannot chdir into $(distuninstallcheck_dir)' >&2; \ exit 1; \ }; \ test `$(am__distuninstallcheck_listfiles) | wc -l` -eq 0 \ || { echo "ERROR: files left after uninstall:" ; \ if test -n "$(DESTDIR)"; then \ echo " (check DESTDIR support)"; \ fi ; \ $(distuninstallcheck_listfiles) ; \ exit 1; } >&2 distcleancheck: distclean @if test '$(srcdir)' = . ; then \ echo "ERROR: distcleancheck can only run from a VPATH build" ; \ exit 1 ; \ fi @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \ || { echo "ERROR: files left in build directory after distclean:" ; \ $(distcleancheck_listfiles) ; \ exit 1; } >&2 check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) $(PROGRAMS) $(MANS) $(DATA) $(HEADERS) install-binPROGRAMS: install-libLTLIBRARIES installdirs: for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)" "$(DESTDIR)$(pkgconfigdir)" "$(DESTDIR)$(libincludedir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) -rm -f cdrskin/$(DEPDIR)/$(am__dirstamp) -rm -f cdrskin/$(am__dirstamp) -rm -f libburn/$(DEPDIR)/$(am__dirstamp) -rm -f libburn/$(am__dirstamp) -rm -f test/$(DEPDIR)/$(am__dirstamp) -rm -f test/$(am__dirstamp) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-binPROGRAMS clean-generic clean-libLTLIBRARIES \ clean-libtool clean-local clean-noinstPROGRAMS mostlyclean-am distclean: distclean-am -rm -f $(am__CONFIG_DISTCLEAN_FILES) -rm -rf cdrskin/$(DEPDIR) libburn/$(DEPDIR) test/$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-libtool distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-data-local install-libincludeHEADERS \ install-man install-nodist_pkgconfigDATA install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-binPROGRAMS install-libLTLIBRARIES @$(NORMAL_INSTALL) $(MAKE) $(AM_MAKEFLAGS) install-exec-hook install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-man1 install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f $(am__CONFIG_DISTCLEAN_FILES) -rm -rf $(top_srcdir)/autom4te.cache -rm -rf cdrskin/$(DEPDIR) libburn/$(DEPDIR) test/$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-binPROGRAMS uninstall-libLTLIBRARIES \ uninstall-libincludeHEADERS uninstall-local uninstall-man \ uninstall-nodist_pkgconfigDATA uninstall-man: uninstall-man1 .MAKE: install-am install-exec-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am am--refresh check check-am clean \ clean-binPROGRAMS clean-cscope clean-generic \ clean-libLTLIBRARIES clean-libtool clean-local \ clean-noinstPROGRAMS cscope cscopelist-am ctags ctags-am dist \ dist-all dist-bzip2 dist-gzip dist-lzip dist-shar dist-tarZ \ dist-xz dist-zip distcheck distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags \ distcleancheck distdir distuninstallcheck dvi dvi-am html \ html-am info info-am install install-am install-binPROGRAMS \ install-data install-data-am install-data-local install-dvi \ install-dvi-am install-exec install-exec-am install-exec-hook \ install-html install-html-am install-info install-info-am \ install-libLTLIBRARIES install-libincludeHEADERS install-man \ install-man1 install-nodist_pkgconfigDATA install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am uninstall-binPROGRAMS \ uninstall-libLTLIBRARIES uninstall-libincludeHEADERS \ uninstall-local uninstall-man uninstall-man1 \ uninstall-nodist_pkgconfigDATA install-exec-hook: $(LIBBURNIA_LDCONFIG_CMD) "$(DESTDIR)$(libdir)" || echo 'NOTE: Explicit dynamic library configuration failed. If needed, configure manually for:' "$(DESTDIR)$(libdir)" # "make clean" shall remove a few stubborn .libs directories # which George Danchev reported Dec 03 2011. # Learned from: http://www.gnu.org/software/automake/manual/automake.html#Clean clean-local: -rm -rf cdrskin/.libs test/.libs doc: doc/html doc/html: doc/doxygen.conf if [ -f ./doc/doc.lock ]; then \ $(RM) -r doc/html; \ doxygen doc/doxygen.conf; \ fi doc-upload: doc/html scp -r $. # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that # program. This Exception is an additional permission under section 7 # of the GNU General Public License, version 3 ("GPLv3"). # # Originally written by Per Bothner. # # You can get the latest version of this script from: # http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD # # Please send patches with a ChangeLog entry to config-patches@gnu.org. me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] Output the configuration name of the system \`$me' is run on. Operation modes: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit Report bugs and patches to ." version="\ GNU config.guess ($timestamp) Originally written by Per Bothner. Copyright 1992-2014 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" Try \`$me --help' for more information." # Parse command line while test $# -gt 0 ; do case $1 in --time-stamp | --time* | -t ) echo "$timestamp" ; exit ;; --version | -v ) echo "$version" ; exit ;; --help | --h* | -h ) echo "$usage"; exit ;; -- ) # Stop option processing shift; break ;; - ) # Use stdin as input. break ;; -* ) echo "$me: invalid option $1$help" >&2 exit 1 ;; * ) break ;; esac done if test $# != 0; then echo "$me: too many arguments$help" >&2 exit 1 fi trap 'exit 1' 1 2 15 # CC_FOR_BUILD -- compiler used by this script. Note that the use of a # compiler to aid in system detection is discouraged as it requires # temporary files to be created and, as you can see below, it is a # headache to deal with in a portable fashion. # Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still # use `HOST_CC' if defined, but it is deprecated. # Portable tmp directory creation inspired by the Autoconf team. set_cc_for_build=' trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; : ${TMPDIR=/tmp} ; { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; dummy=$tmp/dummy ; tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; case $CC_FOR_BUILD,$HOST_CC,$CC in ,,) echo "int x;" > $dummy.c ; for c in cc gcc c89 c99 ; do if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then CC_FOR_BUILD="$c"; break ; fi ; done ; if test x"$CC_FOR_BUILD" = x ; then CC_FOR_BUILD=no_compiler_found ; fi ;; ,,*) CC_FOR_BUILD=$CC ;; ,*,*) CC_FOR_BUILD=$HOST_CC ;; esac ; set_cc_for_build= ;' # This is needed to find uname on a Pyramid OSx when run in the BSD universe. # (ghazi@noc.rutgers.edu 1994-08-24) if (test -f /.attbin/uname) >/dev/null 2>&1 ; then PATH=$PATH:/.attbin ; export PATH fi UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown case "${UNAME_SYSTEM}" in Linux|GNU|GNU/*) # If the system lacks a compiler, then just pick glibc. # We could probably try harder. LIBC=gnu eval $set_cc_for_build cat <<-EOF > $dummy.c #include #if defined(__UCLIBC__) LIBC=uclibc #elif defined(__dietlibc__) LIBC=dietlibc #else LIBC=gnu #endif EOF eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC' | sed 's, ,,g'` ;; esac # Note: order is significant - the case branches are not exclusive. case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in *:NetBSD:*:*) # NetBSD (nbsd) targets should (where applicable) match one or # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*, # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently # switched to ELF, *-*-netbsd* would select the old # object file format. This provides both forward # compatibility and a consistent mechanism for selecting the # object file format. # # Note: NetBSD doesn't particularly care about the vendor # portion of the name. We always set it to "unknown". sysctl="sysctl -n hw.machine_arch" UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ /usr/sbin/$sysctl 2>/dev/null || echo unknown)` case "${UNAME_MACHINE_ARCH}" in armeb) machine=armeb-unknown ;; arm*) machine=arm-unknown ;; sh3el) machine=shl-unknown ;; sh3eb) machine=sh-unknown ;; sh5el) machine=sh5le-unknown ;; *) machine=${UNAME_MACHINE_ARCH}-unknown ;; esac # The Operating System including object format, if it has switched # to ELF recently, or will in the future. case "${UNAME_MACHINE_ARCH}" in arm*|i386|m68k|ns32k|sh3*|sparc|vax) eval $set_cc_for_build if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ELF__ then # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). # Return netbsd for either. FIX? os=netbsd else os=netbsdelf fi ;; *) os=netbsd ;; esac # The OS release # Debian GNU/NetBSD machines have a different userland, and # thus, need a distinct triplet. However, they do not need # kernel version information, so it can be replaced with a # suitable tag, in the style of linux-gnu. case "${UNAME_VERSION}" in Debian*) release='-gnu' ;; *) release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` ;; esac # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: # contains redundant information, the shorter form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. echo "${machine}-${os}${release}" exit ;; *:Bitrig:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'` echo ${UNAME_MACHINE_ARCH}-unknown-bitrig${UNAME_RELEASE} exit ;; *:OpenBSD:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} exit ;; *:ekkoBSD:*:*) echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} exit ;; *:SolidBSD:*:*) echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE} exit ;; macppc:MirBSD:*:*) echo powerpc-unknown-mirbsd${UNAME_RELEASE} exit ;; *:MirBSD:*:*) echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} exit ;; alpha:OSF1:*:*) case $UNAME_RELEASE in *4.0) UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` ;; *5.*) UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` ;; esac # According to Compaq, /usr/sbin/psrinfo has been available on # OSF/1 and Tru64 systems produced since 1995. I hope that # covers most systems running today. This code pipes the CPU # types through head -n 1, so we only detect the type of CPU 0. ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` case "$ALPHA_CPU_TYPE" in "EV4 (21064)") UNAME_MACHINE="alpha" ;; "EV4.5 (21064)") UNAME_MACHINE="alpha" ;; "LCA4 (21066/21068)") UNAME_MACHINE="alpha" ;; "EV5 (21164)") UNAME_MACHINE="alphaev5" ;; "EV5.6 (21164A)") UNAME_MACHINE="alphaev56" ;; "EV5.6 (21164PC)") UNAME_MACHINE="alphapca56" ;; "EV5.7 (21164PC)") UNAME_MACHINE="alphapca57" ;; "EV6 (21264)") UNAME_MACHINE="alphaev6" ;; "EV6.7 (21264A)") UNAME_MACHINE="alphaev67" ;; "EV6.8CB (21264C)") UNAME_MACHINE="alphaev68" ;; "EV6.8AL (21264B)") UNAME_MACHINE="alphaev68" ;; "EV6.8CX (21264D)") UNAME_MACHINE="alphaev68" ;; "EV6.9A (21264/EV69A)") UNAME_MACHINE="alphaev69" ;; "EV7 (21364)") UNAME_MACHINE="alphaev7" ;; "EV7.9 (21364A)") UNAME_MACHINE="alphaev79" ;; esac # A Pn.n version is a patched version. # A Vn.n version is a released version. # A Tn.n version is a released field test version. # A Xn.n version is an unreleased experimental baselevel. # 1.2 uses "1.2" for uname -r. echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` # Reset EXIT trap before exiting to avoid spurious non-zero exit code. exitcode=$? trap '' 0 exit $exitcode ;; Alpha\ *:Windows_NT*:*) # How do we know it's Interix rather than the generic POSIX subsystem? # Should we change UNAME_MACHINE based on the output of uname instead # of the specific Alpha model? echo alpha-pc-interix exit ;; 21064:Windows_NT:50:3) echo alpha-dec-winnt3.5 exit ;; Amiga*:UNIX_System_V:4.0:*) echo m68k-unknown-sysv4 exit ;; *:[Aa]miga[Oo][Ss]:*:*) echo ${UNAME_MACHINE}-unknown-amigaos exit ;; *:[Mm]orph[Oo][Ss]:*:*) echo ${UNAME_MACHINE}-unknown-morphos exit ;; *:OS/390:*:*) echo i370-ibm-openedition exit ;; *:z/VM:*:*) echo s390-ibm-zvmoe exit ;; *:OS400:*:*) echo powerpc-ibm-os400 exit ;; arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) echo arm-acorn-riscix${UNAME_RELEASE} exit ;; arm*:riscos:*:*|arm*:RISCOS:*:*) echo arm-unknown-riscos exit ;; SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) echo hppa1.1-hitachi-hiuxmpp exit ;; Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. if test "`(/bin/universe) 2>/dev/null`" = att ; then echo pyramid-pyramid-sysv3 else echo pyramid-pyramid-bsd fi exit ;; NILE*:*:*:dcosx) echo pyramid-pyramid-svr4 exit ;; DRS?6000:unix:4.0:6*) echo sparc-icl-nx6 exit ;; DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) case `/usr/bin/uname -p` in sparc) echo sparc-icl-nx7; exit ;; esac ;; s390x:SunOS:*:*) echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4H:SunOS:5.*:*) echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) echo i386-pc-auroraux${UNAME_RELEASE} exit ;; i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) eval $set_cc_for_build SUN_ARCH="i386" # If there is a compiler, see if it is configured for 64-bit objects. # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. # This test works for both compilers. if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ grep IS_64BIT_ARCH >/dev/null then SUN_ARCH="x86_64" fi fi echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:6*:*) # According to config.sub, this is the proper way to canonicalize # SunOS6. Hard to guess exactly what SunOS6 will be like, but # it's likely to be more like Solaris than SunOS4. echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:*:*) case "`/usr/bin/arch -k`" in Series*|S4*) UNAME_RELEASE=`uname -v` ;; esac # Japanese Language versions have a version number like `4.1.3-JL'. echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` exit ;; sun3*:SunOS:*:*) echo m68k-sun-sunos${UNAME_RELEASE} exit ;; sun*:*:4.2BSD:*) UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 case "`/bin/arch`" in sun3) echo m68k-sun-sunos${UNAME_RELEASE} ;; sun4) echo sparc-sun-sunos${UNAME_RELEASE} ;; esac exit ;; aushp:SunOS:*:*) echo sparc-auspex-sunos${UNAME_RELEASE} exit ;; # The situation for MiNT is a little confusing. The machine name # can be virtually everything (everything which is not # "atarist" or "atariste" at least should have a processor # > m68000). The system name ranges from "MiNT" over "FreeMiNT" # to the lowercase version "mint" (or "freemint"). Finally # the system name "TOS" denotes a system which is actually not # MiNT. But MiNT is downward compatible to TOS, so this should # be no problem. atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit ;; atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit ;; *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit ;; milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) echo m68k-milan-mint${UNAME_RELEASE} exit ;; hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) echo m68k-hades-mint${UNAME_RELEASE} exit ;; *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) echo m68k-unknown-mint${UNAME_RELEASE} exit ;; m68k:machten:*:*) echo m68k-apple-machten${UNAME_RELEASE} exit ;; powerpc:machten:*:*) echo powerpc-apple-machten${UNAME_RELEASE} exit ;; RISC*:Mach:*:*) echo mips-dec-mach_bsd4.3 exit ;; RISC*:ULTRIX:*:*) echo mips-dec-ultrix${UNAME_RELEASE} exit ;; VAX*:ULTRIX*:*:*) echo vax-dec-ultrix${UNAME_RELEASE} exit ;; 2020:CLIX:*:* | 2430:CLIX:*:*) echo clipper-intergraph-clix${UNAME_RELEASE} exit ;; mips:*:*:UMIPS | mips:*:*:RISCos) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #ifdef __cplusplus #include /* for printf() prototype */ int main (int argc, char *argv[]) { #else int main (argc, argv) int argc; char *argv[]; { #endif #if defined (host_mips) && defined (MIPSEB) #if defined (SYSTYPE_SYSV) printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_SVR4) printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); #endif #endif exit (-1); } EOF $CC_FOR_BUILD -o $dummy $dummy.c && dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` && SYSTEM_NAME=`$dummy $dummyarg` && { echo "$SYSTEM_NAME"; exit; } echo mips-mips-riscos${UNAME_RELEASE} exit ;; Motorola:PowerMAX_OS:*:*) echo powerpc-motorola-powermax exit ;; Motorola:*:4.3:PL8-*) echo powerpc-harris-powermax exit ;; Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) echo powerpc-harris-powermax exit ;; Night_Hawk:Power_UNIX:*:*) echo powerpc-harris-powerunix exit ;; m88k:CX/UX:7*:*) echo m88k-harris-cxux7 exit ;; m88k:*:4*:R4*) echo m88k-motorola-sysv4 exit ;; m88k:*:3*:R3*) echo m88k-motorola-sysv3 exit ;; AViiON:dgux:*:*) # DG/UX returns AViiON for all architectures UNAME_PROCESSOR=`/usr/bin/uname -p` if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] then if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ [ ${TARGET_BINARY_INTERFACE}x = x ] then echo m88k-dg-dgux${UNAME_RELEASE} else echo m88k-dg-dguxbcs${UNAME_RELEASE} fi else echo i586-dg-dgux${UNAME_RELEASE} fi exit ;; M88*:DolphinOS:*:*) # DolphinOS (SVR3) echo m88k-dolphin-sysv3 exit ;; M88*:*:R3*:*) # Delta 88k system running SVR3 echo m88k-motorola-sysv3 exit ;; XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) echo m88k-tektronix-sysv3 exit ;; Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) echo m68k-tektronix-bsd exit ;; *:IRIX*:*:*) echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` exit ;; ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' i*86:AIX:*:*) echo i386-ibm-aix exit ;; ia64:AIX:*:*) if [ -x /usr/bin/oslevel ] ; then IBM_REV=`/usr/bin/oslevel` else IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} fi echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} exit ;; *:AIX:2:3) if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #include main() { if (!__power_pc()) exit(1); puts("powerpc-ibm-aix3.2.5"); exit(0); } EOF if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` then echo "$SYSTEM_NAME" else echo rs6000-ibm-aix3.2.5 fi elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then echo rs6000-ibm-aix3.2.4 else echo rs6000-ibm-aix3.2 fi exit ;; *:AIX:*:[4567]) IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then IBM_ARCH=rs6000 else IBM_ARCH=powerpc fi if [ -x /usr/bin/oslevel ] ; then IBM_REV=`/usr/bin/oslevel` else IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} fi echo ${IBM_ARCH}-ibm-aix${IBM_REV} exit ;; *:AIX:*:*) echo rs6000-ibm-aix exit ;; ibmrt:4.4BSD:*|romp-ibm:BSD:*) echo romp-ibm-bsd4.4 exit ;; ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to exit ;; # report: romp-ibm BSD 4.3 *:BOSX:*:*) echo rs6000-bull-bosx exit ;; DPX/2?00:B.O.S.:*:*) echo m68k-bull-sysv3 exit ;; 9000/[34]??:4.3bsd:1.*:*) echo m68k-hp-bsd exit ;; hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) echo m68k-hp-bsd4.4 exit ;; 9000/[34678]??:HP-UX:*:*) HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` case "${UNAME_MACHINE}" in 9000/31? ) HP_ARCH=m68000 ;; 9000/[34]?? ) HP_ARCH=m68k ;; 9000/[678][0-9][0-9]) if [ -x /usr/bin/getconf ]; then sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` case "${sc_cpu_version}" in 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 532) # CPU_PA_RISC2_0 case "${sc_kernel_bits}" in 32) HP_ARCH="hppa2.0n" ;; 64) HP_ARCH="hppa2.0w" ;; '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 esac ;; esac fi if [ "${HP_ARCH}" = "" ]; then eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #define _HPUX_SOURCE #include #include int main () { #if defined(_SC_KERNEL_BITS) long bits = sysconf(_SC_KERNEL_BITS); #endif long cpu = sysconf (_SC_CPU_VERSION); switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0"); break; case CPU_PA_RISC1_1: puts ("hppa1.1"); break; case CPU_PA_RISC2_0: #if defined(_SC_KERNEL_BITS) switch (bits) { case 64: puts ("hppa2.0w"); break; case 32: puts ("hppa2.0n"); break; default: puts ("hppa2.0"); break; } break; #else /* !defined(_SC_KERNEL_BITS) */ puts ("hppa2.0"); break; #endif default: puts ("hppa1.0"); break; } exit (0); } EOF (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` test -z "$HP_ARCH" && HP_ARCH=hppa fi ;; esac if [ ${HP_ARCH} = "hppa2.0w" ] then eval $set_cc_for_build # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler # generating 64-bit code. GNU and HP use different nomenclature: # # $ CC_FOR_BUILD=cc ./config.guess # => hppa2.0w-hp-hpux11.23 # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess # => hppa64-hp-hpux11.23 if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | grep -q __LP64__ then HP_ARCH="hppa2.0w" else HP_ARCH="hppa64" fi fi echo ${HP_ARCH}-hp-hpux${HPUX_REV} exit ;; ia64:HP-UX:*:*) HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` echo ia64-hp-hpux${HPUX_REV} exit ;; 3050*:HI-UX:*:*) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #include int main () { long cpu = sysconf (_SC_CPU_VERSION); /* The order matters, because CPU_IS_HP_MC68K erroneously returns true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct results, however. */ if (CPU_IS_PA_RISC (cpu)) { switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; default: puts ("hppa-hitachi-hiuxwe2"); break; } } else if (CPU_IS_HP_MC68K (cpu)) puts ("m68k-hitachi-hiuxwe2"); else puts ("unknown-hitachi-hiuxwe2"); exit (0); } EOF $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` && { echo "$SYSTEM_NAME"; exit; } echo unknown-hitachi-hiuxwe2 exit ;; 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) echo hppa1.1-hp-bsd exit ;; 9000/8??:4.3bsd:*:*) echo hppa1.0-hp-bsd exit ;; *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) echo hppa1.0-hp-mpeix exit ;; hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) echo hppa1.1-hp-osf exit ;; hp8??:OSF1:*:*) echo hppa1.0-hp-osf exit ;; i*86:OSF1:*:*) if [ -x /usr/sbin/sysversion ] ; then echo ${UNAME_MACHINE}-unknown-osf1mk else echo ${UNAME_MACHINE}-unknown-osf1 fi exit ;; parisc*:Lites*:*:*) echo hppa1.1-hp-lites exit ;; C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) echo c1-convex-bsd exit ;; C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) if getsysinfo -f scalar_acc then echo c32-convex-bsd else echo c2-convex-bsd fi exit ;; C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) echo c34-convex-bsd exit ;; C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) echo c38-convex-bsd exit ;; C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) echo c4-convex-bsd exit ;; CRAY*Y-MP:*:*:*) echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*[A-Z]90:*:*:*) echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ -e 's/\.[^.]*$/.X/' exit ;; CRAY*TS:*:*:*) echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*T3E:*:*:*) echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*SV1:*:*:*) echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; *:UNICOS/mp:*:*) echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit ;; 5000:UNIX_System_V:4.*:*) FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit ;; i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} exit ;; sparc*:BSD/OS:*:*) echo sparc-unknown-bsdi${UNAME_RELEASE} exit ;; *:BSD/OS:*:*) echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} exit ;; *:FreeBSD:*:*) UNAME_PROCESSOR=`/usr/bin/uname -p` case ${UNAME_PROCESSOR} in amd64) echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; *) echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; esac exit ;; i*:CYGWIN*:*) echo ${UNAME_MACHINE}-pc-cygwin exit ;; *:MINGW64*:*) echo ${UNAME_MACHINE}-pc-mingw64 exit ;; *:MINGW*:*) echo ${UNAME_MACHINE}-pc-mingw32 exit ;; *:MSYS*:*) echo ${UNAME_MACHINE}-pc-msys exit ;; i*:windows32*:*) # uname -m includes "-pc" on this system. echo ${UNAME_MACHINE}-mingw32 exit ;; i*:PW*:*) echo ${UNAME_MACHINE}-pc-pw32 exit ;; *:Interix*:*) case ${UNAME_MACHINE} in x86) echo i586-pc-interix${UNAME_RELEASE} exit ;; authenticamd | genuineintel | EM64T) echo x86_64-unknown-interix${UNAME_RELEASE} exit ;; IA64) echo ia64-unknown-interix${UNAME_RELEASE} exit ;; esac ;; [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) echo i${UNAME_MACHINE}-pc-mks exit ;; 8664:Windows_NT:*) echo x86_64-pc-mks exit ;; i*:Windows_NT*:* | Pentium*:Windows_NT*:*) # How do we know it's Interix rather than the generic POSIX subsystem? # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we # UNAME_MACHINE based on the output of uname instead of i386? echo i586-pc-interix exit ;; i*:UWIN*:*) echo ${UNAME_MACHINE}-pc-uwin exit ;; amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) echo x86_64-unknown-cygwin exit ;; p*:CYGWIN*:*) echo powerpcle-unknown-cygwin exit ;; prep*:SunOS:5.*:*) echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; *:GNU:*:*) # the GNU system echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-${LIBC}`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` exit ;; *:GNU/*:*:*) # other systems with GNU libc and userland echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-${LIBC} exit ;; i*86:Minix:*:*) echo ${UNAME_MACHINE}-pc-minix exit ;; aarch64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; aarch64_be:Linux:*:*) UNAME_MACHINE=aarch64_be echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; alpha:Linux:*:*) case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in EV5) UNAME_MACHINE=alphaev5 ;; EV56) UNAME_MACHINE=alphaev56 ;; PCA56) UNAME_MACHINE=alphapca56 ;; PCA57) UNAME_MACHINE=alphapca56 ;; EV6) UNAME_MACHINE=alphaev6 ;; EV67) UNAME_MACHINE=alphaev67 ;; EV68*) UNAME_MACHINE=alphaev68 ;; esac objdump --private-headers /bin/sh | grep -q ld.so.1 if test "$?" = 0 ; then LIBC="gnulibc1" ; fi echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; arc:Linux:*:* | arceb:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; arm*:Linux:*:*) eval $set_cc_for_build if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_EABI__ then echo ${UNAME_MACHINE}-unknown-linux-${LIBC} else if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_PCS_VFP then echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabi else echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabihf fi fi exit ;; avr32*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; cris:Linux:*:*) echo ${UNAME_MACHINE}-axis-linux-${LIBC} exit ;; crisv32:Linux:*:*) echo ${UNAME_MACHINE}-axis-linux-${LIBC} exit ;; frv:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; hexagon:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; i*86:Linux:*:*) echo ${UNAME_MACHINE}-pc-linux-${LIBC} exit ;; ia64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; m32r*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; m68*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; mips:Linux:*:* | mips64:Linux:*:*) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #undef CPU #undef ${UNAME_MACHINE} #undef ${UNAME_MACHINE}el #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) CPU=${UNAME_MACHINE}el #else #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) CPU=${UNAME_MACHINE} #else CPU= #endif #endif EOF eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'` test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; } ;; openrisc*:Linux:*:*) echo or1k-unknown-linux-${LIBC} exit ;; or32:Linux:*:* | or1k*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; padre:Linux:*:*) echo sparc-unknown-linux-${LIBC} exit ;; parisc64:Linux:*:* | hppa64:Linux:*:*) echo hppa64-unknown-linux-${LIBC} exit ;; parisc:Linux:*:* | hppa:Linux:*:*) # Look for CPU level case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in PA7*) echo hppa1.1-unknown-linux-${LIBC} ;; PA8*) echo hppa2.0-unknown-linux-${LIBC} ;; *) echo hppa-unknown-linux-${LIBC} ;; esac exit ;; ppc64:Linux:*:*) echo powerpc64-unknown-linux-${LIBC} exit ;; ppc:Linux:*:*) echo powerpc-unknown-linux-${LIBC} exit ;; ppc64le:Linux:*:*) echo powerpc64le-unknown-linux-${LIBC} exit ;; ppcle:Linux:*:*) echo powerpcle-unknown-linux-${LIBC} exit ;; s390:Linux:*:* | s390x:Linux:*:*) echo ${UNAME_MACHINE}-ibm-linux-${LIBC} exit ;; sh64*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; sh*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; sparc:Linux:*:* | sparc64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; tile*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; vax:Linux:*:*) echo ${UNAME_MACHINE}-dec-linux-${LIBC} exit ;; x86_64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; xtensa*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; i*86:DYNIX/ptx:4*:*) # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. # earlier versions are messed up and put the nodename in both # sysname and nodename. echo i386-sequent-sysv4 exit ;; i*86:UNIX_SV:4.2MP:2.*) # Unixware is an offshoot of SVR4, but it has its own version # number series starting with 2... # I am not positive that other SVR4 systems won't match this, # I just have to hope. -- rms. # Use sysv4.2uw... so that sysv4* matches it. echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} exit ;; i*86:OS/2:*:*) # If we were able to find `uname', then EMX Unix compatibility # is probably installed. echo ${UNAME_MACHINE}-pc-os2-emx exit ;; i*86:XTS-300:*:STOP) echo ${UNAME_MACHINE}-unknown-stop exit ;; i*86:atheos:*:*) echo ${UNAME_MACHINE}-unknown-atheos exit ;; i*86:syllable:*:*) echo ${UNAME_MACHINE}-pc-syllable exit ;; i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*) echo i386-unknown-lynxos${UNAME_RELEASE} exit ;; i*86:*DOS:*:*) echo ${UNAME_MACHINE}-pc-msdosdjgpp exit ;; i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} else echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} fi exit ;; i*86:*:5:[678]*) # UnixWare 7.x, OpenUNIX and OpenServer 6. case `/bin/uname -X | grep "^Machine"` in *486*) UNAME_MACHINE=i486 ;; *Pentium) UNAME_MACHINE=i586 ;; *Pent*|*Celeron) UNAME_MACHINE=i686 ;; esac echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} exit ;; i*86:*:3.2:*) if test -f /usr/options/cb.name; then UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ && UNAME_MACHINE=i586 (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ && UNAME_MACHINE=i686 (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ && UNAME_MACHINE=i686 echo ${UNAME_MACHINE}-pc-sco$UNAME_REL else echo ${UNAME_MACHINE}-pc-sysv32 fi exit ;; pc:*:*:*) # Left here for compatibility: # uname -m prints for DJGPP always 'pc', but it prints nothing about # the processor, so we play safe by assuming i586. # Note: whatever this is, it MUST be the same as what config.sub # prints for the "djgpp" host, or else GDB configury will decide that # this is a cross-build. echo i586-pc-msdosdjgpp exit ;; Intel:Mach:3*:*) echo i386-pc-mach3 exit ;; paragon:*:*:*) echo i860-intel-osf1 exit ;; i860:*:4.*:*) # i860-SVR4 if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 else # Add other i860-SVR4 vendors below as they are discovered. echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 fi exit ;; mini*:CTIX:SYS*5:*) # "miniframe" echo m68010-convergent-sysv exit ;; mc68k:UNIX:SYSTEM5:3.51m) echo m68k-convergent-sysv exit ;; M680?0:D-NIX:5.3:*) echo m68k-diab-dnix exit ;; M68*:*:R3V[5678]*:*) test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) OS_REL='' test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4.3${OS_REL}; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4; exit; } ;; NCR*:*:4.2:* | MPRAS*:*:4.2:*) OS_REL='.3' test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4.3${OS_REL}; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) echo m68k-unknown-lynxos${UNAME_RELEASE} exit ;; mc68030:UNIX_System_V:4.*:*) echo m68k-atari-sysv4 exit ;; TSUNAMI:LynxOS:2.*:*) echo sparc-unknown-lynxos${UNAME_RELEASE} exit ;; rs6000:LynxOS:2.*:*) echo rs6000-unknown-lynxos${UNAME_RELEASE} exit ;; PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*) echo powerpc-unknown-lynxos${UNAME_RELEASE} exit ;; SM[BE]S:UNIX_SV:*:*) echo mips-dde-sysv${UNAME_RELEASE} exit ;; RM*:ReliantUNIX-*:*:*) echo mips-sni-sysv4 exit ;; RM*:SINIX-*:*:*) echo mips-sni-sysv4 exit ;; *:SINIX-*:*:*) if uname -p 2>/dev/null >/dev/null ; then UNAME_MACHINE=`(uname -p) 2>/dev/null` echo ${UNAME_MACHINE}-sni-sysv4 else echo ns32k-sni-sysv fi exit ;; PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort # says echo i586-unisys-sysv4 exit ;; *:UNIX_System_V:4*:FTX*) # From Gerald Hewes . # How about differentiating between stratus architectures? -djm echo hppa1.1-stratus-sysv4 exit ;; *:*:*:FTX*) # From seanf@swdc.stratus.com. echo i860-stratus-sysv4 exit ;; i*86:VOS:*:*) # From Paul.Green@stratus.com. echo ${UNAME_MACHINE}-stratus-vos exit ;; *:VOS:*:*) # From Paul.Green@stratus.com. echo hppa1.1-stratus-vos exit ;; mc68*:A/UX:*:*) echo m68k-apple-aux${UNAME_RELEASE} exit ;; news*:NEWS-OS:6*:*) echo mips-sony-newsos6 exit ;; R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) if [ -d /usr/nec ]; then echo mips-nec-sysv${UNAME_RELEASE} else echo mips-unknown-sysv${UNAME_RELEASE} fi exit ;; BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. echo powerpc-be-beos exit ;; BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. echo powerpc-apple-beos exit ;; BePC:BeOS:*:*) # BeOS running on Intel PC compatible. echo i586-pc-beos exit ;; BePC:Haiku:*:*) # Haiku running on Intel PC compatible. echo i586-pc-haiku exit ;; x86_64:Haiku:*:*) echo x86_64-unknown-haiku exit ;; SX-4:SUPER-UX:*:*) echo sx4-nec-superux${UNAME_RELEASE} exit ;; SX-5:SUPER-UX:*:*) echo sx5-nec-superux${UNAME_RELEASE} exit ;; SX-6:SUPER-UX:*:*) echo sx6-nec-superux${UNAME_RELEASE} exit ;; SX-7:SUPER-UX:*:*) echo sx7-nec-superux${UNAME_RELEASE} exit ;; SX-8:SUPER-UX:*:*) echo sx8-nec-superux${UNAME_RELEASE} exit ;; SX-8R:SUPER-UX:*:*) echo sx8r-nec-superux${UNAME_RELEASE} exit ;; Power*:Rhapsody:*:*) echo powerpc-apple-rhapsody${UNAME_RELEASE} exit ;; *:Rhapsody:*:*) echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} exit ;; *:Darwin:*:*) UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown eval $set_cc_for_build if test "$UNAME_PROCESSOR" = unknown ; then UNAME_PROCESSOR=powerpc fi if test `echo "$UNAME_RELEASE" | sed -e 's/\..*//'` -le 10 ; then if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ grep IS_64BIT_ARCH >/dev/null then case $UNAME_PROCESSOR in i386) UNAME_PROCESSOR=x86_64 ;; powerpc) UNAME_PROCESSOR=powerpc64 ;; esac fi fi elif test "$UNAME_PROCESSOR" = i386 ; then # Avoid executing cc on OS X 10.9, as it ships with a stub # that puts up a graphical alert prompting to install # developer tools. Any system running Mac OS X 10.7 or # later (Darwin 11 and later) is required to have a 64-bit # processor. This is not true of the ARM version of Darwin # that Apple uses in portable devices. UNAME_PROCESSOR=x86_64 fi echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} exit ;; *:procnto*:*:* | *:QNX:[0123456789]*:*) UNAME_PROCESSOR=`uname -p` if test "$UNAME_PROCESSOR" = "x86"; then UNAME_PROCESSOR=i386 UNAME_MACHINE=pc fi echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} exit ;; *:QNX:*:4*) echo i386-pc-qnx exit ;; NEO-?:NONSTOP_KERNEL:*:*) echo neo-tandem-nsk${UNAME_RELEASE} exit ;; NSE-*:NONSTOP_KERNEL:*:*) echo nse-tandem-nsk${UNAME_RELEASE} exit ;; NSR-?:NONSTOP_KERNEL:*:*) echo nsr-tandem-nsk${UNAME_RELEASE} exit ;; *:NonStop-UX:*:*) echo mips-compaq-nonstopux exit ;; BS2000:POSIX*:*:*) echo bs2000-siemens-sysv exit ;; DS/*:UNIX_System_V:*:*) echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} exit ;; *:Plan9:*:*) # "uname -m" is not consistent, so use $cputype instead. 386 # is converted to i386 for consistency with other x86 # operating systems. if test "$cputype" = "386"; then UNAME_MACHINE=i386 else UNAME_MACHINE="$cputype" fi echo ${UNAME_MACHINE}-unknown-plan9 exit ;; *:TOPS-10:*:*) echo pdp10-unknown-tops10 exit ;; *:TENEX:*:*) echo pdp10-unknown-tenex exit ;; KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) echo pdp10-dec-tops20 exit ;; XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) echo pdp10-xkl-tops20 exit ;; *:TOPS-20:*:*) echo pdp10-unknown-tops20 exit ;; *:ITS:*:*) echo pdp10-unknown-its exit ;; SEI:*:*:SEIUX) echo mips-sei-seiux${UNAME_RELEASE} exit ;; *:DragonFly:*:*) echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` exit ;; *:*VMS:*:*) UNAME_MACHINE=`(uname -p) 2>/dev/null` case "${UNAME_MACHINE}" in A*) echo alpha-dec-vms ; exit ;; I*) echo ia64-dec-vms ; exit ;; V*) echo vax-dec-vms ; exit ;; esac ;; *:XENIX:*:SysV) echo i386-pc-xenix exit ;; i*86:skyos:*:*) echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//' exit ;; i*86:rdos:*:*) echo ${UNAME_MACHINE}-pc-rdos exit ;; i*86:AROS:*:*) echo ${UNAME_MACHINE}-pc-aros exit ;; x86_64:VMkernel:*:*) echo ${UNAME_MACHINE}-unknown-esx exit ;; esac cat >&2 < in order to provide the needed information to handle your system. config.guess timestamp = $timestamp uname -m = `(uname -m) 2>/dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` /bin/uname -X = `(/bin/uname -X) 2>/dev/null` hostinfo = `(hostinfo) 2>/dev/null` /bin/universe = `(/bin/universe) 2>/dev/null` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` /bin/arch = `(/bin/arch) 2>/dev/null` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` UNAME_MACHINE = ${UNAME_MACHINE} UNAME_RELEASE = ${UNAME_RELEASE} UNAME_SYSTEM = ${UNAME_SYSTEM} UNAME_VERSION = ${UNAME_VERSION} EOF exit 1 # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" # End: libburn-1.4.2/cdrskin/0000755000175700017510000000000012652650103011621 500000000000000libburn-1.4.2/cdrskin/README0000644000175700017510000006200212652646112012426 00000000000000------------------------------------------------------------------------------ libburnia-project.org scdbackup.sourceforge.net/cdrskin_eng.html ------------------------------------------------------------------------------ cdrskin. By Thomas Schmitt Integrated sub project of libburnia-project.org but also published via: http://scdbackup.sourceforge.net/cdrskin_eng.html http://scdbackup.sourceforge.net/cdrskin-1.4.2.pl01.tar.gz Copyright (C) 2006-2016 Thomas Schmitt, provided under GPL version 2 or later. ------------------------------------------------------------------------------ cdrskin is a limited cdrecord compatibility wrapper which allows to use most of the libburn features from the command line. Currently it is fully supported on GNU/Linux with kernels >= 2.4, on FreeBSD, on OpenSolaris, and on NetBSD. IDE drives under Linux 2.4. need kernel module ide-scsi. ATA and SATA drives under FreeBSD need kernel module atapicam. On other X/Open compliant systems there will only be emulated drives, but no direct MMC operation on real CD/DVD/BD drives. By using this software you agree to the disclaimer at the end of this text "This software is provided as is. There is no warranty implied and ..." Compilation, First Glimpse, Installation Obtain cdrskin-1.4.2.pl01.tar.gz, take it to a directory of your choice and do: tar xzf cdrskin-1.4.2.pl01.tar.gz cd cdrskin-1.4.2 Within that directory execute: ./configure --prefix=/usr make This will already produce a cdrskin binary. But it will be necessary to install libburn in order to use this binary. In order to surely get a standalone binary, execute cdrskin/compile_cdrskin.sh Version identification and help texts available afterwards: cdrskin/cdrskin -version cdrskin/cdrskin --help cdrskin/cdrskin -help man cdrskin/cdrskin.1 Install (eventually as superuser) cdrskin to a directory where it can be found: The command for global installation of both, libburn and cdrskin is make install If the library libburn.so.4 is not found with a test run of cdrskin, then try whether command ldconfig makes it accessible. With the statically linked binary this should not matter. With that static binary you may as well do the few necessary actions manually. If cdrskin was already installed by a previous version, or by "make install" in the course of this installation, then find out where: which cdrskin Copy your standalone binary to exactly the address which you get as reply. E.g.: cp cdrskin/cdrskin /usr/bin/cdrskin Check the version timestamps of the globally installed binary cdrskin -version It is not necessary for the standalone cdrskin binary to have libburn installed, since it incorporates the necessary libburn parts at compile time. It will not collide with an installed version of libburn either. But libpthread must be installed on the system and glibc has to match. (See below for a way to create a totally static linked binary.) To install the man page, you may do: echo $MANPATH and choose one of the listed directories to copy the man-page under its ./man1 directory. Like: cp cdrskin/cdrskin.1 /usr/share/man/man1/cdrskin.1 Note: The content of the cdrskin tarball is essentially the complete libburn of the same version number. You may thus perform above steps in a local SVN copy of libburn or in a unpacked libburn tarball as well. Usage The user of cdrskin needs rw-permission for the CD burner device. A list of rw-accessible drives can be obtained by cdrskin --devices CD devices which offer no rw-permission are invisible to normal users. The superuser should be able to see any usable drive and then set the permissions as needed. If this hangs then there is a drive with unexpected problems (locked, busy, broken, whatever). You might have to guess the address of your (non-broken) burner by other means, then. On Linux 2.4 this would be some /dev/sgN and on 2.6. some /dev/srM or /dev/hdX. The output of cdrskin --devices might look like 0 dev='/dev/sr0' rwrwr- : '_NEC' 'DVD_RW ND-4570A' 1 dev='/dev/sr1' rwrw-- : 'HL-DT-ST' 'DVDRAM GSA-4082B' On Linux, full and insecure enabling of both for everybody would look like chmod a+rw /dev/sr0 /dev/hda This is equivalent to the traditional setup chmod a+x,u+s cdrecord. On FreeBSD, device rw-permissions are to be set in /etc/devfs.rules. On Solaris, pfexec privileges may be restricted to "basic,sys_devices". On NetBSD, rw-permission may be granted by chmod a+rw /dev/rcd?d. See below "System Dependend Drive Permission Examples". I strongly discourage to run cdrskin with setuid root or via sudo ! It is not checked for the necessary degree of hacker safety. Better consider to grant the necessary permissions to group "floppy" and to add users to it. A behavioral conflict is known between any burn software and demons like hald which probe CD drives. This can spoil burn runs for CD-R or CD-RW. You may have to keep your hald away from the drive. See for example http://www.freebsd.org/gnome/docs/halfaq.html Helpful with Linux kernel 2.4 is a special SCSI feature: It is possible to address a scsi(-emulated) drive via associated device files which are not listed by option --devices but point to the same SCSI addresses as listed device files. This addressing via e.g. /dev/sr0 or /dev/scd1 is compatible with generic read programs like dd and with write program growisofs. For finding /dev/sg1 from /dev/sr0, the program needs rw-access to both files. Usage examples For options and recordable media classes see man 1 cdrskin Get an overview of cdrecord style addresses of available devices cdrskin -scanbus cdrskin dev=ATA -scanbus cdrskin --devices Adresses reported with dev=ATA need prefix "ATA:". Address examples: dev=0,1,0 dev=ATA:1,0,0 dev=/dev/sg1 dev=/dev/hdc dev=/dev/sr0 See also "Drive Addressing" below. Obtain some info about the drive cdrskin dev=0,1,0 -checkdrive Obtain some info about the drive and the inserted media cdrskin dev=0,1,0 -atip -v -minfo Prepare CD-RW or DVD-RW for re-use, DVD-RAM or BD-RE for first use cdrskin -v dev=/dev/sg1 blank=as_needed -eject Format DVD-RW to avoid need for blanking before re-use cdrskin -v dev=0,1,0 blank=format_overwrite De-format DVD-RW to make it capable of multi-session again cdrskin -v dev=/dev/sr0 blank=deformat_sequential Burn image file my_image.iso to media cdrskin -v dev=0,1,0 speed=12 fs=8m driveropts=burnfree padsize=300k \ -eject my_image.iso Write multi-session to the same CD , DVD-R[W] or DVD+R[/DL] cdrskin dev=/dev/hdc padsize=300k -multi 1.iso cdrskin dev=/dev/hdc padsize=300k -multi 2.iso cdrskin dev=/dev/hdc padsize=300k -multi 3.iso cdrskin dev=/dev/hdc padsize=300k 4.iso Get multi-session info for option -C of program mkisofs: c_values=$(cdrskin dev=/dev/hdc -msinfo 2>/dev/null) mkisofs ... -C "$c_values" ... Burn a compressed afio archive to media on-the-fly find . | afio -oZ - | cdrskin -v dev=0,1,0 fs=32m speed=8 \ driveropts=burnfree padsize=300k - Burn 6 audio tracks from files with different formats to CD (not to any DVD). Anything except .wav or .au files has to be converted into raw format first. See below "Audio CD" for specifications. ogg123 -d raw -f track01.cd /path/to/track1.ogg oggdec -R -o track02.cd /path/to/track2.ogg lame --decode -t /path/to/track3.mp3 track03.cd madplay -o raw:track04.cd /path/to/track4.mp3 mppdec --raw-le /path/to/track5.mpc track05.cd cdrskin -v dev=0,1,0 blank=fast -eject speed=48 -sao \ -audio -swab track0[1-5].cd /path/to/track6.wav Extract audio tracks and CD-TEXT from CD into directory /home/me/my_cd: mkdir /home/me/my_cd cdrskin -v dev=/dev/sr0 extract_audio_to=/home/me/my_cd \ cdtext_to_v07t=/home/me/my_cd/cdtext.v07t Restrictions Several advanced CD related options of cdrecord are still unsupported. See output of command cdrskin --list_ignored_options If you have use cases for them, please report your wishes and expectations. On the other hand, the capability of multi-session and of writing streams of unpredicted lenght surpass the current DVD capabilities of cdrecord. Inspiration and Standard cdrskin combines the command line interface standard set by cdrecord with libburn, which is a control software for optical drives according to standard MMC-5. For particular CD legacy commands, standards MMC-3 and MMC-1 apply. For the original meaning of cdrecord options see : man cdrecord (http://cdrecord.berlios.de/old/private/man/cdrecord-2.0.html) Do not bother Joerg Schilling with any cdrskin problems. (Be cursed if you install cdrskin as "cdrecord" without clearly forwarding this "don't bother Joerg" demand.) cdrskin does not contain any bytes copied from cdrecord's sources. Many bytes have been copied from the message output of cdrecord runs, though. I am thankful to Joerg Schilling for every single one of them. I have the hope that Joerg feels more flattered than annoyed by cdrskin. Many thanks to Andy Polyakov for his dvd+rw-tools http://fy.chalmers.se/~appro/linux/DVD+RW/tools which provide me with examples and pointers into MMC specs for DVD writing. Startup Files If not --no_rc is the first argument then cdrskin attempts on startup to read arguments from the following three files: /etc/default/cdrskin /etc/opt/cdrskin/rc /etc/cdrskin/cdrskin.conf $HOME/.cdrskinrc The files are read in the sequence given above. Each readable line is treated as one single argument. No extra blanks. A first character '#' marks a comment, empty lines are ignored. Example content of a startup file: # This is the default device dev=0,1,0 # Some more options fifo_start_at=0 fs=16m Audio CD Lorenzo Taylor enabled option -audio in cdrskin (thanks !) and reports neat results with audio data files which are : headerless PCM (i.e. uncompressed) 44100 Hz sampling rate 16 bits per sample stereo (2 channels) little-endian byte order with option -swab, or big-endian without -swab Files with name extension .wav get examined wether they are in Microsoft WAVE format with above parameters and eventually get extracted by cdrskin itself. In the same way files with name extension .au get examined wether they are in SUN's audio format. For both formats, track format -audio and eventual endianness option -swab are enabled automatically. Any other formats are to be converted to format .wav with above parameters or to be extracted as raw CD track data by commands like those given above under "Usage examples". Those raw files need option -audio and in most cases option -swab to mark them as little-endian/Intel/LSB-first 16-bit data. Incorrect endianness setting results in random noise on CD. I myself am not into audio. So libburn-hackers@pykix.org might be the best address for suggestions, requests and bug reports. DVD+RW , DVD-RAM , BD-RE These random access media get treated as blank media regardless wether they hold data or not. Options -audio and -multi are not allowed. Only one track is allowed. -toc does not return information about the media content. Speed is counted in DVD units (i.e. 1x = 1,385,000 bytes/second) or BD units (1x = 4,495,625 bytes/second). Currently there is no difference between -sao and -tao. If ever, then -tao will be the mode which preserves the current behavior. BD-RE media need formatting before first use. cdrskin option "blank=as_needed" recognizes unformatted BD-RE and applies a lengthy formatting run. During write operations DVD-RAM and BD-RE automatically apply Defect Management. This usually slows them down to half nominal speed. If drive and media produce flawless results anyway, then one can try to reach full nominal speed by option "stream_recording=on". In this case bad blocks are not detected during write and not even previously known bad blocks are avoided. So you have to make your own readability tests and go back to half speed as soon as the first read errors show up. Instead of "on" one may also set a start address for stream recording. Like "stream_recording=100m". This will write slowly to the first 100 MB of the media and accelerate when writing to higher addresses. Option --grow_overwriteable_iso allows -multi (although unneeded), enables -msinfo and -toc, and makes blank=fast an invalidator for ISO filesystems on overwriteable media. Initial session (equivalent to growisofs -Z): mkisofs ... | cdrskin --grow_overwriteable_iso blank=fast ... Add-on session (equivalent to growisofs -M): cparms=$(cdrskin dev=/dev/sr0 --grow_overwriteable_iso -msinfo) mkisofs -C "$cparms" -M /dev/sr0 ... | \ cdrskin dev=/dev/sr0 --grow_overwriteable_iso ... - DVD-RW , DVD-R , DVD-R DL DVD-RW are usable if formatted to state "Restricted Overwrite" or if in state "Sequential Recording". DVD-R are always in sequential state. DVD-R DL are always sequential and incapable of multi-session. "Sequential" is the state of unused media and of media previously blanked or written by cdrecord. dvd+rw-format -blank can also achieve this state. The according cdrskin option is blank=deformat_sequential . If "Incremental Streaming" is available, then sequential media are capable of multi-session like CD-R[W]. (But not capable of -audio recording.) This means they need option -multi to stay appendable, need to be blanked to be writeable from start, return useable info with -toc and -msinfo, eventually perform appending automatically. Without Incremental Streaming offered by the drive, only write mode DAO is available with sequential DVD-R[W]. It only works with blank media, allows only one single track, no -multi, and demands a fixely predicted track size. (growisofs uses it with DVD-R[W] if option -dvd-compat is given.) Overwriteable DVD-RW behave much like DVD+RW. "Restricted" refers only to the granularity of random access and block size which have always to be aligned to full 32 kB. Sequential DVD-RW are converted into overwriteable DVD-RW by cdrskin dev=... -v blank=format_overwrite (Command dvd+rw-format -force can achieve Restricted Overwrite, too.) Formatting or first use of freshly formatted DVD-RW can produce unusual noises from the drive and last several minutes. Depending on mutual compatibility of drive and media, formatting can yield unusable media. It seems that those die too on blanking by cdrecord, dvd+rw-format or cdrskin. Perils of DVD-RW. There are three DVD-RW formatting variants with cdrskin currently: blank=format_overwrite uses "DVD-RW Quick" formatting (MMC-type 15h) and writes a first session of 128 MiB. This leads to media which are expandable and random addressable by cdrskin. blank=format_overwrite_quickest uses "DVD-RW Quick" formatting (type 15h) too, but leaves the media in "intermediate" state. In the first session of writing one may only write sequentially to such a DVD. After that, it gets random addressable by cdrskin. DVD-ROM drives might show ill behavior with them. blank=format_overwrite_full uses preferrably "Full Format" (type 00h). This formatting lasts as long as writing a full DVD. It includes writing of lead-out which is said to be good for DVD ROM compatibility. De-formatting options are available to make overwriteable DVD-RW sequential: blank=deformat_sequential performs thorough blanking of all states of DVD-RW. blank=all and blank=fast perform the same thorough blanking, but refuse to do this with overwriteable DVD-RW, thus preserving their formatting. The specs allow minimal blanking but the resulting media on my drives offer no Incremental Streaming afterwards. So blank=fast will do full blanking. blank=deformat_sequential_quickest is faster but might yield DAO-only media. DVD+R , DVD+R DL , BD-R From the view of cdrskin they behave much like DVD-R. Each track gets wrapped into an own session, though. DVD+R DL appear as extra large DVD+R. cdrskin does not allow to set the address of the layer break where a reading drive might show some delay while switching between both media layers. BD-R are sold unformatted blank. If used without initial formatting then the drive is supposed to format them to maximum payload size with no Defect Management (see also above with BD-RE). If Defect Management is desired then BD-R need to be formatted before the first attempt to write a session to them. blank=format_if_needed will detect the situation and eventually apply default sized Defect Management formatting. blank=format_defectmgt_* will apply non-default parameters to formatting. Emulated Drives cdrskin can use filesystem objects as emulated drives. Regular files or block devices appear similar to DVD-RAM. Other file types resemble blank DVD-R. Necessary precondition is option --allow_emulated_drives which is not accepted if cdrskin took another user identity because of the setuid bit of its access permissions. Addresses of emulated drives begin with prefix "stdio:". E.g. dev=stdio:/tmp/my_pseudo_drive For safety reasons the superuser is only allowed to use /dev/null as emulated drive. See man page section FILES for a way to lift that ban. ------------------------------------------------------------------------------ Special compilation variations All following options of ./configure and cdrskin/compile_cdrskin.sh are combinable. After runs of ./configure do as next: make clean ; make In some situations Linux may deliver a better write performance to drives if the track input is read with O_DIRECT (see man 2 open). The API call burn_os_open_track_src() and the input readers of cdrskin and libburn fifo can be told to use this peculiar read mode by: --enable-track-src-odirect But often cdrskin option dvd_obs=64k will yield even better performance in such a situation. 64k can be made default at compile time by cdrskin/compile_cdrskin.sh -dvd_obs_64k It can also be enabled at configure time by ./configure ... --enable-dvd-obs-64k ... Alternatively the transport of SCSI commands can be done via libcdio-0.83. You may install it and re-run libburn's ./configure with option --enable-libcdio Add option -use_libcdio to your run of cdrskin/compile_cdrskin.sh . You may get a (super fat) statically linked binary by : cdrskin/compile_cdrskin.sh -static if your system supports static linking, at all. This will not help with kernels which do not properly support the necessary low-level interfaces chosen by your compile-time libraries. A size reduced but fully functional binary may be produced by cdrskin/compile_cdrskin.sh -do_strip An extra lean binary with reduced capabilities is created by cdrskin/compile_cdrskin.sh -do_diet -do_strip It will not read startup files, will abort on option dev_translation= , will not have a fifo buffer, and will not be able to put out help texts or debugging messages. Linux only: libburn tries to avoid a collision with udev's drive examination by waiting 0.1 seconds before opening the device file for a longer time, after udev might have been alarmed by drive scanning activities. The waiting time can be set at ./configure time with microsecond granularity. E.g. 2 seconds: CFLAGS="$CFLAGS -DLibburn_udev_wait_useC=2000000" ./configure ...options... Waiting can be disabled by zero waiting time: CFLAGS="$CFLAGS -DLibburn_udev_wait_useC=0" Alternatively, libburn can try to be nice by opening the device file, closing it immediately, waiting, and only then opening it for real: CFLAGS="$CFLAGS -DLibburn_udev_extra_open_cyclE -DLibburn_udev_wait_useC=500000" ------------------------------------------------------------------------------ System Dependend Drive Permission Examples Accessing the optical drives requires privileges which usually are granted only to the superuser. Linux, FreeBSD, Solaris, NetBSD, offer quite different approaches for avoiding the need for unrestricted privileges. First check whether some friendly system setting already allows you to access the drives as normal user: cdrskin --devices Those drives of which you see address and type strings are already usable. If there remain drives invisible which the superuser can see by the same command, then the following examples might help: --------------- On all systems: --------------- Add the authorized users of CD drives to group "floppy" in /etc/group. If missing: create this group. Changes to /etc/group often only affect new login sessions. So log out and in before making the first tests. --------- On Linux: --------- Allow rw-access to the drives chgrp floppy /dev/sr0 /dev/sr1 chmod g+rw /dev/sr0 /dev/sr1 It might be necessary to perform chgrp and chmod after each reboot or to edit distro dependent device configuration files for permanent settings. ----------- On FreeBSD: ----------- Edit /etc/devfs.rules and make sure to have these lines [localrules=10] add path 'acd*' mode 0664 group floppy add path 'cd*' mode 0664 group floppy add path 'pass*' mode 0664 group floppy add path 'xpt*' mode 0664 group floppy [localrules=5] add path 'pass*' mode 0664 group floppy add path 'cd*' mode 0664 group floppy add path 'xpt*' mode 0664 group floppy add path 'acd*' mode 0664 group floppy Edit /etc/rc.conf and add the following line if missing devfs_system_ruleset="localrules" This gets into effect by reboot or by command /etc/rc.d/devfs start ----------- On Solaris: ----------- Run cdrskin by pfexec cdrskin ...arguments... The following settings will make pfexec keep original UID and EUID and prevent most superuser powers. Be aware that you still can manipulate all device files if you have the file permissions for that. Full root privileges for cdrskin can then be aquired only by command su. Edit /etc/security/exec_attr and add this line to the other "Media Backup" lines: Media Backup:solaris:cmd:::/usr/local/bin/cdrskin:privs=basic,sys_devices Edit /etc/user_attr and add profile "Media Backup" to the user's line: thomas::::profiles=Media Backup,Primary Administrator;roles=root See also man privileges, man exec_attr, man user_attr. Then allow the group r-access to the drives pfexec chgrp floppy /dev/rdsk/c3t0d0s2 /dev/rdsk/c4t0d0s2 pfexec chmod g+r /dev/rdsk/c3t0d0s2 /dev/rdsk/c4t0d0s2 The last two commands have to be executed after each boot. I do not know the relevant device configuration files yet. ---------- On NetBSD: ---------- Allow rw-access to the drives chgrp floppy /dev/rcd[01]d chmod g+rw /dev/rcd[01]d ------------------------------------------------------------------------------ Project aspects and legal stuff ------------------------------------------------------------------------------ Important Disclaimer : This software is provided as is. There is no warranty implied and no protection against possible damages. You use this on your own risk. Don't blame me or other authors of libburn if anything goes wrong. Actually, in case of severe trouble, nearly always the drive and the media are the cause. Any mistake of the burn program is supposed to be caught by the drive's firmware and to lead to mere misburns. The worst mishaps which hit the author imposed the need to reboot the system because of drives gnawing endlessly on ill media. Permanent hardware damage did not occur in 3.5 years of development. But one never knows ... ------------------------------------------------------------------------------ Interested users are invited to participate in the development of cdrskin. Contact: scdbackup@gmx.net or libburn-hackers@pykix.org . We will keep copyright narrow but will of course acknowledge valuable contributions in a due way. ------------------------------------------------------------------------------ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 or later as published by the Free Software Foundation. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ------------------------------------------------------------------------------ Based on and sub project of: libburnia-project.org By Mario Danic and Thomas Schmitt Copyright (C) 2006-2014 Mario Danic, Thomas Schmitt libburnia-project.org is inspired by and in other components still containing parts of Libburn. By Derek Foreman and Ben Jansens Copyright (C) 2002-2006 Derek Foreman and Ben Jansens See toplevel README for an overview of the current copyright situation in libburnia-project.org. libburn-1.4.2/cdrskin/cdrskin.c0000644000175700017510000115544112652646531013367 00000000000000 /* cdrskin.c , Copyright 2006-2016 Thomas Schmitt Provided under GPL version 2 or later. A cdrecord compatible command line interface for libburn. This project is neither directed against original cdrecord nor does it exploit any source code of said program. It rather tries to be an alternative method to burn CD, DVD, or BD, which is not based on the same code as cdrecord. See also : http://scdbackup.sourceforge.net/cdrskin_eng.html Interested users of cdrecord are encouraged to contribute further option implementations as they need them. Contributions will get published under GPL but it is essential that the authors allow a future release under LGPL. There is a script test/cdrecord_spy.sh which may be installed between the cdrecord command and real cdrecord in order to learn about the options used by your favorite cdrecord frontend. Edit said script and install it according to the instructions given inside. The implementation of an option would probably consist of - necessary structure members for structs CdrpreskiN and/or CdrskiN - code in Cdrpreskin_setup() and Cdrskin_setup() which converts argv[i] into CdrpreskiN/CdrskiN members (or into direct actions) - removal of option from ignore list "ignored_partial_options" or "ignored_full_options" in Cdrskin_setup() - functions which implement the option's run time functionality - eventually calls of those functions in Cdrskin_run() - changes to be made within Cdrskin_burn() or Cdrskin_blank() or other existing methods See option blank= for an example. ------------------------------------------------------------------------------ For a more comprehensive example of the advised way to write an application of libburn see test/libburner.c . ------------------------------------------------------------------------------ This program is currently copyright Thomas Schmitt only. The copyrights of several components of libburnia-project.org are willfully tangled at toplevel to form an irrevocable commitment to true open source spirit. We have chosen the GPL for legal compatibility and clearly express that it shall not hamper the use of our software by non-GPL applications which show otherwise the due respect to the open source community. See toplevel README and cdrskin/README for that commitment. For a short time, this place showed a promise to release a BSD license on mere request. I have to retract that promise now, and replace it by the promise to make above commitment reality in a way that any BSD conformant usage in due open source spirit will be made possible somehow and in the particular special case. I will not raise public protest if you fork yourself a BSD license from an (outdated) cdrskin.c which still bears that old promise. Note that this extended commitment is valid only for cdrskin.[ch], cdrfifo.[ch] and cleanup.[ch], but not for libburnia-project.org as a whole. cdrskin is originally inspired by libburn-0.2/test/burniso.c : (c) Derek Foreman and Ben Jansens ------------------------------------------------------------------------------ Compilation within cdrskin-* : cd cdrskin cc -g -I.. -DCdrskin_build_timestamP='...' \ -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE=1 \ -o cdrskin cdrskin.c cdrfifo.c cleanup.c \ -L../libburn/.libs -lburn -lpthread or cd .. cc -g -I. -DCdrskin_build_timestamP='...' \ -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE=1 \ -o cdrskin/cdrskin cdrskin/cdrskin.c cdrskin/cdrfifo.c cdrskin/cleanup.c \ libburn/async.o libburn/crc.o libburn/debug.o libburn/drive.o \ libburn/file.o libburn/init.o libburn/lec.o \ libburn/mmc.o libburn/options.o libburn/sbc.o libburn/sector.o \ libburn/sg.o libburn/spc.o libburn/source.o libburn/structure.o \ libburn/toc.o libburn/util.o libburn/write.o libburn/read.o \ libburn/libdax_audioxtr.o libburn/libdax_msgs.o \ -lpthread */ /** The official program version */ #ifndef Cdrskin_prog_versioN #define Cdrskin_prog_versioN "1.4.2" #endif /** The official libburn interface revision to use. (May get changed further below) */ #ifndef Cdrskin_libburn_majoR #define Cdrskin_libburn_majoR 1 #endif #ifndef Cdrskin_libburn_minoR #define Cdrskin_libburn_minoR 4 #endif #ifndef Cdrskin_libburn_micrO #define Cdrskin_libburn_micrO 2 #endif /** The source code release timestamp */ #include "cdrskin_timestamp.h" #ifndef Cdrskin_timestamP #define Cdrskin_timestamP "-none-given-" #endif /** The binary build timestamp is to be set externally by the compiler */ #ifndef Cdrskin_build_timestamP #define Cdrskin_build_timestamP "-none-given-" #endif #ifdef Cdrskin_libburn_versioN #undef Cdrskin_libburn_versioN #endif #ifdef Cdrskin_libburn_1_4_2 #define Cdrskin_libburn_versioN "1.4.2" #endif #ifdef Cdrskin_libburn_1_4_3 #define Cdrskin_libburn_versioN "1.4.3" #endif #ifndef Cdrskin_libburn_versioN #define Cdrskin_libburn_1_4_2 #define Cdrskin_libburn_versioN "1.4.2" #endif #ifdef Cdrskin_libburn_1_4_2 #undef Cdrskin_libburn_majoR #undef Cdrskin_libburn_minoR #undef Cdrskin_libburn_micrO #define Cdrskin_libburn_majoR 1 #define Cdrskin_libburn_minoR 4 #define Cdrskin_libburn_micrO 2 #endif #ifdef Cdrskin_libburn_1_4_3 #undef Cdrskin_libburn_majoR #undef Cdrskin_libburn_minoR #undef Cdrskin_libburn_micrO #define Cdrskin_libburn_majoR 1 #define Cdrskin_libburn_minoR 4 #define Cdrskin_libburn_micrO 3 #endif /* History of development macros. As of version 1.1.8 they are now unconditional, thus removing the option to compile a heavily restricted cdrskin for the old libburn at icculus.org. */ /* 0.2.2 */ /* Cdrskin_libburn_does_ejecT */ /* Cdrskin_libburn_has_drive_get_adR */ /* Cdrskin_progress_track_does_worK */ /* Cdrskin_is_erasable_on_load_does_worK */ /* Cdrskin_grab_abort_does_worK */ /* 0.2.4 */ /* Cdrskin_allow_libburn_taO */ /* Cdrskin_libburn_has_is_enumerablE */ /* Cdrskin_libburn_has_convert_fs_adR */ /* Cdrskin_libburn_has_convert_scsi_adR */ /* Cdrskin_libburn_has_burn_msgS */ /* Cdrskin_libburn_has_burn_aborT */ /* Cdrskin_libburn_has_cleanup_handleR */ /* Cdrskin_libburn_has_audioxtR */ /* Cdrskin_libburn_has_get_start_end_lbA */ /* Cdrskin_libburn_has_burn_disc_unsuitablE */ /* Cdrskin_libburn_has_read_atiP */ /* Cdrskin_libburn_has_buffer_progresS */ /* 0.2.6 */ /* Cdrskin_libburn_has_pretend_fulL */ /* Cdrskin_libburn_has_multI */ /* Cdrskin_libburn_has_buffer_min_filL */ /* 0.3.0 */ /* Cdrskin_atip_speed_is_oK */ /* Cdrskin_libburn_has_get_profilE */ /* Cdrskin_libburn_has_set_start_bytE */ /* Cdrskin_libburn_has_wrote_welL */ /* Cdrskin_libburn_has_bd_formattinG */ /* Cdrskin_libburn_has_burn_disc_formaT */ /* 0.3.2 */ /* Cdrskin_libburn_has_get_msc1 */ /* Cdrskin_libburn_has_toc_entry_extensionS */ /* Cdrskin_libburn_has_get_multi_capS */ /* 0.3.4 */ /* Cdrskin_libburn_has_set_filluP */ /* Cdrskin_libburn_has_get_spacE */ /* Cdrskin_libburn_write_mode_ruleS */ /* Cdrskin_libburn_has_allow_untested_profileS */ /* Cdrskin_libburn_has_set_forcE */ /* 0.3.6 */ /* Cdrskin_libburn_preset_device_familY */ /* Cdrskin_libburn_has_track_set_sizE */ /* 0.3.8 */ /* Cdrskin_libburn_has_set_waitinG */ /* Cdrskin_libburn_has_get_best_speeD */ /* 0.4.0 */ /* Cdrskin_libburn_has_random_access_rW */ /* Cdrskin_libburn_has_get_drive_rolE */ /* Cdrskin_libburn_has_drive_equals_adR */ /* 0.4.2 */ /* no novel libburn features but rather organizational changes */ /* 0.4.4 */ /* novel libburn features are transparent to cdrskin */ /* 0.4.6 */ /* Cdrskin_libburn_has_stream_recordinG */ /* 0.4.8 */ /* Bug fix release for write_start_address=... on DVD-RAM and BD-RE */ /* 0.5.0 , 0.5.2 , 0.5.4 , 0.5.6 , 0.5.8 , 0.6.0 , 0.6.2 */ /* novel libburn features are transparent to cdrskin */ /* 0.6.4 */ /* Ended to mark novelties by macros. libburnia libburn and cdrskin are fixely in sync now. icculus libburn did not move for 30 months. */ /* 1.1.8 */ /* The code which got enabled by novelty macros was made unconditional. */ #ifdef Cdrskin_new_api_tesT /* put macros under test caveat here */ #endif /* Cdrskin_new_api_tesT */ /** ts A90901 The raw write modes of libburn depend in part on code borrowed from cdrdao. Since this code is not understood by the current developers and since CDs written with cdrskin -raw96r seem unreadable anyway, -raw96r is given up for now. */ #define Cdrskin_disable_raw96R 1 /** A macro which is able to eat up a function call like printf() */ #ifdef Cdrskin_extra_leaN #define ClN(x) #define Cdrskin_no_cdrfifO 1 #else #define ClN(x) x #ifdef Cdrskin_use_libburn_fifO /* # define Cdrskin_no_cdrfifO 1 */ #endif #endif /** Verbosity level for pacifying progress messages */ #define Cdrskin_verbose_progresS 1 /** Verbosity level for command recognition and execution logging */ #define Cdrskin_verbose_cmD 2 /** Verbosity level for reporting of debugging messages */ #define Cdrskin_verbose_debuG 3 /** Verbosity level for fifo debugging */ #define Cdrskin_verbose_debug_fifO 4 #include #include #include #include #include #include #include #include #include #include #include "../libburn/libburn.h" #define Cleanup_set_handlers burn_set_signal_handling #define Cleanup_app_handler_T burn_abort_handler_t /* # define Cdrskin_use_libburn_cleanuP 1 */ /* May not use libburn cleanup with cdrskin fifo */ #ifndef Cdrskin_use_libburn_fifO #ifdef Cdrskin_use_libburn_cleanuP #undef Cdrskin_use_libburn_cleanuP #endif #endif #ifdef Cdrskin_use_libburn_cleanuP #define Cleanup_handler_funC NULL #define Cleanup_handler_handlE "cdrskin: " #define Cleanup_handler_flaG 48 #else #define Cleanup_handler_funC (Cleanup_app_handler_T) Cdrskin_abort_handler #define Cleanup_handler_handlE skin #define Cleanup_handler_flaG 4 #endif /* ! Cdrskin_use_libburn_cleanuP */ /* 0= no abort going on, -1= Cdrskin_abort_handler was called */ static int Cdrskin_abort_leveL= 0; /** The size of a string buffer for pathnames and similar texts */ #define Cdrskin_strleN 4096 /** The maximum length +1 of a drive address */ #define Cdrskin_adrleN BURN_DRIVE_ADR_LEN /** If tsize= sets a value smaller than media capacity divided by this number then there will be a warning and gracetime set at least to 15 */ #define Cdrskin_minimum_tsize_quotienT 2048.0 /* --------------------------------------------------------------------- */ /* Imported from scdbackup-0.8.5/src/cd_backup_planer.c */ /** Macro for creation of arrays of objects (or single objects) */ #define TSOB_FELD(typ,anz) (typ *) calloc(anz, sizeof(typ)); /** Convert a text so that eventual characters special to the shell are made literal. Note: this does not make a text terminal-safe ! @param in_text The text to be converted @param out_text The buffer for the result. It should have size >= strlen(in_text)*5+2 @param flag Unused yet @return For convenience out_text is returned */ char *Text_shellsafe(char *in_text, char *out_text, int flag) { int l,i,w=0; /* enclose everything by hard quotes */ l= strlen(in_text); out_text[w++]= '\''; for(i=0;i0) if(line[l-1]=='\r') line[--l]= 0; if(l>0) if(line[l-1]=='\n') line[--l]= 0; if(l>0) if(line[l-1]=='\r') line[--l]= 0; return(ret); } #ifndef Cdrskin_extra_leaN /** Destroy a synthetic argument array */ int Sfile_destroy_argv(int *argc, char ***argv, int flag) { int i; if(*argc>0 && *argv!=NULL){ for(i=0;i<*argc;i++){ if((*argv)[i]!=NULL) free((*argv)[i]); } free((char *) *argv); } *argc= 0; *argv= NULL; return(1); } /** Read a synthetic argument array from a list of files. @param progname The content for argv[0] @param filenames The paths of the filex from where to read @param filenamecount The number of paths in filenames @param argc Returns the number of read arguments (+1 for progname) @param argv Returns the array of synthetic arguments @param argidx Returns source file indice of argv[] items @param arglno Returns source file line numbers of argv[] items @param flag Bitfield for control purposes: bit0= read progname as first argument from line bit1= just release argument array argv and return bit2= tolerate failure to open file @return 1=ok , 0=cannot open file , -1=cannot create memory objects */ int Sfile_multi_read_argv(char *progname, char **filenames, int filename_count, int *argc, char ***argv, int **argidx, int **arglno, int flag) { int ret,i,pass,maxl=0,l,argcount=0,line_no; char buf[Cdrskin_strleN]; FILE *fp= NULL; Sfile_destroy_argv(argc,argv,0); if(flag&2) return(1); if((*argidx)!=NULL) free((char *) *argidx); if((*arglno)!=NULL) free((char *) *arglno); *argidx= *arglno= NULL; for(pass=0;pass<2;pass++) { if(!(flag&1)){ argcount= 1; if(pass==0) maxl= strlen(progname)+1; else { (*argv)[0]= (char *) calloc(1, strlen(progname)+1); if((*argv)[0]==NULL) {ret= -1; goto ex;} strcpy((*argv)[0],progname); } } else { argcount= 0; if(pass==0) maxl= 1; } for(i=0; imaxl) maxl= l; } else { if(argcount >= *argc) break; (*argv)[argcount]= (char *) calloc(1, l+1); if((*argv)[argcount]==NULL) {ret= -1; goto ex;} strcpy((*argv)[argcount],buf); (*argidx)[argcount]= i; (*arglno)[argcount]= line_no; } argcount++; } fclose(fp); fp= NULL; } if(pass==0){ *argc= argcount; if(argcount>0) { *argv= (char **) calloc(argcount, sizeof(char *)); *argidx= (int *) calloc(argcount, sizeof(int)); *arglno= (int *) calloc(argcount, sizeof(int)); if(*argv==NULL || *argidx==NULL || *arglno==NULL) {ret= -1; goto ex;} } for(i=0;i<*argc;i++) { (*argv)[i]= NULL; (*argidx)[i]= -1; (*arglno)[i]= -1; } } } ret= 1; ex:; if(fp!=NULL) fclose(fp); return(ret); } /** Combine environment variable HOME with given filename @param filename Address relative to $HOME @param fileadr Resulting combined address @param fa_size Size of array fileadr @param flag Unused yet @return 1=ok , 0=no HOME variable , -1=result address too long */ int Sfile_home_adr_s(char *filename, char *fileadr, int fa_size, int flag) { char *home; strcpy(fileadr,filename); home= getenv("HOME"); if(home==NULL) return(0); if((int) (strlen(home) + strlen(filename) + 1) >= fa_size) return(-1); strcpy(fileadr,home); if(filename[0]!=0){ strcat(fileadr,"/"); strcat(fileadr,filename); } return(1); } #endif /* ! Cdrskin_extra_leaN */ /* -------------------------- other misc functions ----------------------- */ /* Learned from reading growisofs.c , watching mkisofs, and viewing its results via od -c */ /* @return 0=no size found , 1=*size_in_bytes is valid */ int Scan_for_iso_size(unsigned char data[2048], double *size_in_bytes, int flag) { double sectors= 0.0; if(data[0]!=1) return(0); if(strncmp((char *) (data+1),"CD001",5)!=0) return(0); sectors= data[80] | (data[81]<<8) | (data[82]<<16) | (data[83]<<24); *size_in_bytes= sectors*2048.0; return(1); } int Set_descr_iso_size(unsigned char data[2048], double size_in_bytes, int flag) { unsigned int sectors, i; sectors= size_in_bytes/2048.0; if(size_in_bytes>((double) sectors) * 2048.0) sectors++; for(i=0;i<4;i++) data[87-i]= data[80+i]= (sectors >> (8*i)) & 0xff; return(1); } int Wait_for_input(int fd, int microsec, int flag) { struct timeval wt; fd_set rds,wts,exs; int ready; FD_ZERO(&rds); FD_ZERO(&wts); FD_ZERO(&exs); FD_SET(fd,&rds); FD_SET(fd,&exs); wt.tv_sec= microsec/1000000; wt.tv_usec= microsec%1000000; ready= select(fd+1,&rds,&wts,&exs,&wt); if(ready<=0) return(0); if(FD_ISSET(fd,&exs)) return(-1); if(FD_ISSET(fd,&rds)) return(1); return(0); } /* --------------------------------------------------------------------- */ /** Address translation table for users/applications which do not look for the output of -scanbus but guess a Bus,Target,Lun on their own. */ /** The maximum number of entries in the address translation table */ #define Cdradrtrn_leN 256 /** The address prefix which will prevent translation */ #define Cdrskin_no_transl_prefiX "LITERAL_ADR:" struct CdradrtrN { char *from_address[Cdradrtrn_leN]; char *to_address[Cdradrtrn_leN]; int fill_counter; }; #ifndef Cdrskin_extra_leaN /** Create a device address translator object */ int Cdradrtrn_new(struct CdradrtrN **trn, int flag) { struct CdradrtrN *o; int i; (*trn)= o= TSOB_FELD(struct CdradrtrN,1); if(o==NULL) return(-1); for(i= 0;ifrom_address[i]= NULL; o->to_address[i]= NULL; } o->fill_counter= 0; return(1); } /** Release from memory a device address translator object */ int Cdradrtrn_destroy(struct CdradrtrN **o, int flag) { int i; struct CdradrtrN *trn; trn= *o; if(trn==NULL) return(0); for(i= 0;ifill_counter;i++) { if(trn->from_address[i]!=NULL) free(trn->from_address[i]); if(trn->to_address[i]!=NULL) free(trn->to_address[i]); } free((char *) trn); *o= NULL; return(1); } /** Add a translation pair to the table @param trn The translator which shall learn @param from The user side address @param to The cdrskin side address @param flag Bitfield for control purposes: bit0= "from" contains from+to address, to[0] contains delimiter */ int Cdradrtrn_add(struct CdradrtrN *trn, char *from, char *to, int flag) { char buf[2*Cdrskin_adrleN+1],*from_pt,*to_pt; int cnt; cnt= trn->fill_counter; if(cnt>=Cdradrtrn_leN) return(-1); if(flag&1) { if(strlen(from)>=sizeof(buf)) return(0); strcpy(buf,from); to_pt= strchr(buf,to[0]); if(to_pt==NULL) return(0); *(to_pt)= 0; from_pt= buf; to_pt++; } else { from_pt= from; to_pt= to; } if(strlen(from)>=Cdrskin_adrleN || strlen(to)>=Cdrskin_adrleN) return(0); trn->from_address[cnt]= calloc(1, strlen(from_pt)+1); trn->to_address[cnt]= calloc(1, strlen(to_pt)+1); if(trn->from_address[cnt]==NULL || trn->to_address[cnt]==NULL) return(-2); strcpy(trn->from_address[cnt],from_pt); strcpy(trn->to_address[cnt],to_pt); trn->fill_counter++; return(1); } /** Apply eventual device address translation @param trn The translator @param from The address from which to translate @param driveno With backward translation only: The libburn drive number @param to The result of the translation @param flag Bitfield for control purposes: bit0= translate backward @return <=0 error, 1=no translation found, 2=translation found, 3=collision avoided */ int Cdradrtrn_translate(struct CdradrtrN *trn, char *from, int driveno, char to[Cdrskin_adrleN], int flag) { int i,ret= 1; char *adr; to[0]= 0; adr= from; if(flag&1) goto backward; if(strncmp(adr,Cdrskin_no_transl_prefiX, strlen(Cdrskin_no_transl_prefiX))==0) { adr= adr+strlen(Cdrskin_no_transl_prefiX); ret= 2; } else { for(i=0;ifill_counter;i++) if(strcmp(adr,trn->from_address[i])==0) break; if(ifill_counter) { adr= trn->to_address[i]; ret= 2; } } if(strlen(adr)>=Cdrskin_adrleN) return(-1); strcpy(to,adr); return(ret); backward:; if(strlen(from)>=Cdrskin_adrleN) sprintf(to,"%s%d",Cdrskin_no_transl_prefiX,driveno); else strcpy(to,from); for(i=0;ifill_counter;i++) if(strcmp(from,trn->to_address[i])==0 && strlen(trn->from_address[i])fill_counter) { ret= 2; strcpy(to,trn->from_address[i]); } else { for(i=0;ifill_counter;i++) if(strcmp(from,trn->from_address[i])==0) break; if(ifill_counter) if(strlen(from)+strlen(Cdrskin_no_transl_prefiX)boss= boss; o->trackno= trackno; o->source_path[0]= 0; o->original_source_path[0]= 0; o->source_fd= -1; o->is_from_stdin= !!(flag&2); o->fixed_size= 0.0; o->tao_to_sao_tsize= 0.0; o->padding= 0.0; o->set_by_padsize= 0; o->sector_pad_up= 1; o->track_type= BURN_MODE1; o->mode_modifiers= 0; o->sector_size= 2048.0; o->track_type_by_default= 1; o->swap_audio_bytes= 0; o->cdxa_conversion= 0; o->isrc[0]= 0; o->index_string= NULL; o->sao_pregap= -1; o->sao_postgap= -1; o->data_image_size= -1.0; o->iso_fs_descr= NULL; o->use_data_image_size= 0; o->extracting_container= 0; o->fifo_enabled= 0; o->fifo= NULL; o->fifo_outlet_fd= -1; o->fifo_size= 0; o->ff_fifo= NULL; o->ff_idx= -1; o->libburn_track= NULL; o->libburn_track_is_own= 0; #ifdef Cdrskin_use_libburn_fifO o->libburn_fifo= NULL; #endif /* Cdrskin_use_libburn_fifO */ if(flag & 1) return(1); ret= Cdrskin_get_source(boss,o->source_path,&(o->fixed_size), &(o->tao_to_sao_tsize),&(o->use_data_image_size), &(o->padding),&(o->set_by_padsize),&(skin_track_type), &(o->track_type_by_default), &(o->mode_modifiers), &(o->swap_audio_bytes), &(o->cdxa_conversion), 0); if(ret<=0) goto failed; strcpy(o->original_source_path,o->source_path); if(o->fixed_size>0.0) o->extracting_container= 1; Cdrtrack_set_track_type(o,skin_track_type,0); #ifndef Cdrskin_extra_leaN ret= Cdrskin_get_fifo_par(boss, &(o->fifo_enabled),&(o->fifo_size), &fifo_start_at,0); if(ret<=0) goto failed; #endif /* ! Cdrskin_extra_leaN */ return(1); failed:; Cdrtrack_destroy(track,0); return(-1); } /** Release from memory a track object previously created by Cdrtrack_new() */ int Cdrtrack_destroy(struct CdrtracK **o, int flag) { struct CdrtracK *track; track= *o; if(track==NULL) return(0); #ifndef Cdrskin_no_cdrfifO Cdrfifo_destroy(&(track->fifo),0); #endif if(track->libburn_track != NULL && track->libburn_track_is_own) burn_track_free(track->libburn_track); if(track->iso_fs_descr!=NULL) free((char *) track->iso_fs_descr); if(track->index_string != NULL) free(track->index_string); free((char *) track); *o= NULL; return(1); } int Cdrtrack_set_track_type(struct CdrtracK *o, int track_type, int flag) { if(track_type==BURN_AUDIO) { o->track_type= BURN_AUDIO; o->sector_size= 2352.0; } else { o->track_type= BURN_MODE1; o->sector_size= 2048.0; } return(1); } int Cdrtrack_get_track_type(struct CdrtracK *o, int *track_type, int *sector_size, int flag) { *track_type= o->track_type; *sector_size= o->sector_size; return(1); } /** @param flag Bitfield for control purposes: bit0= size returns number of actually processed source bytes rather than the predicted fixed_size (if available). padding returns the difference from number of written bytes. bit1= size returns fixed_size, padding returns tao_to_sao_tsize */ int Cdrtrack_get_size(struct CdrtracK *track, double *size, double *padding, double *sector_size, int *use_data_image_size, int flag) { off_t readcounter= 0,writecounter= 0; *size= track->fixed_size; *padding= track->padding; *use_data_image_size= track->use_data_image_size; if((flag&1) && track->libburn_track!=NULL) { burn_track_get_counters(track->libburn_track,&readcounter,&writecounter); *size= readcounter; *padding= writecounter-readcounter; } else if(flag&2) *padding= track->tao_to_sao_tsize; *sector_size= track->sector_size; return(1); } int Cdrtrack_get_iso_fs_descr(struct CdrtracK *track, char **descr, double *size, int flag) { *descr= track->iso_fs_descr; *size= track->data_image_size; return(*descr != NULL && *size > 0.0); } int Cdrtrack_get_source_path(struct CdrtracK *track, char **source_path, int *source_fd, int *is_from_stdin, int flag) { *source_path= track->original_source_path; *source_fd= track->source_fd; *is_from_stdin= track->is_from_stdin; return(1); } #ifdef Cdrskin_use_libburn_fifO int Cdrtrack_get_libburn_fifo(struct CdrtracK *track, struct burn_source **fifo, int flag) { *fifo= track->libburn_fifo; return(1); } int Cdrtrack_report_fifo(struct CdrtracK *track, int flag) { int size, free_bytes, ret; int total_min_fill, interval_min_fill, put_counter, get_counter; int empty_counter, full_counter; double fifo_percent; char *status_text; if(track->libburn_fifo == NULL) return(0); /* Check for open input or leftover bytes in liburn fifo */ ret = burn_fifo_inquire_status(track->libburn_fifo, &size, &free_bytes, &status_text); if(ret >= 0 && size - free_bytes > 1) { /* not clear why free_bytes is reduced by 1 */ fprintf(stderr, "cdrskin: FATAL : Fifo still contains data after burning has ended.\n"); fprintf(stderr, "cdrskin: FATAL : %d bytes left.\n", size - free_bytes - 1); fprintf(stderr, "cdrskin: FATAL : This indicates an overflow of the last track.\n"); fprintf(stderr, "cdrskin: NOTE : The media might appear ok but is probably truncated.\n"); return(-1); } burn_fifo_get_statistics(track->libburn_fifo, &total_min_fill, &interval_min_fill, &put_counter, &get_counter, &empty_counter, &full_counter); fifo_percent= 100.0*((double) total_min_fill)/(double) size; if(fifo_percent==0 && total_min_fill>0) fifo_percent= 1; fflush(stdout); fprintf(stderr,"Cdrskin: fifo had %d puts and %d gets.\n", put_counter,get_counter); fprintf(stderr, "Cdrskin: fifo was %d times empty and %d times full, min fill was %.f%%.\n", empty_counter, full_counter, fifo_percent); return(1); } #endif /* Cdrskin_use_libburn_fifO */ int Cdrtrack_get_fifo(struct CdrtracK *track, struct CdrfifO **fifo, int flag) { *fifo= track->fifo; return(1); } /** Try whether automatic audio extraction is appropriate and eventually open a file descriptor to the raw data. @return -3 identified as .wav but with cdrecord-inappropriate parameters -2 could not open track source, no use in retrying -1 severe error 0 not appropriate to extract, burn plain file content 1 to be extracted, *fd is a filedescriptor delivering raw data */ int Cdrtrack_extract_audio(struct CdrtracK *track, int *fd, off_t *xtr_size, int flag) { int l, ok= 0; struct libdax_audioxtr *xtr= NULL; char *fmt,*fmt_info; int num_channels,sample_rate,bits_per_sample,msb_first,ret; *fd= -1; if(track->track_type!=BURN_AUDIO && !track->track_type_by_default) return(0); l= strlen(track->source_path); if(l>=4) if(strcmp(track->source_path+l-4,".wav")==0) ok= 1; if(l>=3) if(strcmp(track->source_path+l-3,".au")==0) ok= 1; if(!ok) return(0); if(track->track_type_by_default) { Cdrtrack_set_track_type(track,BURN_AUDIO,0); track->track_type_by_default= 2; fprintf(stderr,"cdrskin: NOTE : Activated -audio for '%s'\n", track->source_path); } ret= libdax_audioxtr_new(&xtr,track->source_path,0); if(ret<=0) return(ret); libdax_audioxtr_get_id(xtr,&fmt,&fmt_info, &num_channels,&sample_rate,&bits_per_sample,&msb_first,0); if((strcmp(fmt,".wav")!=0 && strcmp(fmt,".au")!=0) || num_channels!=2 || sample_rate!=44100 || bits_per_sample!=16) { fprintf(stderr,"cdrskin: ( %s )\n",fmt_info); fprintf(stderr,"cdrskin: FATAL : Inappropriate audio coding in '%s'.\n", track->source_path); {ret= -3; goto ex;} } libdax_audioxtr_get_size(xtr,xtr_size,0); ret= libdax_audioxtr_detach_fd(xtr,fd,0); if(ret<=0) {ret= -1*!!ret; goto ex;} track->swap_audio_bytes= !!msb_first; track->extracting_container= 1; fprintf(stderr,"cdrskin: NOTE : %.f %saudio bytes in '%s'\n", (double) *xtr_size, (msb_first ? "" : "(-swab) "), track->source_path); ret= 1; ex: libdax_audioxtr_destroy(&xtr,0); return(ret); } /* @param flag bit0=set *size_used as the detected data image size */ int Cdrtrack_activate_image_size(struct CdrtracK *track, double *size_used, int flag) { if(flag&1) track->data_image_size= *size_used; else *size_used= track->data_image_size; if(track->use_data_image_size!=1) return(2); if(*size_used<=0) return(0); track->fixed_size= *size_used; track->use_data_image_size= 2; if(track->libburn_track!=NULL) burn_track_set_size(track->libburn_track, (off_t) *size_used); /* man cdrecord prescribes automatic -pad with -isosize. cdrskin obeys only if the current padding is less than that. */ if(track->padding<15*2048) { track->padding= 15*2048; track->set_by_padsize= 0; } track->extracting_container= 1; #ifndef Cdrskin_no_cdrfifO if(track->ff_fifo!=NULL) Cdrfifo_set_fd_in_limit(track->ff_fifo,track->fixed_size,track->ff_idx,0); #endif return(1); } int Cdrtrack_seek_isosize(struct CdrtracK *track, int fd, int flag) { struct stat stbuf; char secbuf[2048]; int ret,got,i; double size; if(fstat(fd,&stbuf)==-1) return(0); if((stbuf.st_mode&S_IFMT)!=S_IFREG && (stbuf.st_mode&S_IFMT)!=S_IFBLK) return(2); if(track->iso_fs_descr!=NULL) free((char *) track->iso_fs_descr); track->iso_fs_descr= TSOB_FELD(char,16*2048); if(track->iso_fs_descr==NULL) return(-1); for(i=0;i<32 && track->data_image_size<=0;i++) { for(got= 0; got<2048;got+= ret) { ret= read(fd, secbuf+got, 2048-got); if(ret<=0) return(0); } if(i<16) continue; memcpy(track->iso_fs_descr+(i-16)*2048,secbuf,2048); if(i>16) continue; ret= Scan_for_iso_size((unsigned char *) secbuf, &size, 0); if(ret<=0) break; track->data_image_size= size; if(track->use_data_image_size) { Cdrtrack_activate_image_size(track,&size,1); track->fixed_size= size; track->use_data_image_size= 2; } } ret= lseek(fd, (off_t) 0, SEEK_SET); if(ret!=0) { fprintf(stderr, "cdrskin: FATAL : Cannot lseek() to 0 after -isosize determination\n"); if(errno!=0) fprintf(stderr, "cdrskin: errno=%d : %s\n", errno, strerror(errno)); return(-1); } return(track->data_image_size>0); } /** Deliver an open file descriptor corresponding to the source path of track. @param flag Bitfield for control purposes: bit0=debugging verbosity bit1=open as source for direct write: no audio extract, no minimum track size bit2=permission to use burn_os_open_track_src() (evtl O_DIRECT) @return <=0 error, 1 success */ int Cdrtrack_open_source_path(struct CdrtracK *track, int *fd, int flag) { int is_wav= 0, size_from_file= 0, ret, self_opened= 0; off_t xtr_size= 0; struct stat stbuf; char *device_adr,*raw_adr; int no_convert_fs_adr; int Cdrskin_get_device_adr(struct CdrskiN *skin, char **device_adr, char **raw_adr, int *no_convert_fs_adr,int flag); int Cdrskin_get_drive(struct CdrskiN *skin, struct burn_drive **drive, int flag); struct burn_drive *drive; if(track->source_path[0]=='-' && track->source_path[1]==0) *fd= 0; else if(track->source_path[0]=='#' && (track->source_path[1]>='0' && track->source_path[1]<='9')) *fd= atoi(track->source_path+1); else { *fd= -1; self_opened= 1; ret= Cdrskin_get_device_adr(track->boss,&device_adr,&raw_adr, &no_convert_fs_adr,0); if(ret <= 0) { fprintf(stderr, "cdrskin: FATAL : No drive found. Cannot prepare track.\n"); return(0); } /* fprintf(stderr, "cdrskin: DEBUG : device_adr='%s' , raw_adr='%s' , ncfs=%d\n", device_adr, raw_adr, no_convert_fs_adr); */ if(!no_convert_fs_adr) { if(flag&1) ClN(fprintf(stderr, "cdrskin_debug: checking track source for identity with drive\n")); ret= Cdrskin_get_drive(track->boss,&drive,0); if(ret<=0) { fprintf(stderr, "cdrskin: FATAL : Program error. Cannot determine libburn drive.\n"); return(0); } if(burn_drive_equals_adr(drive,track->source_path,2)>0) { fprintf(stderr, "cdrskin: FATAL : track source address leads to burner drive\n"); fprintf(stderr, "cdrskin: : dev='%s' -> '%s' <- track source '%s'\n", raw_adr, device_adr, track->source_path); return(0); } } /* fprintf(stderr,"cdrskin: EXPERIMENTAL : Deliberate abort\n"); return(0); */ if(!(flag&2)) is_wav= Cdrtrack_extract_audio(track,fd,&xtr_size,0); if(is_wav==-1) return(-1); if(is_wav==-3) return(0); if(is_wav==0) { if(track->track_type != BURN_MODE1 || (track->cdxa_conversion & 0x7fffffff)) flag&= ~4; /* Better avoid O_DIRECT with odd sectors */ if(flag & 4) *fd= burn_os_open_track_src(track->source_path, O_RDONLY, 0); else *fd= open(track->source_path, O_RDONLY); } if(*fd==-1) { fprintf(stderr,"cdrskin: failed to open source address '%s'\n", track->source_path); fprintf(stderr,"cdrskin: errno=%d , \"%s\"\n",errno, errno==0?"-no error code available-":strerror(errno)); return(0); } if(track->use_data_image_size==1 && xtr_size<=0) { ret= Cdrtrack_seek_isosize(track,*fd,0); if(ret == -1) { close(*fd); *fd= -1; return(-1); } } else if(track->fixed_size<=0) { /* >>> ??? is it intentional that tsize overrides .wav header ? */ if(xtr_size>0) { track->fixed_size= xtr_size; if(track->use_data_image_size==1) track->use_data_image_size= 2; /* count this as image size found */ size_from_file= 1; } else { if(fstat(*fd,&stbuf)!=-1) { if((stbuf.st_mode&S_IFMT)==S_IFREG) { track->fixed_size= stbuf.st_size; size_from_file= 1; } /* all other types are assumed of open ended size */ } } } } track->source_fd= *fd; if(track->fixed_size < Cdrtrack_minimum_sizE * track->sector_size && (track->fixed_size>0 || size_from_file) && !(flag&2)) { if(track->track_type == BURN_AUDIO) { /* >>> cdrecord: We differ in automatic padding with audio: Audio tracks must be at least 705600 bytes and a multiple of 2352. */ fprintf(stderr, "cdrskin: FATAL : Audio tracks must be at least %.f bytes\n", Cdrtrack_minimum_sizE*track->sector_size); return(0); } else { fprintf(stderr, "cdrskin: NOTE : Enforcing minimum track size of %.f bytes\n", Cdrtrack_minimum_sizE*track->sector_size); track->fixed_size= Cdrtrack_minimum_sizE*track->sector_size; } } return((*fd >= 0) * (1 + self_opened)); } #ifndef Cdrskin_no_cdrfifO /** Install a fifo object between data source and libburn. Its parameters are known to track. @param outlet_fd Returns the filedescriptor of the fifo outlet. @param previous_fifo Object address for chaining or follow-up attachment. @param flag Bitfield for control purposes: bit0= Debugging verbosity bit1= Do not create and attach a new fifo but attach new follow-up fd pair to previous_fifo bit2= Do not enforce fixed_size if not container extraction @return <=0 error, 1 success */ int Cdrtrack_attach_fifo(struct CdrtracK *track, int *outlet_fd, struct CdrfifO *previous_fifo, int flag) { struct CdrfifO *ff; int source_fd,pipe_fds[2],ret; *outlet_fd= -1; if(track->fifo_size<=0) return(2); ret= Cdrtrack_open_source_path(track,&source_fd, (flag&1) | (4 * (track->fifo_size >= 256 * 1024))); if(ret<=0) return(ret); if(pipe(pipe_fds)==-1) return(0); Cdrfifo_destroy(&(track->fifo),0); if(flag&2) { ret= Cdrfifo_attach_follow_up_fds(previous_fifo,source_fd,pipe_fds[1],0); if(ret<=0) return(ret); track->ff_fifo= previous_fifo; track->ff_idx= ret-1; } else { /* >>> ??? obtain track sector size and use instead of 2048 ? */ ret= Cdrfifo_new(&ff,source_fd,pipe_fds[1],2048,track->fifo_size, flag & 1); if(ret<=0) return(ret); if(previous_fifo!=NULL) Cdrfifo_attach_peer(previous_fifo,ff,0); track->fifo= track->ff_fifo= ff; track->ff_idx= -1; } track->fifo_outlet_fd= pipe_fds[0]; if((track->extracting_container || !(flag&4)) && track->fixed_size>0) Cdrfifo_set_fd_in_limit(track->ff_fifo,track->fixed_size,track->ff_idx,0); if(flag&1) printf( "cdrskin_debug: track %d fifo replaced source_address '%s' by '#%d'\n", track->trackno+1,track->source_path,track->fifo_outlet_fd); sprintf(track->source_path,"#%d",track->fifo_outlet_fd); track->source_fd= track->fifo_outlet_fd; *outlet_fd= track->fifo_outlet_fd; return(1); } #endif /* ! Cdrskin_no_cdrfifO */ #ifndef Cdrskin_extra_leaN #ifdef Cdrskin_use_libburn_fifO /** Read data into the eventual libburn fifo until either fifo_start_at bytes are read (-1 = no limit), it is full or or the data source is exhausted. @return <=0 error, 1 success */ int Cdrtrack_fill_libburn_fifo(struct CdrtracK *track, int fifo_start_at, int flag) { int ret, bs= 32 * 1024; int buffer_size, buffer_free; double data_image_size; char buf[64 * 1024], *buffer_text; if(fifo_start_at == 0) return(2); if(track->libburn_fifo == NULL) return(2); if(fifo_start_at>0 && fifo_start_atfifo_size) printf( "cdrskin: NOTE : Input buffer will be initially filled up to %d bytes\n", fifo_start_at); printf("Waiting for reader process to fill input buffer ... "); fflush(stdout); ret= burn_fifo_fill(track->libburn_fifo, fifo_start_at, (fifo_start_at == -1)); if(ret < 0) return(0); /** Ticket 55: check fifos for input, throw error on 0-bytes from stdin @return <=0 abort run, 1 go on with burning */ ret= burn_fifo_inquire_status(track->libburn_fifo, &buffer_size, &buffer_free, &buffer_text); if(track->is_from_stdin) { if(ret<0 || buffer_size <= buffer_free) { fprintf(stderr,"\ncdrskin: FATAL : (First track) fifo did not read a single byte from stdin\n"); return(0); } } /* Try to obtain ISO 9660 Volume Descriptors and size from fifo. Not an error if there is no ISO 9660. */ if(track->iso_fs_descr != NULL) free(track->iso_fs_descr); track->iso_fs_descr = NULL; if(buffer_size - buffer_free >= 64 * 1024) { ret= burn_fifo_peek_data(track->libburn_fifo, buf, 64 * 1024, 0); if(ret == 1) { track->iso_fs_descr = calloc(1, bs); if(track->iso_fs_descr == NULL) return(-1); memcpy(track->iso_fs_descr, buf + bs, bs); ret= Scan_for_iso_size((unsigned char *) buf + bs, &data_image_size, 0); if(ret > 0) track->data_image_size= data_image_size; } } return(1); } #endif /* Cdrskin_use_libburn_fifO */ #ifdef Cdrskin_no_cdrfifO int Cdrtrack_fill_fifo(struct CdrtracK *track, int fifo_start_at, int flag) { return(Cdrtrack_fill_libburn_fifo(track, fifo_start_at, 0)); } #else /* Cdrskin_no_cdrfifO */ int Cdrtrack_fill_fifo(struct CdrtracK *track, int fifo_start_at, int flag) { int ret,buffer_fill,buffer_space; double data_image_size; if(fifo_start_at==0) return(2); if(track->fifo==NULL) { #ifdef Cdrskin_use_libburn_fifO ret= Cdrtrack_fill_libburn_fifo(track, fifo_start_at, 0); return(ret); #else return(2); #endif } if(fifo_start_at>0 && fifo_start_atfifo_size) printf( "cdrskin: NOTE : Input buffer will be initially filled up to %d bytes\n", fifo_start_at); printf("Waiting for reader process to fill input buffer ... "); fflush(stdout); ret= Cdrfifo_fill(track->fifo,fifo_start_at,0); if(ret<=0) return(ret); /** Ticket 55: check fifos for input, throw error on 0-bytes from stdin @return <=0 abort run, 1 go on with burning */ if(track->is_from_stdin) { ret= Cdrfifo_get_buffer_state(track->fifo,&buffer_fill,&buffer_space,0); if(ret<0 || buffer_fill<=0) { fprintf(stderr,"\ncdrskin: FATAL : (First track) fifo did not read a single byte from stdin\n"); return(0); } } ret= Cdrfifo_get_iso_fs_size(track->fifo,&data_image_size,0); if(ret>0) track->data_image_size= data_image_size; if(track->iso_fs_descr!=NULL) free((char *) track->iso_fs_descr); Cdrfifo_adopt_iso_fs_descr(track->fifo,&(track->iso_fs_descr),0); return(1); } #endif /* ! Cdrskin_no_cdrfifO */ #endif /* ! Cdrskin_extra_leaN */ int Cdrtrack_set_indice(struct CdrtracK *track, int flag) { int idx= 1, adr, prev_adr= -1, ret; char *cpt, *ept; if(track->sao_pregap >= 0) { ret= burn_track_set_pregap_size(track->libburn_track, track->sao_pregap, 0); if(ret <= 0) return(ret); } if(track->sao_postgap >= 0) { ret= burn_track_set_postgap_size(track->libburn_track, track->sao_postgap, 0); if(ret <= 0) return(ret); } if(track->index_string == NULL) return(2); for(ept= cpt= track->index_string; ept != NULL; cpt= ept + 1) { ept= strchr(cpt, ','); if(ept != NULL) *ept= 0; adr= -1; sscanf(cpt, "%d", &adr); if(adr < 0) { fprintf(stderr, "cdrskin: SORRY : Bad address number with index=\n"); return(0); } if(idx == 1 && adr != 0) { fprintf(stderr, "cdrskin: SORRY : First address number of index= is not 0\n"); return(0); } if(idx > 1 && adr < prev_adr) { fprintf(stderr, "cdrskin: SORRY : Backward address number with index=\n"); return(0); } ret= burn_track_set_index(track->libburn_track, idx, adr, 0); if(ret <= 0) return(ret); prev_adr= adr; if(ept != NULL) *ept= ','; idx++; } return(1); } /** Create a corresponding libburn track object and add it to the libburn session. This may change the trackno index set by Cdrtrack_new(). */ int Cdrtrack_add_to_session(struct CdrtracK *track, int trackno, struct burn_session *session, int flag) /* bit0= debugging verbosity bit1= apply padding hack (<<< should be unused for now) bit2= permission to use O_DIRECT (if enabled at compile time) */ { struct burn_track *tr; struct burn_source *src= NULL; double padding,lib_padding; int ret,sector_pad_up; double fixed_size; int source_fd; #ifdef Cdrskin_use_libburn_fifO struct burn_source *fd_src= NULL; #endif track->trackno= trackno; tr= burn_track_create(); if(tr == NULL) {ret= -1; goto ex;} track->libburn_track= tr; track->libburn_track_is_own= 1; /* Note: track->track_type may get set in here */ if(track->source_fd==-1) { ret= Cdrtrack_open_source_path(track, &source_fd, flag & (4 | 1)); if(ret<=0) goto ex; } padding= 0.0; sector_pad_up= track->sector_pad_up; if(track->padding>0) { if(track->set_by_padsize || track->track_type!=BURN_AUDIO) padding= track->padding; else sector_pad_up= 1; } if(flag&2) lib_padding= 0.0; else lib_padding= padding; if(flag&1) { if(sector_pad_up) { ClN(fprintf(stderr,"cdrskin_debug: track %d telling burn_track_define_data() to pad up last sector\n",trackno+1)); } if(lib_padding>0 || !sector_pad_up) { ClN(fprintf(stderr, "cdrskin_debug: track %d telling burn_track_define_data() to pad %.f bytes\n", trackno+1,lib_padding)); } } burn_track_define_data(tr,0,(int) lib_padding,sector_pad_up, track->track_type | track->mode_modifiers); burn_track_set_default_size(tr, (off_t) track->tao_to_sao_tsize); burn_track_set_byte_swap(tr, (track->track_type==BURN_AUDIO && track->swap_audio_bytes)); if(!(track->cdxa_conversion & (1 << 31))) burn_track_set_cdxa_conv(tr, track->cdxa_conversion & 0x7fffffff); fixed_size= track->fixed_size; if((flag&2) && track->padding>0) { if(flag&1) ClN(fprintf(stderr,"cdrskin_debug: padding hack : %.f + %.f = %.f\n", track->fixed_size,track->padding, track->fixed_size+track->padding)); fixed_size+= track->padding; } src= burn_fd_source_new(track->source_fd,-1,(off_t) fixed_size); #ifdef Cdrskin_use_libburn_fifO if(src != NULL && track->fifo == NULL) { int fifo_enabled, fifo_size, fifo_start_at, chunksize, chunks; int Cdrskin_get_fifo_par(struct CdrskiN *skin, int *fifo_enabled, int *fifo_size, int *fifo_start_at, int flag); Cdrskin_get_fifo_par(track->boss, &fifo_enabled, &fifo_size, &fifo_start_at, 0); if(track->track_type == BURN_AUDIO) chunksize= 2352; else if (track->cdxa_conversion == 1) chunksize= 2056; else chunksize= 2048; chunks= fifo_size / chunksize; if(chunks > 1 && fifo_enabled) { fd_src= src; src= burn_fifo_source_new(fd_src, chunksize, chunks, (chunksize * chunks >= 128 * 1024)); if((flag & 1) || src == NULL) fprintf(stderr, "cdrskin_DEBUG: %s libburn fifo of %d bytes\n", src != NULL ? "installed" : "failed to install", chunksize * chunks); track->libburn_fifo= src; if(src == NULL) { src= fd_src; fd_src= NULL; } } } #endif /* Cdrskin_use_libburn_fifO */ if(src==NULL) { fprintf(stderr, "cdrskin: FATAL : Could not create libburn data source object\n"); {ret= 0; goto ex;} } if(burn_track_set_source(tr,src)!=BURN_SOURCE_OK) { fprintf(stderr,"cdrskin: FATAL : libburn rejects data source object\n"); {ret= 0; goto ex;} } ret= Cdrtrack_set_indice(track, 0); if(ret <= 0) goto ex; burn_session_add_track(session,tr,BURN_POS_END); ret= 1; ex: #ifdef Cdrskin_use_libburn_fifO if(fd_src!=NULL) burn_source_free(fd_src); #endif if(src!=NULL) burn_source_free(src); return(ret); } /** Release libburn track information after a session is done */ int Cdrtrack_cleanup(struct CdrtracK *track, int flag) { if(track->libburn_track==NULL) return(0); if(track->libburn_track_is_own) burn_track_free(track->libburn_track); track->libburn_track= NULL; return(1); } int Cdrtrack_ensure_padding(struct CdrtracK *track, int flag) /* flag: bit0= debugging verbosity */ { if(track->track_type!=BURN_AUDIO) return(2); if(flag&1) fprintf(stderr,"cdrskin_debug: enforcing -pad on last -audio track\n"); track->sector_pad_up= 1; return(1); } int Cdrtrack_get_sectors(struct CdrtracK *track, int flag) { return(burn_track_get_sectors(track->libburn_track)); } #ifndef Cdrskin_no_cdrfifO /** Try to read bytes from the track's fifo outlet and eventually discard them. Not to be called unless the track is completely written. */ int Cdrtrack_has_input_left(struct CdrtracK *track, int flag) { int ready,ret; char buf[2]; if(track->fifo_outlet_fd<=0) return(0); ready= Wait_for_input(track->fifo_outlet_fd, 0, 0); if(ready<=0) return(0); ret= read(track->fifo_outlet_fd,buf,1); if(ret>0) return(1); return(0); } #endif /* ! Cdrskin_no_cdrfifO */ /* --------------------------------------------------------------------- */ /** The list of startup file names */ #define Cdrpreskin_rc_nuM 4 static char Cdrpreskin_sys_rc_nameS[Cdrpreskin_rc_nuM][80]= { "/etc/default/cdrskin", "/etc/opt/cdrskin/rc", "/etc/cdrskin/cdrskin.conf", "placeholder for $HOME/.cdrskinrc" }; /** A structure which bundles several parameters for creation of the CdrskiN object. It finally becomes a managed subordinate of the CdrskiN object. */ struct CdrpreskiN { /* to be transfered into skin */ int verbosity; char queue_severity[81]; char print_severity[81]; /** Whether to wait for available standard input data before touching drives*/ int do_waiti; /** Stores eventually given absolute device address before translation */ char raw_device_adr[Cdrskin_adrleN]; /** Stores an eventually given translated absolute device address between Cdrpreskin_setup() and Cdrskin_create() . */ char device_adr[Cdrskin_adrleN]; /** The eventual address translation table */ struct CdradrtrN *adr_trn; /** Memorizes the abort handling mode from presetup to creation of control object. Defined handling modes are: 0= no abort handling 1= try to cancel, release, exit (leave signal mode as set by caller) 2= try to ignore all signals 3= mode 1 in normal operation, mode 2 during abort handling 4= mode 1 in normal operation, mode 0 during abort handling -1= install abort handling 1 only in Cdrskin_burn() after burning started */ int abort_handler; /** Whether to allow getuid()!=geteuid() */ int allow_setuid; /** Whether to allow user provided addresses like #4 */ int allow_fd_source; /** Whether to support media types which are implemented but yet untested */ int allow_untested_media; /** Whether to allow libburn pseudo-drives "stdio:" . 0=forbidden, 1=seems ok, 2=potentially forbidden (depends on uid, euid, file type) */ int allow_emulated_drives; /** Whether an option is given which needs a full bus scan */ int no_whitelist; /** Whether the translated device address shall not follow softlinks, device clones and SCSI addresses */ int no_convert_fs_adr; /** Whether Bus,Target,Lun addresses shall be converted literally as old Pseudo SCSI-Adresses. New default is to use (possibly system emulated) real SCSI addresses via burn_drive_convert_scsi_adr() and literally emulated and cdrecord-incompatible ATA: addresses. */ int old_pseudo_scsi_adr; /** Whether to omit bus scanning */ int do_not_scan; /** Whether bus scans shall exit!=0 if no drive was found */ int scan_demands_drive; /** Whether to abort when a busy drive is encountered during bus scan */ int abort_on_busy_drive; /** Linux specific : Whether to try to avoid collisions when opening drives */ int drive_exclusive; /** Linux specific : Whether to obtain an exclusive drive lock via fcntl() */ int drive_fcntl_f_setlk; /** Linux specific : Device file address family to use : 0=default , 1=sr , 2=scd , 4=sg */ int drive_scsi_dev_family; /** Whether to try to wait for unwilling drives to become willing to open */ int drive_blocking; /** Explicit write mode option is determined before skin processes any track arguments */ char write_mode_name[80]; #ifndef Cdrskin_extra_leaN /** List of startupfiles */ char rc_filenames[Cdrpreskin_rc_nuM][Cdrskin_strleN]; int rc_filename_count; /** Non-argument options from startupfiles */ int pre_argc; char **pre_argv; int *pre_argidx; int *pre_arglno; #endif /* ! Cdrskin_extra_leaN */ /* The eventual name of a program to be executed if demands_cdrecord_caps is >0 and demands_cdrskin_caps is <=0 */ char fallback_program[Cdrskin_strleN]; int demands_cdrecord_caps; int demands_cdrskin_caps; int result_fd; }; /** Create a preliminary cdrskin program run control object. It will become part of the final control object. @param preskin Returns pointer to resulting @param flag Bitfield for control purposes: unused yet @return <=0 error, 1 success */ int Cdrpreskin_new(struct CdrpreskiN **preskin, int flag) { struct CdrpreskiN *o; int i; (*preskin)= o= TSOB_FELD(struct CdrpreskiN,1); if(o==NULL) return(-1); o->verbosity= 0; strcpy(o->queue_severity,"NEVER"); strcpy(o->print_severity,"SORRY"); o->do_waiti= 0; o->raw_device_adr[0]= 0; o->device_adr[0]= 0; o->adr_trn= NULL; o->abort_handler= 3; o->allow_setuid= 0; o->allow_fd_source= 0; o->allow_untested_media= 0; o->allow_emulated_drives= 0; o->no_whitelist= 0; o->no_convert_fs_adr= 0; o->old_pseudo_scsi_adr= 0; o->do_not_scan= 0; o->scan_demands_drive= 0; o->abort_on_busy_drive= 0; o->drive_exclusive= 1; o->drive_fcntl_f_setlk= 1; o->drive_scsi_dev_family= 0; o->drive_blocking= 0; strcpy(o->write_mode_name,"DEFAULT"); #ifndef Cdrskin_extra_leaN o->rc_filename_count= Cdrpreskin_rc_nuM; for(i=0;irc_filename_count-1;i++) strcpy(o->rc_filenames[i],Cdrpreskin_sys_rc_nameS[i]); o->rc_filenames[o->rc_filename_count-1][0]= 0; o->pre_argc= 0; o->pre_argv= NULL; o->pre_argidx= NULL; o->pre_arglno= NULL; #endif /* ! Cdrskin_extra_leaN */ o->fallback_program[0]= 0; o->demands_cdrecord_caps= 0; o->demands_cdrskin_caps= 0; o->result_fd = -1; return(1); } int Cdrpreskin_destroy(struct CdrpreskiN **preskin, int flag) { struct CdrpreskiN *o; o= *preskin; if(o==NULL) return(0); #ifndef Cdrskin_extra_leaN if((o->pre_arglno)!=NULL) free((char *) o->pre_arglno); if((o->pre_argidx)!=NULL) free((char *) o->pre_argidx); if(o->pre_argc>0 && o->pre_argv!=NULL) Sfile_destroy_argv(&(o->pre_argc),&(o->pre_argv),0); Cdradrtrn_destroy(&(o->adr_trn),0); #endif /* ! Cdrskin_extra_leaN */ free((char *) o); *preskin= NULL; return(1); } int Cdrpreskin_set_severities(struct CdrpreskiN *preskin, char *queue_severity, char *print_severity, int flag) { if(queue_severity!=NULL) strcpy(preskin->queue_severity,queue_severity); if(print_severity!=NULL) strcpy(preskin->print_severity,print_severity); burn_msgs_set_severities(preskin->queue_severity, preskin->print_severity, "cdrskin: "); return(1); } int Cdrpreskin_initialize_lib(struct CdrpreskiN *preskin, int flag) { int ret, major, minor, micro; /* Needed are at least 44 bits in signed type off_t . This is a popular mistake in configuration or compilation. */ if(sizeof(off_t) < 6) { fprintf(stderr, "\ncdrskin: FATAL : Compile time misconfiguration. sizeof(off_t) too small.\n" ); return(0); } /* This is the minimum requirement of cdrskin towards the libburn header at compile time. It gets compared against the version macros in libburn/libburn.h : burn_header_version_major burn_header_version_minor burn_header_version_micro If the header is too old then the following code shall cause failure of cdrskin compilation rather than to allow production of a program with unpredictable bugs or memory corruption. The compiler message supposed to appear in this case is: error: 'LIBBURN_MISCONFIGURATION' undeclared (first use in this function) error: 'INTENTIONAL_ABORT_OF_COMPILATION__HEADERFILE_libburn_dot_h_TOO_OLD__SEE_cdrskin_dot_c' undeclared (first use in this function) error: 'LIBBURN_MISCONFIGURATION_' undeclared (first use in this function) */ /* The indendation is an advise of man gcc to help old compilers ignoring */ #if Cdrskin_libburn_majoR > burn_header_version_major #define Cdrskin_libburn_dot_h_too_olD 1 #endif #if Cdrskin_libburn_majoR == burn_header_version_major && Cdrskin_libburn_minoR > burn_header_version_minor #define Cdrskin_libburn_dot_h_too_olD 1 #endif #if Cdrskin_libburn_minoR == burn_header_version_minor && Cdrskin_libburn_micrO > burn_header_version_micro #define Cdrskin_libburn_dot_h_too_olD 1 #endif #ifdef Cdrskin_libburn_dot_h_too_olD LIBBURN_MISCONFIGURATION = 0; INTENTIONAL_ABORT_OF_COMPILATION__HEADERFILE_libburn_dot_h_TOO_OLD__SEE_cdrskin_dot_c = 0; LIBBURN_MISCONFIGURATION_ = 0; #endif ret= burn_initialize(); if(ret==0) { fprintf(stderr,"cdrskin: FATAL : Initialization of libburn failed\n"); return(0); } /* This is the runtime check towards eventual dynamically linked libburn. cdrskin deliberately does not to allow the library to be older than the header file which was seen at compile time. More liberal would be to use here Cdrskin_libburn_* instead of burn_header_version_* . */ burn_version(&major, &minor, µ); if(majorqueue_severity); strcpy(print_severity,o->print_severity); } if(o->verbosity>=Cdrskin_verbose_debuG) Cdrpreskin_set_severities(o,"DEBUG","NEVER",0); else Cdrpreskin_set_severities(o,"SORRY","NEVER",0); queueing= 1; return(1); } if(queueing) Cdrpreskin_set_severities(o,queue_severity,print_severity,0); queueing= 0; for(first= 1; ; first= 0) { ret= burn_msgs_obtain("ALL",&error_code,msg,&os_errno,msg_severity); if(ret==0) break; if(ret<0) { fprintf(stderr, "cdrskin: NOTE : Please inform libburn-hackers@pykix.org about:\n"); fprintf(stderr, "cdrskin: burn_msgs_obtain() returns %d\n",ret); break; } if(first) fprintf(stderr, "cdrskin: -------------------- Messages from Libburn ---------------------\n"); for(i=0;msg_severity[i]!=0;i++) filler[i]= ' '; filler[i]= 0; fprintf(stderr,"cdrskin: %s : %s\n",msg_severity,msg); if(strcmp(msg_severity,"DEBUG")!=0 && os_errno!=0) fprintf(stderr,"cdrskin: %s ( errno=%d '%s')\n", filler,os_errno,strerror(os_errno)); } if(first==0) fprintf(stderr, "cdrskin: ----------------------------------------------------------------\n"); #endif /* Cdrskin_debug_libdax_msgS */ return(1); } /** Evaluate whether the user would be allowed in any case to use device_adr as pseudo-drive */ int Cdrpreskin__allows_emulated_drives(char *device_adr, char reason[4096], int flag) { struct stat stbuf; reason[0]= 0; if(device_adr[0]) { if(strcmp(device_adr,"/dev/null")==0) return(1); strcat(reason,"File object is not /dev/null. "); } if(getuid()!=geteuid()) { strcat(reason,"UID and EUID differ"); return(0); } if(getuid()!=0) return(1); strcat(reason,"UID is 0. "); /* Directory must be owned by root and write protected against any others*/ if(lstat("/root/cdrskin_permissions",&stbuf)==-1 || !S_ISDIR(stbuf.st_mode)) { strcat(reason, "No directory /root/cdrskin_permissions exists"); return(0); } if(stbuf.st_uid!=0) { strcat(reason, "Directory /root/cdrskin_permissions not owned by UID 0"); return(0); } if(stbuf.st_mode & (S_IWGRP | S_IWOTH)) { strcat(reason, "Directory /root/cdrskin_permissions has w-permission for group or others"); return(0); } if(stat("/root/cdrskin_permissions/allow_emulated_drives",&stbuf)==-1) { strcat(reason, "No file /root/cdrskin_permissions/allow_emulated_drives exists"); return(0); } reason[0]= 0; return(1); } int Cdrpreskin_consider_normal_user(int flag) { fprintf(stderr, "cdrskin: HINT : Consider to allow rw-access to the writer devices and\n"); fprintf(stderr, "cdrskin: HINT : to run cdrskin under your normal user identity.\n"); return(1); } /* Start the fallback program as replacement of the cdrskin run. @param flag bit0=do not report start command */ int Cdrpreskin_fallback(struct CdrpreskiN *preskin, int argc, char **argv, int flag) { char **hargv= NULL; int i, wp= 1; char *ept, *upt; if(preskin->fallback_program[0] == 0) return(1); if(getuid()!=geteuid() && !preskin->allow_setuid) { fprintf(stderr, "cdrskin: SORRY : uid and euid differ. Will not start external fallback program.\n"); Cdrpreskin_consider_normal_user(0); fprintf(stderr, "cdrskin: HINT : Option --allow_setuid disables this safety check.\n"); goto failure; } if(!(flag&1)) { fprintf(stderr,"cdrskin: --------------------------------------------------------------------\n"); fprintf(stderr,"cdrskin: Starting fallback program:\n"); } hargv= TSOB_FELD(char *,argc+1); if(hargv==NULL) goto failure; hargv[0]= strdup(preskin->fallback_program); if(argv[0]==NULL) goto failure; if(!(flag&1)) fprintf(stderr," %s", hargv[0]); for(i= 1; ifallback_program); fprintf(stderr,"cdrskin: errno=%d \"%s\"\n", errno, (errno > 0 ? strerror(errno) : "unidentified error")); exit(15); } /** Convert a cdrecord-style device address into a libburn device address or into a libburn drive number. It depends on the "scsibus" number of the cdrecord-style address which kind of libburn address emerges: bus=0 : drive number , bus=1 : /dev/sgN , bus=2 : /dev/hdX (This call intentionally has no CdrpreskiN argument) @param flag Bitfield for control purposes: bit0= old_pseudo_scsi_adr @return 1 success, 0=no recognizable format, -1=severe error, -2 could not find scsi device, -3 address format error */ int Cdrpreskin__cdrecord_to_dev(char *adr, char device_adr[Cdrskin_adrleN], int *driveno, int flag) { int comma_seen= 0,digit_seen= 0,busno= 0,k,lun_no= -1; *driveno= -1; device_adr[0]= 0; if(strlen(adr)==0) return(0); if(strncmp(adr,"stdio:",6)==0) return(0); /* read the trailing numeric string as device address code */ /* accepts "1" , "0,1,0" , "ATA:0,1,0" , ... */ for(k= strlen(adr)-1;k>=0;k--) { if(adr[k]==',' && !comma_seen) { sscanf(adr+k+1,"%d",&lun_no); comma_seen= 1; digit_seen= 0; continue; } if(adr[k]<'0' || adr[k]>'9') break; digit_seen= 1; } if(!digit_seen) { k= strlen(adr)-1; if(adr[k]==':' || (adr[k]>='A' && adr[k]<='Z')) {/* empty prefix ? */ *driveno= 0; return(1); } return(0); } sscanf(adr+k+1,"%d",driveno); digit_seen= 0; if(k>0) if(adr[k]==',') { for(k--;k>=0;k--) { if(adr[k]<'0' || adr[k]>'9') break; digit_seen= 1; } if(digit_seen) { sscanf(adr+k+1,"%d",&busno); if(flag&1) { /* look for symbolic bus : 1=/dev/sgN 2=/dev/hdX */ if(busno==1) { sprintf(device_adr,"/dev/sg%d",*driveno); } else if(busno==2) { sprintf(device_adr,"/dev/hd%c",'a'+(*driveno)); } else if(busno!=0) { fprintf(stderr, "cdrskin: FATAL : dev=[Prefix:]Bus,Target,Lun expects Bus out of {0,1,2}\n"); return(-3); } } else { if(busno<0) { fprintf(stderr, "cdrskin: FATAL : dev=[Prefix:]Bus,Target,Lun expects Bus number >= 0\n"); return(-3); } if(busno>=1000) { busno-= 1000; goto ata_bus; } else if((strncmp(adr,"ATA",3)==0 && (adr[3]==0 || adr[3]==':')) || (strncmp(adr,"ATAPI",5)==0 && (adr[5]==0 || adr[5]==':'))) { ata_bus:; if(busno>12 || (*driveno)<0 || (*driveno)>1) { fprintf(stderr, "cdrskin: FATAL : dev=ATA:Bus,Target,Lun expects Bus {0..12}, Target {0,1}\n"); return(-3); } sprintf(device_adr,"/dev/hd%c",'a'+(2*busno)+(*driveno)); } else { int ret; ret= burn_drive_convert_scsi_adr(busno,-1,-1,*driveno,lun_no, device_adr); if(ret==0) { fprintf(stderr, "cdrskin: FATAL : Cannot find /dev/* with Bus,Target,Lun = %d,%d,%d\n", busno,*driveno,lun_no); fprintf(stderr, "cdrskin: HINT : This drive may be in use by another program currently\n"); return(-2); } else if(ret<0) return(-1); return(1); } } } } return(1); } /** Set the eventual output fd for the result of Cdrskin_msinfo() */ int Cdrpreskin_set_result_fd(struct CdrpreskiN *o, int result_fd, int flag) { o->result_fd= result_fd; return(1); } #ifndef Cdrskin_extra_leaN /** Load content startup files into preskin cache */ int Cdrpreskin_read_rc(struct CdrpreskiN *o, char *progname, int flag) { int ret,i; char **filenames_v; filenames_v= TSOB_FELD(char *, o->rc_filename_count+1); if(filenames_v==NULL) return(-1); for(i=0;irc_filename_count;i++) filenames_v[i]= o->rc_filenames[i]; Sfile_home_adr_s(".cdrskinrc",o->rc_filenames[o->rc_filename_count-1], Cdrskin_strleN,0); ret= Sfile_multi_read_argv(progname,filenames_v,o->rc_filename_count, &(o->pre_argc),&(o->pre_argv), &(o->pre_argidx),&(o->pre_arglno),4); free((char *) filenames_v); return(ret); } #endif /* ! Cdrskin_extra_leaN */ /** Interpret those arguments which do not need libburn or which influence the startup of libburn and/or the creation of the CdrskiN object. This is run before libburn gets initialized and before Cdrskin_new() is called. Options which need libburn or a CdrskiN object are processed in a different function named Cdrskin_setup(). @param flag Bitfield for control purposes: bit0= do not finalize setup bit1= do not read and interpret rc files @return <=0 error, 1 success , 2 end program run with exit value 0 */ int Cdrpreskin_setup(struct CdrpreskiN *o, int argc, char **argv, int flag) /* return: <=0 error 1 ok 2 end program run (--help) */ { int i,ret; char *value_pt, reason[4096], *argpt; #ifndef Cdrskin_extra_leaN if(argc>1) { if(strcmp(argv[1],"--no_rc")==0 || strcmp(argv[1],"-version")==0 || strcmp(argv[1],"--help")==0 || strcmp(argv[1],"-help")==0 || strncmp(argv[1], "textfile_to_v07t=", 17) == 0 || strncmp(argv[1], "-textfile_to_v07t=", 18) == 0) flag|= 2; } if(!(flag&2)) { ret= Cdrpreskin_read_rc(o,argv[0],0); if(ret<0) return(-1); if(o->pre_argc>1) { ret= Cdrpreskin_setup(o,o->pre_argc,o->pre_argv,flag|1|2); if(ret<=0) return(ret); /* ??? abort on ret==2 ? */ } } #endif if(argc==1) { fprintf(stderr,"cdrskin: SORRY : No options given. Try option --help\n"); return(0); } /* The two predefined fallback personalities are triggered by the progname */ value_pt= strrchr(argv[0],'/'); if(value_pt==NULL) value_pt= argv[0]; else value_pt++; if(strcmp(value_pt,"unicord")==0) strcpy(o->fallback_program,"cdrecord"); else if(strcmp(value_pt,"codim")==0) strcpy(o->fallback_program,"wodim"); for (i= 1;i 3) argpt++; if(strcmp(argv[i],"--abort_handler")==0) { o->abort_handler= 3; } else if(strcmp(argv[i],"--allow_emulated_drives")==0) { if(Cdrpreskin__allows_emulated_drives("",reason,0)<=0) { fprintf(stderr,"cdrskin: WARNING : %s.\n",reason); fprintf(stderr, "cdrskin: WARNING : Only /dev/null will be available with \"stdio:\".\n"); Cdrpreskin_consider_normal_user(0); o->allow_emulated_drives= 2; } else o->allow_emulated_drives= 1; } else if(strcmp(argv[i],"--allow_setuid")==0) { o->allow_setuid= 1; } else if(strcmp(argv[i],"--allow_untested_media")==0) { o->allow_untested_media= 1; } else if(strcmp(argpt, "blank=help") == 0 || strcmp(argpt, "-blank=help") == 0) { #ifndef Cdrskin_extra_leaN fprintf(stderr,"Blanking options:\n"); fprintf(stderr,"\tall\t\tblank the entire disk\n"); fprintf(stderr,"\tdisc\t\tblank the entire disk\n"); fprintf(stderr,"\tdisk\t\tblank the entire disk\n"); fprintf(stderr,"\tfast\t\tminimally blank the entire disk\n"); fprintf(stderr,"\tminimal\t\tminimally blank the entire disk\n"); fprintf(stderr, "\tas_needed\tblank or format media to make it ready for (re-)use\n"); fprintf(stderr, "\tdeformat_sequential\t\tfully blank, even formatted DVD-RW\n"); fprintf(stderr, "\tdeformat_sequential_quickest\tminimally blank, even DVD-RW\n"); fprintf(stderr, "\tformat_if_needed\t\tmake overwriteable if needed and possible\n"); fprintf(stderr, "\tformat_overwrite\t\tformat a DVD-RW to \"Restricted Overwrite\"\n"); fprintf(stderr, "\tformat_overwrite_quickest\tto \"Restricted Overwrite intermediate\"\n"); fprintf(stderr, "\tformat_overwrite_full\t\tfull-size format a DVD-RW or DVD+RW\n"); fprintf(stderr, "\tformat_defectmgt[_max|_min|_none]\tformat DVD-RAM or BD-R[E]\n"); fprintf(stderr, "\tformat_defectmgt[_cert_on|_cert_off]\tcertification slow|quick\n"); fprintf(stderr, "\tformat_defectmgt_payload_\tformat DVD-RAM or BD-R[E]\n"); fprintf(stderr, "\tformat_by_index_\t\tformat by index from --list_formats\n"); #else /* ! Cdrskin_extra_leaN */ goto see_cdrskin_eng_html; #endif /* ! Cdrskin_extra_leaN */ if(argc==2) {ret= 2; goto final_checks;} } else if(strcmp(argv[i],"--bragg_with_audio")==0) { /* OBSOLETE 0.2.3 */; } else if(strcmp(argv[i],"--demand_a_drive")==0) { o->scan_demands_drive= 1; o->demands_cdrskin_caps= 1; } else if(strcmp(argv[i],"--devices") == 0 || strcmp(argv[i],"--device_links") == 0) { o->no_whitelist= 1; o->demands_cdrskin_caps= 1; } else if(strncmp(argv[i],"dev_translation=",16)==0) { o->demands_cdrskin_caps= 1; #ifndef Cdrskin_extra_leaN if(o->adr_trn==NULL) { ret= Cdradrtrn_new(&(o->adr_trn),0); if(ret<=0) goto no_adr_trn_mem; } if(argv[i][16]==0) { fprintf(stderr, "cdrskin: FATAL : dev_translation= : missing separator character\n"); return(0); } ret= Cdradrtrn_add(o->adr_trn,argv[i]+17,argv[i]+16,1); if(ret==-2) { no_adr_trn_mem:; fprintf(stderr, "cdrskin: FATAL : address_translation= : cannot allocate memory\n"); } else if(ret==-1) fprintf(stderr, "cdrskin: FATAL : address_translation= : table full (%d items)\n", Cdradrtrn_leN); else if(ret==0) fprintf(stderr, "cdrskin: FATAL : address_translation= : no address separator '%c' found\n", argv[i][17]); if(ret<=0) return(0); #else /* ! Cdrskin_extra_leaN */ fprintf(stderr, "cdrskin: FATAL : dev_translation= is not available in lean version\n"); return(0); #endif /* Cdrskin_extra_leaN */ } else if(strncmp(argpt, "-dev=", 5) == 0) { value_pt= argpt + 5; goto set_dev; } else if(strncmp(argpt, "dev=", 4) == 0) { value_pt= argpt + 4; set_dev:; if(strcmp(value_pt,"help")==0) { #ifndef Cdrskin_extra_leaN printf("\nSupported SCSI transports for this platform:\n"); fflush(stdout); if(o->old_pseudo_scsi_adr) { fprintf(stderr,"\nTransport name:\t\tlibburn OLD_PSEUDO\n"); fprintf(stderr, "Transport descr.:\tBus0=DriveNum , Bus1=/dev/sgN , Bus2=/dev/hdX\n"); } else { fprintf(stderr,"\nTransport name:\t\tlibburn SCSI\n"); fprintf(stderr, "Transport descr.:\tSCSI Bus,Id,Lun as of operating system\n"); } fprintf(stderr,"Transp. layer ind.:\t\n"); fprintf(stderr,"Target specifier:\tbus,target,lun\n"); fprintf(stderr,"Target example:\t\t1,2,0\n"); fprintf(stderr,"SCSI Bus scanning:\tsupported\n"); fprintf(stderr,"Open via UNIX device:\tsupported\n"); if(!o->old_pseudo_scsi_adr) { fprintf(stderr,"\nTransport name:\t\tlibburn HD\n"); fprintf(stderr, "Transport descr.:\tLinux specific alias for /dev/hdX\n"); fprintf(stderr,"Transp. layer ind.:\tATA:\n"); fprintf(stderr,"Target specifier:\tbus,target,lun\n"); fprintf(stderr,"Target example:\t\tATA:1,0,0\n"); fprintf(stderr,"SCSI Bus scanning:\tsupported\n"); fprintf(stderr,"Open via UNIX device:\tsupported\n"); } if(o->allow_emulated_drives) { fprintf(stderr,"\nTransport name:\t\tlibburn on standard i/o\n"); if(o->allow_emulated_drives==2) fprintf(stderr, "Transport descr.:\troot or setuid may only write into /dev/null\n"); else fprintf(stderr, "Transport descr.:\twrite into file objects\n"); fprintf(stderr,"Transp. layer ind.:\tstdio:\n"); fprintf(stderr,"Target specifier:\tpath\n"); fprintf(stderr,"Target example:\t\tstdio:/tmp/pseudo_drive\n"); fprintf(stderr,"SCSI Bus scanning:\tnot supported\n"); fprintf(stderr,"Open via UNIX device:\tnot supported\n"); } else { if(Cdrpreskin__allows_emulated_drives("",reason,0)>0) printf("\ncdrskin: NOTE : Option --allow_emulated_drives would allow dev=stdio:\n"); } #else /* ! Cdrskin_extra_leaN */ goto see_cdrskin_eng_html; #endif /* Cdrskin_extra_leaN */ {ret= 2; goto final_checks;} } if(strlen(value_pt)>=sizeof(o->raw_device_adr)) goto dev_too_long; strcpy(o->raw_device_adr,value_pt); } else if(strcmp(argv[i],"--drive_abort_on_busy")==0) { o->abort_on_busy_drive= 1; } else if(strcmp(argv[i],"--drive_blocking")==0) { o->drive_blocking= 1; } else if(strcmp(argv[i],"--drive_f_setlk")==0) { o->drive_fcntl_f_setlk= 1; } else if(strcmp(argv[i],"--drive_not_exclusive")==0) { o->drive_exclusive= 0; o->drive_fcntl_f_setlk= 0; } else if(strcmp(argv[i],"--drive_not_f_setlk")==0) { o->drive_fcntl_f_setlk= 0; } else if(strcmp(argv[i],"--drive_not_o_excl")==0) { o->drive_exclusive= 0; } else if(strncmp(argv[i],"drive_scsi_dev_family=",22)==0) { value_pt= argv[i]+22; if(strcmp(value_pt,"sr")==0) o->drive_scsi_dev_family= 1; else if(strcmp(value_pt,"scd")==0) o->drive_scsi_dev_family= 2; else if(strcmp(value_pt,"sg")==0) o->drive_scsi_dev_family= 4; else o->drive_scsi_dev_family= 0; } else if(strcmp(argv[i],"--drive_scsi_exclusive")==0) { o->drive_exclusive= 2; o->demands_cdrskin_caps= 1; } else if(strcmp(argpt,"driveropts=help")==0 || strcmp(argpt,"-driveropts=help")==0) { #ifndef Cdrskin_extra_leaN fprintf(stderr,"Driver options:\n"); fprintf(stderr,"burnfree\tPrepare writer to use BURN-Free technology\n"); fprintf(stderr,"noburnfree\tDisable using BURN-Free technology\n"); #else /* ! Cdrskin_extra_leaN */ goto see_cdrskin_eng_html; #endif /* Cdrskin_extra_leaN */ if(argc==2 || (i==2 && argc==3 && strncmp(argv[1],"dev=",4)==0)) {ret= 2; goto final_checks;} } else if(strcmp(argv[i],"--help")==0) { #ifndef Cdrskin_extra_leaN printf("\n"); printf("Usage: %s [options|source_addresses]\n", argv[0]); printf("Burns preformatted data to CD or DVD via libburn.\n"); printf("For the cdrecord compatible options which control the work of\n"); printf( "blanking and burning see output of option -help rather than --help.\n"); printf("Non-cdrecord options:\n"); printf(" --abort_handler do not leave the drive in busy state\n"); printf( " --adjust_speed_to_drive set only speeds offered by drive and media\n"); printf(" --allow_emulated_drives dev=stdio: on file objects\n"); printf( " --allow_setuid disable setuid warning (setuid is insecure !)\n"); printf( " --allow_untested_media enable implemented untested media types\n"); printf( " --any_track allow source_addresses to match '^-.' or '='\n"); printf( " assert_write_lba= abort if not next write address == lba\n"); printf( " cd_start_tno= set number of first track in CD SAO session\n"); printf( " --cdtext_dummy show CD-TEXT pack array instead of writing CD\n"); printf( " cdtext_to_textfile= extract CD-TEXT from CD to disk file\n"); printf( " cdtext_to_v07t= report CD-TEXT from CD to file or stdout\n"); printf(" --cdtext_verbose show CD-TEXT pack array before writing CD\n"); printf( " direct_write_amount= write random access to media like DVD+RW\n"); printf(" --demand_a_drive exit !=0 on bus scans with empty result\n"); printf(" --devices list accessible devices (tells /dev/...)\n"); printf(" --device_links list accessible devices by (udev) links\n"); printf( " dev_translation= set input address alias\n"); printf(" e.g.: dev_translation=+ATA:1,0,0+/dev/sg1\n"); printf(" --drive_abort_on_busy abort process if busy drive is found\n"); printf(" (might be triggered by a busy hard disk)\n"); printf(" --drive_blocking try to wait for busy drive to become free\n"); printf(" (might be stalled by a busy hard disk)\n"); printf(" --drive_f_setlk obtain exclusive lock via fcntl.\n"); printf(" --drive_not_exclusive combined not_o_excl and not_f_setlk.\n"); printf(" --drive_not_f_setlk do not obtain exclusive lock via fcntl.\n"); printf(" --drive_not_o_excl do not ask kernel to prevent opening\n"); printf(" busy drives. Effect is kernel dependend.\n"); printf( " drive_scsi_dev_family= select Linux device\n"); printf(" file family to be used for (pseudo-)SCSI.\n"); printf( " --drive_scsi_exclusive try to exclusively reserve device files\n"); printf(" /dev/srN, /dev/scdM, /dev/stK of drive.\n"); printf(" dvd_obs=\"default\"|number\n"); printf( " set number of bytes per DVD/BD write: 32k or 64k\n"); printf(" extract_audio_to=\n"); printf( " Copy all tracks of an audio CD as separate\n"); printf( " .WAV files /track.wav to hard disk\n"); printf(" extract_basename=\n"); printf( " Compose track files as /.wav\n"); printf( " --extract_dap Enable flaw obscuring mechanisms for audio reading\n"); printf(" extract_tracks=\n"); printf( " Restrict extract_audio_to= to list of tracks.\n"); printf( " fallback_program= use external program for exotic CD jobs.\n"); printf(" --fifo_disable disable fifo despite any fs=...\n"); printf(" --fifo_per_track use a separate fifo for each track\n"); printf( " fifo_start_at= do not wait for full fifo but start burning\n"); printf( " as soon as the given number of bytes is read\n"); printf(" --fill_up_media cause the last track to have maximum size\n"); printf(" --four_channel indicate that audio tracks have 4 channels\n"); printf( " grab_drive_and_wait= grab drive, wait given number of\n"); printf( " seconds, release drive, and do normal work\n"); printf( " --grow_overwriteable_iso emulate multi-session on media like DVD+RW\n"); printf( " --ignore_signals try to ignore any signals rather than to abort\n"); printf(" input_sheet_v07t= read a Sony CD-TEXT definition file\n"); printf(" --list_formats list format descriptors for loaded media.\n"); printf(" --list_ignored_options list all ignored cdrecord options.\n"); printf(" --list_speeds list speed descriptors for loaded media.\n"); printf(" --long_toc print overview of media content\n"); printf(" modesty_on_drive= no writing into full drive buffer\n"); printf(" --no_abort_handler exit even if the drive is in busy state\n"); printf(" --no_blank_appendable refuse to blank appendable CD-RW\n"); printf(" --no_convert_fs_adr only literal translations of dev=\n"); printf(" --no_load do not try to load the drive tray\n"); printf( " --no_rc as first argument: do not read startup files\n"); printf(" --obs_pad pad DVD DAO to full 16 or 32 blocks\n"); printf(" --old_pseudo_scsi_adr use and report literal Bus,Target,Lun\n"); printf(" rather than real SCSI and pseudo ATA.\n"); printf( " --pacifier_with_newline do not overwrite pacifier line by next one.\n"); printf(" --prodvd_cli_compatible react on some DVD types more like\n"); printf(" cdrecord-ProDVD with blank= and -multi\n"); printf(" sao_postgap=\"off\"|number\n"); printf(" defines whether the next track will get a\n"); printf( " post-gap and how many sectors it shall have\n"); printf(" sao_pregap=\"off\"|number\n"); printf(" defines whether the next track will get a\n"); printf( " pre-gap and how many sectors it shall have\n"); printf( " --single_track accept only last argument as source_address\n"); printf(" stream_recording=\"on\"|\"off\"|number\n"); printf( " \"on\" requests to prefer speed over write\n"); printf( " error management. A number prevents this with\n"); printf( " byte addresses below that number.\n"); printf(" stdio_sync=\"default\"|\"off\"|number\n"); printf( " set number of bytes after which to force output\n"); printf( " to drives with prefix \"stdio:\".\n"); printf( " tao_to_sao_tsize= use num as fixed track size if in a\n"); printf( " non-TAO mode track data are read from \"-\"\n"); printf( " and no tsize= was specified.\n"); printf( " --tell_media_space print maximum number of writeable data blocks\n"); printf(" textfile_to_v07t=file_path\n"); printf( " print CD-TEXT file in Sony format and exit.\n"); printf(" --two_channel indicate that audio tracks have 2 channels\n"); printf( " write_start_address= write to given byte address (DVD+RW)\n"); printf( " --xa1-ignore with -xa1 do not strip 8 byte headers\n"); printf( " -xamix DO NOT USE (Dummy announcement to make K3B use -xa)\n"); printf( "Preconfigured arguments are read from the following startup files\n"); printf( "if they exist and are readable. The sequence is as listed here:\n"); printf(" /etc/default/cdrskin /etc/opt/cdrskin/rc\n"); printf(" /etc/cdrskin/cdrskin.conf $HOME/.cdrskinrc\n"); printf("Each file line is a single argument. No whitespace.\n"); printf( "By default any argument that does not match grep '^-.' or '=' is\n"); printf( "used as track source. If it is \"-\" then stdin is used.\n"); printf("cdrskin : http://scdbackup.sourceforge.net/cdrskin_eng.html\n"); printf(" mailto:scdbackup@gmx.net (Thomas Schmitt)\n"); printf("libburn : http://libburnia-project.org\n"); printf("cdrecord : ftp://ftp.berlios.de/pub/cdrecord/\n"); printf("My respect to the authors of cdrecord and libburn.\n"); printf("scdbackup: http://scdbackup.sourceforge.net/main_eng.html\n"); printf("\n"); #else /* ! Cdrskin_extra_leaN */ see_cdrskin_eng_html:; printf("This is a capability reduced lean version without help texts.\n"); printf("See http://scdbackup.sourceforge.net/cdrskin_eng.html\n"); #endif /* Cdrskin_extra_leaN */ {ret= 2; goto final_checks;} } else if(strcmp(argv[i],"-help")==0) { #ifndef Cdrskin_extra_leaN fprintf(stderr,"Usage: %s [options|source_addresses]\n",argv[0]); fprintf(stderr,"Note: This is not cdrecord. See cdrskin start message on stdout. See --help.\n"); fprintf(stderr,"Options:\n"); fprintf(stderr,"\t-version\tprint version information and exit\n"); fprintf(stderr, "\tdev=target\tpseudo-SCSI target to use as CD-Recorder\n"); fprintf(stderr, "\tgracetime=#\tset the grace time before starting to write to #.\n"); fprintf(stderr,"\t-v\t\tincrement general verbose level by one\n"); fprintf(stderr, "\t-V\t\tincrement SCSI command transport verbose level by one\n"); fprintf(stderr, "\tdriveropts=opt\topt= one of {burnfree,noburnfree,help}\n"); fprintf(stderr, "\t-checkdrive\tcheck if a driver for the drive is present\n"); fprintf(stderr,"\t-inq\t\tdo an inquiry for the drive and exit\n"); fprintf(stderr,"\t-scanbus\tscan the SCSI bus and exit\n"); fprintf(stderr,"\tspeed=#\t\tset speed of drive\n"); fprintf(stderr,"\tblank=type\tblank a CD-RW disc (see blank=help)\n"); fprintf(stderr,"\t-format\t\tformat a CD-RW/DVD-RW/DVD+RW disc\n"); fprintf(stderr, "\tfs=#\t\tSet fifo size to # (0 to disable, default is 4 MB)\n"); fprintf(stderr, "\t-load\t\tload the disk and exit (works only with tray loader)\n"); fprintf(stderr, "\t-lock\t\tload and lock the disk and exit (works only with tray loader)\n"); fprintf(stderr, "\t-eject\t\teject the disk after doing the work\n"); fprintf(stderr,"\t-dummy\t\tdo everything with laser turned off\n"); fprintf(stderr,"\t-minfo\t\tretrieve and print media information/status\n"); fprintf(stderr,"\t-media-info\tretrieve and print media information/status\n"); fprintf(stderr, "\t-msinfo\t\tretrieve multi-session info for mkisofs >= 1.10\n"); fprintf(stderr,"\tmsifile=path\trun -msinfo and copy output to file\n"); fprintf(stderr,"\t-toc\t\tretrieve and print TOC/PMA data\n"); fprintf(stderr, "\t-atip\t\tretrieve media state, print \"Is *erasable\"\n"); fprintf(stderr, "\tminbuf=percent\tset lower limit for drive buffer modesty\n"); fprintf(stderr, "\t-multi\t\tgenerate a TOC that allows multi session\n"); fprintf(stderr, "\t-waiti\t\twait until input is available before opening SCSI\n"); fprintf(stderr, "\t-immed\t\tTry to use the SCSI IMMED flag with certain long lasting commands\n"); fprintf(stderr, "\t-force\t\tforce to continue on some errors to allow blanking\n"); fprintf(stderr,"\t-tao\t\tWrite disk in TAO mode.\n"); fprintf(stderr,"\t-dao\t\tWrite disk in SAO mode.\n"); fprintf(stderr,"\t-sao\t\tWrite disk in SAO mode.\n"); #ifndef Cdrskin_disable_raw96R fprintf(stderr,"\t-raw96r\t\tWrite disk in RAW/RAW96R mode\n"); #endif fprintf(stderr,"\ttsize=#\t\tannounces exact size of source data\n"); fprintf(stderr,"\tpadsize=#\tAmount of padding\n"); fprintf(stderr, "\tmcn=text\tSet the media catalog number for this CD to 'text'\n"); fprintf(stderr, "\tisrc=text\tSet the ISRC number for the next track to 'text'\n"); fprintf(stderr, "\tindex=list\tSet the index list for the next track to 'list'\n"); fprintf(stderr, "\t-text\t\tWrite CD-Text from information from *.cue files\n"); fprintf(stderr, "\ttextfile=name\tSet the file with CD-Text data to 'name'\n"); fprintf(stderr, "\tcuefile=name\tSet the file with CDRWIN CUE data to 'name'\n"); fprintf(stderr,"\t-audio\t\tSubsequent tracks are CD-DA audio tracks\n"); fprintf(stderr, "\t-data\t\tSubsequent tracks are CD-ROM data mode 1 (default)\n"); fprintf(stderr, "\t-xa1\t\tSubsequent tracks are CD-ROM XA mode 2 form 1 - 2056 bytes\n"); fprintf(stderr, "\t-isosize\tUse iso9660 file system size for next data track\n"); fprintf(stderr,"\t-preemp\t\tAudio tracks are mastered with 50/15 microseconds preemphasis\n"); fprintf(stderr,"\t-nopreemp\tAudio tracks are mastered with no preemphasis (default)\n"); fprintf(stderr,"\t-copy\t\tAudio tracks have unlimited copy permission\n"); fprintf(stderr,"\t-nocopy\t\tAudio tracks may only be copied once for personal use (default)\n"); fprintf(stderr,"\t-scms\t\tAudio tracks will not have any copy permission at all\n"); fprintf(stderr,"\t-pad\t\tpadsize=30k\n"); fprintf(stderr, "\t-nopad\t\tDo not pad (default, but applies only to data tracks)\n"); fprintf(stderr, "\t-swab\t\tAudio data source is byte-swapped (little-endian/Intel)\n"); fprintf(stderr,"\t-help\t\tprint this text to stderr and exit\n"); fprintf(stderr, "Without option -data, .wav and .au files are extracted and burned as -audio.\n"); fprintf(stderr, "By default any argument that does not match grep '^-.' or '=' is used\n"); fprintf(stderr, "as track source address. Address \"-\" means stdin.\n"); fprintf(stderr, "cdrskin will ensure that an announced tsize= is written even if\n"); fprintf(stderr, "the source delivers fewer bytes. But 0 bytes from stdin with fifo\n"); fprintf(stderr, "enabled will lead to abort and no burn attempt at all.\n"); #else /* ! Cdrskin_extra_leaN */ fprintf(stderr,"Note: This is not cdrecord. See cdrskin start message on stdout.\n"); fprintf(stderr, "(writer profile: -atip retrieve, blank=type, -eject after work)\n"); goto see_cdrskin_eng_html; #endif /* Cdrskin_extra_leaN */ {ret= 2; goto final_checks;} } else if(strcmp(argv[i],"--ignore_signals")==0) { o->abort_handler= 2; } else if(strncmp(argv[i],"fallback_program=",17)==0) { if(strlen(argv[i] + 17) >= sizeof(o->fallback_program)) { fprintf(stderr, "cdrskin: FATAL : fallback_program=... too long (max. %d characters)\n", (int) sizeof(o->fallback_program) - 1); {ret= 0; goto ex;} } strcpy(o->fallback_program,argv[i]+17); } else if(strcmp(argv[i],"--no_abort_handler")==0) { o->abort_handler= 0; } else if(strcmp(argv[i],"--no_convert_fs_adr")==0) { o->no_convert_fs_adr= 1; } else if(strcmp(argv[i],"--old_pseudo_scsi_adr")==0) { o->old_pseudo_scsi_adr= 1; o->demands_cdrskin_caps= 1; } else if(strcmp(argv[i],"--no_rc")==0) { if(i!=1) fprintf(stderr, "cdrskin: NOTE : option --no_rc would only work as first argument.\n"); #ifndef Cdrskin_disable_raw96R } else if(strcmp(argpt,"-raw96r")==0) { strcpy(o->write_mode_name,"RAW/RAW96R"); #endif } else if(strcmp(argpt,"-sao")==0 || strcmp(argpt,"-dao")==0) { strcpy(o->write_mode_name,"SAO"); } else if(strcmp(argpt,"-scanbus")==0) { o->no_whitelist= 1; } else if(strcmp(argpt,"-tao")==0) { strcpy(o->write_mode_name,"TAO"); } else if(strncmp(argpt, "-textfile_to_v07t=", 18) == 0) { o->do_not_scan= 1; } else if(strncmp(argpt ,"textfile_to_v07t=", 17) == 0) { o->do_not_scan= 1; } else if(strcmp(argv[i],"-V")==0 || strcmp(argpt, "-Verbose") == 0) { burn_set_scsi_logging(2 | 4); /* log SCSI to stderr */ } else if(strcmp(argv[i],"-v")==0 || strcmp(argpt, "-verbose") == 0) { (o->verbosity)++; ClN(printf("cdrskin: verbosity level : %d\n",o->verbosity)); set_severities:; if(o->verbosity>=Cdrskin_verbose_debuG) Cdrpreskin_set_severities(o,"NEVER","DEBUG",0); else if(o->verbosity >= Cdrskin_verbose_progresS) Cdrpreskin_set_severities(o, "NEVER", "UPDATE", 0); } else if(strcmp(argv[i],"-vv")==0 || strcmp(argv[i],"-vvv")==0 || strcmp(argv[i],"-vvvv")==0) { (o->verbosity)+= strlen(argv[i])-1; goto set_severities; } else if(strcmp(argpt,"-version")==0) { int major, minor, micro; printf( "Cdrecord 2.01a27 Emulation. Copyright (C) 2006-2014, see libburnia-project.org\n"); if(o->fallback_program[0]) { char *hargv[2]; printf("Fallback program : %s\n",o->fallback_program); printf("Fallback version :\n"); hargv[0]= argv[0]; hargv[1]= "-version"; Cdrpreskin_fallback(o,2,hargv,1); /* dirty never come back */ } printf("System adapter : %s\n", burn_scsi_transport_id(0)); printf("libburn interface : %d.%d.%d\n", burn_header_version_major, burn_header_version_minor, burn_header_version_micro); burn_version(&major, &minor, µ); printf("libburn in use : %d.%d.%d\n", major, minor, micro); #ifndef Cdrskin_extra_leaN printf("cdrskin version : %s\n",Cdrskin_prog_versioN); #else printf("cdrskin version : %s.lean (capability reduced lean version)\n", Cdrskin_prog_versioN); #endif printf("Version timestamp : %s\n",Cdrskin_timestamP); printf("Build timestamp : %s\n",Cdrskin_build_timestamP); {ret= 2; goto ex;} } else if(strcmp(argpt,"-waiti")==0) { o->do_waiti= 1; } else if(strcmp(argpt,"-xamix")==0) { fprintf(stderr, "cdrskin: FATAL : Option -xamix not implemented and data not yet convertible to other modes.\n"); return(0); } } ret= 1; final_checks:; if(flag&1) goto ex; if(o->verbosity >= Cdrskin_verbose_debuG) ClN(fprintf(stderr, "cdrskin: DEBUG : Using %s\n", burn_scsi_transport_id(0))); if(o->do_waiti) { fprintf(stderr, "cdrskin: Option -waiti pauses program until input appears at stdin\n"); printf("Waiting for data on stdin...\n"); for(ret= 0; ret==0; ) ret= Wait_for_input(0,1000000,0); if(ret<0 || feof(stdin)) fprintf(stderr, "cdrskin: NOTE : stdin produces exception rather than data\n"); fprintf(stderr,"cdrskin: Option -waiti pausing is done.\n"); } burn_preset_device_open(o->drive_exclusive | (o->drive_scsi_dev_family<<2) | ((!!o->drive_fcntl_f_setlk)<<5), o->drive_blocking, o->abort_on_busy_drive); if(strlen(o->raw_device_adr)>0 && !o->no_whitelist) { int driveno,hret; char *adr,buf[Cdrskin_adrleN]; if(strcmp(o->raw_device_adr,"stdio:-")==0) { fprintf(stderr, "cdrskin: SORRY : Cannot accept drive address \"stdio:-\".\n"); fprintf(stderr, "cdrskin: HINT : Use \"stdio:/dev/fd/1\" if you really want to write to stdout.\n"); {ret= 0; goto ex;} } adr= o->raw_device_adr; #ifndef Cdrskin_extra_leaN if(o->adr_trn!=NULL) { hret= Cdradrtrn_translate(o->adr_trn,adr,-1,buf,0); if(hret<=0) { fprintf(stderr, "cdrskin: FATAL : address translation failed (address too long ?) \n"); {ret= 0; goto ex;} } adr= buf; } #endif /* ! Cdrskin_extra_leaN */ if(adr[0]=='/') { if(strlen(adr)>=sizeof(o->device_adr)) { dev_too_long:; fprintf(stderr, "cdrskin: FATAL : dev=... too long (max. %d characters)\n", (int) sizeof(o->device_adr)-1); {ret= 0; goto ex;} } strcpy(o->device_adr,adr); } else { ret= Cdrpreskin__cdrecord_to_dev(adr,o->device_adr,&driveno, !!o->old_pseudo_scsi_adr); if(ret==-2 || ret==-3) {ret= 0; goto ex;} if(ret<0) goto ex; if(ret==0) { strcpy(o->device_adr,adr); ret= 1; } } if(strlen(o->device_adr)>0 && !o->no_convert_fs_adr) { int lret; char link_adr[Cdrskin_strleN+1]; strcpy(link_adr,o->device_adr); lret = burn_drive_convert_fs_adr(link_adr,o->device_adr); if(lret<0) { fprintf(stderr, "cdrskin: NOTE : Please inform libburn-hackers@pykix.org about:\n"); fprintf(stderr, "cdrskin: burn_drive_convert_fs_adr() returned %d\n",lret); } } } burn_allow_untested_profiles(!!o->allow_untested_media); /* A60927 : note to myself : no "ret= 1;" here. It breaks --help , -version */ ex:; /* Eventually replace current stdout by dup(1) from start of program */ if(strcmp(o->device_adr,"stdio:/dev/fd/1")==0 && o->result_fd >= 0) sprintf(o->device_adr,"stdio:/dev/fd/%d",o->result_fd); #ifndef Cdrskin_extra_leaN if(ret<=0 || !(flag&1)) Cdradrtrn_destroy(&(o->adr_trn),0); #endif return(ret); } /* --------------------------------------------------------------------- */ /** The maximum number of tracks */ #define Cdrskin_track_maX 99 /** Work around the fact that libburn leaves the track input fds open after the track is done. This can hide a few overflow bytes buffered by the fifo-to-libburn pipe which would cause a broken-pipe error if libburn would close that outlet. This macro enables a coarse workaround which tries to read bytes from the track inlets after burning has ended. Probably not a good idea if libburn would close the inlet fds. */ #define Cdrskin_libburn_leaves_inlet_opeN 1 /** List of furter wishes towards libburn: - a possibilty to implement cdrskin -reset */ #define Cdrskin_tracksize_maX 1024.0*1024.0*1024.0*1024.0 /* Some constants obtained by hearsay and experiments */ /** The CD payload speed factor for reporting progress: 1x = 150 kB/s */ static double Cdrskin_cd_speed_factoR= 150.0*1024.0; /** The DVD payload speed factor for reporting progress: 1x */ static double Cdrskin_dvd_speed_factoR= 1385000; /** The BD payload speed factor for reporting progress: 1x */ static double Cdrskin_bd_speed_factoR= 4495625; /** The effective payload speed factor for reporting progress */ static double Cdrskin_speed_factoR= 150.0*1024.0; /** The speed conversion factors consumer x-speed to libburn speed as used with burn_drive_set_speed() burn_drive_get_write_speed() */ static double Cdrskin_libburn_cd_speed_factoR= 176.4; static double Cdrskin_libburn_dvd_speed_factoR= 1385.0; static double Cdrskin_libburn_bd_speed_factoR= 4495.625; /* The effective speed conversion factor for burn_drive_set_speed() */ static double Cdrskin_libburn_speed_factoR= 176.4; /** Add-on for burn_drive_set_speed() to accomodate to the slightley oversized speed ideas of my LG DVDRAM GSA-4082B. LITE-ON LTR-48125S tolerates it. */ static double Cdrskin_libburn_cd_speed_addoN= 40.0; static double Cdrskin_libburn_dvd_speed_addoN= 1.0; /*poor accuracy with 2.4x*/ static double Cdrskin_libburn_bd_speed_addoN= 1.0; static double Cdrskin_libburn_speed_addoN = 40.0; /** The program run control object. Defaults: see Cdrskin_new(). */ struct CdrskiN { /** Settings already interpreted by Cdrpreskin_setup */ struct CdrpreskiN *preskin; /** Job: what to do, plus some parameters. */ int verbosity; int pacifier_with_newline; double x_speed; int adjust_speed_to_drive; int gracetime; int dummy_mode; int force_is_set; int stream_recording_is_set; /* see burn_write_opts_set_stream_recording() */ int dvd_obs; /* DVD write chunk size: 0, 32k or 64k */ int obs_pad; /* Whether to force obs end padding */ int stdio_sync; /* stdio fsync interval: -1, 0, >=32 */ int single_track; int prodvd_cli_compatible; int do_devices; /* 1= --devices , 2= --device_links */ int do_scanbus; int do_load; /* 1= -load , 2= -lock , -1= --no_load */ int do_checkdrive; int do_msinfo; char msifile[Cdrskin_strleN]; int do_atip; int do_list_speeds; int do_list_formats; int do_cdtext_to_textfile; char cdtext_to_textfile_path[Cdrskin_strleN]; int do_cdtext_to_vt07; char cdtext_to_vt07_path[Cdrskin_strleN]; int do_extract_audio; char extract_audio_dir[Cdrskin_strleN]; char extract_basename[249]; char extract_audio_tracks[100]; /* if [i] > 0 : extract track i */ int extract_flags; /* bit3 = for flag bit3 of burn_drive_extract_audio() */ #ifdef Libburn_develop_quality_scaN int do_qcheck; /* 0= no , 1=nec_optiarc_rep_err_rate */ #endif /* Libburn_develop_quality_scaN */ int do_blank; int blank_fast; int no_blank_appendable; int blank_format_type; /* bit0-7: job type 0=blank 1=format_overwrite for DVD+RW, DVD-RW bit8-15: bit0-7 of burn_disc_format(flag) bit8 = write zeros after formatting bit9 = insist in size 0 bit10= format to maximum available size bit11= - reserved - bit12= - reserved - bit13= try to disable eventual defect management bit14= - reserved - bit15= format by index 2=deformat_sequential (blank_fast might matter) 3=format (= format_overwrite restricted to DVD+RW) 4=format_defectmgt for DVD-RAM, BD-R[E] bit8-15: bit0-7 of burn_disc_format(flag) bit8 = write zeros after formatting bit9+10: size mode 0 = use parameter size as far as it makes sense 1 = (identical to size mode 0) 2 = without bit7: format to maximum size with bit7 : take size from indexed format descriptor 3 = without bit7: format to default size with bit7 : take size from indexed format descriptor bit11= - reserved - bit12= - reserved - bit13= try to disable defect management bit14= - reserved - bit15= format by index 5=format_by_index gets mapped to 4 with DVD-RAM and BD-RE else to 1, bit15 should be set and bit16-23 should contain a usable index number 6=format_if_needed gets mapped to default variants of specialized formats if the media state requires formatting before writing 7=if_needed gets mapped to 6 for DVD-RAM and BD-RE, to 0 with all other non-blanks bit8-15: bit0-7 of burn_disc_format(flag) depending on job type */ int blank_format_index; /* bit8-15 of burn_disc_format(flag) */ double blank_format_size; /* to be used with burn_disc_format() */ int blank_format_no_certify; int do_direct_write; int do_burn; int tell_media_space; /* actually do not burn but tell the available space */ int burnfree; /** The write mode (like SAO or TAO). See libburn. Controled by preskin->write_mode_name */ enum burn_write_types write_type; int block_type; int multi; int cdxa_conversion; /* bit0-30: for burn_track_set_cdxa_conv() bit31 : ignore bits 0 to 30 */ int modesty_on_drive; int min_buffer_usec; /* The other parameters for this function */ int max_buffer_usec; int buffer_timeout_sec; int min_buffer_percent; int max_buffer_percent; double write_start_address; double direct_write_amount; int assert_write_lba; int do_eject; char eject_device[Cdrskin_strleN]; /** The current data source and its eventual parameters. source_path may be either "-" for stdin, "#N" for open filedescriptor N or the address of a readable file. */ char source_path[Cdrskin_strleN]; double fixed_size; double smallest_tsize; int has_open_ended_track; double padding; int set_by_padsize; int fill_up_media; /** track_type may be set to BURN_MODE1, BURN_AUDIO, etc. */ int track_type; int track_type_by_default; /* 0= explicit, 1=not set, 2=by file extension */ int swap_audio_bytes; int track_modemods; /** CDRWIN cue sheet file */ char cuefile[Cdrskin_adrleN]; int use_cdtext; /** CD-TEXT */ unsigned char *text_packs; int num_text_packs; int sheet_v07t_blocks; char sheet_v07t_paths[8][Cdrskin_adrleN]; int cdtext_test; /* Media Catalog Number and ISRC */ char mcn[14]; char next_isrc[13]; char *index_string; int sao_pregap; int sao_postgap; /** The list of tracks with their data sources and parameters */ struct CdrtracK *tracklist[Cdrskin_track_maX]; int track_counter; /** a guess about what track might be processing right now */ int supposed_track_idx; /** The number of the first track in a CD SAO session */ int cd_start_tno; int fifo_enabled; /** Optional fifo between input fd and libburn. It uses a pipe(2) to transfer data to libburn. This fifo may be actually the start of a chain of fifos which are to be processed simultaneously. The fifo object knows the real input fd and the fd[1] of the pipe. This is just a reference pointer. The fifos are managed by the tracks which either line up their fifos or share the fifo of the first track. */ struct CdrfifO *fifo; /** fd[0] of the fifo pipe. This is from where libburn reads its data. */ int fifo_outlet_fd; int fifo_size; int fifo_start_at; int fifo_per_track; struct burn_source *cuefile_fifo; /** User defined address translation */ struct CdradrtrN *adr_trn; /** The drives known to libburn after scan */ struct burn_drive_info *drives; unsigned int n_drives; /** The drive selected for operation by CdrskiN */ int driveno; /** The persistent drive address of that drive */ char device_adr[Cdrskin_adrleN]; /** Progress state info: whether libburn is actually processing payload data*/ int is_writing; /** Previously detected drive state */ enum burn_drive_status previous_drive_status; /** abort parameters */ int abort_max_wait; /** Engagement info for eventual abort */ int lib_is_initialized; pid_t control_pid; /* pid of the thread that calls libburn */ int drive_is_grabbed; struct burn_drive *grabbed_drive; /* Whether drive was told to do something cancel-worthy 0= no: directly call burn_abort 1= yes: A worker thread is busy (e.g. writing, formatting) 2= yes: A synchronous operation is busy (e.g. grabbing). */ int drive_is_busy; #ifndef Cdrskin_extra_leaN /** Abort test facility */ double abort_after_bytecount; #endif /* ! Cdrskin_extra_leaN */ /** Some intermediate option info which is stored until setup finalization */ double tao_to_sao_tsize; int stdin_source_used; /* Info about media capabilities */ int media_does_multi; int media_is_overwriteable; /* For option -isosize and --grow_overwriteable_iso */ int use_data_image_size; /* For growisofs stunt : 0=disabled, 1=do stunt, fabricate toc, allow multi, 2=overwriteable_iso_head is valid 3=initial session (mostly to appease -multi on overwriteables) */ int grow_overwriteable_iso; /* New image head buffer for --grow_overwriteable_iso */ char overwriteable_iso_head[32*2048]; /* block 0 to 31 of target */ }; int Cdrskin_destroy(struct CdrskiN **o, int flag); int Cdrskin_grab_drive(struct CdrskiN *skin, int flag); int Cdrskin_release_drive(struct CdrskiN *skin, int flag); int Cdrskin_report_disc_status(struct CdrskiN *skin, enum burn_disc_status s, int flag); /** Create a cdrskin program run control object. @param skin Returns pointer to resulting @param flag Bitfield for control purposes: bit0= library is already initialized @return <=0 error, 1 success */ int Cdrskin_new(struct CdrskiN **skin, struct CdrpreskiN *preskin, int flag) { struct CdrskiN *o; int ret,i; (*skin)= o= TSOB_FELD(struct CdrskiN,1); if(o==NULL) return(-1); o->preskin= preskin; o->verbosity= preskin->verbosity; o->pacifier_with_newline= 0; o->x_speed= -1.0; o->adjust_speed_to_drive= 0; o->gracetime= 0; o->dummy_mode= 0; o->force_is_set= 0; o->stream_recording_is_set= 0; o->dvd_obs= 0; o->obs_pad= 0; o->stdio_sync= 0; o->single_track= 0; o->prodvd_cli_compatible= 0; o->do_devices= 0; o->do_scanbus= 0; o->do_load= 0; o->do_checkdrive= 0; o->do_msinfo= 0; o->msifile[0]= 0; o->do_atip= 0; o->do_list_speeds= 0; o->do_list_formats= 0; o->do_cdtext_to_textfile= 0; o->cdtext_to_textfile_path[0]= 0; o->do_cdtext_to_vt07= 0; o->cdtext_to_vt07_path[0]= 0; o->do_extract_audio= 0; o->extract_audio_dir[0]= 0; o->extract_basename[0]= 0; for(i= 0; i < 100; i++) o->extract_audio_tracks[i]= 0; o->extract_flags= 0; #ifdef Libburn_develop_quality_scaN o->do_qcheck= 0; #endif /* Libburn_develop_quality_scaN */ o->do_blank= 0; o->blank_fast= 0; o->no_blank_appendable= 0; o->blank_format_type= 0; o->blank_format_index= -1; o->blank_format_size= 0.0; o->blank_format_no_certify= 0; o->do_direct_write= 0; o->do_burn= 0; o->tell_media_space= 0; o->write_type= BURN_WRITE_SAO; o->block_type= BURN_BLOCK_SAO; o->multi= 0; o->cdxa_conversion= 0; o->modesty_on_drive= 0; o->buffer_timeout_sec= 120; o->min_buffer_usec= 10000; o->max_buffer_usec= 100000; o->min_buffer_percent= 65; o->max_buffer_percent= 95; o->write_start_address= -1.0; o->direct_write_amount= -1.0; o->assert_write_lba= -1; o->burnfree= 1; o->do_eject= 0; o->eject_device[0]= 0; o->source_path[0]= 0; o->fixed_size= 0.0; o->smallest_tsize= -1.0; o->has_open_ended_track= 0; o->padding= 0.0; o->set_by_padsize= 0; o->fill_up_media= 0; o->track_type= BURN_MODE1; o->swap_audio_bytes= 1; /* cdrecord default is big-endian (msb_first) */ o->cuefile[0] = 0; o->use_cdtext = 0; o->text_packs= NULL; o->num_text_packs= 0; o->sheet_v07t_blocks= 0; for(i= 0; i < 8; i++) memset(o->sheet_v07t_paths, 0, Cdrskin_adrleN); o->cdtext_test= 0; o->mcn[0]= 0; o->next_isrc[0]= 0; o->index_string= NULL; o->sao_pregap= -1; o->sao_postgap= -1; o->track_modemods= 0; o->track_type_by_default= 1; for(i=0;itracklist[i]= NULL; o->track_counter= 0; o->supposed_track_idx= -1; o->cd_start_tno= 0; o->fifo_enabled= 1; o->fifo= NULL; o->fifo_outlet_fd= -1; o->fifo_size= 4*1024*1024; o->fifo_start_at= -1; o->fifo_per_track= 0; o->cuefile_fifo= NULL; o->adr_trn= NULL; o->drives= NULL; o->n_drives= 0; o->driveno= 0; o->device_adr[0]= 0; o->is_writing= 0; o->previous_drive_status = BURN_DRIVE_IDLE; o->abort_max_wait= 74*60; o->lib_is_initialized= (flag&1); o->control_pid= getpid(); o->drive_is_grabbed= 0; o->drive_is_busy= 0; o->grabbed_drive= NULL; #ifndef Cdrskin_extra_leaN o->abort_after_bytecount= -1.0; #endif /* ! Cdrskin_extra_leaN */ o->tao_to_sao_tsize= 0.0; o->stdin_source_used= 0; o->use_data_image_size= 0; o->media_does_multi= 0; o->media_is_overwriteable= 0; o->grow_overwriteable_iso= 0; memset(o->overwriteable_iso_head,0,sizeof(o->overwriteable_iso_head)); #ifndef Cdrskin_extra_leaN ret= Cdradrtrn_new(&(o->adr_trn),0); if(ret<=0) goto failed; #endif /* ! Cdrskin_extra_leaN */ return(1); failed:; Cdrskin_destroy(skin,0); return(-1); } /** Release from memory a cdrskin object */ int Cdrskin_destroy(struct CdrskiN **o, int flag) { struct CdrskiN *skin; int i; skin= *o; if(skin==NULL) return(0); if(skin->drive_is_grabbed) Cdrskin_release_drive(skin,0); for(i=0;itrack_counter;i++) Cdrtrack_destroy(&(skin->tracklist[i]),0); if(skin->index_string != NULL) free(skin->index_string); #ifndef Cdrskin_extra_leaN Cdradrtrn_destroy(&(skin->adr_trn),0); #endif /* ! Cdrskin_extra_leaN */ if(skin->cuefile_fifo != NULL) burn_source_free(skin->cuefile_fifo); if(skin->text_packs != NULL) free(skin->text_packs); Cdrpreskin_destroy(&(skin->preskin),0); if(skin->drives!=NULL) burn_drive_info_free(skin->drives); free((char *) skin); *o= NULL; return(1); } int Cdrskin_assert_driveno(struct CdrskiN *skin, int flag) { if(skin->driveno < 0 || (unsigned int) skin->driveno >= skin->n_drives) { fprintf(stderr, "cdrskin: FATAL : No drive found. Cannot perform desired operation.\n"); return(0); } return(1); } /** Return the addresses of the drive. device_adr is the libburn persistent address of the drive, raw_adr is the address as given by the user. */ int Cdrskin_get_device_adr(struct CdrskiN *skin, char **device_adr, char **raw_adr, int *no_convert_fs_adr, int flag) { int ret; if(skin->driveno < 0 || (unsigned int) skin->driveno >= skin->n_drives) return(0); ret= burn_drive_get_adr(&skin->drives[skin->driveno],skin->device_adr); if(ret <= 0) return(0); *device_adr= skin->device_adr; *raw_adr= skin->preskin->raw_device_adr; *no_convert_fs_adr= skin->preskin->no_convert_fs_adr; return(1); } int Cdrskin_get_drive(struct CdrskiN *skin, struct burn_drive **drive,int flag) { if(skin->driveno<0 || (unsigned int) skin->driveno >= skin->n_drives) return(0); *drive= skin->drives[skin->driveno].drive; return ((*drive) != NULL); } /** Return information about current track source */ int Cdrskin_get_source(struct CdrskiN *skin, char *source_path, double *fixed_size, double *tao_to_sao_tsize, int *use_data_image_size, double *padding, int *set_by_padsize, int *track_type, int *track_type_by_default, int *mode_mods, int *swap_audio_bytes, int *cdxa_conversion, int flag) { strcpy(source_path,skin->source_path); *fixed_size= skin->fixed_size; *tao_to_sao_tsize = skin->tao_to_sao_tsize; *use_data_image_size= skin->use_data_image_size; *padding= skin->padding; *set_by_padsize= skin->set_by_padsize; *track_type= skin->track_type; *track_type_by_default= skin->track_type_by_default; *mode_mods= skin->track_modemods; *swap_audio_bytes= skin->swap_audio_bytes; *cdxa_conversion= skin->cdxa_conversion; return(1); } #ifndef Cdrskin_extra_leaN /** Return information about current fifo setting */ int Cdrskin_get_fifo_par(struct CdrskiN *skin, int *fifo_enabled, int *fifo_size, int *fifo_start_at, int flag) { *fifo_enabled= skin->fifo_enabled; *fifo_size= skin->fifo_size; *fifo_start_at= skin->fifo_start_at; return(1); } #ifndef Cdrskin_no_cdrfifO /** Create and install fifo objects between track data sources and libburn. The sources and parameters are known to skin. @return <=0 error, 1 success */ int Cdrskin_attach_fifo(struct CdrskiN *skin, int flag) { struct CdrfifO *ff= NULL; int ret,i,hflag; #ifdef Cdrskin_use_libburn_fifO int profile_number; char profile_name[80]; ret= Cdrskin_assert_driveno(skin, 0); if(ret <= 0) return(ret); /* Refuse here and thus use libburn fifo only with single track, non-CD */ ret= burn_disc_get_profile(skin->drives[skin->driveno].drive, &profile_number, profile_name); if(profile_number != 0x09 && profile_number != 0x0a && skin->track_counter == 1) return(1); #endif /* Cdrskin_use_libburn_fifO */ skin->fifo= NULL; for(i=0;itrack_counter;i++) { hflag= (skin->verbosity>=Cdrskin_verbose_debuG); if(i==skin->track_counter-1) hflag|= 4; if(skin->verbosity>=Cdrskin_verbose_cmD) { if(skin->fifo_per_track) printf("cdrskin: track %d establishing fifo of %d bytes\n", i+1,skin->fifo_size); else if(i==0) printf("cdrskin: establishing fifo of %d bytes\n",skin->fifo_size); else { if(skin->verbosity>=Cdrskin_verbose_debuG) ClN(fprintf(stderr,"cdrskin_debug: attaching track %d to fifo\n",i+1)); hflag|= 2; } } ret= Cdrtrack_attach_fifo(skin->tracklist[i],&(skin->fifo_outlet_fd),ff, hflag); if(ret<=0) { fprintf(stderr,"cdrskin: FATAL : failed to attach fifo.\n"); return(0); } if(i==0 || skin->fifo_per_track) Cdrtrack_get_fifo(skin->tracklist[i],&ff,0); if(i==0) skin->fifo= ff; } return(1); } #endif /* ! Cdrskin_no_cdrfifO */ /** Read data into the track fifos until either #1 is full or its data source is exhausted. @return <=0 error, 1 success */ int Cdrskin_fill_fifo(struct CdrskiN *skin, int flag) { int ret; ret= Cdrtrack_fill_fifo(skin->tracklist[0],skin->fifo_start_at,0); if(ret<=0) return(ret); printf("input buffer ready.\n"); fflush(stdout); return(1); } #endif /* ! Cdrskin_extra_leaN */ /** Inform libburn about the consumer x-speed factor of skin */ int Cdrskin_adjust_speed(struct CdrskiN *skin, int flag) { int k_speed, modesty= 0; if(skin->x_speed<0) k_speed= 0; /* libburn.h promises 0 to be max speed. */ else if(skin->x_speed==0) { /* cdrecord specifies 0 as minimum speed. */ k_speed= -1; } else k_speed= skin->x_speed*Cdrskin_libburn_speed_factoR + Cdrskin_libburn_speed_addoN; if(skin->verbosity>=Cdrskin_verbose_debuG) ClN(fprintf(stderr,"cdrskin_debug: k_speed= %d\n",k_speed)); if(skin->adjust_speed_to_drive && !skin->force_is_set) { struct burn_speed_descriptor *best_descr; burn_drive_get_best_speed(skin->drives[skin->driveno].drive,k_speed, &best_descr,0); if(best_descr!=NULL) { k_speed= best_descr->write_speed; skin->x_speed = ((double) k_speed) / Cdrskin_libburn_speed_factoR; } } burn_drive_set_speed(skin->drives[skin->driveno].drive,k_speed,k_speed); modesty= skin->modesty_on_drive; burn_drive_set_buffer_waiting(skin->drives[skin->driveno].drive, modesty, skin->min_buffer_usec, skin->max_buffer_usec, skin->buffer_timeout_sec, skin->min_buffer_percent, skin->max_buffer_percent); return(1); } int Cdrskin_determine_media_caps(struct CdrskiN *skin, int flag) { int ret; struct burn_multi_caps *caps = NULL; skin->media_is_overwriteable= skin->media_does_multi= 0; ret= burn_disc_get_multi_caps(skin->grabbed_drive,BURN_WRITE_NONE,&caps,0); if(ret<=0) goto ex; skin->media_is_overwriteable= !!caps->start_adr; skin->media_does_multi= !!caps->multi_session; ret= 1; ex:; if(caps != NULL) burn_disc_free_multi_caps(&caps); return(ret); } int Cdrskin__is_aborting(int flag) { if(Cdrskin_abort_leveL) return(-1); return(burn_is_aborting(0)); } int Cdrskin_abort(struct CdrskiN *skin, int flag) { int ret; Cdrskin_abort_leveL= 1; ret= burn_abort(skin->abort_max_wait, burn_abort_pacifier, "cdrskin: "); if(ret<=0) { fprintf(stderr, "\ncdrskin: ABORT : Cannot cancel burn session and release drive.\n"); } else { fprintf(stderr, "cdrskin: ABORT : Drive is released and library is shut down now.\n"); } fprintf(stderr, "cdrskin: ABORT : Program done. Even if you do not see a shell prompt.\n"); fprintf(stderr,"\n"); exit(1); } /** Obtain access to a libburn drive for writing or information retrieval. If libburn is not restricted to a single persistent address then the unused drives are dropped. This might be done by shutting down and restartiing libburn with the wanted drive only. Thus, after this call, libburn is supposed to have open only the reserved drive. All other drives should be free for other use. Warning: Do not store struct burn_drive pointer over this call. Any such pointer might be invalid afterwards. @param flag Bitfield for control purposes: bit0= bus is unscanned, device is known, use burn_drive_scan_and_grab() bit1= do not load drive tray bit2= do not issue error message on failure bit3= demand and evtl. report media, return 0 if none to see bit4= grab drive with unsuitable media even if fallback program bit5= do not re-assess the drive if it is already grabbed but rather perform a release-and-grab cycle @return <=0 error, 1 success */ int Cdrskin_grab_drive(struct CdrskiN *skin, int flag) { int ret,i,profile_number, mem; struct burn_drive *drive; char profile_name[80]; enum burn_disc_status s; if(skin->drive_is_grabbed && (flag & 32)) Cdrskin_release_drive(skin,0); if(!skin->drive_is_grabbed) { if(flag&1) { skin->driveno= 0; drive= NULL; skin->grabbed_drive= drive; } else { ret= Cdrskin_assert_driveno(skin, 0); if(ret <= 0) return(ret); drive= skin->drives[skin->driveno].drive; skin->grabbed_drive= drive; } } if(skin->drive_is_grabbed) { drive= skin->grabbed_drive; mem= skin->drive_is_busy; skin->drive_is_busy= 2; ret= burn_drive_re_assess(skin->grabbed_drive, 0); skin->drive_is_busy= mem; if(Cdrskin__is_aborting(0)) { fprintf(stderr,"cdrskin: ABORT : Drive re-assessment aborted\n"); Cdrskin_abort(skin, 0); /* Never comes back */ } if(ret <= 0) { if(!(flag&4)) fprintf(stderr,"cdrskin: FATAL : unable to re-assess drive '%s'\n", skin->preskin->device_adr); goto ex; } } else if(flag&1) { mem= skin->drive_is_busy; skin->drive_is_busy= 2; ret= burn_drive_scan_and_grab(&(skin->drives),skin->preskin->device_adr, (skin->do_load != -1) && !(flag&2)); skin->drive_is_busy= mem; if(Cdrskin__is_aborting(0)) { aborted:; fprintf(stderr,"cdrskin: ABORT : Drive aquiration aborted\n"); Cdrskin_abort(skin, 0); /* Never comes back */ } if(ret<=0) { if(!(flag&4)) fprintf(stderr,"cdrskin: FATAL : unable to open drive '%s'\n", skin->preskin->device_adr); goto ex; } skin->driveno= 0; drive= skin->drives[skin->driveno].drive; skin->grabbed_drive= drive; } else { if(strlen(skin->preskin->device_adr)<=0) { if(skin->verbosity>=Cdrskin_verbose_debuG) ClN(fprintf(stderr, "cdrskin_debug: Cdrskin_grab_drive() dropping unwanted drives (%d)\n", skin->n_drives-1)); for(i= 0; i < (int) skin->n_drives; i++) { if(i==skin->driveno) continue; if(skin->verbosity>=Cdrskin_verbose_debuG) ClN(fprintf(stderr, "cdrskin_debug: Cdrskin_grab_drive() dropped drive number %d\n",i)); ret= burn_drive_info_forget(&(skin->drives[i]), 0); if(ret==1 || ret==2) continue; fprintf(stderr, "cdrskin: NOTE : Please inform libburn-hackers@pykix.org about:\n"); fprintf(stderr, "cdrskin: burn_drive_info_forget() returns %d\n",ret); } } mem= skin->drive_is_busy; skin->drive_is_busy= 2; ret= burn_drive_grab(drive,(skin->do_load != -1) && !(flag&2)); skin->drive_is_busy= mem; if(Cdrskin__is_aborting(0)) goto aborted; if(ret==0) { if(!(flag&4)) fprintf(stderr,"cdrskin: FATAL : unable to open drive %d\n", skin->driveno); goto ex; } } skin->drive_is_grabbed= 1; s= burn_disc_get_status(drive); if((flag&8)) { if(skin->verbosity>=Cdrskin_verbose_progresS) Cdrskin_report_disc_status(skin,s,1); if(s==BURN_DISC_EMPTY) { Cdrskin_release_drive(skin,0); fprintf(stderr,"cdrskin: SORRY : No media found in drive\n"); ret= 0; goto ex; } } Cdrskin_speed_factoR= Cdrskin_cd_speed_factoR; Cdrskin_libburn_speed_factoR= Cdrskin_libburn_cd_speed_factoR; Cdrskin_libburn_speed_addoN= Cdrskin_libburn_cd_speed_addoN; ret= burn_disc_get_profile(drive,&profile_number,profile_name); if(ret>0) { if(strstr(profile_name,"DVD")==profile_name || strstr(profile_name,"stdio")==profile_name ) { Cdrskin_speed_factoR= Cdrskin_dvd_speed_factoR; Cdrskin_libburn_speed_factoR= Cdrskin_libburn_dvd_speed_factoR; Cdrskin_libburn_speed_addoN= Cdrskin_libburn_dvd_speed_addoN; } else if(strstr(profile_name,"BD")==profile_name) { Cdrskin_speed_factoR= Cdrskin_bd_speed_factoR; Cdrskin_libburn_speed_factoR= Cdrskin_libburn_bd_speed_factoR; Cdrskin_libburn_speed_addoN= Cdrskin_libburn_bd_speed_addoN; } } if(skin->preskin->fallback_program[0] && s==BURN_DISC_UNSUITABLE && skin->preskin->demands_cdrskin_caps<=0 && !(flag&16)) { skin->preskin->demands_cdrecord_caps= 1; fprintf(stderr, "cdrskin: NOTE : Will delegate job to fallback program '%s'.\n", skin->preskin->fallback_program); Cdrskin_release_drive(skin,0); ret= 0; goto ex; } Cdrskin_determine_media_caps(skin,0); ret= 1; ex:; if(ret<=0) { skin->drive_is_grabbed= 0; skin->grabbed_drive= NULL; } return(ret); } /** Release grabbed libburn drive @param flag Bitfield for control purposes: bit0= eject bit1= leave tray locked (eventually overrides bit0) */ int Cdrskin_release_drive(struct CdrskiN *skin, int flag) { if((!skin->drive_is_grabbed) || skin->grabbed_drive==NULL) { fprintf(stderr,"cdrskin: CAUGHT : release of non-grabbed drive.\n"); return(0); } if(flag&2) burn_drive_leave_locked(skin->grabbed_drive,0); else burn_drive_release(skin->grabbed_drive,(flag&1)); skin->drive_is_grabbed= 0; skin->grabbed_drive= NULL; return(1); } /** Clean up resources in abort situations. To be called by Cleanup subsystem but hardly ever by the application. The program must exit afterwards. */ int Cdrskin_abort_handler(struct CdrskiN *skin, int signum, int flag) { struct burn_progress p; enum burn_drive_status drive_status= BURN_DRIVE_SPAWNING; /* fprintf(stderr, "cdrskin_DEBUG: Cdrskin_abort_handler: signum=%d, flag=%d, drive_is_busy=%d\n", signum, flag, skin->drive_is_busy); */ if(skin->drive_is_busy == 0) Cdrskin_abort(skin, 0); /* Never comes back */ if(getpid()!=skin->control_pid) { if(skin->verbosity>=Cdrskin_verbose_debuG) ClN(fprintf(stderr, "\ncdrskin_debug: ABORT : [%lu] Thread rejected: pid=%lu, signum=%lu\n", (unsigned long int) skin->control_pid, (unsigned long int) getpid(), (unsigned long int) signum)); #ifdef Not_yeT /* >>> find more abstract and system independent way to determine signals which make no sense with a return */ if(signum==11) { Cleanup_set_handlers(NULL,NULL,1); /* allow abort */ return(0); /* let exit */ } #endif usleep(1000000); return(-2); /* do only process the control thread */ } if(skin->preskin->abort_handler==3) Cleanup_set_handlers(NULL,NULL,2); /* ignore all signals */ else if(skin->preskin->abort_handler==4) Cleanup_set_handlers(NULL,NULL,1); /* allow abort */ fprintf(stderr, "\ncdrskin: ABORT : Handling started. Please do not press CTRL+C now.\n"); if(skin->preskin->abort_handler==3) fprintf(stderr,"cdrskin: ABORT : Trying to ignore any further signals\n"); #ifndef Cdrskin_no_cdrfifO if(skin->fifo!=NULL) Cdrfifo_close_all(skin->fifo,0); #endif /* Only for user info */ if(skin->grabbed_drive!=NULL) drive_status= burn_drive_get_status(skin->grabbed_drive,&p); if(drive_status!=BURN_DRIVE_IDLE) { fprintf(stderr,"cdrskin: ABORT : Abort processing depends on speed and buffer size\n"); fprintf(stderr,"cdrskin: ABORT : Usually it is done with 4x speed after about a MINUTE\n"); fprintf(stderr,"cdrskin: URGE : But wait at least the normal burning time before any kill -9\n"); } Cdrskin_abort_leveL= -1; if (!(flag & 1)) { if(skin->verbosity>=Cdrskin_verbose_debuG) ClN(fprintf(stderr,"cdrskin: ABORT : Calling burn_abort(-1)\n")); burn_abort(-1, burn_abort_pacifier, "cdrskin: "); } fprintf(stderr, "cdrskin: ABORT : Urged drive worker threads to do emergency halt.\n"); return(-2); } /** Convert a libburn device address into a libburn drive number @return <=0 error, 1 success */ int Cdrskin_driveno_of_location(struct CdrskiN *skin, char *devicename, int *driveno, int flag) { int i,ret; char adr[Cdrskin_adrleN]; for(i= 0; i < (int) skin->n_drives; i++) { ret= burn_drive_get_adr(&(skin->drives[i]), adr); if(ret<=0) continue; if(strcmp(adr,devicename)==0) { *driveno= i; return(1); } } return(0); } /** Convert a cdrskin address into a libburn drive number @return <=0 error, 1 success */ int Cdrskin_dev_to_driveno(struct CdrskiN *skin, char *in_adr, int *driveno, int flag) { int ret; char *adr,translated_adr[Cdrskin_adrleN],synthetic_adr[Cdrskin_adrleN]; adr= in_adr; #ifndef Cdrskin_extra_leaN /* user defined address translation */ ret= Cdradrtrn_translate(skin->adr_trn,adr,-1,translated_adr,0); if(ret<=0) { fprintf(stderr, "cdrskin: FATAL : address translation failed (address too long ?) \n"); return(0); } if(skin->verbosity>=Cdrskin_verbose_cmD && strcmp(adr,translated_adr)!=0) printf("cdrskin: dev_translation=... : dev='%s' to dev='%s'\n", adr,translated_adr); adr= translated_adr; #endif /* ! Cdrskin_extra_leaN */ if(strncmp(adr, "stdio:", 6)==0) { if(skin->n_drives<=0) goto wrong_devno; *driveno= 0; return(1); } else if(adr[0]=='/') { ret= Cdrskin_driveno_of_location(skin,adr,driveno,0); if(ret<=0) { location_not_found:; fprintf(stderr, "cdrskin: FATAL : cannot find '%s' among accessible drive devices.\n", adr); fprintf(stderr, "cdrskin: HINT : use option --devices for a list of drive devices.\n"); return(0); } return(1); } ret= Cdrpreskin__cdrecord_to_dev(adr,synthetic_adr,driveno, !!skin->preskin->old_pseudo_scsi_adr); if(ret<=0) { wrong_devno:; if(skin->n_drives<=0) { fprintf(stderr,"cdrskin: FATAL : No accessible drives.\n"); } else { fprintf(stderr, "cdrskin: FATAL : Address does not lead to an accessible drive: %s\n", in_adr); fprintf(stderr, "cdrskin: HINT : dev= expects /dev/xyz, Bus,Target,0 or a number [0,%d]\n", skin->n_drives-1); } return(0); } if(strlen(synthetic_adr)>0) { if(skin->verbosity>=Cdrskin_verbose_cmD) ClN(printf("cdrskin: converted address '%s' to '%s'\n",adr,synthetic_adr)); ret= Cdrskin_driveno_of_location(skin,synthetic_adr,driveno,0); if(ret<=0) { fprintf(stderr, "cdrskin: failure while using address converted from '%s'\n",adr); adr= synthetic_adr; goto location_not_found; } } if((unsigned int) (*driveno) >= skin->n_drives || (*driveno) < 0) { ClN(fprintf(stderr,"cdrskin: obtained drive number %d from '%s'\n", *driveno,adr)); goto wrong_devno; } return(1); } /** Convert a libburn drive number into a cdrecord-style address which represents a device address if possible and the drive number else. @param flag Bitfield for control purposes: bit0= do not apply user defined address translation @return <0 error, pseudo transport groups: 0 volatile drive number, 1 /dev/sgN, 2 /dev/hdX, 3 stdio, 1000000+busno = non-pseudo SCSI bus 2000000+busno = pseudo-ATA|ATAPI SCSI bus (currently busno==2) */ int Cdrskin_driveno_to_btldev(struct CdrskiN *skin, int driveno, char btldev[Cdrskin_adrleN], int flag) { int k,ret,still_untranslated= 1,hret,k_start; char *loc= NULL,buf[Cdrskin_adrleN],adr[Cdrskin_adrleN]; if(driveno < 0 || driveno > (int) skin->n_drives) goto fallback; ret= burn_drive_get_adr(&(skin->drives[driveno]), adr); if(ret<=0) goto fallback; loc= adr; ret= burn_drive_get_drive_role(skin->drives[driveno].drive); if(ret!=1) { sprintf(btldev,"stdio:%s",adr); {ret= 2; goto adr_translation;} } if(!skin->preskin->old_pseudo_scsi_adr) { int host_no= -1,channel_no= -1,target_no= -1,lun_no= -1, bus_no= -1; ret= burn_drive_obtain_scsi_adr(loc,&bus_no,&host_no,&channel_no, &target_no,&lun_no); if(ret<=0) { if(strncmp(loc,"/dev/hd",7)==0) if(loc[7]>='a' && loc[7]<='z') if(loc[8]==0) { bus_no= (loc[7]-'a')/2; sprintf(btldev,"%d,%d,0",bus_no,(loc[7]-'a')%2); {ret= 2000000 + bus_no; goto adr_translation;} } goto fallback; } else { sprintf(btldev,"%d,%d,%d",bus_no,target_no,lun_no); ret= 1000000+bus_no; goto adr_translation; } } k_start= 0; if(strncmp(loc,"/dev/sg",7)==0 || strncmp(loc,"/dev/sr",7)==0) k_start= 7; if(strncmp(loc,"/dev/scd",8)==0) k_start= 8; if(k_start>0) { for(k= k_start;loc[k]!=0;k++) if(loc[k]<'0' || loc[k]>'9') break; if(loc[k]==0 && k>k_start) { sprintf(btldev,"1,%s,0",loc+k_start); {ret= 1; goto adr_translation;} } } if(strncmp(loc,"/dev/hd",7)==0) if(loc[7]>='a' && loc[7]<='z') if(loc[8]==0) { sprintf(btldev,"2,%d,0",loc[7]-'a'); {ret= 2; goto adr_translation;} } fallback:; if(skin->preskin->old_pseudo_scsi_adr) { sprintf(btldev,"0,%d,0",driveno); } else { if(loc!=NULL) strcpy(btldev,loc); else sprintf(btldev,"%d",driveno); } ret= 0; adr_translation:; #ifndef Cdrskin_extra_leaN /* user defined address translation */ if(!(flag&1)) { if(ret>0) { /* try whether a translation points to loc */ hret= Cdradrtrn_translate(skin->adr_trn,loc,driveno,buf,1); if(hret==2) { still_untranslated= 0; strcpy(btldev,buf); } } if(still_untranslated) { Cdradrtrn_translate(skin->adr_trn,btldev,driveno,buf,1); strcpy(btldev,buf); } } #endif /* ! Cdrskin_extra_leaN */ return(ret); } /** Read and buffer the start of an existing ISO-9660 image from overwriteable target media. */ int Cdrskin_overwriteable_iso_size(struct CdrskiN *skin, int *size, int flag) { int ret; off_t data_count= 0; double size_in_bytes; char *buf; buf= skin->overwriteable_iso_head; if(!skin->media_is_overwriteable) {ret= 0; goto ex;} /* Read first 64 kB */ ret= burn_read_data(skin->grabbed_drive,(off_t) 0,buf,32*2048,&data_count,0); if(ret<=0) {ret= 0; goto ex;} ret= Scan_for_iso_size((unsigned char *) (buf+16*2048), &size_in_bytes,0); if(ret<=0) { if(skin->verbosity>=Cdrskin_verbose_debuG) ClN(fprintf(stderr,"cdrskin_debug: No detectable ISO-9660 size on media\n")); {ret= 0; goto ex;} } if(skin->verbosity>=Cdrskin_verbose_debuG) ClN(fprintf(stderr,"cdrskin_debug: detected ISO-9660 size : %.f (%fs)\n", size_in_bytes, size_in_bytes/2048.0)); if(size_in_bytes/2048.0>2147483647-1-16) { fprintf(stderr, "cdrskin: FATAL : ISO-9660 filesystem in terabyte size detected\n"); {ret= 0; goto ex;} } *size= size_in_bytes/2048.0; if(size_in_bytes-((double) *size)*2048.0>0.0) (*size)++; if((*size)%16) *size+= 16-((*size)%16); if(skin->grow_overwriteable_iso==1) skin->grow_overwriteable_iso= 2; ret= 1; ex:; return(ret); } int Cdrskin_invalidate_iso_head(struct CdrskiN *skin, int flag) { int ret; int size; fprintf(stderr, "cdrskin: blank=... : invalidating ISO-9660 head on overwriteable media\n"); ret= Cdrskin_overwriteable_iso_size(skin,&size,0); if(ret<=0) { fprintf(stderr, "cdrskin: NOTE : Not an ISO-9660 file system. Left unaltered.\n"); return(2); } skin->overwriteable_iso_head[16*2048]= skin->overwriteable_iso_head[16*2048+3]= skin->overwriteable_iso_head[16*2048+4]= 'x'; ret= burn_random_access_write(skin->grabbed_drive,(off_t) 16*2048, skin->overwriteable_iso_head+16*2048, (off_t) 16*2048,1); return(ret); } /** Report media status s to the user @param flag Bitfield for control purposes: bit0= permission to check for overwriteable ISO image bit1= do not report media profile bit2= do not report but only check for pseudo appendable @return 1=ok, 2=ok, is pseudo appendable, <=0 error */ int Cdrskin_report_disc_status(struct CdrskiN *skin, enum burn_disc_status s, int flag) { int ret, iso_size, pseudo_appendable= 0; if(flag&1) { if(skin->media_is_overwriteable && skin->grow_overwriteable_iso>0) { if(skin->grow_overwriteable_iso==2) ret= 1; else ret= Cdrskin_overwriteable_iso_size(skin,&iso_size,0); if(ret>0) { s= BURN_DISC_APPENDABLE; pseudo_appendable= 1; } } } if(flag&4) return(1+pseudo_appendable); printf("cdrskin: status %d ",s); if(s==BURN_DISC_FULL) { printf("burn_disc_full \"There is a disc with data on it in the drive\"\n"); } else if(s==BURN_DISC_BLANK) { printf("burn_disc_blank \"The drive holds a blank disc\"\n"); } else if(s==BURN_DISC_APPENDABLE) { printf( "BURN_DISC_APPENDABLE \"There is an incomplete disc in the drive\"\n"); } else if(s==BURN_DISC_EMPTY) { printf("BURN_DISC_EMPTY \"There is no disc at all in the drive\"\n"); } else if(s==BURN_DISC_UNREADY) { printf("BURN_DISC_UNREADY \"The current status is not yet known\"\n"); } else if(s==BURN_DISC_UNGRABBED) { printf("BURN_DISC_UNGRABBED \"API usage error: drive not grabbed\"\n"); } else if(s==BURN_DISC_UNSUITABLE) { printf("BURN_DISC_UNSUITABLE \"Media is not suitable\"\n"); } else printf("-unknown status code-\n"); if(flag&2) return(1+pseudo_appendable); if((s==BURN_DISC_FULL || s==BURN_DISC_APPENDABLE || s==BURN_DISC_BLANK || s==BURN_DISC_UNSUITABLE) && skin->driveno>=0) { char profile_name[80]; int profile_number; printf("Current: "); ret= burn_disc_get_profile(skin->drives[skin->driveno].drive, &profile_number,profile_name); if(ret>0 && profile_name[0]!=0) printf("%s\n", profile_name); else if(ret>0) printf("UNSUITABLE MEDIA (Profile %4.4Xh)\n",profile_number); else printf("-unidentified-\n"); } else if(s==BURN_DISC_EMPTY) { printf("Current: none\n"); } return(1+pseudo_appendable); } /** Perform operations -scanbus or --devices @param flag Bitfield for control purposes: bit0= perform --devices rather than -scanbus bit1= with bit0: perform --device_links @return <=0 error, 1 success */ int Cdrskin_scanbus(struct CdrskiN *skin, int flag) { int ret,i,busno,first_on_bus,pseudo_transport_group= 0,skipped_devices= 0; int busmax= 16, busidx, max_dev_len, pad, j; char shellsafe[5*Cdrskin_strleN+2],perms[40],btldev[Cdrskin_adrleN]; char adr[Cdrskin_adrleN],*raw_dev,*drives_shown= NULL; char link_adr[BURN_DRIVE_ADR_LEN]; int *drives_busses= NULL; struct stat stbuf; drives_shown= calloc(1, skin->n_drives+1); drives_busses= calloc((skin->n_drives+1), sizeof(int)); if(drives_shown == NULL || drives_busses == NULL) {ret= -1; goto ex;} if(flag&1) { max_dev_len= 0; for(i= 0; i < (int) skin->n_drives; i++) { drives_shown[i]= 0; ret= burn_drive_get_adr(&(skin->drives[i]), adr); if(ret<=0) continue; if(flag & 2) { ret= burn_lookup_device_link(adr, link_adr, "/dev", NULL, 0, 0); if(ret == 1) strcpy(adr, link_adr); } if(strlen(adr)>=Cdrskin_strleN) Text_shellsafe("failure:oversized string", shellsafe, 0); else Text_shellsafe(adr, shellsafe,0); if((int) strlen(shellsafe) > max_dev_len) max_dev_len= strlen(shellsafe); } printf("cdrskin: Overview of accessible drives (%d found) :\n", skin->n_drives); printf("-----------------------------------------------------------------------------\n"); for(i= 0; i < (int) skin->n_drives; i++) { ret= burn_drive_get_adr(&(skin->drives[i]), adr); if(ret<=0) { /* >>> one should massively complain */; continue; } if(stat(adr,&stbuf)==-1) { sprintf(perms,"errno=%d",errno); } else { strcpy(perms,"------"); if(stbuf.st_mode&S_IRUSR) perms[0]= 'r'; if(stbuf.st_mode&S_IWUSR) perms[1]= 'w'; if(stbuf.st_mode&S_IRGRP) perms[2]= 'r'; if(stbuf.st_mode&S_IWGRP) perms[3]= 'w'; if(stbuf.st_mode&S_IROTH) perms[4]= 'r'; if(stbuf.st_mode&S_IWOTH) perms[5]= 'w'; } if(flag & 2) { ret= burn_lookup_device_link(adr, link_adr, "/dev", NULL, 0, 0); if(ret == 1) strcpy(adr, link_adr); } if(strlen(adr)>=Cdrskin_strleN) Text_shellsafe("failure:oversized string",shellsafe,0); else Text_shellsafe(adr,shellsafe,0); printf("%d dev=%s", i, shellsafe); pad= max_dev_len - strlen(shellsafe); if(pad > 0) for(j= 0; j < pad; j++) printf(" "); printf(" %s : '%-8.8s' '%s'\n", perms, skin->drives[i].vendor, skin->drives[i].product); } printf("-----------------------------------------------------------------------------\n"); } else { if(!skin->preskin->old_pseudo_scsi_adr) { pseudo_transport_group= 1000000; raw_dev= skin->preskin->raw_device_adr; if(strncmp(raw_dev,"ATA",3)==0 && (raw_dev[3]==0 || raw_dev[3]==':')) pseudo_transport_group= 2000000; if(strncmp(raw_dev,"ATAPI",5)==0 && (raw_dev[5]==0 || raw_dev[5]==':')) pseudo_transport_group= 2000000; if(pseudo_transport_group==2000000) { fprintf(stderr,"scsidev: 'ATA'\ndevname: 'ATA'\n"); fprintf(stderr,"scsibus: -2 target: -2 lun: -2\n"); } } /* >>> fprintf(stderr,"Linux sg driver version: 3.1.25\n"); */ printf("Using libburn version '%s'.\n", Cdrskin_libburn_versioN); if(pseudo_transport_group!=1000000) if(skin->preskin->old_pseudo_scsi_adr) printf("cdrskin: NOTE : The printed addresses are not cdrecord compatible !\n"); for(i= 0; i < (int) skin->n_drives; i++) { drives_busses[i]= -1; ret= Cdrskin_driveno_to_btldev(skin,i,btldev,1); if(ret >= pseudo_transport_group && ret < pseudo_transport_group + 1000000) { drives_busses[i]= ret - pseudo_transport_group; if(ret > pseudo_transport_group + busmax) busmax= 1 + ret - pseudo_transport_group; } } for(busidx= 0; busidx < (int) skin->n_drives + 1; busidx++) { if(busidx < (int) skin->n_drives) busno= drives_busses[busidx]; else busno= busmax; if(busno < 0) continue; for(i= 0; i < busidx; i++) if(drives_busses[i] == busno) break; if(i < busidx) continue; first_on_bus= 1; for(i= 0; i < (int) skin->n_drives; i++) { ret= Cdrskin_driveno_to_btldev(skin,i,btldev,1); if(busno==busmax && drives_shown[i]==0) { if(ret/1000000 != pseudo_transport_group) { skipped_devices++; if(skin->verbosity>=Cdrskin_verbose_debuG) ClN(fprintf(stderr,"cdrskin_debug: skipping drive '%s%s'\n", ((ret/1000000)==2?"ATA:":""), btldev)); continue; } } else if(ret != pseudo_transport_group + busno) continue; if(first_on_bus) printf("scsibus%d:\n",busno); first_on_bus= 0; printf("\t%s\t %d) '%-8s' '%-16s' '%-4s' Removable CD-ROM\n", btldev,i,skin->drives[i].vendor,skin->drives[i].product, skin->drives[i].revision); drives_shown[i]= 1; } } } if(skipped_devices>0) { if(skipped_devices>1) printf("cdrskin: NOTE : There were %d drives not shown.\n", skipped_devices); else printf("cdrskin: NOTE : There was 1 drive not shown.\n"); printf("cdrskin: HINT : To surely see all drives try option: --devices\n"); if(pseudo_transport_group!=2000000) printf("cdrskin: HINT : or try options: dev=ATA -scanbus\n"); } ret= 1; ex:; if(drives_shown!=NULL) free((char *) drives_shown); if(drives_busses!=NULL) free((char *) drives_busses); return(ret); } /** Perform -checkdrive . @param flag Bitfield for control purposes: bit0= do not print message about pseudo-checkdrive @return <=0 error, 1 success */ int Cdrskin_checkdrive(struct CdrskiN *skin, char *profile_name, int flag) { struct burn_drive_info *drive_info; int ret; char btldev[Cdrskin_adrleN]; char *sno= NULL; int sno_len = 0; if(!(flag&1)) { if(flag&2) ClN(printf("cdrskin: pseudo-inquiry on drive %d\n",skin->driveno)); else ClN(printf("cdrskin: pseudo-checkdrive on drive %d\n",skin->driveno)); } if(skin->driveno >= (int) skin->n_drives || skin->driveno < 0) { fprintf(stderr,"cdrskin: FATAL : there is no drive #%d\n",skin->driveno); {ret= 0; goto ex;} } drive_info= &(skin->drives[skin->driveno]); ret= Cdrskin_driveno_to_btldev(skin,skin->driveno,btldev,0); if(ret>=0) fprintf(stderr,"scsidev: '%s'\n",btldev); printf("Device type : "); ret= burn_drive_get_drive_role(drive_info->drive); if(ret==0) printf("%s\n","Emulated (null-drive)"); else if(ret==2) printf("%s\n","Emulated (stdio-drive, 2k random read-write)"); else if(ret==3) printf("%s\n","Emulated (stdio-drive, sequential write-only)"); else if(ret==4) printf("%s\n","Emulated (stdio-drive, 2k random read-only)"); else if(ret == 5) printf("%s\n","Emulated (stdio-drive, 2k random write-only)"); else if(ret!=1) printf("%s\n","Emulated (stdio-drive)"); else printf("%s\n","Removable CD-ROM"); printf("Vendor_info : '%s'\n",drive_info->vendor); printf("Identifikation : '%s'\n",drive_info->product); printf("Revision : '%s'\n",drive_info->revision); if(flag&2) {ret= 1; goto ex;} burn_drive_get_serial_no(drive_info->drive, &sno, &sno_len); if(sno_len > 0) printf("Drive id : '%s'\n", sno); if(sno != NULL) free(sno); sno= NULL; printf("Driver flags : %s\n","BURNFREE"); printf("Supported modes:"); if((drive_info->tao_block_types & (BURN_BLOCK_MODE1)) == (BURN_BLOCK_MODE1)) printf(" TAO"); if(drive_info->sao_block_types & BURN_BLOCK_SAO) printf(" SAO"); #ifndef Cdrskin_disable_raw96R if((drive_info->raw_block_types & BURN_BLOCK_RAW96R) && strstr(profile_name,"DVD")!=profile_name && strstr(profile_name,"BD")!=profile_name) printf(" RAW/RAW96R"); #endif /* ! Cdrskin_disable_raw96R */ printf("\n"); ret= 1; ex:; return(ret); } /** Predict address block number where the next write will go to @param flag Bitfield for control purposes: bit0= do not return nwa from eventual write_start_address @return <=0 error, 1 nwa from drive , 2 nwa from write_start_address */ int Cdrskin_obtain_nwa(struct CdrskiN *skin, int *nwa, int flag) { int ret,lba; struct burn_drive *drive; struct burn_write_opts *o= NULL; if(skin->write_start_address>=0 && !(flag&1)) { /* (There is no sense in combining random addressing with audio) */ *nwa= skin->write_start_address/2048; return(2); } /* Set write opts in order to provoke MODE SELECT. LG GSA-4082B needs it. */ drive= skin->drives[skin->driveno].drive; o= burn_write_opts_new(drive); if(o!=NULL) { burn_write_opts_set_perform_opc(o, 0); burn_write_opts_set_write_type(o,skin->write_type,skin->block_type); burn_write_opts_set_underrun_proof(o,skin->burnfree); } ret= burn_disc_track_lba_nwa(drive,o,0,&lba,nwa); if(o!=NULL) burn_write_opts_free(o); return(ret); } /* @param flag bit0-3= source of text packs: 0= CD Lead-in 1= session and tracks 2= textfile= bit4-7= output format 0= -vv -toc 1= Sony CD-TEXT Input Sheet Version 0.7T */ int Cdrskin_print_text_packs(struct CdrskiN *skin, unsigned char *text_packs, int num_packs, int flag) { int i, j, from, fmt, ret, char_code= 0; char *from_text= "", *result= NULL; unsigned char *pack; from= flag & 15; fmt= (flag >> 4) & 15; if(from == 0) from_text= " from CD Lead-in"; else if(from == 1) from_text= " from session and tracks"; else if(from == 2) from_text= " from textfile= or cuefile= CDTEXTFILE"; if (fmt == 1) { ret = burn_make_input_sheet_v07t(text_packs, num_packs, 0, 0, &result, &char_code, 0); if(ret <= 0) goto ex; if(char_code == 0x80) fprintf(stderr, "cdrskin : WARNING : Double byte characters encountered.\n"); for(i = 0; i < ret; i++) printf("%c", result[i]); } else { printf("CD-TEXT data%s:\n", from_text); for(i= 0; i < num_packs; i++) { pack= text_packs + 18 * i; printf("%4d :", i); for(j= 0; j < 18; j++) { if(j >= 4 && j <= 15 && pack[j] >= 32 && pack[j] <= 126 && pack[0] != 0x88 && pack[0] != 0x89 && pack[0] != 0x8f) printf(" %c", pack[j]); else printf(" %2.2x", pack[j]); } printf("\n"); } } ret= 1; ex:; if(result != NULL) free(result); return(ret); } /* @param flag bit4= no not overwrite existing target file */ int Cdrskin_store_text_packs(struct CdrskiN *skin, unsigned char *text_packs, int num_packs, char *path, int flag) { int data_length, ret; struct stat stbuf; FILE *fp; unsigned char fake_head[4]; if(stat(path, &stbuf) != -1 && (flag & 16)) { fprintf(stderr, "cdrskin: SORRY : Will not overwrite file '%s'\n", path); return(0); } fp= fopen(path, "w"); if(fp == NULL) { fprintf(stderr, "cdrskin: SORRY : Cannot open file '%s' for storing extracted CD-TEXT\n", path); fprintf(stderr, "cdrskin: %s (errno=%d)\n", strerror(errno), errno); return(0); } data_length= num_packs * 18 + 2; fake_head[0]= (data_length >> 8) & 0xff; fake_head[1]= data_length & 0xff; fake_head[2]= fake_head[3]= 0; ret= fwrite(fake_head, 4, 1, fp); if(ret != 1) { write_failure:; fprintf(stderr, "cdrskin: SORRY : Cannot write all data to file '%s'\n", path); fprintf(stderr, "cdrskin: %s (errno=%d)\n", strerror(errno), errno); fclose(fp); return(0); } ret= fwrite(text_packs, data_length - 2, 1, fp); if(ret != 1) goto write_failure; fprintf(stderr, "cdrskin: NOTE : Wrote header and %d CD-TEXT bytes to file '%s'\n", data_length - 2, path); fclose(fp); return(1); } /* @param flag bit0-3= output format 1= Sony CD-TEXT Input Sheet Version 0.7T 15= Cdrskin_store_text_packs bit4= do not overwrite existing the target file */ int Cdrskin_cdtext_to_file(struct CdrskiN *skin, char *path, int flag) { int ret, fmt, char_code= 0, to_write; struct burn_drive *drive; unsigned char *text_packs= NULL; int num_packs= 0; char *result= 0; FILE *fp= NULL; struct stat stbuf; ret= Cdrskin_grab_drive(skin, 0); if(ret<=0) goto ex; fmt= flag & 15; drive= skin->drives[skin->driveno].drive; ret= burn_disc_get_leadin_text(drive, &text_packs, &num_packs, 0); if(ret <= 0 || num_packs <= 0) { fprintf(stderr, "cdrskin: No CD-Text or CD-Text unaware drive.\n"); ret= 2; goto ex; } if(fmt == 1) { ret = burn_make_input_sheet_v07t(text_packs, num_packs, 0, 0, &result, &char_code, 0); if(ret <= 0) goto ex; to_write= ret; if(stat(path, &stbuf) != -1 && (flag & 16)) { fprintf(stderr, "cdrskin: SORRY : Will not overwrite file '%s'\n", path); return(0); } if(strcmp(path, "-") == 0) fp= stdout; else fp = fopen(path, "w"); if(fp == NULL) { if(errno > 0) fprintf(stderr, "cdrskin: %s (errno=%d)\n", strerror(errno), errno); fprintf(stderr, "cdrskin: SORRY : Cannot write CD-TEXT list to file '%s'\n", path); {ret= 0; goto ex;} } ret = fwrite(result, to_write, 1, fp); if(ret != 1) { if(errno > 0) fprintf(stderr, "cdrskin: %s (errno=%d)\n", strerror(errno), errno); fprintf(stderr, "cdrskin: SORRY : Cannot write all CD-TEXT to file '%s'\n", path); ret= 0; } if(ret <= 0) goto ex; } else if(fmt == 15) { if(skin->verbosity >= Cdrskin_verbose_debuG) Cdrskin_print_text_packs(skin, text_packs, num_packs, 0); ret= Cdrskin_store_text_packs(skin, text_packs, num_packs, path, flag & 16); if(ret <= 0) goto ex; printf("CD-Text len: %d\n", num_packs * 18 + 4); } else { fprintf(stderr, "cdrskin: FATAL : Program error : Unknow format %d with Cdrskin_cdtext_to_file.\n", fmt); {ret= -1; goto ex;} } ret= 1; ex:; if(result != NULL) free(result); if(text_packs != NULL) free(text_packs); if(fp != NULL && fp != stdout) fclose(fp); return(1); } /** Perform -toc under control of Cdrskin_atip(). @param flag Bitfield for control purposes: bit0= do not list sessions separately (do it cdrecord style) @return <=0 error, 1 success */ int Cdrskin_toc(struct CdrskiN *skin, int flag) { int num_sessions= 0,num_tracks= 0,lba= 0,track_count= 0,total_tracks= 0; int session_no, track_no, pmin, psec, pframe, ret, final_ret= 1; int track_offset = 1, open_sessions= 0, have_real_open_session= 0; struct burn_drive *drive; struct burn_disc *disc= NULL; struct burn_session **sessions; struct burn_track **tracks; struct burn_toc_entry toc_entry; enum burn_disc_status s; char profile_name[80]; int profile_number; drive= skin->drives[skin->driveno].drive; s= burn_disc_get_status(drive); if(s == BURN_DISC_EMPTY || s == BURN_DISC_BLANK) goto summary; disc= burn_drive_get_disc(drive); if(disc==NULL) { if(skin->grow_overwriteable_iso>0) { ret= Cdrskin_overwriteable_iso_size(skin,&lba,0); if(ret>0) { printf( "first: 1 last: 1 (fabricated from ISO-9660 image on overwriteable media)\n"); printf( "track: 1 lba: 0 ( 0) 00:02:00 adr: 1 control: 4 mode: 1\n"); burn_lba_to_msf(lba, &pmin, &psec, &pframe); printf("track:lout lba: %9d (%9d) %2.2d:%2.2d:%2.2d", lba,4*lba,pmin,psec,pframe); printf(" adr: 1 control: 4 mode: -1\n"); goto summary; } } goto cannot_read; } sessions= burn_disc_get_sessions(disc,&num_sessions); open_sessions= burn_disc_get_incomplete_sessions(disc); if(num_sessions > 0) track_offset = burn_session_get_start_tno(sessions[0], 0); if(track_offset <= 0) track_offset= 1; if(flag&1) { for(session_no= 0; session_no < num_sessions + open_sessions; session_no++) { tracks= burn_session_get_tracks(sessions[session_no],&num_tracks); total_tracks+= num_tracks; if(session_no == num_sessions + open_sessions - 1 && open_sessions > 0) { total_tracks--; /* Do not count invisible track */ if(num_tracks > 1) have_real_open_session= 1; } } printf("first: %d last %d\n", track_offset, total_tracks + track_offset - 1); } for(session_no= 0; session_no < num_sessions + open_sessions; session_no++) { tracks= burn_session_get_tracks(sessions[session_no],&num_tracks); if(tracks==NULL) continue; if(session_no == num_sessions + open_sessions - 1 && open_sessions > 0) num_tracks--; if(num_tracks <= 0) continue; if(!(flag&1)) printf("first: %d last: %d\n", track_count + track_offset, track_count + num_tracks + track_offset - 1); for(track_no= 0; track_no>> From where does cdrecord take "mode" ? */ /* This is not the "mode" as printed by cdrecord : printf(" mode: %d\n",burn_track_get_mode(tracks[track_no])); */ /* own guess: cdrecord says "1" on data and "0" on audio : */ printf(" mode: %d\n",((toc_entry.control&7)<4?0:1)); } if((flag&1) && session_no < num_sessions + open_sessions - 1 + have_real_open_session - 1) continue; if(have_real_open_session) { /* Use start of invisible track */ burn_track_get_entry(tracks[num_tracks], &toc_entry); } else { burn_session_get_leadout_entry(sessions[session_no],&toc_entry); } if(toc_entry.extensions_valid&1) { /* DVD extension valid */ lba= toc_entry.start_lba; burn_lba_to_msf(lba, &pmin, &psec, &pframe); } else { pmin= toc_entry.pmin; psec= toc_entry.psec; pframe= toc_entry.pframe; lba= burn_msf_to_lba(pmin,psec,pframe); } printf("track:lout lba: %9d (%9d) %2.2d:%2.2d:%2.2d", lba,4*lba,pmin,psec,pframe); printf(" adr: %d control: %d",toc_entry.adr,toc_entry.control); printf(" mode: -1\n"); } if(skin->verbosity >= Cdrskin_verbose_cmD) { ret= Cdrskin_cdtext_to_file(skin, "cdtext.dat", 15 | 16); if(ret <= 0 && ret < final_ret) final_ret= ret; } summary: ret= burn_disc_get_profile(drive, &profile_number, profile_name); if(ret <= 0) strcpy(profile_name, "media"); if(open_sessions > 0 && !have_real_open_session) open_sessions--; printf("Media summary: %d sessions, %d tracks, %s %s\n", num_sessions + open_sessions, track_count, s==BURN_DISC_BLANK ? "blank" : s==BURN_DISC_APPENDABLE ? "appendable" : s==BURN_DISC_FULL ? "closed" : s==BURN_DISC_EMPTY ? "no " : "unknown ", profile_name); if(have_real_open_session) printf("Warning : Incomplete session encountered !\n"); if(disc!=NULL) burn_disc_free(disc); if(s == BURN_DISC_EMPTY) return(0); return(final_ret); cannot_read:; fprintf(stderr,"cdrecord_emulation: Cannot read TOC header\n"); fprintf(stderr,"cdrecord_emulation: Cannot read TOC/PMA\n"); return(0); } /** Perform -minfo under control of Cdrskin_atip(). @param flag Bitfield for control purposes: @return <=0 error, 1 success */ int Cdrskin_minfo(struct CdrskiN *skin, int flag) { int num_sessions= 0,num_tracks= 0,lba= 0,track_count= 0,total_tracks= 0; int session_no, track_no, pmin, psec, pframe, ret, size= 0, nwa= 0; int last_leadout= 0, ovwrt_full= 0, track_offset= 1, open_sessions= 0; struct burn_drive *drive; struct burn_disc *disc= NULL; struct burn_session **sessions= NULL; struct burn_track **tracks; struct burn_toc_entry toc_entry; enum burn_disc_status s, show_status; char profile_name[80]; int pno; char media_class[80]; int nominal_sessions= 1, ftils= 1, ltils= 1, first_track= 1, read_capacity= 0; int app_code, cd_info_valid, lra, alloc_blocks, free_blocks; int have_real_open_session= 0; off_t avail, buf_count; char disc_type[80], bar_code[9], buf[2 * 2048], *type_text; unsigned int disc_id; drive= skin->drives[skin->driveno].drive; s= burn_disc_get_status(drive); if(s == BURN_DISC_EMPTY) { fprintf(stderr, "cdrecord-Emulation: No disk / Wrong disk!\n"); return(1); } ret= burn_disc_get_profile(drive, &pno, profile_name); if(ret <= 0) { fprintf(stderr, "cdrskin: SORRY : Cannot inquire current media profile\n"); return(1); } if(pno >= 0x08 && pno <= 0x0a) strcpy(media_class, "CD"); else if(pno >= 0x10 && pno <= 0x2f) strcpy(media_class, "DVD"); else if(pno >= 0x40 && pno <= 0x43) strcpy(media_class, "BD"); else sprintf(media_class, "Unknown class (profile 0x%4.4X)", pno); printf("\n"); printf("Mounted media class: %s\n", media_class); printf("Mounted media type: %s\n", profile_name); ret= burn_disc_erasable(drive); printf("Disk Is %serasable\n", (ret || skin->media_is_overwriteable) ? "" : "not "); show_status= s; ret = burn_get_read_capacity(drive, &read_capacity, 0); if(ret <= 0) read_capacity= 0; if(skin->media_is_overwriteable && read_capacity > 0) ovwrt_full= 1; if(ovwrt_full) show_status= BURN_DISC_FULL; printf("disk status: %s\n", show_status == BURN_DISC_BLANK ? "empty" : show_status == BURN_DISC_APPENDABLE ? "incomplete/appendable" : show_status == BURN_DISC_FULL ? "complete" : "unusable"); printf("session status: %s\n", show_status == BURN_DISC_BLANK ? "empty" : show_status == BURN_DISC_APPENDABLE ? "empty" : show_status == BURN_DISC_FULL ? "complete" : "unknown"); disc= burn_drive_get_disc(drive); if(disc==NULL || s == BURN_DISC_BLANK) { first_track= 1; num_sessions= 0; nominal_sessions= 1; ftils= ltils= 1; } else { sessions= burn_disc_get_sessions(disc, &num_sessions); open_sessions= burn_disc_get_incomplete_sessions(disc); if(num_sessions > 0) track_offset= burn_session_get_start_tno(sessions[0], 0); if(track_offset <= 0) track_offset= 1; first_track= track_offset; nominal_sessions= num_sessions + open_sessions; if(s == BURN_DISC_APPENDABLE && open_sessions == 0) nominal_sessions++; for(session_no= 0; session_no < num_sessions + open_sessions; session_no++) { ftils= total_tracks + 1; tracks= burn_session_get_tracks(sessions[session_no],&num_tracks); if(tracks==NULL) continue; total_tracks+= num_tracks; ltils= total_tracks; if(session_no==0 && burn_session_get_hidefirst(sessions[session_no]) && total_tracks >= 2) first_track= 2; } if(s == BURN_DISC_APPENDABLE && open_sessions == 0) ftils= ltils= total_tracks + 1; } printf("first track: %d\n", first_track); printf("number of sessions: %d\n", nominal_sessions); printf("first track in last sess: %d\n", ftils + track_offset - 1); printf("last track in last sess: %d\n", ltils + track_offset - 1); burn_disc_get_cd_info(drive, disc_type, &disc_id, bar_code, &app_code, &cd_info_valid); printf("Disk Is %sunrestricted\n", (cd_info_valid & 16) ? "" : "not "); if((cd_info_valid & 8) && !(cd_info_valid & 16)) printf("Disc application code: %d\n", app_code); if(strcmp(media_class, "DVD") == 0 || strcmp(media_class, "BD") == 0) printf("Disk type: DVD, HD-DVD or BD\n"); else if(strcmp(media_class, "CD") == 0 && (cd_info_valid & 1)) printf("Disk type: %s\n", disc_type); else printf("Disk type: unrecognizable\n"); if(cd_info_valid & 2) printf("Disk id: 0x%-X\n", disc_id); ret= burn_disc_get_bd_spare_info(drive, &alloc_blocks, &free_blocks, 0); if(ret == 1) { printf("BD Spare Area consumed: %d\n", alloc_blocks - free_blocks); printf("BD Spare Area available: %d\n", free_blocks); } printf("\n"); printf("Track Sess Type Start Addr End Addr Size\n"); printf("==============================================\n"); for(session_no= 0; session_no < num_sessions + open_sessions; session_no++) { tracks= burn_session_get_tracks(sessions[session_no],&num_tracks); if(tracks==NULL) continue; for(track_no= 0; track_no= 0x08 && pno <= 0x0a && ((toc_entry.control & 7) >= 4) && lra >= 2 && size >= 2) { /* If last two blocks not readable then assume TAO and subtract 2 from lra and size. */; ret= burn_read_data(drive, (off_t) (lra - 1) * (off_t) 2048, buf, 2 * 2048, &buf_count, 2 | 4); if(ret <= 0) { lra-= 2; size-= 2; } } #ifdef Cdrskin_with_last_recorded_addresS /* Interesting, but obviously not what cdrecord prints as "End Addr" */ if(toc_entry.extensions_valid & 2) { /* LRA extension valid */ if(pno == 0x11 || pno == 0x13 || pno == 0x14 || pno == 0x15 || pno == 0x41 || pno == 0x42 || pno == 0x51) lra= toc_entry.last_recorded_address; } #endif /* Cdrskin_with_last_recorded_addresS */ if(session_no < num_sessions) { type_text= ((toc_entry.control&7)<4) ? "Audio" : "Data"; } else { if(track_no < num_tracks - 1) { type_text= "Rsrvd"; have_real_open_session = 1; } else { type_text= "Blank"; } if(toc_entry.extensions_valid & 4) { if(toc_entry.track_status_bits & (1 << 14)) type_text= "Blank"; else if(toc_entry.track_status_bits & (1 << 16)) { type_text= "Apdbl"; have_real_open_session = 1; } else if(toc_entry.track_status_bits & (1 << 15)) { type_text= "Rsrvd"; have_real_open_session = 1; } else type_text= "Invsb"; } } printf("%5d %5d %-6s %-10d %-10d %-10d\n", track_count + track_offset - 1, session_no + 1, type_text, lba, lra, size); if(session_no < num_sessions) last_leadout= lba + size; } } if(last_leadout > 0) if(read_capacity > last_leadout) read_capacity= last_leadout; if(nominal_sessions > num_sessions) { ret= burn_disc_track_lba_nwa(drive, NULL, 0, &lba, &nwa); if(ret > 0) { avail= burn_disc_available_space(drive, NULL); size= avail / 2048; if(read_capacity == 0 && skin->media_is_overwriteable) size= 0; /* unformatted overwriteable media */ if(nominal_sessions > num_sessions + open_sessions) { printf("%5d %5d %-6s %-10d %-10d %-10d\n", track_count + track_offset, nominal_sessions, ovwrt_full ? "Data" : "Blank", nwa, nwa + size - 1, size); } } } printf("\n"); if(num_sessions > 0) { ret= burn_disc_get_msc1(drive, &lba); if(ret > 0) printf("Last session start address: %-10d\n", lba); if(last_leadout > 0) printf("Last session leadout start address: %-10d\n", last_leadout); if(s == BURN_DISC_FULL) { if(read_capacity > 0 && (last_leadout != read_capacity || pno == 0x08 || pno == 0x10 || pno == 0x40 || pno == 0x50)) printf("Read capacity: %-10d\n", read_capacity); } } else if(ovwrt_full) { printf("Last session start address: %-10d\n", nwa); printf("Last session leadout start address: %-10d\n", size); } if(nominal_sessions > num_sessions && !skin->media_is_overwriteable) { printf("Next writable address: %-10d\n", nwa); printf("Remaining writable size: %-10d\n", size); } if(ovwrt_full) { printf("\n"); printf("cdrskin: Media is overwriteable. No blanking needed. No reliable track size.\n"); printf("cdrskin: Above contrary statements follow cdrecord traditions.\n"); } if(have_real_open_session) printf("\nWarning: Incomplete session encountered !\n"); if(disc!=NULL) burn_disc_free(disc); if(s == BURN_DISC_EMPTY) return(0); return(1); } int Cdrskin_print_all_profiles(struct CdrskiN *skin, struct burn_drive *drive, int flag) { int num_profiles, profiles[64], i, ret; char is_current[64], profile_name[80]; burn_drive_get_all_profiles(drive, &num_profiles, profiles, is_current); for(i= 0; i < num_profiles; i++) { ret= burn_obtain_profile_name(profiles[i], profile_name); if(ret <= 0) strcpy(profile_name, "unknown"); printf("Profile: 0x%4.4X (%s)%s\n", (unsigned int) profiles[i], profile_name, is_current[i] ? " (current)" : ""); } return(1); } /** Perform -atip . @param flag Bitfield for control purposes: bit0= perform -toc bit1= perform -toc with session markers bit2= perform -minfo @return <=0 error, 1 success */ int Cdrskin_atip(struct CdrskiN *skin, int flag) { int ret,is_not_really_erasable= 0, current_is_cd= 1; double x_speed_max= -1.0, x_speed_min= -1.0; enum burn_disc_status s; struct burn_drive *drive; int profile_number= 0; char profile_name[80], *manuf= NULL, *media_code1= NULL, *media_code2= NULL; char *book_type= NULL, *product_id= NULL; char *sno= NULL; int sno_len = 0, i; ClN(printf("cdrskin: pseudo-atip on drive %d\n",skin->driveno)); ret= Cdrskin_grab_drive(skin,0); if(ret<=0) return(ret); drive= skin->drives[skin->driveno].drive; s= burn_disc_get_status(drive); Cdrskin_report_disc_status(skin,s,1|2); if(s==BURN_DISC_APPENDABLE && skin->no_blank_appendable) is_not_really_erasable= 1; profile_name[0]= 0; ret= burn_disc_get_profile(drive,&profile_number,profile_name); if(ret<=0) { profile_number= 0; strcpy(profile_name, "-unidentified-"); } if(profile_number != 0x08 && profile_number != 0x09 && profile_number != 0x0a) current_is_cd= 0; ret= Cdrskin_checkdrive(skin,profile_name,1); if(ret<=0) return(ret); if(burn_disc_get_status(drive) != BURN_DISC_UNSUITABLE) { ret= burn_disc_read_atip(drive); if(ret>0) { ret= burn_drive_get_min_write_speed(drive); x_speed_min= ((double) ret)/Cdrskin_libburn_speed_factoR; } } if(burn_disc_get_status(drive) == BURN_DISC_UNSUITABLE) { if(skin->verbosity>=Cdrskin_verbose_progresS) { if(profile_name[0]) printf("Current: %s\n",profile_name); else printf("Current: UNSUITABLE MEDIA (Profile %4.4Xh)\n",profile_number); } {ret= 0; goto ex;} } if(burn_disc_get_status(drive) != BURN_DISC_EMPTY) { ret= burn_drive_get_write_speed(drive); x_speed_max= ((double) ret)/Cdrskin_libburn_speed_factoR; if(x_speed_min<0) x_speed_min= x_speed_max; } printf("cdrskin: burn_drive_get_write_speed = %d (%.1fx)\n",ret,x_speed_max); if(skin->verbosity>=Cdrskin_verbose_progresS) { if(burn_disc_get_status(drive) == BURN_DISC_EMPTY) printf("Current: none\n"); else if(profile_name[0]) printf("Current: %s\n",profile_name); else if(burn_disc_erasable(drive)) printf("Current: CD-RW\n"); else printf("Current: CD-R\n"); Cdrskin_print_all_profiles(skin, drive, 0); } if(burn_disc_get_status(drive) == BURN_DISC_EMPTY) {ret= 0; goto ex;} if(strstr(profile_name,"DVD")==profile_name) { /* These are dummy messages for project scdbackup, so its media recognition gets a hint that the media is suitable and not in need of blanking. scdbackup will learn to interpret cdrskin's DVD messages but the current stable version needs to believe it is talking to its own growisofs_wrapper. So this is an emulation of an emulator. The real book type is available meanwhile. But that one is not intended. */ printf("book type: %s (emulated booktype)\n", profile_name); if(profile_number==0x13) /* DVD-RW */ printf("cdrskin: message for sdvdbackup: \"(growisofs mode Restricted Overwrite)\"\n"); } else if(strstr(profile_name,"BD")==profile_name) { printf("Mounted Media: %2.2Xh, %s\n", profile_number, profile_name); } else { printf("ATIP info from disk:\n"); if(burn_disc_erasable(drive)) { if(is_not_really_erasable) printf(" Is erasable (but not while in this incomplete state)\n"); else printf(" Is erasable\n"); } else { printf(" Is not erasable\n"); } { int start_lba,end_lba,min,sec,fr; int m_lo, s_lo, f_lo; ret= burn_drive_get_start_end_lba(drive,&start_lba,&end_lba,0); if(ret>0) { burn_lba_to_msf(start_lba,&min,&sec,&fr); printf(" ATIP start of lead in: %d (%-2.2d:%-2.2d/%-2.2d)\n", start_lba,min,sec,fr); burn_lba_to_msf(end_lba,&m_lo,&s_lo,&f_lo); printf(" ATIP start of lead out: %d (%-2.2d:%-2.2d/%-2.2d)\n", end_lba, m_lo, s_lo, f_lo); if(current_is_cd) manuf= burn_guess_cd_manufacturer(min, sec, fr, m_lo, s_lo, f_lo, 0); } } printf(" 1T speed low: %.f 1T speed high: %.f\n",x_speed_min,x_speed_max); } ret= burn_disc_get_media_id(drive, &product_id, &media_code1, &media_code2, &book_type, 0); if(ret > 0 && (!current_is_cd) && manuf == NULL && media_code1 != NULL && media_code2 != NULL) { manuf= burn_guess_manufacturer(profile_number, media_code1, media_code2, 0); } if(product_id != NULL) printf("Product Id: %s\n", product_id); if(manuf != NULL) printf("Producer: %s\n", manuf); if(skin->verbosity >= Cdrskin_verbose_progresS) { if (current_is_cd) { if(manuf != NULL) printf("Manufacturer: %s\n", manuf); } else if(product_id != NULL && media_code1 != NULL && media_code2 != NULL){ free(product_id); free(media_code1); free(media_code2); if(book_type != NULL) free(book_type); product_id= media_code1= media_code2= book_type= NULL; ret= burn_disc_get_media_id(drive, &product_id, &media_code1, &media_code2, &book_type, 1); if(ret > 0) { if(profile_number == 0x11 || profile_number == 0x13 || profile_number == 0x14 || profile_number == 0x15) printf("Manufacturer: '%s'\n", media_code1); else if(profile_number >= 0x40 && profile_number <= 0x43) { printf("Manufacturer: '%s'\n", media_code1); if(media_code2[0]) printf("Media type: '%s'\n", media_code2); } else { printf("Manufacturer: '%s'\n", media_code1); if(media_code2[0]) printf("Media type: '%s'\n", media_code2); } } } } burn_drive_get_media_sno(drive, &sno, &sno_len); if(sno_len > 0) { printf("Media id: "); for(i= 0; i < sno_len && i < 1024; i++) printf("%2.2X", (unsigned int) ((unsigned char *) sno)[i]); if(i < sno_len) printf("..."); printf("\n"); } if(sno != NULL) free(sno); sno= NULL; ret= 1; if(flag&1) ret= Cdrskin_toc(skin, !(flag & 2)); /*cdrecord seems to ignore -toc errors if -atip is ok */ if(ret > 0 && (flag & 4)) ret= Cdrskin_minfo(skin, 0); ex:; if(manuf != NULL) free(manuf); if(media_code1 != NULL) free(media_code1); if(media_code2 != NULL) free(media_code2); if(book_type != NULL) free(book_type); if(product_id != NULL) free(product_id); return(ret); } /** Perform --list_formats @param flag Bitfield for control purposes: @return <=0 error, 1 success */ int Cdrskin_list_formats(struct CdrskiN *skin, int flag) { struct burn_drive *drive; int ret, i, status, num_formats, profile_no, type, alloc_blocks, free_blocks; off_t size; unsigned dummy; char status_text[80], profile_name[90]; ret= Cdrskin_grab_drive(skin,0); if(ret<=0) return(ret); drive= skin->drives[skin->driveno].drive; ret = burn_disc_get_formats(drive, &status, &size, &dummy, &num_formats); if(ret <= 0) { fprintf(stderr, "cdrskin: SORRY: Cannot obtain format list info\n"); ret= 0; goto ex; } ret= burn_disc_get_profile(drive, &profile_no, profile_name); printf("Media current: "); if(profile_no > 0 && ret > 0) { if(profile_name[0]) printf("%s\n", profile_name); else printf("%4.4Xh\n", profile_no); } else printf("is not recognizable\n"); if(status == BURN_FORMAT_IS_UNFORMATTED) sprintf(status_text, "unformatted, up to %.1f MiB", ((double) size) / 1024.0 / 1024.0); else if(status == BURN_FORMAT_IS_FORMATTED) { if(profile_no==0x12 || profile_no==0x13 || profile_no==0x1a || profile_no==0x43) sprintf(status_text, "formatted, with %.1f MiB", ((double) size) / 1024.0 / 1024.0); else sprintf(status_text, "written, with %.1f MiB", ((double) size) / 1024.0 / 1024.0); } else if(status == BURN_FORMAT_IS_UNKNOWN) { if (profile_no > 0) sprintf(status_text, "intermediate or unknown"); else sprintf(status_text, "no media or unknown media"); } else sprintf(status_text, "illegal status according to MMC-5"); printf("Format status: %s\n", status_text); ret= burn_disc_get_bd_spare_info(drive, &alloc_blocks, &free_blocks, 0); if(ret == 1) printf("BD Spare Area: %d blocks consumed, %d blocks available\n", alloc_blocks - free_blocks, free_blocks); for (i = 0; i < num_formats; i++) { ret= burn_disc_get_format_descr(drive, i, &type, &size, &dummy); if (ret <= 0) continue; printf("Format idx %-2d: %2.2Xh , %.fs , %.1f MiB\n", i, type, ((double) size) / 2048.0, ((double) size) / 1024.0/1024.0); } ret= 1; ex:; return(ret); } /** Perform --list_speeds @param flag Bitfield for control purposes: @return <=0 error, 1 success */ int Cdrskin_list_speeds(struct CdrskiN *skin, int flag) { struct burn_drive *drive; int ret, i, profile_no, high= -1, low= 0x7fffffff, is_cd= 0; char profile_name[90], *speed_unit= "D"; double speed_factor= 1385000.0, cd_factor= 75.0 * 2352; struct burn_speed_descriptor *speed_list= NULL, *item, *other; ret= Cdrskin_grab_drive(skin,0); if(ret<=0) return(ret); drive= skin->drives[skin->driveno].drive; ret= burn_drive_get_speedlist(drive, &speed_list); if(ret <= 0) { fprintf(stderr, "cdrskin: SORRY: Cannot obtain speed list info\n"); ret= 0; goto ex; } ret= burn_disc_get_profile(drive, &profile_no, profile_name); printf("Media current: "); if(profile_no > 0 && ret > 0) { if(profile_name[0]) printf("%s\n", profile_name); else printf("%4.4Xh\n", profile_no); } else printf("is not recognizable\n"); if(profile_no >= 0x08 && profile_no <= 0x0a) is_cd= profile_no; speed_factor= Cdrskin_libburn_speed_factoR * 1000.0; if(Cdrskin_libburn_speed_factoR == Cdrskin_libburn_cd_speed_factoR) speed_unit= "C"; else if(Cdrskin_libburn_speed_factoR == Cdrskin_libburn_bd_speed_factoR) speed_unit= "B"; for (item= speed_list; item != NULL; item= item->next) { if(item->source == 1) { /* CD mode page 2Ah : report only if not same speed by GET PERFORMANCE */ for(other= speed_list; other != NULL; other= other->next) if(other->source == 2 && item->write_speed == other->write_speed) break; if(other != NULL) continue; } printf("Write speed : %5dk , %4.1fx%s\n", item->write_speed, ((double) item->write_speed) * 1000.0 / speed_factor, speed_unit); if(item->write_speed > high) high= item->write_speed; if(item->write_speed < low) low= item->write_speed; } /* Maybe there is ATIP info */ if(is_cd) { ret= burn_disc_read_atip(drive); if(ret < 0) goto ex; if(ret > 0) { for(i= 0; i < 2; i++) { if(i == 0) ret= burn_drive_get_min_write_speed(drive); else ret= burn_drive_get_write_speed(drive); if(ret > 0) { if(ret < low || (i == 0 && ret != low)) { printf("Write speed l: %5dk , %4.1fx%s\n", ret, ((double) ret) * 1000.0 / cd_factor, "C"); low= ret; } if(ret > high || (i == 1 && ret != high)) { printf("Write speed h: %5dk , %4.1fx%s\n", ret, ((double) ret) * 1000.0 / cd_factor, "C"); high= ret; } } } } } if(high > -1) { printf("Write speed L: %5dk , %4.1fx%s\n", low, ((double) low) * 1000.0 / speed_factor, speed_unit); printf("Write speed H: %5dk , %4.1fx%s\n", high, ((double) high) * 1000.0 / speed_factor, speed_unit); ret= burn_drive_get_best_speed(drive, -1, &item, 2); if(ret > 0 && item != NULL) if(item->write_speed != low) printf("Write speed 0: %5dk , %4.1fx%s\n", item->write_speed, ((double) item->write_speed) * 1000.0 / speed_factor, speed_unit); ret= burn_drive_get_best_speed(drive, 0, &item, 2); if(ret > 0 && item != NULL) if(item->write_speed != high) printf("Write speed-1: %5dk , %4.1fx%s\n", item->write_speed, ((double) item->write_speed) * 1000.0 / speed_factor, speed_unit); } else { fprintf(stderr, "cdrskin: SORRY : Could not get any write speed information from drive"); } ret= 1; ex:; if(speed_list != NULL) burn_drive_free_speedlist(&speed_list); return(ret); } int Cdrskin_read_textfile(struct CdrskiN *skin, char *path, int flag) { int ret, num_packs = 0; unsigned char *text_packs = NULL; ret= burn_cdtext_from_packfile(path, &text_packs, &num_packs, 0); if(ret <= 0) goto ex; if(skin->text_packs != NULL) free(skin->text_packs); skin->text_packs= text_packs; skin->num_text_packs= num_packs; ret= 1; ex:; if(ret <= 0 && text_packs != NULL) free(text_packs); return(ret); } /* @param flag Bitfield for control purposes: bit3= Enable DAP : "flaw obscuring mechanisms like audio data mute and interpolate" */ int Cdrskin_extract_audio_to_dir(struct CdrskiN *skin, char *dir, char *basename, char print_tracks[100], int flag) { int num_sessions= 0, num_tracks= 0, profile_number, session_no, track_no; int track_count= 0, existing= 0, ret, pass, not_audio= 0, pick_tracks= 0, i; int tracks_extracted= 0, min_tno= 100, max_tno= 0; struct burn_drive *drive; struct burn_disc *disc= NULL; struct burn_session **sessions; struct burn_track **tracks; enum burn_disc_status s; struct burn_toc_entry toc_entry; struct stat stbuf; char profile_name[80], path[4096 + 256]; ret= Cdrskin_grab_drive(skin, 0); if(ret<=0) goto ex; drive= skin->drives[skin->driveno].drive; s= burn_disc_get_status(drive); disc= burn_drive_get_disc(drive); if(s == BURN_DISC_EMPTY || s == BURN_DISC_BLANK || disc == NULL) { not_readable:; fprintf(stderr, "cdrskin: SORRY : No audio CD in drive.\n"); ret= 0; goto ex; } ret= burn_disc_get_profile(drive, &profile_number, profile_name); if(ret <= 0 || profile_number < 0x08 || profile_number > 0x0a) { not_audio_cd:; fprintf(stderr, "cdrskin: SORRY : Medium in drive is not an audio CD.\n"); ret= 0; goto ex; } for(i= 0; i < 99; i++) if(print_tracks[i]) pick_tracks= 1; sessions= burn_disc_get_sessions(disc, &num_sessions); if(num_sessions <= 0) goto not_readable; for(pass= 0; pass < 2; pass++) { if(pass > 0) { if(existing > 0) {ret= 0; goto ex;} if(not_audio == track_count) goto not_audio_cd; } track_count= 0; for(session_no= 0; session_no < num_sessions; session_no++) { tracks= burn_session_get_tracks(sessions[session_no],&num_tracks); if(tracks==NULL) continue; for(track_no= 0; track_no < num_tracks; track_no++) { track_count++; burn_track_get_entry(tracks[track_no], &toc_entry); if(toc_entry.point < min_tno) min_tno= toc_entry.point; if(toc_entry.point > max_tno) max_tno= toc_entry.point; if(pick_tracks) { if(toc_entry.point <= 0 || toc_entry.point > 99) continue; /* should not happen */ if(print_tracks[toc_entry.point] == 0) continue; } if((toc_entry.control & 7) >= 4) { if(pass == 0) fprintf(stderr, "cdrskin: WARNING : Track %2.2d is not an audio track.\n", toc_entry.point); not_audio++; continue; } sprintf(path, "%s/%s%2.2u.wav", dir, basename, toc_entry.point); if(pass == 0) { if(stat(path, &stbuf) != -1) { fprintf(stderr, "cdrskin: SORRY : May not overwrite existing file: '%s'\n", path); existing++; } continue; } if(skin->verbosity >= Cdrskin_verbose_progresS) fprintf(stderr, "cdrskin: Writing audio track file: %s\n", path); ret= burn_drive_extract_audio_track(drive, tracks[track_no], path, (flag & 8) | (skin->verbosity >= Cdrskin_verbose_progresS)); if(ret <= 0) goto ex; tracks_extracted++; } } } if(tracks_extracted == 0 && pick_tracks) { fprintf(stderr, "cdrskin: SORRY : Not a single track matched the list of extract_tracks=\n"); if(min_tno < 100 && max_tno > 0) fprintf(stderr, "cdrskin: HINT : Track range is %2.2d to %2.2d\n", min_tno, max_tno); ret= 0; goto ex; } ret= 1; ex:; return(ret); } #ifndef Cdrskin_extra_leaN /* A70324: proposal by Eduard Bloch */ int Cdrskin_warn_of_mini_tsize(struct CdrskiN *skin, int flag) { off_t media_space= 0; enum burn_disc_status s; struct burn_drive *drive; int ret; ret= burn_drive_get_drive_role(skin->drives[skin->driveno].drive); if(ret != 1) return(1); if(skin->multi || skin->has_open_ended_track || skin->smallest_tsize<0) return(1); drive= skin->drives[skin->driveno].drive; s= burn_disc_get_status(drive); if(s!=BURN_DISC_BLANK) return(1); media_space= burn_disc_available_space(drive, NULL); if(media_space<=0 || skin->smallest_tsize >= media_space / Cdrskin_minimum_tsize_quotienT) return(1); fprintf(stderr,"\n"); fprintf(stderr,"\n"); fprintf(stderr, "cdrskin: WARNING: Very small track size set by option tsize=\n"); fprintf(stderr, "cdrskin: Track size %.1f MB <-> media capacity %.1f MB\n", skin->smallest_tsize/1024.0/1024.0, ((double) media_space)/1024.0/1024.0); fprintf(stderr,"\n"); fprintf(stderr, "cdrskin: Will wait at least 15 seconds until real burning starts\n"); fprintf(stderr,"\n"); if(skin->gracetime<15) skin->gracetime= 15; return(1); } /** Emulate the gracetime= behavior of cdrecord @param flag Bitfield for control purposes: bit0= do not print message about pseudo-checkdrive */ int Cdrskin_wait_before_action(struct CdrskiN *skin, int flag) /* flag: bit0= BLANK rather than write mode bit1= FORMAT rather than write mode */ { int i; Cdrskin_warn_of_mini_tsize(skin,0); if(skin->verbosity>=Cdrskin_verbose_progresS) { char speed_text[80]; if(skin->x_speed<0) strcpy(speed_text,"MAX"); else if(skin->x_speed==0) strcpy(speed_text,"MIN"); else sprintf(speed_text,"%.f",skin->x_speed); printf( "Starting to write CD/DVD at speed %s in %s %s mode for %s session.\n", speed_text,(skin->dummy_mode?"dummy":"real"), (flag&2?"FORMAT":(flag&1?"BLANK":skin->preskin->write_mode_name)), (skin->multi?"multi":"single")); printf("Last chance to quit, starting real write in %3d seconds.", skin->gracetime); fflush(stdout); } for(i= skin->gracetime-1;i>=0;i--) { usleep(1000000); if(Cdrskin__is_aborting(0)) return(0); if(skin->verbosity>=Cdrskin_verbose_progresS) { printf("\b\b\b\b\b\b\b\b\b\b\b\b\b %3d seconds.",i); fflush(stdout); } } if(skin->verbosity>=Cdrskin_verbose_progresS) {printf(" Operation starts.\n");fflush(stdout);} return(1); } #endif /* Cdrskin_extra_leaN */ /** Perform blank=[all|fast] @return <=0 error, 1 success */ int Cdrskin_blank(struct CdrskiN *skin, int flag) { enum burn_disc_status s; struct burn_progress p; struct burn_drive *drive; int ret,loop_counter= 0,hint_force= 0,do_format= 0, profile_number= -1; int wrote_well= 1, format_flag= 0, status, num_formats; off_t size; unsigned dummy; double start_time; char *verb= "blank", *presperf="blanking", *fmt_text= "..."; char profile_name[80]; static char fmtp[][40]= { "...", "format_overwrite", "deformat_sequential", "(-format)", "format_defectmgt", "format_by_index", "format_if_needed", "as_needed"}; static int fmtp_max= 7; start_time= Sfile_microtime(0); /* will be refreshed later */ ret= Cdrskin_grab_drive(skin,0); if(ret<=0) return(ret); drive= skin->drives[skin->driveno].drive; s= burn_disc_get_status(drive); profile_name[0]= 0; if(skin->grabbed_drive) burn_disc_get_profile(skin->grabbed_drive,&profile_number,profile_name); ret= Cdrskin_report_disc_status(skin,s, 1|(4*!(skin->verbosity>=Cdrskin_verbose_progresS))); if(ret==2) s= BURN_DISC_APPENDABLE; do_format= skin->blank_format_type & 0xff; if(s==BURN_DISC_UNSUITABLE) { if(skin->force_is_set) { ClN(fprintf(stderr,"cdrskin: NOTE : -force blank=... : Treating unsuitable media as burn_disc_full\n")); ret= burn_disc_pretend_full(drive); if(ret <= 0) { ClN(fprintf(stderr, "cdrskin: FAILURE : Medium still considered unsuitable\n")); {ret= 0; goto ex;} } s= burn_disc_get_status(drive); } else hint_force= 1; } if(do_format) if(do_format>=0 && do_format<=fmtp_max) fmt_text= fmtp[do_format]; if(do_format==5) { /* format_by_index */ if(profile_number == 0x12 || profile_number == 0x43) do_format= 4; else do_format= 1; } else if(do_format==6 || do_format==7) { /* format_if_needed , as_needed */ /* Find out whether format is needed at all. Eventuelly set up a suitable formatting run */ if(profile_number == 0x14 && do_format==6) { /* sequential DVD-RW */ do_format= 1; skin->blank_format_type= 1|(1<<8); skin->blank_format_size= 128*1024*1024; } else if(profile_number == 0x12 || profile_number == 0x43 || (profile_number == 0x41 && do_format==6)) { /* DVD-RAM , BD-RE , BD-R SRM */ ret= burn_disc_get_formats(drive, &status, &size, &dummy, &num_formats); if((ret>0 && status!=BURN_FORMAT_IS_FORMATTED)) { do_format= 4; skin->blank_format_type= 4|(3<<9); /* default payload size */ skin->blank_format_size= 0; } } else if(do_format==7) { /* try to blank what is not blank yet */ if(s!=BURN_DISC_BLANK) { do_format= 0; skin->blank_fast= 1; } } if(do_format==6 || do_format==7) { if(skin->verbosity>=Cdrskin_verbose_cmD) ClN(fprintf(stderr, "cdrskin: NOTE : blank=%s : no need for action detected\n", fmt_text)); {ret= 2; goto ex;} } } if(do_format == 1 || do_format == 3 || do_format == 4) { verb= "format"; presperf= "formatting"; } if(do_format==2) { /* Forceful blanking to Sequential Recording for DVD-R[W] and CD-RW */ if(!(profile_number == 0x14 || profile_number == 0x13 || profile_number == 0x0a)) { if(skin->grow_overwriteable_iso>0 && skin->media_is_overwriteable) goto pseudo_blank_ov; else goto unsupported_format_type; } } else if(do_format==1 || do_format==3) { /* Formatting to become overwriteable for DVD-RW and DVD+RW */ if(do_format==3 && profile_number != 0x1a) { fprintf(stderr, "cdrskin: SORRY : -format does DVD+RW only\n"); if(profile_number==0x14) fprintf(stderr, "cdrskin: HINT : blank=format_overwrite would format this media\n"); {ret= 0; goto ex;} } if(profile_number == 0x14) { /* DVD-RW sequential */ /* ok */; } else if(profile_number == 0x13) { /* DVD-RW restricted overwrite */ if(!(skin->force_is_set || ((skin->blank_format_type>>8)&4))) { fprintf(stderr, "cdrskin: NOTE : blank=format_... : media is already formatted\n"); fprintf(stderr, "cdrskin: HINT : If you really want to re-format, add option -force\n"); {ret= 2; goto ex;} } } else if(profile_number == 0x1a) { /* DVD+RW */ if(!((skin->blank_format_type>>8)&4)) { fprintf(stderr, "cdrskin: NOTE : blank=format_... : DVD+RW do not need this\n"); fprintf(stderr, "cdrskin: HINT : For de-icing use option blank=format_overwrite_full\n"); {ret= 2; goto ex;} } } else { fprintf(stderr, "cdrskin: SORRY : blank=%s for now does DVD-RW and DVD+RW only\n", fmt_text); {ret= 0; goto ex;} } if(s==BURN_DISC_UNSUITABLE) fprintf(stderr, "cdrskin: NOTE : blank=%s accepted not yet suitable media\n", fmt_text); } else if(do_format==4) { /* Formatting and influencing defect management of DVD-RAM , BD-RE */ if(!(profile_number == 0x12 || profile_number == 0x41 || profile_number == 0x43)) { fprintf(stderr, "cdrskin: SORRY : blank=%s for now does DVD-RAM and BD only\n", fmt_text); {ret= 0; goto ex;} } if(s==BURN_DISC_UNSUITABLE) fprintf(stderr, "cdrskin: NOTE : blank=%s accepted not yet suitable media\n", fmt_text); } else if(do_format==0) { /* Classical blanking of erasable media */ if(skin->grow_overwriteable_iso>0 && skin->media_is_overwriteable) { pseudo_blank_ov:; if(skin->dummy_mode) { fprintf(stderr, "cdrskin: would have begun to pseudo-blank disc if not in -dummy mode\n"); goto blanking_done; } skin->grow_overwriteable_iso= 3; ret= Cdrskin_invalidate_iso_head(skin, 0); if(ret<=0) goto ex; goto blanking_done; } else if(s!=BURN_DISC_FULL && (s!=BURN_DISC_APPENDABLE || skin->no_blank_appendable) && (profile_number!=0x13 || !skin->prodvd_cli_compatible) && (s!=BURN_DISC_BLANK || !skin->force_is_set)) { if(s==BURN_DISC_BLANK) { fprintf(stderr, "cdrskin: NOTE : blank=... : media was already blank (and still is)\n"); {ret= 2; goto ex;} } else if(s==BURN_DISC_APPENDABLE) { fprintf(stderr, "cdrskin: FATAL : blank=... : media is still appendable\n"); } else { fprintf(stderr, "cdrskin: FATAL : blank=... : no blankworthy disc found\n"); if(hint_force) fprintf(stderr, "cdrskin: HINT : If you are certain to have a CD-RW, try option -force\n"); } {ret= 0; goto ex;} } if(!burn_disc_erasable(drive)) { fprintf(stderr,"cdrskin: FATAL : blank=... : media is not erasable\n"); {ret= 0; goto ex;} } if((profile_number == 0x14 || profile_number == 0x13) && !skin->prodvd_cli_compatible) skin->blank_fast= 0; /* only with deformat_sequential_quickest */ } else { unsupported_format_type:; fprintf(stderr, "cdrskin: SORRY : blank=%s is unsupported with media type %s\n", fmt_text, profile_name); {ret= 0; goto ex;} } if(skin->dummy_mode) { fprintf(stderr, "cdrskin: would have begun to %s disc if not in -dummy mode\n", verb); goto blanking_done; } fprintf(stderr,"cdrskin: beginning to %s disc\n",verb); Cdrskin_adjust_speed(skin,0); #ifndef Cdrskin_extra_leaN Cdrskin_wait_before_action(skin, 1+(do_format==1 || do_format==3 || do_format==4)); #endif /* ! Cdrskin_extra_leaN */ if(Cdrskin__is_aborting(0)) {ret= 0; goto ex;} skin->drive_is_busy= 1; if(do_format==0 || do_format==2) { burn_disc_erase(drive,skin->blank_fast); } else if(do_format==1 || do_format==3 || do_format==4) { format_flag= (skin->blank_format_type>>8)&(1|2|4|32|128); if(skin->force_is_set) format_flag|= 16; if(format_flag&128) format_flag|= (skin->blank_format_index&255)<<8; if(skin->blank_format_no_certify) format_flag|= 64; burn_disc_format(drive,(off_t) skin->blank_format_size,format_flag); } else { fprintf(stderr,"cdrskin: SORRY : Format type %d not implemented yet.\n", do_format); ret= 0; goto ex; } loop_counter= 0; start_time= Sfile_microtime(0); while(burn_drive_get_status(drive, &p) != BURN_DRIVE_IDLE) { if(loop_counter>0) if(skin->verbosity>=Cdrskin_verbose_progresS) { double percent= 50.0; if(p.sectors>0) /* i want a display of 1 to 99 percent */ percent= 1.0+((double) p.sector+1.0)/((double) p.sectors)*98.0; fprintf(stderr, "%scdrskin: %s ( done %.1f%% , %lu seconds elapsed ) %s", skin->pacifier_with_newline ? "" : "\r", presperf,percent,(unsigned long) (Sfile_microtime(0)-start_time), skin->pacifier_with_newline ? "\n" : ""); } sleep(1); loop_counter++; } blanking_done:; wrote_well = burn_drive_wrote_well(drive); if(wrote_well && skin->verbosity>=Cdrskin_verbose_progresS) { fprintf(stderr, "%scdrskin: %s done \n", skin->pacifier_with_newline ? "" : "\r", presperf); printf("%s time: %.3fs\n", (do_format==1 || do_format==3 || do_format==4 ? "Formatting":"Blanking"), Sfile_microtime(0)-start_time); } fflush(stdout); if(!wrote_well) fprintf(stderr, "%scdrskin: %s failed \n", skin->pacifier_with_newline ? "" : "\r", presperf); ret= !!(wrote_well); ex:; skin->drive_is_busy= 0; if(Cdrskin__is_aborting(0)) Cdrskin_abort(skin, 0); /* Never comes back */ return(ret); } int Cdrskin__libburn_fifo_status(struct burn_source *current_fifo, char fifo_text[80], int flag) { int ret, size, free_space, fill, fifo_percent; char *status_text= ""; ret= burn_fifo_inquire_status(current_fifo, &size, &free_space, &status_text); if(ret <= 0 || ret >= 4) { strcpy(fifo_text, "(fifo 0%) "); } else if(ret == 1) { burn_fifo_next_interval(current_fifo, &fill); fifo_percent= 100.0 * ((double) fill) / (double) size; if(fifo_percent<100 && fill>0) fifo_percent++; sprintf(fifo_text, "(fifo %3d%%) ", fifo_percent); } return(1); } /** Report burn progress. This is done partially in cdrecord style. Actual reporting happens only if write progress hit the next MB or if in non-write-progress states a second has elapsed since the last report. After an actual report a new statistics interval begins. @param drive_status As obtained from burn_drive_get_status() @param p Progress information from burn_drive_get_status() @param start_time Timestamp of burn start in seconds @param last_time Timestamp of report interval start in seconds @param total_count Returns the total number of bytes written so far @param total_count Returns the number of bytes written during interval @param flag Bitfield for control purposes: bit0= report in growisofs style rather than cdrecord style @return <=0 error, 1 seems to be writing payload, 2 doing something else */ int Cdrskin_burn_pacifier(struct CdrskiN *skin, int start_tno, enum burn_drive_status drive_status, struct burn_progress *p, double start_time, double *last_time, double *total_count, double *last_count, int *min_buffer_fill, int flag) /* bit0= growisofs style */ { double bytes_to_write= 0.0; double written_bytes= 0.0,written_total_bytes= 0.0; double fixed_size= 0.0, padding,sector_size,speed_factor; double measured_total_speed,measured_speed; double elapsed_time,elapsed_total_time,current_time; double estim_time,estim_minutes,estim_seconds,percent; int ret,fifo_percent,fill,advance_interval=0,new_mb,old_mb,time_to_tell; int old_track_idx,buffer_fill,formatting= 0,use_data_image_size; char fifo_text[80],mb_text[40], pending[40]; char *debug_mark= ""; /* use this to prepend a marker text for experiments */ #ifndef Cdrskin_no_cdrfifO double buffer_size; int fs, bs, space; #endif #ifdef Cdrskin_use_libburn_fifO struct burn_source *current_fifo= NULL; #ifdef NIX int size, free_space; char *status_text= ""; #endif #endif /* Cdrskin_use_libburn_fifO */ /* for debugging */ static double last_fifo_in= 0.0,last_fifo_out= 0.0,curr_fifo_in,curr_fifo_out; if(Cdrskin__is_aborting(0)) Cdrskin_abort(skin, 0); /* Never comes back */ current_time= Sfile_microtime(0); elapsed_total_time= current_time-start_time; elapsed_time= current_time-*last_time; time_to_tell= (elapsed_time>=1.0)&&(elapsed_total_time>=1.0); written_total_bytes= *last_count; /* to be overwritten by p.sector */ if(drive_status==BURN_DRIVE_FORMATTING) formatting= 1; if(drive_status==BURN_DRIVE_WRITING) { ; } else if(drive_status==BURN_DRIVE_WRITING_LEADIN || drive_status==BURN_DRIVE_WRITING_PREGAP || formatting) { if(time_to_tell || skin->is_writing) { if(skin->verbosity>=Cdrskin_verbose_progresS) { if(skin->is_writing) fprintf(stderr,"\n"); fprintf(stderr, "%scdrskin: %s (burning since %.f seconds)%s", skin->pacifier_with_newline ? "" : "\r", (formatting?"formatting":"working pre-track"), elapsed_total_time, skin->pacifier_with_newline ? "\n" : " "); } skin->is_writing= 0; advance_interval= 1; } {ret= 2; goto ex;} } else if(drive_status==BURN_DRIVE_WRITING_LEADOUT || drive_status==BURN_DRIVE_CLOSING_TRACK || drive_status==BURN_DRIVE_CLOSING_SESSION) { if(drive_status==BURN_DRIVE_CLOSING_SESSION && skin->previous_drive_status!=drive_status) {printf("\nFixating...\n"); fflush(stdout);} if(time_to_tell || skin->is_writing) { if(skin->verbosity>=Cdrskin_verbose_progresS) { if(skin->is_writing && !skin->pacifier_with_newline) fprintf(stderr,"\n"); fprintf(stderr, "%scdrskin: working post-track (burning since %.f seconds)%s", skin->pacifier_with_newline ? "" : "\r", elapsed_total_time, skin->pacifier_with_newline ? "\n" : " "); } skin->is_writing= 0; advance_interval= 1; } {ret= 2; goto ex;} } else goto thank_you_for_patience; old_track_idx= skin->supposed_track_idx; skin->supposed_track_idx= p->track; if(old_track_idx>=0 && old_track_idxsupposed_track_idx && skin->supposed_track_idx < skin->track_counter) { Cdrtrack_get_size(skin->tracklist[old_track_idx],&fixed_size,&padding, §or_size,&use_data_image_size,1); if(skin->verbosity>=Cdrskin_verbose_progresS) printf("\n"); printf("%sTrack %-2.2d: Total bytes read/written: %.f/%.f (%.f sectors).\n", debug_mark, old_track_idx + start_tno, fixed_size,fixed_size+padding, (fixed_size+padding)/sector_size); *last_count= 0; } sector_size= 2048.0; if(skin->supposed_track_idx>=0 && skin->supposed_track_idxtrack_counter) Cdrtrack_get_size(skin->tracklist[skin->supposed_track_idx],&fixed_size, &padding,§or_size,&use_data_image_size,0); bytes_to_write= ((double) p->sectors)*sector_size; written_total_bytes= ((double) p->sector)*sector_size; written_bytes= written_total_bytes-*last_count; if(written_total_bytes<1024*1024) { thank_you_for_patience:; if(time_to_tell || (skin->is_writing && elapsed_total_time>=1.0)) { if(skin->verbosity>=Cdrskin_verbose_progresS) { if(skin->is_writing) { fprintf(stderr,"\n"); } pending[0]= 0; /* if(bytes_to_write > 0 && skin->verbosity >= Cdrskin_verbose_debuG) sprintf(pending, " pnd %.f", bytes_to_write - written_total_bytes); */ fprintf(stderr, "%scdrskin: thank you for being patient for %.f seconds%21.21s%s", skin->pacifier_with_newline ? "" : "\r", elapsed_total_time, pending, skin->pacifier_with_newline ? "\n" : ""); } advance_interval= 1; } skin->is_writing= 0; {ret= 2; goto ex;} } new_mb= written_total_bytes/(1024*1024); old_mb= (*last_count)/(1024*1024); if(new_mb==old_mb && !(written_total_bytes>=skin->fixed_size && skin->fixed_size>0 && time_to_tell)) {ret= 1; goto ex;} #ifndef Cdrskin_extra_leaN percent= 0.0; if(bytes_to_write>0) percent= written_total_bytes/bytes_to_write*100.0; measured_total_speed= 0.0; measured_speed= 0.0; estim_time= -1.0; estim_minutes= -1.0; estim_seconds= -1.0; if(elapsed_total_time>0.0) { measured_total_speed= written_total_bytes/elapsed_total_time; estim_time= (bytes_to_write-written_bytes)/measured_total_speed; if(estim_time>0.0 && estim_time<86400.0) { estim_minutes= ((int) estim_time)/60; estim_seconds= estim_time-estim_minutes*60.0; if(estim_seconds<0.0) estim_seconds= 0.0; } } if(written_bytes==written_total_bytes && elapsed_total_time>0) { measured_speed= measured_total_speed; } else if(elapsed_time>0.0) { measured_speed= written_bytes/elapsed_time; } else if(written_bytes>0.0) { measured_speed= 99.91*Cdrskin_speed_factoR; } if(measured_speed<=0.0 && written_total_bytes>=skin->fixed_size && skin->fixed_size>0) { if(!skin->is_writing) goto thank_you_for_patience; skin->is_writing= 0; measured_speed= measured_total_speed; } else skin->is_writing= 1; if(skin->supposed_track_idx<0) skin->supposed_track_idx= 0; if(*last_count <= 0.0 && !skin->pacifier_with_newline) printf("\r%-78.78s\r", ""); /* wipe output line */ if(skin->verbosity>=Cdrskin_verbose_progresS) { if(flag&1) { printf("%.f/%.f (%2.1f%%) @%1.1f, remaining %.f:%2.2d\n", written_total_bytes,bytes_to_write,percent, measured_speed/Cdrskin_speed_factoR, estim_minutes,(int) estim_seconds); } else { fill= 0; fifo_percent= 50; fifo_text[0]= 0; curr_fifo_in= last_fifo_in; curr_fifo_out= last_fifo_out; if(skin->cuefile_fifo != NULL) Cdrskin__libburn_fifo_status(skin->cuefile_fifo, fifo_text, 0); #ifdef Cdrskin_use_libburn_fifO /* Inquire fifo fill and format fifo pacifier text */ if(skin->fifo == NULL && skin->supposed_track_idx >= 0 && skin->supposed_track_idx < skin->track_counter && skin->fifo_size > 0 && fifo_text[0] == 0) { Cdrtrack_get_libburn_fifo(skin->tracklist[skin->supposed_track_idx], ¤t_fifo, 0); if(current_fifo != NULL) { Cdrskin__libburn_fifo_status(current_fifo, fifo_text, 0); } else if(skin->fifo_size > 0) { strcpy(fifo_text, "(fifo 100%) "); } } #endif /* Cdrskin_use_libburn_fifO */ #ifndef Cdrskin_no_cdrfifO if(skin->fifo!=NULL) { ret= Cdrfifo_get_buffer_state(skin->fifo,&fill,&space,0); buffer_size= fill+space; if(ret==2 || ret==0) { fifo_percent= 100; } else if(ret>0 && buffer_size>0.0) { /* obtain minimum fill of pacifier interval */ Cdrfifo_next_interval(skin->fifo,&fill,0); fifo_percent= 100.0*((double) fill)/buffer_size; if(fifo_percent<100 && fill>0) fifo_percent++; } if(skin->verbosity>=Cdrskin_verbose_debuG) { Cdrfifo_get_counters(skin->fifo,&curr_fifo_in,&curr_fifo_out,0); Cdrfifo_get_sizes(skin->fifo,&bs,&fs,0); } if(skin->fifo_size>0) { sprintf(fifo_text,"(fifo %3d%%) ",fifo_percent); if(skin->verbosity>=Cdrskin_verbose_debug_fifO) { fprintf(stderr, "\ncdrskin_debug: fifo >= %9d / %d : %8.f in, %8.f out\n", fill,(int) buffer_size, curr_fifo_in-last_fifo_in,curr_fifo_out-last_fifo_out); last_fifo_in= curr_fifo_in; last_fifo_out= curr_fifo_out; } } } #endif /* ! Cdrskin_no_cdrfifO */ if(skin->supposed_track_idx >= 0 && skin->supposed_track_idx < skin->track_counter) { /* fixed_size,padding are fetched above via Cdrtrack_get_size() */; } else if(skin->fixed_size!=0) { fixed_size= skin->fixed_size; padding= skin->padding; } if(fixed_size || (skin->fill_up_media && skin->supposed_track_idx==skin->track_counter-1)) { sprintf(mb_text,"%4d of %4d",(int) (written_total_bytes/1024.0/1024.0), (int) ((double) Cdrtrack_get_sectors( skin->tracklist[skin->supposed_track_idx],0)* sector_size/1024.0/1024.0)); } else sprintf(mb_text,"%4d",(int) (written_total_bytes/1024.0/1024.0)); speed_factor= Cdrskin_speed_factoR*sector_size/2048; buffer_fill= 50; if(p->buffer_capacity>0) buffer_fill= (double) (p->buffer_capacity - p->buffer_available)*100.0 / (double) p->buffer_capacity; if(p->buffered_bytes > p->buffer_capacity) if(buffer_fill < *min_buffer_fill) *min_buffer_fill= buffer_fill; printf("%s%sTrack %-2.2d: %s MB written %s[buf %3d%%] %4.1fx.%s", skin->pacifier_with_newline ? "" : "\r", debug_mark, skin->supposed_track_idx + start_tno, mb_text, fifo_text, buffer_fill, measured_speed / speed_factor, skin->pacifier_with_newline ? "\n" : ""); fflush(stdout); } if(skin->is_writing==0) { printf("\n"); goto thank_you_for_patience; } } #else /* ! Cdrskin_extra_leaN */ if(skin->supposed_track_idx<0) skin->supposed_track_idx= 0; if(written_bytes<=0.0 && written_total_bytes>=skin->fixed_size && skin->fixed_size>0) { if(!skin->is_writing) goto thank_you_for_patience; skin->is_writing= 0; } else { if((!skin->is_writing) && !skin->pacifier_with_newline) printf("\n"); skin->is_writing= 1; } printf("%sTrack %-2.2d: %3d MB written %s", skin->pacifier_with_newline ? "" : "\r", skin->supposed_track_idx + start_tno, (int) (written_total_bytes / 1024.0 / 1024.0), skin->pacifier_with_newline ? "\n" : ""); if(skin->is_writing == 0 && !skin->pacifier_with_newline) printf("\n"); fflush(stdout); #endif /* Cdrskin_extra_leaN */ advance_interval= 1; ret= 1; ex:; if(advance_interval) { if(written_total_bytes>0) *last_count= written_total_bytes; else *last_count= 0.0; if(*last_count>*total_count) *total_count= *last_count; *last_time= current_time; } skin->previous_drive_status= drive_status; return(ret); } /** After everything else about burn_write_opts and burn_disc is set up, this call determines the effective write mode and checks whether the drive promises to support it. */ int Cdrskin_activate_write_mode(struct CdrskiN *skin, struct burn_write_opts *opts, struct burn_disc *disc, int flag) { int profile_number= -1, ret, was_still_default= 0; char profile_name[80], reasons[BURN_REASONS_LEN]; enum burn_disc_status s= BURN_DISC_UNGRABBED; enum burn_write_types wt; profile_name[0]= 0; if(skin->grabbed_drive) { burn_disc_get_profile(skin->grabbed_drive,&profile_number,profile_name); s= burn_disc_get_status(skin->grabbed_drive); } if(strcmp(skin->preskin->write_mode_name,"DEFAULT")==0) { was_still_default= 1; wt= burn_write_opts_auto_write_type(opts, disc, reasons, 0); if(wt==BURN_WRITE_NONE) { if(strncmp(reasons,"MEDIA: ",7)==0) ret= -1; else ret= 0; goto report_failure; } skin->write_type= wt; #ifndef Cdrskin_disable_raw96R if(wt==BURN_WRITE_RAW) strcpy(skin->preskin->write_mode_name,"RAW/RAW96R"); else #endif /* ! Cdrskin_disable_raw96R */ if(wt==BURN_WRITE_TAO) strcpy(skin->preskin->write_mode_name,"TAO"); else if(wt==BURN_WRITE_SAO) strcpy(skin->preskin->write_mode_name,"SAO"); else sprintf(skin->preskin->write_mode_name,"LIBBURN/%d", (int) wt); } #ifndef Cdrskin_disable_raw96R if(strcmp(skin->preskin->write_mode_name,"RAW/RAW96R")==0) { skin->write_type= BURN_WRITE_RAW; skin->block_type= BURN_BLOCK_RAW96R; } else #endif /* ! Cdrskin_disable_raw96R */ if(strcmp(skin->preskin->write_mode_name,"TAO")==0) { skin->write_type= BURN_WRITE_TAO; skin->block_type= BURN_BLOCK_MODE1; } else if(strncmp(skin->preskin->write_mode_name,"LIBBURN/",8)==0) { skin->block_type= BURN_BLOCK_MODE1; } else { strcpy(skin->preskin->write_mode_name,"SAO"); skin->write_type= BURN_WRITE_SAO; skin->block_type= BURN_BLOCK_SAO; /* cdrecord tolerates the combination of -sao and -multi. -multi wins. */ burn_write_opts_set_write_type(opts,skin->write_type,skin->block_type); ret = burn_precheck_write(opts,disc,reasons,0); if(ret <= 0) { if(strstr(reasons, "multi session capability lacking") != NULL) { fprintf(stderr,"cdrskin: WARNING : Cannot do SAO/DAO. Reason: %s\n", reasons); fprintf(stderr,"cdrskin: Defaulting to TAO/Incremental.\n"); skin->write_type= BURN_WRITE_TAO; skin->block_type= BURN_BLOCK_MODE1; } } } if(!was_still_default) burn_write_opts_set_write_type(opts,skin->write_type,skin->block_type); ret = burn_precheck_write(opts,disc,reasons,0); if(ret<=0) { report_failure:; if(ret!=-1) fprintf(stderr,"cdrskin: Reason: %s\n",reasons); fprintf(stderr,"cdrskin: Media : %s%s\n", s==BURN_DISC_BLANK?"blank ": s==BURN_DISC_APPENDABLE?"appendable ": s==BURN_DISC_FULL?"** closed ** ":"", profile_name[0]?profile_name: s==BURN_DISC_EMPTY?"no media":"unknown media"); return(0); } if(skin->verbosity>=Cdrskin_verbose_cmD) printf("cdrskin: Write type : %s\n", skin->preskin->write_mode_name); return(1); } #ifndef Cdrskin_extra_leaN int Cdrskin_announce_tracks(struct CdrskiN *skin, int start_tno, int flag) { int i,mb,use_data_image_size; double size,padding,sector_size= 2048.0; double sectors; if(skin->verbosity>=Cdrskin_verbose_progresS) { if(start_tno < 1) start_tno= 1; for(i=0;itrack_counter;i++) { Cdrtrack_get_size(skin->tracklist[i],&size,&padding,§or_size, &use_data_image_size,0); if(size<=0) { printf("Track %-2.2d: %s unknown length", i + start_tno, (sector_size==2048?"data ":"audio")); } else { mb= size/1024.0/1024.0; printf("Track %-2.2d: %s %4d MB ", i + start_tno, (sector_size==2048?"data ":"audio"), mb); } if(padding>0) printf(" padsize: %.f KB\n",padding/1024.0); else printf("\n"); } if(skin->fixed_size<=0) { printf("Total size: 0 MB (00:00.00) = 0 sectors\n"); printf("Lout start: 0 MB (00:02/00) = 0 sectors\n"); } else { /* >>> This is quite a fake. Need to learn about 12:35.25 and "Lout" ??? Is there a way to obtain the toc in advance (print_cue()) ? */ double seconds; int min,sec,frac; mb= skin->fixed_size/1024.0/1024.0; seconds= skin->fixed_size/150.0/1024.0+2.0; min= seconds/60.0; sec= seconds-min*60; frac= (seconds-min*60-sec)*100; if(frac>99) frac= 99; sectors= (int) (skin->fixed_size/sector_size); if(sectors*sector_size != skin->fixed_size) sectors++; printf("Total size: %5d MB (%-2.2d:%-2.2d.%-2.2d) = %d sectors\n", mb,min,sec,frac,(int) sectors); seconds+= 2; min= seconds/60.0; sec= seconds-min*60; frac= (seconds-min*60-sec)*100; if(frac>99) frac= 99; sectors+= 150; printf("Lout start: %5d MB (%-2.2d:%-2.2d/%-2.2d) = %d sectors\n", mb,min,sec,frac,(int) sectors); } } return(1); } #endif /* ! Cdrskin_extra_leaN */ int Cdrskin_direct_write(struct CdrskiN *skin, int flag) { off_t byte_address, data_count, chunksize, i, alignment, fill; int ret, max_chunksize= 64*1024, source_fd= -1, is_from_stdin, eof_sensed= 0; int self_opened= 0; char *buf= NULL, *source_path, amount_text[81]; struct burn_multi_caps *caps= NULL; ret= Cdrskin_grab_drive(skin,0); if(ret<=0) goto ex; ret= burn_disc_get_multi_caps(skin->grabbed_drive,BURN_WRITE_NONE,&caps,0); if(ret<=0) goto ex; if(caps->start_adr==0) { fprintf(stderr, "cdrskin: SORRY : Direct writing is not supported by drive and media\n"); {ret= 0; goto ex;} } alignment= caps->start_alignment; if(alignment>0 && (((off_t) skin->direct_write_amount) % alignment)!=0) { fprintf(stderr, "cdrskin: SORRY : direct_write_amount=%.f not aligned to blocks of %dk\n", skin->direct_write_amount,(int) alignment/1024); {ret= 0; goto ex;} } if(skin->track_counter<=0) { fprintf(stderr, "cdrskin: SORRY : No track source given for direct writing\n"); {ret= 0; goto ex;} } Cdrtrack_get_source_path(skin->tracklist[0], &source_path,&source_fd,&is_from_stdin,0); if(source_fd==-1) { ret= Cdrtrack_open_source_path(skin->tracklist[0],&source_fd, 2 | (skin->verbosity >= Cdrskin_verbose_debuG) | (4 * (skin->fifo_size >= 256 * 1024))); if(ret<=0) goto ex; if(ret == 2) self_opened= 1; } buf= calloc(1, max_chunksize); if(buf==NULL) { fprintf(stderr, "cdrskin: FATAL : Cannot allocate %d bytes of read buffer.\n", max_chunksize); {ret= -1; goto ex;} } byte_address= skin->write_start_address; if(byte_address<0) byte_address= 0; data_count= skin->direct_write_amount; if(data_count>0) sprintf(amount_text,"%.fk",(double) (data_count/1024)); else strcpy(amount_text,"0=open_ended"); fprintf(stderr,"Beginning direct write (start=%.fk,amount=%s) ...\n", (double) (byte_address/1024),amount_text); for(i= 0; i 0 ? alignment : 2048); else chunksize= data_count-i; if(chunksize>max_chunksize) chunksize= max_chunksize; /* read buffer from first track */ for(fill= 0; fill0) fprintf(stderr,"cdrskin: %s (errno=%d)\n", strerror(errno), errno); ret= 0; goto ex; } else if(ret==0) { eof_sensed= 1; if(data_count==0) { memset(buf+fill,0,(size_t) (chunksize-fill)); break; } else { fprintf(stderr, "cdrskin: FATAL : Premature EOF while reading from '%s'\n", source_path); ret= 0; goto ex; } } } ret= burn_random_access_write(skin->grabbed_drive,byte_address, buf,chunksize,0); if(ret<=0) goto ex; if(eof_sensed) break; byte_address+= chunksize; fprintf(stderr, "%s%9.fk written %s", skin->pacifier_with_newline ? "" : "\r", ((double) (i+chunksize)) / 1024.0, skin->pacifier_with_newline ? "\n" : ""); } fprintf(stderr, "%s%9.fk written \n", skin->pacifier_with_newline ? "" : "\r", ((double) i) / 1024.0); /* flush drive buffer */ fprintf(stderr,"syncing cache ...\n"); ret = burn_random_access_write(skin->grabbed_drive,byte_address,buf,0,1); if(ret<=0) goto ex; ret= 1; ex:; if(caps!=NULL) burn_disc_free_multi_caps(&caps); if(buf!=NULL) free(buf); if(self_opened && source_fd >= 0) close(source_fd); if(ret>0) fprintf(stderr,"writing done\n"); else fprintf(stderr,"writing failed\n"); return(ret); } int Cdrskin_grow_overwriteable_iso(struct CdrskiN *skin, int flag) { int ret, i, went_well= 1; char *track_descr, *md; unsigned char *td; /* Because the representation of 255 in char is ambigous */ double track_size, media_size; ret= Cdrtrack_get_iso_fs_descr(skin->tracklist[0],&track_descr,&track_size,0); if(ret<=0) { fprintf(stderr,"cdrskin: SORRY : Saw no ISO-9660 filesystem in track 0\n"); return(ret); } if(skin->grow_overwriteable_iso==3) /* initial session */ return(1); if(skin->grow_overwriteable_iso!=2) { fprintf(stderr, "cdrskin: SORRY : Could not read ISO-9660 descriptors from media\n"); return(0); } ret= Scan_for_iso_size((unsigned char *) skin->overwriteable_iso_head+16*2048, &media_size, 0); if(ret<=0) { fprintf(stderr,"cdrskin: SORRY : No recognizable ISO-9660 on media\n"); return(0); } if(skin->write_start_address>=0.0) media_size= skin->write_start_address; /* Write new sum into media descr 0 */ md= skin->overwriteable_iso_head+16*2048; memcpy(md,track_descr,2048); Set_descr_iso_size((unsigned char *) md,track_size+media_size,0); if(skin->verbosity>=Cdrskin_verbose_debuG) ClN(fprintf(stderr,"cdrskin_debug: new ISO-9660 size : %.f (%fs)\n", track_size+media_size, (track_size+media_size)/2048)); /* Copy type 255 CD001 descriptors from track to media descriptor buffer and adjust their size entries */ for(i=1; i<16; i++) { td= (unsigned char *) (track_descr + i * 2048); md= skin->overwriteable_iso_head+(16+i)*2048; if(td[0] != 255) break; /* demand media descrN[0] == track descrN[0] */ if(((char *) td)[0] != md[0]) { fprintf(stderr, "cdrskin: SORRY : Type mismatch of ISO volume descriptor #%d (%u <-> %u)\n", i, ((unsigned int) td[0]) & 0xff, ((unsigned int) md[0])&0xff); went_well= 0; } memcpy(md,td,2048); Set_descr_iso_size((unsigned char *) md,track_size+media_size,0); } if(skin->verbosity>=Cdrskin_verbose_debuG) ClN(fprintf(stderr,"cdrskin_debug: copied %d secondary ISO descriptors\n", i-1)); /* write block 16 to 31 to media */ if(skin->verbosity>=Cdrskin_verbose_debuG) ClN(fprintf(stderr,"cdrskin_debug: writing to media: blocks 16 to 31\n")); ret= burn_random_access_write(skin->grabbed_drive, (off_t) (16*2048), skin->overwriteable_iso_head+16*2048, (off_t) (16*2048), 1); if(ret<=0) return(ret); return(went_well); } int Cdrskin_cdtext_test(struct CdrskiN *skin, struct burn_write_opts *o, struct burn_session *session, int flag) { int ret, num_packs; unsigned char *text_packs = NULL; if(skin->num_text_packs > 0) { Cdrskin_print_text_packs(skin, skin->text_packs, skin->num_text_packs, 2); ret= 1; goto ex; } ret= burn_cdtext_from_session(session, &text_packs, &num_packs, 0); if(ret < 0) goto ex; if(ret > 0) { Cdrskin_print_text_packs(skin, text_packs, num_packs, 1); ret= 1; goto ex; } ret= 1; ex: if (text_packs != NULL) free(text_packs); return(ret); } int Cdrskin_read_input_sheet_v07t(struct CdrskiN *skin, char *path, int block, struct burn_session *session, int flag) { int ret= 0; ret= burn_session_input_sheet_v07t(session, path, block, 1); return(ret); } int Cdrskin_cdrtracks_from_session(struct CdrskiN *skin, struct burn_session *session, int flag) { int ret, num_tracks, i; struct burn_track **tracks; struct CdrtracK *t; double sectors; for(i= 0; i < skin->track_counter; i++) Cdrtrack_destroy(&(skin->tracklist[i]), 0); skin->track_counter= 0; tracks= burn_session_get_tracks(session, &num_tracks); if(num_tracks <= 0) { fprintf(stderr, "cdrskin: SORRY : No tracks defined for burn run.\n"); ret= 0; goto ex; } for(i= 0; i < num_tracks; i++) { /* Create Cdrtrack without reading parameters from skin */ ret= Cdrtrack_new(&(skin->tracklist[skin->track_counter]), skin, skin->track_counter, 1); if(ret <= 0) { fprintf(stderr, "cdrskin: FATAL : Creation of track control object failed.\n"); goto ex; } /* Set essential properties */ t= skin->tracklist[skin->track_counter]; t->track_type= burn_track_get_mode(tracks[i]); if(t->track_type & BURN_AUDIO) { t->sector_size= 2352; t->track_type= BURN_AUDIO; } else { t->sector_size= 2048; t->track_type= BURN_MODE1; } sectors= burn_track_get_sectors(tracks[i]); t->fixed_size= sectors * t->sector_size; t->libburn_track= tracks[i]; t->libburn_track_is_own= 0; skin->track_counter++; } ret= 1; ex: if(ret <= 0) { for(i= 0; i < skin->track_counter; i++) Cdrtrack_destroy(&(skin->tracklist[i]), 0); skin->track_counter= 0; } return(ret); } int Cdrskin_write_result_string(struct CdrskiN *skin, char *msg, int flag) { int ret; if(skin->preskin->result_fd < 0) { printf("%s",msg); return(1); } ret= write(skin->preskin->result_fd, msg, strlen(msg)); if(ret != (int) strlen(msg)) return(0); return(1); } /** Burn data via libburn according to the parameters set in skin. @return <=0 error, 1 success */ int Cdrskin_burn(struct CdrskiN *skin, int flag) { struct burn_disc *disc = NULL; struct burn_session *session = NULL; struct burn_write_opts *o = NULL; struct burn_source *cuefile_fifo= NULL; enum burn_disc_status s; enum burn_drive_status drive_status; struct burn_progress p; struct burn_drive *drive; int ret,loop_counter= 0,max_track= -1,i,hflag,nwa,num, wrote_well= 2; int fifo_disabled= 0, min_buffer_fill= 101, length, start_tno= 1; int use_data_image_size, needs_early_fifo_fill= 0,iso_size= -1, non_audio= 0; double start_time,last_time; double total_count= 0.0,last_count= 0.0,size,padding,sector_size= 2048.0; char *doing; char *source_path; unsigned char *payload; int source_fd, is_from_stdin; int text_flag= 4; /* Check CRCs and silently repair CRCs if all are 0 */ unsigned char *text_packs= NULL; int num_packs= 0, start_block, block_no; #ifndef Cdrskin_no_cdrfifO double put_counter, get_counter, empty_counter, full_counter; int total_min_fill, fifo_percent; #endif off_t free_space; char msg[80]; if(skin->tell_media_space) doing= "estimating"; else doing= "burning"; printf("cdrskin: beginning to %s disc\n", skin->tell_media_space?"estimate":"burn"); if(skin->fill_up_media && skin->multi) { ClN(fprintf(stderr, "cdrskin: NOTE : Option --fill_up_media disabled option -multi\n")); skin->multi= 0; } ret= Cdrskin_grab_drive(skin,0); if(ret<=0) goto burn_failed; drive= skin->drives[skin->driveno].drive; s= burn_disc_get_status(drive); if(skin->verbosity>=Cdrskin_verbose_progresS) Cdrskin_report_disc_status(skin,s,1); disc= burn_disc_create(); session= burn_session_create(); ret= burn_disc_add_session(disc,session,BURN_POS_END); if(ret==0) { fprintf(stderr,"cdrskin: FATAL : Cannot add session to disc object.\n"); burn_failed:; ret= 0; goto ex; } skin->fixed_size= 0.0; skin->has_open_ended_track= 0; if(skin->cuefile[0]) { if(skin->track_counter > 0) { fprintf(stderr, "cdrskin: SORRY : Option cuefile= cannot be combined with track sources\n"); goto burn_failed; } if(strcmp(skin->preskin->write_mode_name, "SAO") != 0 && strcmp(skin->preskin->write_mode_name, "DEFAULT") != 0) { fprintf(stderr, "cdrskin: SORRY : Option cuefile= works only with write mode SAO"); goto burn_failed; } strcpy(skin->preskin->write_mode_name, "SAO"); ret= burn_session_by_cue_file(session, skin->cuefile, skin->fifo_size, &cuefile_fifo, &text_packs, &num_packs, !skin->use_cdtext); if(ret <= 0) goto burn_failed; if(num_packs > 0) { if(skin->num_text_packs > 0) { fprintf(stderr, "cdrskin: WARNING : Option textfile= overrides CDTEXTFILE from option cuesheet=\n"); if(text_packs != NULL) free(text_packs); } else { skin->text_packs= text_packs; skin->num_text_packs= num_packs; } } text_packs= NULL; /* Now either freed or attached */ ret= Cdrskin_cdrtracks_from_session(skin, session, 0); if(ret <= 0) goto burn_failed; skin->cuefile_fifo= cuefile_fifo; cuefile_fifo= NULL; } else { for(i=0;itrack_counter;i++) { hflag= (skin->verbosity>=Cdrskin_verbose_debuG); if(i==skin->track_counter-1) Cdrtrack_ensure_padding(skin->tracklist[i],hflag&1); /* if(skin->fifo_size >= 256 * 1024) */ hflag|= 4; ret= Cdrtrack_add_to_session(skin->tracklist[i],i,session,hflag); if(ret<=0) { fprintf(stderr,"cdrskin: FATAL : Cannot add track %d to session.\n",i+1); goto burn_failed; } Cdrtrack_get_size(skin->tracklist[i],&size,&padding,§or_size, &use_data_image_size,0); if(use_data_image_size==1) { /* still unfulfilled -isosize demand pending */ needs_early_fifo_fill= 1; } non_audio|= (skin->tracklist[i]->track_type != BURN_AUDIO); } } if(skin->sheet_v07t_blocks > 0) { if(skin->num_text_packs > 0) { fprintf(stderr, "cdrskin: WARNING : Option textfile= or cuefile= overrides option input_sheet_v07t=\n"); } else if(non_audio) { fprintf(stderr, "cdrskin: SORRY : Option input_sheet_v07t= works only if all tracks are -audio\n"); goto burn_failed; } else { /* If cuefile and session has block 0, then start at block 1 */ start_block= 0; if(skin->cuefile[0]) { for(i= 0x80; i < 0x8f; i++) { ret= burn_session_get_cdtext(session, 0, i, "", &payload, &length, 0); if(ret > 0 && length > 0) break; } if(i < 0x8f) start_block= 1; } block_no = start_block; for(i= 0; i < skin->sheet_v07t_blocks && block_no < 8; i++) { ret= Cdrskin_read_input_sheet_v07t(skin, skin->sheet_v07t_paths[i], block_no, session, 0); if(ret <= 0) goto burn_failed; block_no += ret; } if(i < skin->sheet_v07t_blocks) { fprintf(stderr, "cdrskin: WARNING : Too many CD-TEXT blocks. input_sheet_v07t= files ignored: %d\n", skin->sheet_v07t_blocks - i); } } } #ifndef Cdrskin_extra_leaN /* Final decision on track size has to be made after eventual -isosize determination via fifo content. */ if(needs_early_fifo_fill && !skin->tell_media_space) { int start_memorized; start_memorized= skin->fifo_start_at; /* try ISO-9660 size recognition via fifo */ if(32*2048<=skin->fifo_size) skin->fifo_start_at= 32*2048; else skin->fifo_start_at= skin->fifo_size; ret= Cdrskin_fill_fifo(skin,0); if(ret<=0) goto fifo_filling_failed; if((start_memorized>skin->fifo_start_at || start_memorized<=0) && skin->fifo_start_atfifo_size) needs_early_fifo_fill= 2; /* continue filling fifo at normal stage */ skin->fifo_start_at= start_memorized; } #endif /* Cdrskin_extra_leaN */ for(i=0;itrack_counter;i++) { Cdrtrack_get_size(skin->tracklist[i],&size,&padding,§or_size, &use_data_image_size,0); if(use_data_image_size==1 && size<=0 && skin->tell_media_space) size= 1024*1024; /* a dummy size */ ret= Cdrtrack_activate_image_size(skin->tracklist[i],&size, !!skin->tell_media_space); if(ret<=0) { Cdrtrack_get_source_path(skin->tracklist[i], &source_path,&source_fd,&is_from_stdin,0); fprintf(stderr, "cdrskin: FATAL : Cannot determine -isosize of track source\n"); fprintf(stderr, "cdrskin: '%s'\n", source_path); {ret= 0; goto ex;} } Cdrtrack_get_size(skin->tracklist[i],&size,&padding,§or_size, &use_data_image_size,0); if(use_data_image_size==2 && skin->verbosity>=Cdrskin_verbose_debuG) ClN(fprintf(stderr, "cdrskin: DEBUG: track %2.2d : activated -isosize %.fs (= %.fb)\n", i+1, size/2048.0,size)); if(size>0) skin->fixed_size+= size+padding; else skin->has_open_ended_track= 1; if(skin->tracklist[i]->isrc[0] && skin->tracklist[i]->libburn_track != NULL) { ret= burn_track_set_isrc_string(skin->tracklist[i]->libburn_track, skin->tracklist[i]->isrc, 0); if(ret <= 0) goto ex; } } o= burn_write_opts_new(drive); burn_write_opts_set_perform_opc(o, 0); /* growisofs stunt: assessment of media and start for next session */ if((skin->grow_overwriteable_iso==1 || skin->grow_overwriteable_iso==2) && skin->media_is_overwriteable) { /* Obtain ISO size from media, keep 64 kB head in memory */ ret= Cdrskin_overwriteable_iso_size(skin,&iso_size,0); if(ret<0) goto ex; if(ret>0 && skin->write_start_address<0) { skin->write_start_address= ((double) iso_size)*2048.0; if(skin->verbosity>=Cdrskin_verbose_cmD) ClN(printf( "cdrskin: write start address by --grow_overwriteable_iso : %ds\n", iso_size)); } else if(ret==0) skin->grow_overwriteable_iso= 3; /* do not patch ISO header later on */ } burn_write_opts_set_start_byte(o, skin->write_start_address); if(skin->media_is_overwriteable && skin->multi) { if(skin->grow_overwriteable_iso<=0) { fprintf(stderr, "cdrskin: FATAL : -multi cannot leave a recognizable end mark on this media.\n"); fprintf(stderr, "cdrskin: HINT : For ISO-9660 images try --grow_overwriteable_iso -multi\n"); {ret= 0; goto ex;} } skin->multi= 0; } if(skin->multi && !skin->media_does_multi) { if(skin->prodvd_cli_compatible) { skin->multi= 0; if(skin->verbosity>=Cdrskin_verbose_progresS) fprintf(stderr, "cdrskin: NOTE : Ignored option -multi.\n"); } } burn_write_opts_set_multi(o,skin->multi); burn_write_opts_set_fillup(o, skin->fill_up_media); burn_write_opts_set_force(o, !!skin->force_is_set); burn_write_opts_set_stream_recording(o, skin->stream_recording_is_set); #ifdef Cdrskin_dvd_obs_default_64K if(skin->dvd_obs == 0) burn_write_opts_set_dvd_obs(o, 64 * 1024); else #endif burn_write_opts_set_dvd_obs(o, skin->dvd_obs); burn_write_opts_set_obs_pad(o, skin->obs_pad); burn_write_opts_set_stdio_fsync(o, skin->stdio_sync); if(skin->dummy_mode) { fprintf(stderr, "cdrskin: NOTE : -dummy mode will prevent actual writing\n"); burn_write_opts_set_simulate(o, 1); } burn_write_opts_set_underrun_proof(o,skin->burnfree); if(skin->num_text_packs > 0) { if(non_audio) { fprintf(stderr, "cdrskin: SORRY : Option textfile= works only if all tracks are -audio\n"); goto burn_failed; } if(!!skin->force_is_set) text_flag= 1; /* No CRC verification or repairing */ ret= burn_write_opts_set_leadin_text(o, skin->text_packs, skin->num_text_packs, text_flag); if(ret <= 0) goto burn_failed; } if(skin->mcn[0]) { burn_write_opts_set_mediacatalog(o, (unsigned char *) skin->mcn); burn_write_opts_set_has_mediacatalog(o, 1); } if(skin->cd_start_tno >= 1 && skin->cd_start_tno <= 99) { ret= burn_session_set_start_tno(session, skin->cd_start_tno, 0); if(ret <= 0) goto burn_failed; } ret= Cdrskin_activate_write_mode(skin,o,disc,0); if(ret<=0) goto burn_failed; if(skin->cdtext_test) { ret= Cdrskin_cdtext_test(skin, o, session, (skin->cdtext_test == 1)); if(ret <= 0) goto ex; if(skin->cdtext_test >= 2) { fprintf(stderr, "cdrskin: Option --cdtext_dummy prevents actual burn run\n"); ret= 1; goto ex; } } ret= Cdrskin_obtain_nwa(skin, &nwa,0); if(ret<=0) nwa= -1; if(skin->assert_write_lba>=0 && nwa!=skin->assert_write_lba) { fprintf(stderr, "cdrskin: FATAL : Option assert_write_lba= demands block number %10d\n", skin->assert_write_lba); fprintf(stderr, "cdrskin: FATAL : but predicted actual write start address is %10d\n", nwa); {ret= 0; goto ex;} } #ifndef Cdrskin_extra_leaN Cdrskin_announce_tracks(skin, burn_session_get_start_tno(session, 0), 0); #endif if(skin->tell_media_space || skin->track_counter <= 0) { /* write capacity estimation and return without actual burning */ free_space= burn_disc_available_space(drive,o); sprintf(msg,"%d\n",(int) (free_space/(off_t) 2048)); Cdrskin_write_result_string(skin, msg, 0); if(skin->track_counter>0) fprintf(stderr, "cdrskin: NOTE : %s burn run suppressed by option --tell_media_space\n", skin->preskin->write_mode_name); {ret= 1; goto ex;} } if(skin->fixed_size > 0 && !skin->force_is_set) { free_space= burn_disc_available_space(drive,o); if(skin->fixed_size > free_space && free_space > 0) { fprintf(stderr, "cdrskin: FATAL : predicted session size %lus does not fit on media (%lus)\n", (unsigned long) ((skin->fixed_size + 2047.0) / 2048.0), (unsigned long) ((free_space + 2047) / 2048)); ClN(fprintf(stderr, "cdrskin: HINT : This test may be disabled by option -force\n");) {ret= 0; goto ex;} } } Cdrskin_adjust_speed(skin,0); #ifndef Cdrskin_extra_leaN Cdrskin_wait_before_action(skin,0); if(burn_is_aborting(0)) {ret= 0; goto ex;} if(needs_early_fifo_fill==1) ret= 1; else if(skin->cuefile[0] != 0) ret= 1; else ret= Cdrskin_fill_fifo(skin,0); if(ret<=0) { fifo_filling_failed:; fprintf(stderr,"cdrskin: FATAL : Filling of fifo failed\n"); goto ex; } #endif /* ! Cdrskin_extra_leaN */ start_tno = burn_session_get_start_tno(session, 0); if(skin->verbosity>=Cdrskin_verbose_progresS && nwa>=0) { printf("Starting new track at sector: %d\n",nwa); fflush(stdout); } if(burn_is_aborting(0)) {ret= 0; goto ex;} skin->drive_is_busy= 1; burn_disc_write(o, disc); if(skin->preskin->abort_handler==-1) Cleanup_set_handlers(Cleanup_handler_handlE, Cleanup_handler_funC, Cleanup_handler_flaG); last_time= start_time= Sfile_microtime(0); burn_write_opts_free(o); o= NULL; while (burn_drive_get_status(drive, NULL) == BURN_DRIVE_SPAWNING) { /* >>> how do i learn about success or failure ? */ ; } loop_counter= 0; while (1) { drive_status= burn_drive_get_status(drive, &p); if(drive_status==BURN_DRIVE_IDLE) break; /* >>> how do i learn about success or failure ? */ if(loop_counter>0 || Cdrskin__is_aborting(0)) Cdrskin_burn_pacifier(skin, start_tno, drive_status,&p,start_time,&last_time, &total_count,&last_count,&min_buffer_fill,0); if(max_tracksupposed_track_idx) max_track= skin->supposed_track_idx; #ifndef Cdrskin_extra_leaN /* <<< debugging : artificial abort without a previous signal */; if(skin->abort_after_bytecount>=0.0 && total_count>=skin->abort_after_bytecount) { /* whatever signal handling is installed: this thread is the boss now */ fprintf(stderr, "cdrskin: DEVELOPMENT : synthetic abort by abort_after_bytecount=%.f\n", skin->abort_after_bytecount); skin->control_pid= getpid(); ret= Cdrskin_abort_handler(skin,0,0); fprintf(stderr,"cdrskin: done (aborted)\n"); exit(1); } if(Cdrskin__is_aborting(0)) fifo_disabled= 1; if(skin->fifo==NULL || fifo_disabled) { usleep(20000); } else { #ifdef Cdrskin_no_cdrfifO /* Should never happen as skin->fifo should be NULL */ usleep(20000); #else /* Cdrskin_no_cdrfifO */ ret= Cdrfifo_try_to_work(skin->fifo,20000,NULL,NULL,0); if(ret<0) { int abh; abh= skin->preskin->abort_handler; if(abh!=2) fprintf(stderr, "\ncdrskin: FATAL : Fifo encountered error during burn loop.\n"); if(abh==0) { ret= -1; goto ex; } else if(abh==1 || abh==3 || abh==4 || abh==-1) { Cdrskin_abort_handler(skin,0,0); fprintf(stderr,"cdrskin: done (aborted)\n"); exit(10); } else { if(skin->verbosity>=Cdrskin_verbose_debuG) fprintf(stderr, "\ncdrskin_debug: Cdrfifo_try_to_work() returns %d\n",ret); } } if(ret==2) { /* <0 = error , 2 = work is done */ if(skin->verbosity>=Cdrskin_verbose_debuG) fprintf(stderr,"\ncdrskin_debug: fifo ended work with ret=%d\n",ret); fifo_disabled= 1; } #endif /* ! Cdrskin_no_cdrfifO */ } #else /* ! Cdrskin_extra_leaN */ usleep(20000); #endif /* Cdrskin_extra_leaN */ loop_counter++; } skin->drive_is_busy= 0; if(skin->verbosity>=Cdrskin_verbose_progresS) printf("\n"); if(Cdrskin__is_aborting(0)) Cdrskin_abort(skin, 0); /* Never comes back */ wrote_well = burn_drive_wrote_well(drive); if(skin->media_is_overwriteable && skin->grow_overwriteable_iso>0 && wrote_well) { /* growisofs final stunt : update volume descriptors at start of media */ ret= Cdrskin_grow_overwriteable_iso(skin,0); if(ret<=0) wrote_well= 0; } if(max_track<0) { printf("Track %-2.2d: Total bytes read/written: %.f/%.f (%.f sectors).\n", start_tno, total_count, total_count, total_count / sector_size); } else { Cdrtrack_get_size(skin->tracklist[max_track],&size,&padding,§or_size, &use_data_image_size,1); if (start_tno <= 0) start_tno = 1; printf("Track %-2.2d: Total bytes read/written: %.f/%.f (%.f sectors).\n", max_track + start_tno, size,size+padding,(size+padding)/sector_size); } if(skin->verbosity>=Cdrskin_verbose_progresS) printf("Writing time: %.3fs\n",Sfile_microtime(0)-start_time); #ifndef Cdrskin_extra_leaN #ifdef Cdrskin_use_libburn_fifO if(skin->fifo == NULL && skin->verbosity>=Cdrskin_verbose_progresS) { /* >>> this should rather be done for each track (for now this libburn_fifo should only be used with single track) */ Cdrtrack_report_fifo(skin->tracklist[skin->track_counter - 1], 0); } #endif /* Cdrskin_use_libburn_fifO */ #ifndef Cdrskin_no_cdrfifO if(skin->fifo!=NULL && skin->fifo_size>0 && wrote_well) { int dummy,final_fill; Cdrfifo_get_buffer_state(skin->fifo,&final_fill,&dummy,0); if(final_fill>0) { fifo_full_at_end:; fprintf(stderr, "cdrskin: FATAL : Fifo still contains data after burning has ended.\n"); fprintf(stderr, "cdrskin: FATAL : %.d bytes left.\n",final_fill); fprintf(stderr, "cdrskin: FATAL : This indicates an overflow of the last track.\n"); fprintf(stderr, "cdrskin: NOTE : The media might appear ok but is probably truncated.\n"); ret= -1; goto ex; } #ifdef Cdrskin_libburn_leaves_inlet_opeN for(i= 0;itrack_counter;i++) { ret= Cdrtrack_has_input_left(skin->tracklist[i],0); if(ret>0) { fprintf(stderr, "cdrskin: FATAL : Fifo outlet of track #%d is still buffering some bytes.\n", i+1); goto fifo_full_at_end; } } #endif /* Cdrskin_libburn_leaves_inlet_opeN */ } if(skin->verbosity>=Cdrskin_verbose_progresS) { if(skin->fifo!=NULL && skin->fifo_size>0) { int dummy; Cdrfifo_get_min_fill(skin->fifo,&total_min_fill,&dummy,0); fifo_percent= 100.0*((double) total_min_fill)/(double) skin->fifo_size; if(fifo_percent==0 && total_min_fill>0) fifo_percent= 1; Cdrfifo_get_cdr_counters(skin->fifo,&put_counter,&get_counter, &empty_counter,&full_counter,0); fflush(stdout); fprintf(stderr,"Cdrskin: fifo had %.f puts and %.f gets.\n", put_counter,get_counter); fprintf(stderr, "Cdrskin: fifo was %.f times empty and %.f times full, min fill was %d%%.\n", empty_counter,full_counter,fifo_percent); } } #endif /* ! Cdrskin_no_cdrfifO */ if(skin->verbosity>=Cdrskin_verbose_progresS) { drive_status= burn_drive_get_status(drive, &p); if(p.buffer_min_fill<=p.buffer_capacity && p.buffer_capacity>0) { num= 100.0 * ((double) p.buffer_min_fill)/(double) p.buffer_capacity; if(num100) min_buffer_fill= 50; printf("Min drive buffer fill was %d%%\n", min_buffer_fill); } #endif /* ! Cdrskin_extra_leaN */ ret= 1; if(wrote_well) { if(skin->verbosity>=Cdrskin_verbose_progresS) printf("cdrskin: burning done\n"); } else ret= 0; ex:; if(ret<=0) { if(skin->verbosity>=Cdrskin_verbose_progresS) printf("cdrskin: %s failed\n",doing); fprintf(stderr,"cdrskin: FATAL : %s failed.\n",doing); } skin->drive_is_busy= 0; if(skin->verbosity>=Cdrskin_verbose_debuG) ClN(printf("cdrskin_debug: do_eject= %d\n",skin->do_eject)); for(i= 0;itrack_counter;i++) Cdrtrack_cleanup(skin->tracklist[i],0); if(o != NULL) burn_write_opts_free(o); if(cuefile_fifo != NULL) burn_source_free(cuefile_fifo); if(session != NULL) burn_session_free(session); if(disc != NULL) burn_disc_free(disc); return(ret); } #ifdef Libburn_develop_quality_scaN int Cdrskin_qcheck(struct CdrskiN *skin, int flag) { struct burn_drive *drive; int ret, rate_period, profile_number; char profile_name[80]; printf("cdrskin: beginning to perform quality check on disc\n"); ret= Cdrskin_grab_drive(skin,0); if(ret<=0) return(ret); drive= skin->drives[skin->driveno].drive; ret= burn_disc_get_profile(drive, &profile_number, profile_name); if(ret <= 0) profile_number= 0; if(profile_number != 0x08 && profile_number != 0x09 && profile_number != 0x0a) rate_period= 8; else rate_period= 75; if(skin->do_qcheck == 1) { ret= burn_nec_optiarc_rep_err_rate(drive, 0, rate_period, 0); if(ret<=0) return(ret); } return(1); } #endif /* Libburn_develop_quality_scaN */ /** Print lba of first track of last session and Next Writeable Address of the next unwritten session. */ int Cdrskin_msinfo(struct CdrskiN *skin, int flag) { int num_sessions, session_no, ret, num_tracks, open_sessions= 0; int nwa= -123456789, lba= -123456789, aux_lba; char msg[80]; enum burn_disc_status s; struct burn_drive *drive; struct burn_disc *disc= NULL; struct burn_session **sessions= NULL; struct burn_track **tracks; struct burn_toc_entry toc_entry; ret= Cdrskin_grab_drive(skin,0); if(ret<=0) return(ret); drive= skin->drives[skin->driveno].drive; s= burn_disc_get_status(drive); if(s!=BURN_DISC_APPENDABLE) { if(skin->grow_overwriteable_iso==1 || skin->grow_overwriteable_iso==2) { lba= 0; ret= Cdrskin_overwriteable_iso_size(skin,&nwa,0); if(ret>0) { s= BURN_DISC_APPENDABLE; goto put_out; } } Cdrskin_report_disc_status(skin,s,0); fprintf(stderr,"cdrskin: FATAL : -msinfo can only operate on appendable (i.e. -multi) discs\n"); if(skin->grow_overwriteable_iso>0) fprintf(stderr,"cdrskin: or on overwriteables with existing ISO-9660 file system.\n"); {ret= 0; goto ex;} } disc= burn_drive_get_disc(drive); if(disc==NULL) { /* No TOC available. Try to inquire directly. */ ret= burn_disc_get_msc1(drive,&lba); if(ret>0) goto obtain_nwa; fprintf(stderr,"cdrskin: FATAL : Cannot obtain info about CD content\n"); {ret= 0; goto ex;} } sessions= burn_disc_get_sessions(disc,&num_sessions); open_sessions= burn_disc_get_incomplete_sessions(disc); for(session_no= 0; session_no < num_sessions + open_sessions; session_no++) { tracks= burn_session_get_tracks(sessions[session_no],&num_tracks); if(tracks==NULL || num_tracks<=0) continue; burn_track_get_entry(tracks[0],&toc_entry); if(toc_entry.extensions_valid&1) { /* DVD extension valid */ if(session_no >= num_sessions) { if(!(toc_entry.extensions_valid & 4)) continue; /* open session with no track status bits from libburn */ if((toc_entry.track_status_bits & (1 << 14)) || !((toc_entry.track_status_bits & (1 << 16)) || ((toc_entry.track_status_bits & (1 << 17)) && toc_entry.last_recorded_address > toc_entry.start_lba))) continue; /* Blank or not appendable and not recorded */ } lba= toc_entry.start_lba; } else { lba= burn_msf_to_lba(toc_entry.pmin,toc_entry.psec,toc_entry.pframe); } } if(lba==-123456789) { fprintf(stderr,"cdrskin: FATAL : Cannot find any track on CD\n"); {ret= 0; goto ex;} } obtain_nwa:; ret= Cdrskin_obtain_nwa(skin,&nwa,flag); if(ret<=0) { if (sessions == NULL) { fprintf(stderr, "cdrskin: SORRY : Cannot obtain next writeable address\n"); {ret= 0; goto ex;} } ClN(fprintf(stderr, "cdrskin: NOTE : Guessing next writeable address from leadout\n")); burn_session_get_leadout_entry(sessions[num_sessions-1],&toc_entry); if(toc_entry.extensions_valid&1) { /* DVD extension valid */ aux_lba= toc_entry.start_lba; } else { aux_lba= burn_msf_to_lba(toc_entry.pmin,toc_entry.psec,toc_entry.pframe); } if(num_sessions>0) nwa= aux_lba+6900; else nwa= aux_lba+11400; } put_out:; sprintf(msg,"%d,%d\n",lba,nwa); Cdrskin_write_result_string(skin, msg, 0); if(strlen(skin->msifile)) { FILE *fp; fp = fopen(skin->msifile, "w"); if(fp==NULL) { if(errno>0) fprintf(stderr,"cdrskin: %s (errno=%d)\n", strerror(errno), errno); fprintf(stderr,"cdrskin: FATAL : Cannot write msinfo to file '%s'\n", skin->msifile); {ret= 0; goto ex;} } fprintf(fp,"%d,%d",lba,nwa); fclose(fp); } ret= 1; ex:; if(disc!=NULL) burn_disc_free(disc); return(ret); } /** Work around the failure of libburn to eject the tray. This employs a system(2) call and is therefore an absolute no-no for any pseudo user identities. @return <=0 error, 1 success */ int Cdrskin_eject(struct CdrskiN *skin, int flag) { int i,ret,max_try= 5; if(!skin->do_eject) return(1); if((int) skin->n_drives <= skin->driveno || skin->driveno < 0) return(2); /* ??? A61012 : retry loop might now be obsolete (a matching bug in burn_disc_write_sync() was removed ) */ /* A61227 : A kindof race condition with -atip -eject on SuSE 9.3. Loop saved me. Waiting seems to help. I suspect the media demon. */ for(i= 0;i0 || i>=max_try-1) break; if(skin->verbosity>=Cdrskin_verbose_progresS) ClN(fprintf(stderr, "cdrskin: NOTE : Attempt #%d of %d failed to grab drive for eject\n", i+1,max_try)); usleep(1000000); } if(ret>0) { ret= Cdrskin_release_drive(skin,1); if(ret<=0) goto sorry_failed_to_eject; } else { sorry_failed_to_eject:; fprintf(stderr,"cdrskin: SORRY : Failed to finally eject tray.\n"); return(0); } return(1); } /** Interpret all arguments of the program after libburn has been initialized and drives have been scanned. This call reports to stderr any valid cdrecord options which are not implemented yet. @param flag Bitfield for control purposes: bit0= do not finalize setup bit1= do not interpret (again) skin->preskin->pre_argv @return <=0 error, 1 success */ int Cdrskin_setup(struct CdrskiN *skin, int argc, char **argv, int flag) { int i,k,l,ret, idx= -1, cd_start_tno; double value,grab_and_wait_value= -1.0, num; char *cpt,*value_pt,adr[Cdrskin_adrleN],*blank_mode= "", *argpt; struct stat stbuf; /* cdrecord 2.01 options which are not scheduled for implementation, yet */ static char ignored_partial_options[][41]= { "timeout=", "debug=", "kdebug=", "kd=", "driver=", "ts=", "pregap=", "defpregap=", "pktsize=", "" }; static char ignored_full_options[][41]= { "-d", "-silent", "-s", "-setdropts", "-prcap", "-reset", "-abort", "-overburn", "-ignsize", "-useinfo", "-fix", "-nofix", "-raw", "-raw96p", "-raw16", "-raw96r", "-clone", "-cdi", "-shorttrack", "-noshorttrack", "-packet", "-noclose", "" }; /* are we pretending to be cdrecord ? */ cpt= strrchr(argv[0],'/'); if(cpt==NULL) cpt= argv[0]; else cpt++; if(strcmp(cpt,"cdrecord")==0 && !(flag&1)) { fprintf(stderr,"\n"); fprintf(stderr, "Note: This is not cdrecord by Joerg Schilling. Do not bother him.\n"); fprintf(stderr, " See cdrskin start message on stdout. See --help. See -version.\n"); fprintf(stderr,"\n"); /* allow automatic -tao to -sao redirection */ skin->tao_to_sao_tsize=650*1024*1024; } #ifndef Cdrskin_extra_leaN if(!(flag&2)) { if(skin->preskin->pre_argc>1) { ret= Cdrskin_setup(skin,skin->preskin->pre_argc,skin->preskin->pre_argv, flag|1|2); if(ret<=0) return(ret); } } #endif for (i= 1;i 3) argpt++; /* is this a known option which is not planned to be implemented ? */ /* such an option will not be accepted as data source */ for(k=0;ignored_partial_options[k][0]!=0;k++) { if(argpt[0]=='-') if(strncmp(argpt+1,ignored_partial_options[k], strlen(ignored_partial_options[k]))==0) goto no_volunteer; if(strncmp(argpt,ignored_partial_options[k], strlen(ignored_partial_options[k]))==0) goto no_volunteer; } for(k=0;ignored_full_options[k][0]!=0;k++) if(strcmp(argpt,ignored_full_options[k])==0) goto no_volunteer; if(0) { no_volunteer:; skin->preskin->demands_cdrecord_caps= 1; if(skin->preskin->fallback_program[0]) fprintf(stderr,"cdrskin: NOTE : Unimplemented option: '%s'\n",argpt); else fprintf(stderr,"cdrskin: NOTE : ignoring unimplemented option : '%s'\n", argpt); fprintf(stderr, "cdrskin: NOTE : option is waiting for a volunteer to implement it.\n"); continue; } #ifndef Cdrskin_extra_leaN if(strncmp(argv[i],"abort_after_bytecount=",22)==0) { skin->abort_after_bytecount= Scanf_io_size(argv[i]+22,0); fprintf(stderr, "cdrskin: NOTE : will perform synthetic abort after %.f bytes\n", skin->abort_after_bytecount); } else if(strcmp(argv[i],"--abort_handler")==0) { #else /* ! Cdrskin_extra_leaN */ if(strcmp(argv[i],"--abort_handler")==0) { #endif /* is handled in Cdrpreskin_setup() */; } else if(strncmp(argv[i],"-abort_max_wait=",16)==0) { value_pt= argv[i]+16; goto set_abort_max_wait; } else if(strncmp(argv[i],"abort_max_wait=",15)==0) { value_pt= argv[i]+15; set_abort_max_wait:; value= Scanf_io_size(value_pt,0); if(value<0 || value>86400) { fprintf(stderr, "cdrskin: NOTE : ignored out-of-range value: abort_max_wait=%s\n", value_pt); } else { skin->abort_max_wait= value; if(skin->verbosity>=Cdrskin_verbose_cmD) printf( "cdrskin: maximum waiting time with abort handling : %d seconds\n", skin->abort_max_wait); } } else if(strcmp(argv[i],"--adjust_speed_to_drive")==0) { skin->adjust_speed_to_drive= 1; } else if(strcmp(argv[i],"--allow_emulated_drives")==0) { /* is handled in Cdrpreskin_setup() */; } else if(strcmp(argv[i],"--allow_setuid")==0) { /* is handled in Cdrpreskin_setup() */; } else if(strcmp(argv[i],"--allow_untested_media")==0) { /* is handled in Cdrpreskin_setup() */; } else if(strcmp(argv[i],"--any_track")==0) { skin->single_track= -1; if(skin->verbosity>=Cdrskin_verbose_cmD) ClN(printf( "cdrskin: --any_track : will accept any unknown option as track source\n")); } else if(strncmp(argv[i],"assert_write_lba=",17)==0) { value_pt= argv[i]+17; value= Scanf_io_size(value_pt,0); l= strlen(value_pt); if(l>1) if(isalpha(value_pt[l-1])) value/= 2048.0; skin->assert_write_lba= value; } else if(strcmp(argpt,"-atip")==0) { if(skin->do_atip<1) skin->do_atip= 1; if(skin->verbosity>=Cdrskin_verbose_cmD) ClN(printf("cdrskin: will put out some -atip style lines\n")); } else if(strcmp(argpt,"-audio")==0) { skin->track_type= BURN_AUDIO; skin->track_type_by_default= 0; } else if(strncmp(argpt,"-blank=",7)==0) { cpt= argpt + 7; goto set_blank; } else if(strncmp(argpt,"blank=",6)==0) { cpt= argpt + 6; set_blank:; skin->blank_format_type= 0; blank_mode= cpt; if(strcmp(cpt,"all")==0 || strcmp(cpt,"disc")==0 || strcmp(cpt,"disk")==0) { skin->do_blank= 1; skin->blank_fast= 0; blank_mode= "all"; } else if(strcmp(cpt,"fast")==0 || strcmp(cpt,"minimal")==0) { skin->do_blank= 1; skin->blank_fast= 1; blank_mode= "fast"; } else if(strcmp(cpt,"format_if_needed")==0) { skin->do_blank= 1; skin->blank_format_type= 6; skin->preskin->demands_cdrskin_caps= 1; } else if(strcmp(cpt,"format_overwrite")==0) { skin->do_blank= 1; skin->blank_format_type= 1|(1<<8); skin->blank_format_size= 128*1024*1024; skin->preskin->demands_cdrskin_caps= 1; } else if(strcmp(cpt,"format_overwrite_full")==0) { skin->do_blank= 1; skin->blank_format_type= 1|(1<<10); skin->blank_format_size= 0; skin->preskin->demands_cdrskin_caps= 1; } else if(strcmp(cpt,"format_overwrite_quickest")==0) { skin->do_blank= 1; skin->blank_format_type= 1; skin->blank_format_size= 0; skin->preskin->demands_cdrskin_caps= 1; } else if(strncmp(cpt,"format_defectmgt",16)==0) { skin->do_blank= 1; skin->blank_format_type= 4|(3<<9); /* default payload size */ skin->blank_format_size= 0; skin->preskin->demands_cdrskin_caps= 1; if(cpt[16]=='_') { cpt+= 17; if(strcmp(cpt,"none")==0) skin->blank_format_type= 4|(1<<13); else if(strcmp(cpt,"max")==0) skin->blank_format_type= 4; /* smallest payload size above 0 */ else if(strcmp(cpt,"min")==0) skin->blank_format_type= 4|(2<<9); /*largest payload size with mgt*/ else if(strncmp(cpt,"payload_",8)==0) { skin->blank_format_size= Scanf_io_size(cpt+8,0); skin->blank_format_type= 4; } else if(strcmp(cpt,"cert_off")==0) skin->blank_format_no_certify= 1; else if(strcmp(cpt,"cert_on")==0) skin->blank_format_no_certify= 0; else goto unsupported_blank_option; } skin->preskin->demands_cdrskin_caps= 1; } else if(strncmp(cpt,"format_by_index_",16)==0) { sscanf(cpt+16, "%d", &idx); if(idx<0 || idx>255) { fprintf(stderr,"cdrskin: SORRY : blank=%s provides unusable index\n", cpt); return(0); } skin->do_blank= 1; skin->blank_format_type= 5|(2<<9)|(1<<15); skin->blank_format_index= idx; skin->blank_format_size= 0; skin->preskin->demands_cdrskin_caps= 1; } else if(strcmp(cpt,"deformat_sequential")==0) { skin->do_blank= 1; skin->blank_format_type= 2; skin->blank_fast= 0; skin->preskin->demands_cdrskin_caps= 1; } else if(strcmp(cpt,"deformat_sequential_quickest")==0) { skin->do_blank= 1; skin->blank_format_type= 2; skin->blank_fast= 1; skin->preskin->demands_cdrskin_caps= 1; } else if(strcmp(cpt,"as_needed")==0) { skin->do_blank= 1; skin->blank_format_type= 7; } else if(strcmp(cpt,"help")==0) { /* is handled in Cdrpreskin_setup() */; continue; } else { unsupported_blank_option:; fprintf(stderr,"cdrskin: FATAL : Blank option '%s' not supported yet\n", cpt); return(0); } if(skin->verbosity>=Cdrskin_verbose_cmD) ClN(printf("cdrskin: blank mode : blank=%s\n",blank_mode)); } else if(strcmp(argv[i],"--bragg_with_audio")==0) { /* OBSOLETE 0.2.3 : was handled in Cdrpreskin_setup() */; } else if(strncmp(argv[i], "-cd_start_tno=", 14) == 0) { value_pt= argv[i] + 14; goto set_cd_start_tno; } else if(strncmp(argv[i], "cd_start_tno=", 13) == 0) { value_pt= argv[i] + 13; set_cd_start_tno:; cd_start_tno= -1; sscanf(value_pt, "%d", &cd_start_tno); if(cd_start_tno < 1 || cd_start_tno > 99) { fprintf(stderr, "cdrskin: FATAL : cd_start_tno= gives a number outside [1 ... 99]\n"); return(0); } skin->cd_start_tno= cd_start_tno; } else if(strcmp(argv[i],"--cdtext_dummy")==0) { skin->cdtext_test= 2; } else if(strncmp(argv[i], "-cdtext_to_textfile=", 20) == 0) { value_pt= argv[i] + 20; goto set_cdtext_to_textfile; } else if(strncmp(argv[i], "cdtext_to_textfile=", 19) == 0) { value_pt= argv[i] + 19; set_cdtext_to_textfile:; if(strlen(value_pt) >= sizeof(skin->cdtext_to_textfile_path)) { fprintf(stderr, "cdrskin: FATAL : cdtext_to_textfile=... too long. (max: %d, given: %d)\n", (int) sizeof(skin->cdtext_to_textfile_path)-1,(int) strlen(value_pt)); return(0); } skin->do_cdtext_to_textfile= 1; strcpy(skin->cdtext_to_textfile_path, value_pt); } else if(strncmp(argv[i], "-cdtext_to_v07t=", 16) == 0) { value_pt= argv[i] + 16; goto set_cdtext_to_v07t; } else if(strncmp(argv[i], "cdtext_to_v07t=", 15) == 0) { value_pt= argv[i] + 15; set_cdtext_to_v07t:; if(strlen(value_pt) >= sizeof(skin->cdtext_to_vt07_path)) { fprintf(stderr, "cdrskin: FATAL : cdtext_to_vt07=... too long. (max: %d, given: %d)\n", (int) sizeof(skin->cdtext_to_vt07_path)-1,(int) strlen(value_pt)); return(0); } skin->do_cdtext_to_vt07= 1; strcpy(skin->cdtext_to_vt07_path, value_pt); } else if(strcmp(argv[i],"--cdtext_verbose")==0) { skin->cdtext_test= 1; } else if(strcmp(argpt,"-checkdrive")==0) { skin->do_checkdrive= 1; } else if(strcmp(argpt,"-copy")==0) { skin->track_modemods|= BURN_COPY; skin->track_modemods&= ~BURN_SCMS; } else if(strncmp(argpt, "-cuefile=", 9)==0) { value_pt= argpt + 9; goto set_cuefile; } else if(strncmp(argpt, "cuefile=", 8)==0) { value_pt= argpt + 8; set_cuefile:; if(strlen(value_pt) >= sizeof(skin->cuefile)) { fprintf(stderr, "cdrskin: FATAL : cuefile=... too long. (max: %d, given: %d)\n", (int) sizeof(skin->cuefile) - 1, (int) strlen(value_pt)); return(0); } strcpy(skin->cuefile, value_pt); skin->do_burn= 1; } else if(strcmp(argpt,"-data")==0) { option_data:; /* All Subsequent Tracks Option */ skin->cdxa_conversion= (skin->cdxa_conversion & ~0x7fffffff) | 0; skin->track_type= BURN_MODE1; skin->track_type_by_default= 0; } else if(strcmp(argv[i],"--demand_a_drive")==0) { /* is handled in Cdrpreskin_setup() */; } else if(strcmp(argv[i],"--devices")==0) { skin->do_devices= 1; } else if(strcmp(argv[i],"--device_links")==0) { skin->do_devices= 2; #ifndef Cdrskin_extra_leaN } else if(strncmp(argv[i],"dev_translation=",16)==0) { if(argv[i][16]==0) { fprintf(stderr, "cdrskin: FATAL : dev_translation= : missing separator character\n"); return(0); } ret= Cdradrtrn_add(skin->adr_trn,argv[i]+17,argv[i]+16,1); if(ret==-2) fprintf(stderr, "cdrskin: FATAL : address_translation= : cannot allocate memory\n"); else if(ret==-1) fprintf(stderr, "cdrskin: FATAL : address_translation= : table full (%d items)\n", Cdradrtrn_leN); else if(ret==0) fprintf(stderr, "cdrskin: FATAL : address_translation= : no address separator '%c' found\n", argv[i][17]); if(ret<=0) return(0); #endif /* ! Cdrskin_extra_leaN */ } else if(strncmp(argpt,"-dev=",5)==0) { /* is handled in Cdrpreskin_setup() */; } else if(strncmp(argpt,"dev=",4)==0) { /* is handled in Cdrpreskin_setup() */; } else if(strncmp(argv[i],"direct_write_amount=",20)==0) { skin->direct_write_amount= Scanf_io_size(argv[i]+20,0); if(skin->verbosity>=Cdrskin_verbose_cmD) ClN(printf("cdrskin: amount for direct writing : %.f\n", skin->direct_write_amount)); if(skin->direct_write_amount>=0.0) { skin->do_direct_write= 1; printf("cdrskin: NOTE : Direct writing will only use first track source and no fifo.\n"); skin->preskin->demands_cdrskin_caps= 1; } else skin->do_direct_write= 0; } else if(strcmp(argv[i],"--drive_abort_on_busy")==0) { /* is handled in Cdrpreskin_setup() */; } else if(strcmp(argv[i],"--drive_blocking")==0) { /* is handled in Cdrpreskin_setup() */; } else if(strcmp(argv[i],"--drive_not_exclusive")==0 || strcmp(argv[i],"--drive_not_f_setlk")==0 || strcmp(argv[i],"--drive_not_o_excl")==0) { /* is handled in Cdrpreskin_setup() */; } else if(strncmp(argv[i],"drive_scsi_dev_family=",22)==0) { /* is handled in Cdrpreskin_setup() */; if(skin->verbosity>=Cdrskin_verbose_debuG && skin->preskin->drive_scsi_dev_family!=0) ClN(fprintf(stderr,"cdrskin_debug: drive_scsi_dev_family= %d\n", skin->preskin->drive_scsi_dev_family)); } else if(strcmp(argv[i],"--drive_scsi_exclusive")==0) { /* is handled in Cdrpreskin_setup() */; } else if(strncmp(argpt, "-driveropts=", 12)==0) { value_pt= argpt + 12; goto set_driveropts; } else if(strncmp(argpt, "driveropts=", 11)==0) { value_pt= argpt + 11; set_driveropts:; if(strcmp(value_pt,"burnfree")==0 || strcmp(value_pt,"burnproof")==0) { skin->burnfree= 1; if(skin->verbosity>=Cdrskin_verbose_cmD) ClN(printf("cdrskin: burnfree : on\n")); } else if(strcmp(argpt+11,"noburnfree")==0 || strcmp(argpt+11,"noburnproof")==0 ) { skin->burnfree= 0; if(skin->verbosity>=Cdrskin_verbose_cmD) ClN(printf("cdrskin: burnfree : off\n")); } else if(strcmp(argpt+11,"help")==0) { /* handled in Cdrpreskin_setup() */; } else goto ignore_unknown; } else if(strcmp(argpt,"-dummy")==0) { skin->dummy_mode= 1; } else if(strncmp(argv[i], "-dvd_obs=", 9)==0) { value_pt= argv[i] + 9; goto dvd_obs; } else if(strncmp(argv[i], "dvd_obs=", 8)==0) { value_pt= argv[i] + 8; dvd_obs:; if(strcmp(value_pt, "default") == 0) num= 0; else num = Scanf_io_size(value_pt,0); if(num != 0 && num != 32768 && num != 65536) { fprintf(stderr, "cdrskin: SORRY : Option dvd_obs= accepts only sizes 0, 32k, 64k\n"); } else skin->dvd_obs= num; } else if(strcmp(argpt,"-eject")==0) { skin->do_eject= 1; if(skin->verbosity>=Cdrskin_verbose_cmD) ClN(printf("cdrskin: eject after work : on\n")); } else if(strncmp(argv[i],"eject_device=",13)==0) { if(strlen(argv[i]+13)>=sizeof(skin->eject_device)) { fprintf(stderr, "cdrskin: FATAL : eject_device=... too long. (max: %d, given: %d)\n", (int) sizeof(skin->eject_device)-1,(int) strlen(argv[i]+13)); return(0); } strcpy(skin->eject_device,argv[i]+13); if(skin->verbosity>=Cdrskin_verbose_cmD) ClN(printf("cdrskin: ignoring obsolete eject_device=%s\n", skin->eject_device)); } else if(strncmp(argv[i],"-extract_audio_to=", 18)==0) { value_pt= argpt + 18; goto extract_audio_to; } else if(strncmp(argpt, "extract_audio_to=", 17) == 0) { value_pt= argpt + 17; extract_audio_to:; if(strlen(value_pt) >= sizeof(skin->extract_audio_dir)) { fprintf(stderr, "cdrskin: FAILURE : extract_audio_to=... is much too long.\n"); return(0); } skin->do_extract_audio= 1; strcpy(skin->extract_audio_dir, value_pt); } else if(strncmp(argv[i],"-extract_tracks=", 16)==0) { value_pt= argpt + 16; goto extract_tracks; } else if(strncmp(argpt, "extract_tracks=", 15) == 0) { value_pt= argpt + 15; extract_tracks:; value= 0.0; for(cpt= value_pt; ; cpt++) { if(*cpt >= '0' && *cpt <= '9') { value= value * 10 + *cpt - '0'; } else { if(value >= 1.0 && value <= 99.0) { skin->extract_audio_tracks[(int) value]= 1; if(skin->verbosity >= Cdrskin_verbose_cmD) fprintf(stderr, "cdrskin: Will extract track number %.f\n", value); } else { fprintf(stderr, "cdrskin: WARNING : extract_tracks= with unsuitable number: %.f\n", value); } if(*cpt == 0) break; value= 0; } } } else if(strncmp(argv[i],"-extract_basename=", 18)==0) { value_pt= argpt + 18; goto extract_basename; } else if(strncmp(argpt, "extract_basename=", 17) == 0) { value_pt= argpt + 17; extract_basename:; if(strchr(value_pt, '/') != NULL) { fprintf(stderr, "cdrskin: FAILURE : extract_basename=... may not contain '/'\n"); return(0); } if(strlen(value_pt) > 248) { fprintf(stderr, "cdrskin: FAILURE : Oversized extract_basename=... (Max. 248)\n"); return(0); } strcpy(skin->extract_basename, value_pt); } else if(strcmp(argv[i],"--extract_dap") == 0) { skin->extract_flags|= 8; #ifndef Cdrskin_extra_leaN } else if(strcmp(argv[i],"--fifo_disable")==0) { skin->fifo_enabled= 0; skin->fifo_size= 0; if(skin->verbosity>=Cdrskin_verbose_cmD) ClN(printf("cdrskin: option fs=... disabled\n")); } else if(strcmp(argv[i],"--fifo_start_empty")==0) { /* obsoleted */ skin->fifo_start_at= 0; } else if(strncmp(argv[i],"fifo_start_at=",14)==0) { value= Scanf_io_size(argv[i]+14,0); if(value>1024.0*1024.0*1024.0) value= 1024.0*1024.0*1024.0; else if(value<0) value= 0; skin->fifo_start_at= value; } else if(strcmp(argv[i],"--fifo_per_track")==0) { skin->fifo_per_track= 1; #endif /* ! Cdrskin_extra_leaN */ } else if(strcmp(argv[i],"--fill_up_media")==0) { skin->fill_up_media= 1; if(skin->verbosity>=Cdrskin_verbose_cmD) ClN(printf( "cdrskin: will fill up last track to full free media space\n")); } else if(strcmp(argpt,"-force")==0) { skin->force_is_set= 1; } else if(strcmp(argpt,"-format")==0) { skin->do_blank= 1; skin->blank_format_type= 3|(1<<10); skin->blank_format_size= 0; skin->force_is_set= 1; if(skin->verbosity>=Cdrskin_verbose_cmD) ClN(printf( "cdrskin: will format DVD+RW by blank=format_overwrite_full -force\n")); } else if(strcmp(argv[i],"--four_channel")==0) { skin->track_modemods|= BURN_4CH; #ifndef Cdrskin_extra_leaN } else if(strncmp(argpt, "-fs=", 4) == 0) { value_pt= argpt + 4; goto fs_equals; } else if(strncmp(argpt, "fs=", 3) == 0) { value_pt= argpt + 3; fs_equals:; if(skin->fifo_enabled) { value= Scanf_io_size(value_pt,0); if(value<0.0 || value>1024.0*1024.0*1024.0) { fprintf(stderr, "cdrskin: FATAL : fs=N expects a size between 0 and 1g\n"); return(0); } skin->fifo_size= value; if(skin->verbosity>=Cdrskin_verbose_cmD) printf("cdrskin: fifo size : %d\n",skin->fifo_size); } } else if(strncmp(argv[i],"grab_drive_and_wait=",20)==0) { value_pt= argv[i]+20; grab_and_wait_value= Scanf_io_size(value_pt,0); skin->preskin->demands_cdrskin_caps= 1; } else if(strncmp(argpt, "-gracetime=", 11) == 0) { value_pt= argpt + 11; goto gracetime_equals; } else if(strncmp(argpt, "gracetime=", 10) == 0) { value_pt= argpt + 10; gracetime_equals:; sscanf(value_pt,"%d",&(skin->gracetime)); } else if(strncmp(argv[i],"--grow_overwriteable_iso",24)==0) { skin->grow_overwriteable_iso= 1; skin->use_data_image_size= 1; skin->preskin->demands_cdrskin_caps= 1; #else /* ! Cdrskin_extra_leaN */ } else if( strcmp(argv[i],"--fifo_disable")==0 || strcmp(argv[i],"--fifo_start_empty")==0 || strncmp(argv[i],"fifo_start_at=",14)==0 || strcmp(argv[i],"--fifo_per_track")==0 || strncmp(argv[i],"-fs=",4)==0 || strncmp(argv[i],"fs=",3)==0 || strncmp(argv[i],"-gracetime=",11)==0 || strncmp(argv[i],"gracetime=",10)==0) { fprintf(stderr, "cdrskin: NOTE : lean version ignores option: '%s'\n", argv[i]); #endif /* Cdrskin_extra_leaN */ } else if(strcmp(argv[i],"--help")==0) { /* is handled in Cdrpreskin_setup() */; } else if(strcmp(argv[i],"-help")==0) { /* is handled in Cdrpreskin_setup() */; } else if(strcmp(argv[i],"--ignore_signals")==0) { /* is handled in Cdrpreskin_setup() */; } else if(strcmp(argpt,"-immed")==0) { skin->modesty_on_drive= 1; skin->min_buffer_percent= 75; skin->max_buffer_percent= 95; } else if(strncmp(argpt, "-index=", 7) == 0) { value_pt= argpt + 7; goto set_index; } else if(strncmp(argpt, "index=", 6) == 0) { value_pt= argpt + 6; set_index:; if(skin->index_string != NULL) free(skin->index_string); skin->index_string= strdup(value_pt); if(skin->index_string == NULL) { fprintf(stderr, "cdrskin: FATAL : Out of memory\n"); return(-1); } } else if(strncmp(argv[i], "input_sheet_v07t=", 17)==0) { if(skin->sheet_v07t_blocks >= 8) { fprintf(stderr, "cdrskin: SORRY : Too many input_sheet_v07t= options. (Max. 8)\n"); return(0); } if(argv[i][17] == 0) { fprintf(stderr, "cdrskin: SORRY : Missing file path after option input_sheet_v07t=\n"); return(0); } if(strlen(argv[i] + 17) > Cdrskin_adrleN) { fprintf(stderr, "cdrskin: SORRY : File path too long after option input_sheet_v07t=\n"); return(0); } strcpy(skin->sheet_v07t_paths[skin->sheet_v07t_blocks], argv[i] + 17); skin->sheet_v07t_blocks++; skin->preskin->demands_cdrskin_caps= 1; } else if(strcmp(argpt,"-inq")==0) { skin->do_checkdrive= 2; } else if(strcmp(argpt,"-isosize")==0) { skin->use_data_image_size= 1; } else if(strncmp(argpt, "-isrc=", 6) == 0) { value_pt= argpt + 6; goto set_isrc; } else if(strncmp(argpt, "isrc=", 5) == 0) { value_pt= argpt + 5; set_isrc:; if(strlen(value_pt) != 12) { fprintf(stderr, "cdrskin: SORRY : isrc=... is not exactly 12 characters long.\n"); return(0); } memcpy(skin->next_isrc, value_pt, 13); } else if(strcmp(argv[i],"--list_formats")==0) { skin->do_list_formats= 1; skin->preskin->demands_cdrskin_caps= 1; } else if(strcmp(argv[i],"--list_ignored_options")==0) { /* is also handled in Cdrpreskin_setup() */; printf("cdrskin: List of all ignored options:\n"); for(k=0;ignored_partial_options[k][0]!=0;k++) printf("%s\n",ignored_partial_options[k]); for(k=0;ignored_full_options[k][0]!=0;k++) printf("%s\n",ignored_full_options[k]); printf("\n"); } else if(strcmp(argv[i],"--list_speeds")==0) { skin->do_list_speeds= 1; skin->preskin->demands_cdrskin_caps= 1; } else if(strncmp(argv[i],"fallback_program=",17)==0) { /* is handled in Cdrpreskin_setup() */; } else if(strcmp(argpt,"-load")==0) { skin->do_load= 1; } else if(strcmp(argpt,"-lock")==0) { skin->do_load= 2; } else if(strcmp(argv[i],"--long_toc")==0) { skin->do_atip= 3; if(skin->verbosity>=Cdrskin_verbose_cmD) ClN(printf("cdrskin: will put out some -atip style lines plus -toc\n")); } else if(strncmp(argpt,"-mcn=", 5) == 0) { value_pt= argpt + 5; goto set_mcn; } else if(strncmp(argpt,"mcn=", 4) == 0) { value_pt= argpt + 4; set_mcn:; if(strlen(value_pt) != 13) { fprintf(stderr, "cdrskin: SORRY : mcn=... is not exactly 13 characters long.\n"); return(0); } memcpy(skin->mcn, value_pt, 14); } else if(strncmp(argpt, "-minbuf=", 8) == 0) { value_pt= argpt + 8; goto minbuf_equals; } else if(strncmp(argpt, "minbuf=", 7) == 0) { value_pt= argpt + 7; minbuf_equals:; skin->modesty_on_drive= 1; sscanf(value_pt,"%lf",&value); if (value<25 || value>95) { fprintf(stderr, "cdrskin: FATAL : minbuf= value must be between 25 and 95\n"); return(0); } skin->min_buffer_percent= value; skin->max_buffer_percent= 95; ClN(printf("cdrskin: minbuf=%d percent desired buffer fill\n", skin->min_buffer_percent)); } else if(strcmp(argpt,"-minfo") == 0 || strcmp(argpt,"-media-info") == 0) { skin->do_atip= 4; } else if(strcmp(argpt, "-mode2") == 0) { fprintf(stderr, "cdrskin: NOTE : defaulting option -mode2 to option -data\n"); goto option_data; } else if(strncmp(argv[i],"modesty_on_drive=",17)==0) { value_pt= argv[i]+17; if(*value_pt == '0' || strncmp(value_pt, "off", 3) == 0) { skin->modesty_on_drive= 0; if(skin->verbosity>=Cdrskin_verbose_cmD) ClN(printf( "cdrskin: modesty_on_drive=0 : buffer waiting by os driver\n")); } else if(*value_pt=='1' || strncmp(value_pt, "on", 2) == 0) { skin->modesty_on_drive= 1; if(skin->verbosity>=Cdrskin_verbose_cmD) ClN(printf( "cdrskin: modesty_on_drive=1 : buffer waiting by libburn\n")); } else if(*value_pt=='-' && argv[i][18]=='1') { skin->modesty_on_drive= -1; if(skin->verbosity>=Cdrskin_verbose_cmD) ClN(printf( "cdrskin: modesty_on_drive=-1 : buffer waiting as libburn defaults\n")); } else { fprintf(stderr, "cdrskin: FATAL : modesty_on_drive= must be -1, 0 or 1\n"); return(0); } while(1) { value_pt= strchr(value_pt,':'); if(value_pt==NULL) break; value_pt++; if(strncmp(value_pt,"min_percent=",12)==0) { sscanf(value_pt+12,"%lf",&value); if (value<25 || value>100) { fprintf(stderr, "cdrskin: FATAL : modest_on_drive= min_percent value must be between 25 and 100\n"); return(0); } skin->min_buffer_percent= value; if(skin->verbosity >= Cdrskin_verbose_cmD) ClN(printf( "cdrskin: modesty_on_drive : %d percent min buffer fill\n", skin->min_buffer_percent)); } else if(strncmp(value_pt,"max_percent=",12)==0) { sscanf(value_pt+12,"%lf",&value); if (value<25 || value>100) { fprintf(stderr, "cdrskin: FATAL : modest_on_drive= max_percent value must be between 25 and 100\n"); return(0); } skin->max_buffer_percent= value; if(skin->verbosity >= Cdrskin_verbose_cmD) ClN(printf( "cdrskin: modesty_on_drive : %d percent max buffer fill\n", skin->max_buffer_percent)); } else if(strncmp(value_pt, "min_usec=", 9) == 0) { sscanf(value_pt + 9, "%lf", &value); if(value < 0) value= 0; skin->min_buffer_usec= value; if(skin->verbosity >= Cdrskin_verbose_cmD) ClN(printf( "cdrskin: modesty_on_drive : %d microseconds minimum sleep time\n", skin->min_buffer_usec)); } else if(strncmp(value_pt,"max_usec=", 9)==0) { sscanf(value_pt + 9, "%lf", &value); if(value < 0) value= 0; skin->max_buffer_usec= value; if(skin->verbosity >= Cdrskin_verbose_cmD) ClN(printf( "cdrskin: modesty_on_drive : %d microseconds maximum sleep time\n", skin->max_buffer_usec)); } else if(strncmp(value_pt,"timeout_sec=", 12)==0) { sscanf(value_pt + 9, "%lf", &value); if(value < 0) value= 0; skin->buffer_timeout_sec= value; if(skin->verbosity >= Cdrskin_verbose_cmD) ClN(printf( "cdrskin: modesty_on_drive : %d seconds fallback timeout\n", skin->max_buffer_usec)); } else { fprintf(stderr, "cdrskin: SORRY : modest_on_drive= unknown option code : %s\n", value_pt); } } skin->preskin->demands_cdrskin_caps= 1; } else if(strcmp(argpt,"-multi")==0) { skin->multi= 1; } else if(strncmp(argpt, "-msifile=", 9) == 0) { value_pt= argpt + 9; goto msifile_equals; } else if(strncmp(argpt, "msifile=", 8) == 0) { value_pt= argpt + 8; msifile_equals:; if(strlen(value_pt)>=sizeof(skin->msifile)) { fprintf(stderr, "cdrskin: FATAL : msifile=... too long. (max: %d, given: %d)\n", (int) sizeof(skin->msifile)-1,(int) strlen(value_pt)); return(0); } strcpy(skin->msifile, value_pt); skin->do_msinfo= 1; } else if(strcmp(argpt,"-msinfo")==0) { skin->do_msinfo= 1; #ifdef Libburn_develop_quality_scaN } else if(strcmp(argv[i],"--nec_optiarc_qcheck")==0) { skin->do_qcheck= 1; #endif /* Libburn_develop_quality_scaN */ } else if(strcmp(argv[i],"--no_abort_handler")==0) { /* is handled in Cdrpreskin_setup() */; } else if(strcmp(argv[i],"--no_blank_appendable")==0) { skin->no_blank_appendable= 1; } else if(strcmp(argv[i],"--no_convert_fs_adr")==0) { /* is handled in Cdrpreskin_setup() */; } else if(strcmp(argv[i],"--no_load")==0) { skin->do_load= -1; } else if(strcmp(argv[i],"--no_rc")==0) { /* is handled in Cdrpreskin_setup() */; } else if(strcmp(argpt,"-nocopy")==0) { skin->track_modemods&= ~BURN_COPY; } else if(strcmp(argpt,"-nopad")==0) { skin->padding= 0.0; if(skin->verbosity>=Cdrskin_verbose_cmD) ClN(printf("cdrskin: padding : off\n")); } else if(strcmp(argpt,"-nopreemp")==0) { skin->track_modemods&= ~BURN_PREEMPHASIS; } else if(strcmp(argv[i],"--obs_pad")==0) { skin->obs_pad= 1; } else if(strcmp(argv[i],"--old_pseudo_scsi_adr")==0) { /* is handled in Cdrpreskin_setup() */; } else if(strcmp(argv[i], "--pacifier_with_newline") == 0) { skin->pacifier_with_newline= 1; } else if(strcmp(argpt,"-pad")==0) { skin->padding= 15*2048; skin->set_by_padsize= 0; if(skin->verbosity>=Cdrskin_verbose_cmD) ClN(printf("cdrskin: padding : %.f\n",skin->padding)); } else if(strncmp(argpt, "-padsize=", 9) == 0) { value_pt= argpt + 9; goto set_padsize; } else if(strncmp(argpt, "padsize=", 8) == 0) { value_pt= argpt + 8; set_padsize:; skin->padding= Scanf_io_size(value_pt, 0); skin->set_by_padsize= 1; if(skin->verbosity>=Cdrskin_verbose_cmD) ClN(printf("cdrskin: padding : %.f\n",skin->padding)); } else if(strcmp(argpt,"-preemp")==0) { skin->track_modemods|= BURN_PREEMPHASIS; } else if(strcmp(argv[i],"--prodvd_cli_compatible")==0) { skin->prodvd_cli_compatible= 1; } else if(strcmp(argpt,"-sao")==0 || strcmp(argpt,"-dao")==0) { /* is handled in Cdrpreskin_setup() */; } else if(strcmp(argpt,"-scanbus")==0) { skin->do_scanbus= 1; } else if(strcmp(argpt,"-scms")==0) { skin->track_modemods|= BURN_SCMS; } else if(strcmp(argv[i],"--single_track")==0) { skin->single_track= 1; if(skin->verbosity>=Cdrskin_verbose_cmD) ClN(printf( "cdrskin: --single_track : will only accept last argument as track source\n")); skin->preskin->demands_cdrskin_caps= 1; } else if(strncmp(argv[i], "-sao_postgap=", 13) == 0) { value_pt= argv[i] + 13; goto set_sao_postgap; } else if(strncmp(argv[i], "sao_postgap=", 12) == 0) { value_pt= argv[i] + 12; set_sao_postgap:; skin->sao_postgap= -1; if(strcmp(value_pt, "off") == 0) skin->sao_postgap = -1; else sscanf(value_pt, "%d", &(skin->sao_postgap)); if(skin->sao_postgap < 0) { fprintf(stderr, "cdrskin: SORRY : sao_postgap must be \"off\" or a number >= 0\n"); return(0); } } else if(strncmp(argv[i], "-sao_pregap=", 12) == 0) { value_pt= argv[i] + 12; goto set_sao_pregap; } else if(strncmp(argv[i], "sao_pregap=", 11) == 0) { value_pt= argv[i] + 11; set_sao_pregap:; skin->sao_pregap= -1; if(strcmp(value_pt, "off") == 0) skin->sao_pregap = -1; else sscanf(value_pt, "%d", &(skin->sao_pregap)); if(skin->sao_pregap < 0) { fprintf(stderr, "cdrskin: SORRY : sao_pregap must be \"off\" or a number >= 0\n"); return(0); } } else if(strncmp(argpt, "-speed=", 7) == 0) { value_pt= argpt + 7; goto set_speed; } else if(strncmp(argpt, "speed=", 6) == 0) { value_pt= argpt + 6; set_speed:; if(strcmp(value_pt,"any")==0) skin->x_speed= -1; else sscanf(value_pt,"%lf",&(skin->x_speed)); if(skin->x_speed<1.0 && skin->x_speed!=0.0 && skin->x_speed!=-1) { fprintf(stderr,"cdrskin: FATAL : speed= must be -1, 0 or at least 1\n"); return(0); } if(skin->x_speed<0) skin->preskin->demands_cdrskin_caps= 1; /* >>> cdrecord speed=0 -> minimum speed , libburn -> maximum speed */; if(skin->verbosity>=Cdrskin_verbose_cmD) ClN(printf("cdrskin: speed : %f\n",skin->x_speed)); } else if(strncmp(argv[i], "-stdio_sync=", 12)==0) { value_pt= argv[i] + 12; goto stdio_sync; } else if(strncmp(argv[i], "stdio_sync=", 11)==0) { value_pt= argv[i] + 11; stdio_sync:; if(strcmp(value_pt, "default") == 0 || strcmp(value_pt, "on") == 0) num= 0; else if(strcmp(value_pt, "off") == 0) num= -1; else num = Scanf_io_size(value_pt,0); if(num > 0) num/= 2048; if(num != -1 && num != 0 && (num < 32 || num > 512 * 1024)) { fprintf(stderr, "cdrskin: SORRY : Option stdio_sync= accepts only sizes -1, 0, 32k ... 1g\n"); } else skin->stdio_sync= num; } else if(strncmp(argv[i],"-stream_recording=",18)==0) { value_pt= argv[i]+18; goto set_stream_recording; } else if(strncmp(argv[i],"stream_recording=",17)==0) { value_pt= argv[i]+17; set_stream_recording:; if(strcmp(value_pt, "on")==0) skin->stream_recording_is_set= 1; else if(value_pt[0] >= '0' && value_pt[0] <= '9') { num= Scanf_io_size(value_pt, 0); num/= 2048.0; if(num >= 16 && num <= 0x7FFFFFFF) skin->stream_recording_is_set= num; else skin->stream_recording_is_set= 0; } else skin->stream_recording_is_set= 0; } else if(strcmp(argpt,"-swab")==0) { skin->swap_audio_bytes= 0; } else if(strcmp(argpt,"-tao")==0) { /* is handled in Cdrpreskin_setup() */; } else if(strncmp(argv[i],"tao_to_sao_tsize=",17)==0) { skin->tao_to_sao_tsize= Scanf_io_size(argv[i]+17,0); if(skin->tao_to_sao_tsize>Cdrskin_tracksize_maX) goto track_too_large; skin->preskin->demands_cdrskin_caps= 1; #ifndef Cdrskin_extra_leaN if(skin->verbosity>=Cdrskin_verbose_cmD) printf("cdrskin: size default for non-tao write modes: %.f\n", skin->tao_to_sao_tsize); #endif /* ! Cdrskin_extra_leaN */ } else if(strcmp(argv[i],"--tell_media_space")==0) { skin->tell_media_space= 1; skin->preskin->demands_cdrskin_caps= 1; } else if(strcmp(argpt, "-text") == 0) { skin->use_cdtext= 1; } else if(strncmp(argpt, "-textfile=", 10) == 0) { value_pt= argpt + 10; goto set_textfile; } else if(strncmp(argpt ,"textfile=", 9) == 0) { value_pt= argpt + 9; set_textfile:; ret= Cdrskin_read_textfile(skin, value_pt, 0); if(ret <= 0) return(ret); } else if(strncmp(argpt, "-textfile_to_v07t=", 18) == 0) { value_pt= argpt + 18; goto textfile_to_v07t; } else if(strncmp(argpt ,"textfile_to_v07t=", 17) == 0) { value_pt= argpt + 17; textfile_to_v07t:; ret= Cdrskin_read_textfile(skin, value_pt, 0); if(ret <= 0) return(ret); ret= Cdrskin_print_text_packs(skin, skin->text_packs, skin->num_text_packs, (1 << 4) | 2); if(ret <= 0) return(ret); if(i != 1 || argc != 2) fprintf(stderr, "cdrskin: WARNING : Program run ended by option textfile_to_v07t=. Other options may have been ignored.\n"); return(2); } else if(strcmp(argpt,"-toc")==0) { skin->do_atip= 2; if(skin->verbosity>=Cdrskin_verbose_cmD) ClN(printf("cdrskin: will put out some -atip style lines plus -toc\n")); } else if(strncmp(argpt, "-tsize=", 7) == 0) { value_pt= argpt + 7; goto set_tsize; } else if(strncmp(argpt, "tsize=", 6) == 0) { value_pt= argpt + 6; set_tsize:; skin->fixed_size= Scanf_io_size(value_pt,0); if(skin->fixed_size>Cdrskin_tracksize_maX) { track_too_large:; fprintf(stderr,"cdrskin: FATAL : Track size too large\n"); return(0); } if(skin->verbosity>=Cdrskin_verbose_cmD) ClN(printf("cdrskin: fixed track size : %.f\n",skin->fixed_size)); if(skin->smallest_tsize<0 || skin->smallest_tsize>skin->fixed_size) skin->smallest_tsize= skin->fixed_size; } else if(strcmp(argv[i],"--two_channel")==0) { skin->track_modemods&= ~BURN_4CH; } else if(strcmp(argv[i],"-V")==0 || strcmp(argpt, "-Verbose")==0) { /* is handled in Cdrpreskin_setup() */; } else if(strcmp(argv[i],"-v")==0 || strcmp(argpt,"-verbose")==0) { /* is handled in Cdrpreskin_setup() */; } else if(strcmp(argv[i],"-vv")==0 || strcmp(argv[i],"-vvv")==0 || strcmp(argv[i],"-vvvv")==0) { /* is handled in Cdrpreskin_setup() */; } else if(strcmp(argpt,"-version")==0) { /* is handled in Cdrpreskin_setup() and should really not get here */; } else if(strcmp(argpt,"-waiti")==0) { /* is handled in Cdrpreskin_setup() */; } else if(strncmp(argv[i],"write_start_address=",20)==0) { skin->write_start_address= Scanf_io_size(argv[i]+20,0); if(skin->verbosity>=Cdrskin_verbose_cmD) ClN(printf("cdrskin: write start address : %.f\n", skin->write_start_address)); skin->preskin->demands_cdrskin_caps= 1; } else if(strcmp(argpt, "-xa") == 0) { fprintf(stderr,"cdrskin: NOTE : defaulting option -xa to option -data\n"); goto option_data; } else if(strcmp(argpt, "-xa1") == 0) { /* All Subsequent Tracks Option */ skin->cdxa_conversion= (skin->cdxa_conversion & ~0x7fffffff) | 1; skin->track_type= BURN_MODE1; skin->track_type_by_default= 0; } else if(strcmp(argpt, "-xa2") == 0) { fprintf(stderr, "cdrskin: NOTE : defaulting option -xa2 to option -data\n"); goto option_data; } else if(strcmp(argv[i], "--xa1-ignore") == 0) { skin->cdxa_conversion|= (1 << 31); } else if( i==argc-1 || (skin->single_track==0 && strchr(argv[i],'=')==NULL && !(argv[i][0]=='-' && argv[i][1]!=0) ) || (skin->single_track==-1)) { if(strlen(argv[i])>=sizeof(skin->source_path)) { fprintf(stderr, "cdrskin: FATAL : Source address too long. (max: %d, given: %d)\n", (int) sizeof(skin->source_path)-1,(int) strlen(argv[i])); return(0); } strcpy(skin->source_path,argv[i]); if(strcmp(skin->source_path,"-")==0) { if(skin->stdin_source_used) { fprintf(stderr, "cdrskin: FATAL : \"-\" (stdin) can be used as track source only once.\n"); return(0); } skin->stdin_source_used= 1; } else if(argv[i][0]=='#' && (argv[i][1]>='0' && argv[i][1]<='9')) { if(skin->preskin->allow_fd_source==0) { fprintf(stderr, "cdrskin: SORRY : '%s' is a reserved source path with cdrskin\n", argv[i]); fprintf(stderr, "cdrskin: SORRY : which would use an open file descriptor as source.\n"); fprintf(stderr, "cdrskin: SORRY : Its usage is dangerous and disabled for now.\n"); return(0); } } else { if(stat(skin->source_path,&stbuf)!=-1) { if((stbuf.st_mode&S_IFMT)==S_IFREG) ; else if((stbuf.st_mode&S_IFMT)==S_IFDIR) { fprintf(stderr, "cdrskin: FATAL : Source address is a directory: '%s'\n", skin->source_path); return(0); } } } if(skin->track_counter>=Cdrskin_track_maX) { fprintf(stderr,"cdrskin: FATAL : Too many tracks given. (max %d)\n", Cdrskin_track_maX); return(0); } ret= Cdrtrack_new(&(skin->tracklist[skin->track_counter]),skin, skin->track_counter, (strcmp(skin->source_path,"-")==0)<<1); if(ret<=0) { fprintf(stderr, "cdrskin: FATAL : Creation of track control object failed.\n"); return(ret); } if(skin->next_isrc[0]) memcpy(skin->tracklist[skin->track_counter]->isrc, skin->next_isrc, 13); skin->tracklist[skin->track_counter]->index_string= skin->index_string; skin->tracklist[skin->track_counter]->sao_pregap= skin->sao_pregap; skin->tracklist[skin->track_counter]->sao_postgap= skin->sao_postgap; skin->index_string= NULL; skin->sao_postgap= skin->sao_pregap= -1; skin->track_counter++; skin->use_data_image_size= 0; if(skin->verbosity>=Cdrskin_verbose_cmD) { if(strcmp(skin->source_path,"-")==0) printf("cdrskin: track %d data source : '-' (i.e. standard input)\n", skin->track_counter); else printf("cdrskin: track %d data source : '%s'\n", skin->track_counter,skin->source_path); } /* reset track options */ if(skin->set_by_padsize) skin->padding= 0; /* cdrecord-ProDVD-2.01b31 resets to 30k the man page says padsize= is reset to 0 Joerg Schilling will change in 2.01.01 to 0 */ skin->fixed_size= 0; skin->next_isrc[0]= 0; } else { ignore_unknown:; if(skin->preskin->fallback_program[0]) fprintf(stderr,"cdrskin: NOTE : Unknown option : '%s'\n",argv[i]); else fprintf(stderr,"cdrskin: NOTE : ignoring unknown option : '%s'\n", argv[i]); skin->preskin->demands_cdrecord_caps= 1; } } if(flag&1) /* no finalizing yet */ return(1); if(skin->preskin->fallback_program[0] && skin->preskin->demands_cdrecord_caps>0 && skin->preskin->demands_cdrskin_caps<=0) { fprintf(stderr,"cdrskin: NOTE : Unsupported options found.\n"); fprintf(stderr, "cdrskin: NOTE : Will delegate job to fallback program '%s'.\n", skin->preskin->fallback_program); return(0); } #ifndef Cdrskin_extra_leaN if(skin->verbosity>=Cdrskin_verbose_cmD) { if(skin->preskin->abort_handler==1) printf("cdrskin: installed abort handler.\n"); else if(skin->preskin->abort_handler==2) printf("cdrskin: will try to ignore any signals.\n"); else if(skin->preskin->abort_handler==3) printf("cdrskin: installed hard abort handler.\n"); else if(skin->preskin->abort_handler==4) printf("cdrskin: installed soft abort handler.\n"); else if(skin->preskin->abort_handler==-1) printf("cdrskin: will install abort handler in eventual burn loop.\n"); } #endif /* ! Cdrskin_extra_leaN */ if(strlen(skin->preskin->raw_device_adr)>0 || strlen(skin->preskin->device_adr)>0) { if(strlen(skin->preskin->device_adr)>0) cpt= skin->preskin->device_adr; else cpt= skin->preskin->raw_device_adr; if(strcmp(cpt,"ATA")!=0 && strcmp(cpt,"ATAPI")!=0 && strcmp(cpt,"SCSI")!=0){ ret= Cdrskin_dev_to_driveno(skin,cpt,&(skin->driveno),0); if(ret<=0) return(ret); if(skin->verbosity>=Cdrskin_verbose_cmD) { ret= burn_drive_get_adr(&(skin->drives[skin->driveno]), adr); if(ret<=0) adr[0]= 0; printf("cdrskin: active drive number : %d '%s'\n", skin->driveno,adr); } } } if(grab_and_wait_value>0) { Cdrskin_grab_drive(skin,16); for(k= 0; kpacifier_with_newline ? "" : "\r", k, skin->pacifier_with_newline ? "\n" : " "); usleep(1000000); } fprintf(stderr, "%scdrskin: held drive grabbed for %d seconds \n", skin->pacifier_with_newline ? "" : "\r", k); Cdrskin_release_drive(skin,0); } if(skin->track_counter>0) { skin->do_burn= 1; #ifndef Cdrskin_no_cdrfifO if(!skin->do_direct_write) { ret= Cdrskin_attach_fifo(skin,0); if(ret<=0) return(ret); } #endif /* ! Cdrskin_no_cdrfifO */ } return(1); } /** Initialize libburn, create a CdrskiN program run control object, set eventual device whitelist, and obtain the list of available drives. @param o Returns the CdrskiN object created @param lib_initialized Returns whether libburn was initialized here @param exit_value Returns after error the proposal for an exit value @param flag bit0= do not scan for devices @return <=0 error, 1 success */ int Cdrskin_create(struct CdrskiN **o, struct CdrpreskiN **preskin, int *exit_value, int flag) { int ret, stdio_drive= 0, mem; struct CdrskiN *skin; char reason[4096]; *o= NULL; *exit_value= 0; if(strlen((*preskin)->device_adr)>0) { /* disable scan for all others */ ClN(printf( "cdrskin: NOTE : greying out all drives besides given dev='%s'\n", (*preskin)->device_adr)); burn_drive_add_whitelist((*preskin)->device_adr); if(strncmp((*preskin)->device_adr, "stdio:", 6)==0) { ret= Cdrpreskin__allows_emulated_drives((*preskin)->device_adr+6,reason,0); if((*preskin)->allow_emulated_drives && ret>0) { stdio_drive= 1; (*preskin)->demands_cdrskin_caps= 1; } else if((*preskin)->allow_emulated_drives) { fprintf(stderr,"cdrskin: SORRY : dev=stdio:... rejected despite --allow_emulated_drives\n"); fprintf(stderr,"cdrskin: SORRY : Reason: %s.\n", reason); } else { fprintf(stderr,"cdrskin: SORRY : dev=stdio:... works only with option --allow_emulated_drives\n"); if(ret<=0) { fprintf(stderr,"cdrskin: SORRY : but: %s.\n", reason); fprintf(stderr, "cdrskin: SORRY : So this option would not help anyway.\n"); } } if(!stdio_drive) { Cdrpreskin_consider_normal_user(0); {*exit_value= 2; goto ex;} } } } ret= Cdrskin_new(&skin,*preskin,1); if(ret<=0) { fprintf(stderr,"cdrskin: FATAL : Creation of control object failed\n"); {*exit_value= 2; goto ex;} } *preskin= NULL; /* the preskin object now is under management of skin */ *o= skin; if(skin->preskin->abort_handler==1 || skin->preskin->abort_handler==3 || skin->preskin->abort_handler==4) Cleanup_set_handlers(Cleanup_handler_handlE, Cleanup_handler_funC, Cleanup_handler_flaG); else if(skin->preskin->abort_handler==2) Cleanup_set_handlers(Cleanup_handler_handlE, Cleanup_handler_funC, 2 | 8); if(!(flag & 1)) printf("cdrskin: scanning for devices ...\n"); fflush(stdout); if(skin->preskin->verbositypreskin,1); if(stdio_drive) { mem= skin->drive_is_busy; skin->drive_is_busy= 1; ret= burn_drive_scan_and_grab(&(skin->drives),skin->preskin->device_adr,0); skin->drive_is_busy= mem; if(Cdrskin__is_aborting(0)) { fprintf(stderr,"cdrskin: ABORT : Startup aborted\n"); Cdrskin_abort(skin, 0); /* Never comes back */ } if(ret <= 0) { fprintf(stderr,"cdrskin: FATAL : Failed to grab emulated stdio-drive\n"); {*exit_value= 2; goto ex;} } skin->n_drives= 1; skin->driveno= 0; burn_drive_release(skin->drives[0].drive, 0); } else if(flag & 1){ skin->n_drives= 0; skin->driveno= 0; } else { while (!burn_drive_scan(&(skin->drives), &(skin->n_drives))) { usleep(20000); /* >>> ??? set a timeout ? */ } if(skin->n_drives <= 0) skin->driveno= -1; } burn_msgs_set_severities(skin->preskin->queue_severity, skin->preskin->print_severity, "cdrskin: "); /* This prints the eventual queued messages */ Cdrpreskin_queue_msgs(skin->preskin,0); if(!(flag & 1)) printf("cdrskin: ... scanning for devices done\n"); fflush(stdout); ex:; return((*exit_value)==0); } /** Perform the activities which were ordered by setup @param skin Knows what to do @param exit_value Returns the proposal for an exit value @param flag Unused yet @return <=0 error, 1 success */ int Cdrskin_run(struct CdrskiN *skin, int *exit_value, int flag) { int ret; *exit_value= 0; if(skin->preskin->allow_setuid==0 && getuid()!=geteuid()) { fprintf(stderr,"\n"); fprintf(stderr,"cdrskin: WARNING : THIS PROGRAM WAS TREATED WITH chmod u+s WHICH IS INSECURE !\n"); fprintf(stderr, "cdrskin: HINT : Consider to allow rw-access to the writer device and\n"); fprintf(stderr, "cdrskin: HINT : to run cdrskin under your normal user identity.\n"); fprintf(stderr, "cdrskin: HINT : Option --allow_setuid disables this safety check.\n"); fprintf(stderr,"\n"); } if(skin->do_devices) { if(skin->n_drives<=0 && skin->preskin->scan_demands_drive) {*exit_value= 4; goto no_drive;} if(Cdrskin__is_aborting(0)) goto ex; ret= Cdrskin_scanbus(skin, 1 | (2 * (skin->do_devices == 2))); if(ret<=0) { fprintf(stderr,"cdrskin: FATAL : --devices failed.\n"); {*exit_value= 4; goto ex;} } } if(skin->do_scanbus) { if(skin->n_drives<=0 && skin->preskin->scan_demands_drive) {*exit_value= 5; goto no_drive;} if(Cdrskin__is_aborting(0)) goto ex; ret= Cdrskin_scanbus(skin,0); if(ret<=0) fprintf(stderr,"cdrskin: FATAL : -scanbus failed.\n"); {*exit_value= 5*(ret<=0); goto ex;} } if(skin->do_load > 0) { if(Cdrskin__is_aborting(0)) goto ex; ret= Cdrskin_grab_drive(skin,8); if(ret>0) { if(skin->do_load==2 && !skin->do_eject) { printf( "cdrskin: NOTE : Option -lock orders program to exit with locked tray.\n"); printf( "cdrskin: HINT : Run cdrskin with option -eject to unlock the drive tray.\n"); } else if(!skin->do_eject) printf( "cdrskin: NOTE : option -load orders program to exit after loading tray.\n"); Cdrskin_release_drive(skin,(skin->do_load==2)<<1); } {*exit_value= 14*(ret<=0); goto ex;} } if(skin->do_checkdrive) { if(Cdrskin__is_aborting(0)) goto ex; ret= Cdrskin_checkdrive(skin,"",(skin->do_checkdrive==2)<<1); {*exit_value= 6*(ret<=0); goto ex;} } if(skin->do_msinfo) { if(skin->n_drives<=0) {*exit_value= 12; goto no_drive;} if(Cdrskin__is_aborting(0)) goto ex; ret= Cdrskin_msinfo(skin,0); if(ret<=0) {*exit_value= 12; goto ex;} } if(skin->do_atip) { if(skin->n_drives<=0) {*exit_value= 7; goto no_drive;} if(Cdrskin__is_aborting(0)) goto ex; ret= Cdrskin_atip(skin, skin->do_atip == 4 ? 4 : (skin->do_atip>1) | (2 * (skin->do_atip > 2))); if(ret<=0) {*exit_value= 7; goto ex;} } if(skin->do_cdtext_to_textfile) { ret= Cdrskin_cdtext_to_file(skin, skin->cdtext_to_textfile_path, 15); if(ret<=0) {*exit_value= 18; goto ex;} } if(skin->do_cdtext_to_vt07) { ret= Cdrskin_cdtext_to_file(skin, skin->cdtext_to_vt07_path, 1); if(ret<=0) {*exit_value= 19; goto ex;} } if(skin->do_extract_audio) { ret= Cdrskin_extract_audio_to_dir(skin, skin->extract_audio_dir, skin->extract_basename, skin->extract_audio_tracks, skin->extract_flags & 8); if(ret<=0) {*exit_value= 19; goto ex;} } if(skin->do_list_speeds) { if(skin->n_drives<=0) {*exit_value= 17; goto no_drive;} if(Cdrskin__is_aborting(0)) goto ex; ret= Cdrskin_list_speeds(skin, 0); if(ret<=0) {*exit_value= 17; goto ex;} } if(skin->do_list_formats) { if(skin->n_drives<=0) {*exit_value= 16; goto no_drive;} if(Cdrskin__is_aborting(0)) goto ex; ret= Cdrskin_list_formats(skin, 0); if(ret<=0) {*exit_value= 16; goto ex;} } if(skin->do_blank) { if(skin->n_drives<=0) {*exit_value= 8; goto no_drive;} if(Cdrskin__is_aborting(0)) goto ex; ret= Cdrskin_blank(skin,0); if(ret<=0) {*exit_value= 8; goto ex;} } if(skin->do_direct_write) { skin->do_burn= 0; if(Cdrskin__is_aborting(0)) goto ex; ret= Cdrskin_direct_write(skin,0); if(ret<=0) {*exit_value= 13; goto ex;} } if(skin->do_burn || skin->tell_media_space) { if(skin->n_drives<=0) {*exit_value= 10; goto no_drive;} if(Cdrskin__is_aborting(0)) goto ex; ret= Cdrskin_burn(skin,0); if(ret<=0) {*exit_value= 10; goto ex;} } #ifdef Libburn_develop_quality_scaN if(skin->do_qcheck) { ret= Cdrskin_qcheck(skin, 0); if(ret<=0) {*exit_value= 15; goto ex;} } #endif /* Libburn_develop_quality_scaN */ ex:; if(Cdrskin__is_aborting(0)) Cdrskin_abort(skin, 0); /* Never comes back */ return((*exit_value)==0); no_drive:; fprintf(stderr,"cdrskin: FATAL : This run would need an accessible drive\n"); goto ex; } int main(int argc, char **argv) { int ret,exit_value= 0,lib_initialized= 0,i,result_fd= -1, do_not_scan; struct CdrpreskiN *preskin= NULL, *h_preskin= NULL; struct CdrskiN *skin= NULL; char *lean_id= ""; #ifdef Cdrskin_extra_leaN lean_id= ".lean"; #endif /* For -msinfo: Redirect normal stdout to stderr */ for(i=1; ido_not_scan; /* preskin will vanish in Cdrskin_create */ ret= Cdrskin_create(&skin,&preskin,&exit_value, preskin->do_not_scan); if(ret<=0) {exit_value= 2; goto ex;} if(skin->n_drives<=0 && !do_not_scan) { fprintf(stderr,"cdrskin: NOTE : No usable drive detected.\n"); if(getuid()!=0) { fprintf(stderr, "cdrskin: HINT : Run this program as superuser with option --devices\n"); fprintf(stderr, "cdrskin: HINT : Allow rw-access to the dev='...' file of the burner.\n"); fprintf(stderr, "cdrskin: HINT : Busy drives are invisible. (Busy = open O_EXCL)\n"); } } ret= Cdrskin_setup(skin,argc,argv,0); if(ret<=0) {exit_value= 3; goto ex;} if(skin->verbosity>=Cdrskin_verbose_cmD) ClN(printf("cdrskin: called as : %s\n",argv[0])); if(skin->verbosity>=Cdrskin_verbose_debuG) { #ifdef Cdrskin_new_api_tesT ClN(fprintf(stderr,"cdrskin_debug: Compiled with option -experimental\n")); #endif } if(!Cdrskin__is_aborting(0)) Cdrskin_run(skin,&exit_value,0); ex:; if(Cdrskin__is_aborting(0)) Cdrskin_abort(skin, 0); /* Never comes back */ if(preskin!=NULL) h_preskin= preskin; else if(skin!=NULL) h_preskin= skin->preskin; if(h_preskin!=NULL) { if(skin!=NULL) if(skin->verbosity>=Cdrskin_verbose_debuG) ClN(fprintf(stderr, "cdrskin_debug: demands_cdrecord_caps= %d , demands_cdrskin_caps= %d\n", h_preskin->demands_cdrecord_caps, h_preskin->demands_cdrskin_caps)); if(exit_value && h_preskin->demands_cdrecord_caps>0 && h_preskin->demands_cdrskin_caps<=0) { /* prepare fallback */ /* detach preskin from managers which would destroy it */ preskin= NULL; if(skin!=NULL) skin->preskin= NULL; } else h_preskin= NULL; /* prevent fallback */ } if(skin!=NULL) { Cleanup_set_handlers(NULL,NULL,1); if(skin->preskin!=NULL) Cdrskin_eject(skin,0); Cdrskin_destroy(&skin,0); } Cdrpreskin_destroy(&preskin,0); if(lib_initialized) burn_finish(); if(h_preskin!=NULL) Cdrpreskin_fallback(h_preskin,argc,argv,0); /* never come back */ exit(exit_value); } libburn-1.4.2/cdrskin/cleanup.c0000644000175700017510000001223112652644223013341 00000000000000/* cleanup.c , Copyright 2006 Thomas Schmitt A signal handler which cleans up an application and exits. Provided under GPL license within GPL projects, BSD license elsewise. */ /* cc -g -o cleanup -DCleanup_standalonE cleanup.c */ #include #include #include #include #include #include #include typedef void (*sighandler_t)(int); #include "cleanup.h" #ifndef Cleanup_has_no_libburn_os_H #include "../libburn/os.h" /* see os.h for name of particular os-*.h where this is defined */ static int signal_list[]= { BURN_OS_SIGNAL_MACRO_LIST , -1}; static char *signal_name_list[]= { BURN_OS_SIGNAL_NAME_LIST , "@"}; static int signal_list_count= BURN_OS_SIGNAL_COUNT; static int non_signal_list[]= { BURN_OS_NON_SIGNAL_MACRO_LIST, -1}; static int non_signal_list_count= BURN_OS_NON_SIGNAL_COUNT; #else /* ! Cleanup_has_no_libburn_os_H */ /* Outdated. Linux only. For backward compatibility with pre-libburn-0.2.3 */ /* Signals to be caught */ static int signal_list[]= { SIGHUP, SIGINT, SIGQUIT, SIGILL, SIGABRT, SIGFPE, SIGSEGV, SIGPIPE, SIGALRM, SIGTERM, SIGUSR1, SIGUSR2, SIGXCPU, SIGTSTP, SIGTTIN, SIGTTOU, SIGBUS, SIGPOLL, SIGPROF, SIGSYS, SIGTRAP, SIGVTALRM, SIGXCPU, SIGXFSZ, -1 }; static char *signal_name_list[]= { "SIGHUP", "SIGINT", "SIGQUIT", "SIGILL", "SIGABRT", "SIGFPE", "SIGSEGV", "SIGPIPE", "SIGALRM", "SIGTERM", "SIGUSR1", "SIGUSR2", "SIGXCPU", "SIGTSTP", "SIGTTIN", "SIGTTOU", "SIGBUS", "SIGPOLL", "SIGPROF", "SIGSYS", "SIGTRAP", "SIGVTALRM", "SIGXCPU", "SIGXFSZ", "@" }; static int signal_list_count= 24; /* Signals not to be caught */ static int non_signal_list[]= { SIGKILL, SIGCHLD, SIGSTOP, SIGURG, SIGWINCH, -1 }; static int non_signal_list_count= 5; #endif /* Cleanup_has_no_libburn_os_H */ /* run time dynamic part */ static char cleanup_msg[4096]= {""}; static int cleanup_exiting= 0; static int cleanup_has_reported= -1234567890; static void *cleanup_app_handle= NULL; static Cleanup_app_handler_T cleanup_app_handler= NULL; static int cleanup_perform_app_handler_first= 0; static int Cleanup_handler_exit(int exit_value, int signum, int flag) { int ret; if(cleanup_msg[0]!=0 && cleanup_has_reported!=signum) { fprintf(stderr,"\n%s\n",cleanup_msg); cleanup_has_reported= signum; } if(cleanup_perform_app_handler_first) if(cleanup_app_handler!=NULL) { ret= (*cleanup_app_handler)(cleanup_app_handle,signum,0); if(ret==2 || ret==-2) return(2); } if(cleanup_exiting) { fprintf(stderr,"cleanup: ABORT : repeat by pid=%d, signum=%d\n", getpid(),signum); return(0); } cleanup_exiting= 1; alarm(0); if(!cleanup_perform_app_handler_first) if(cleanup_app_handler!=NULL) { ret= (*cleanup_app_handler)(cleanup_app_handle,signum,0); if(ret==2 || ret==-2) return(2); } exit(exit_value); } static void Cleanup_handler_generic(int signum) { int i; sprintf(cleanup_msg,"UNIX-SIGNAL caught: %d errno= %d",signum,errno); for(i= 0; imax_sig) max_sig= signal_list[i]; if(signal_list[i]=non_signal_list_count) { if(i==SIGABRT && (flag&8)) signal(i,Cleanup_handler_generic); else signal(i,sig_handler); } } return(1); } #ifdef Cleanup_standalonE struct Demo_apP { char *msg; }; int Demo_app_handler(struct Demo_apP *demoapp, int signum, int flag) { printf("Handling exit of demo application on signal %d. msg=\"%s\"\n", signum,demoapp->msg); return(1); } main() { struct Demo_apP demoapp; demoapp.msg= "Good Bye"; Cleanup_set_handlers(&demoapp,(Cleanup_app_handler_T) Demo_app_handler,0); if(1) { /* change to 0 in order to wait for external signals */ char *cpt= NULL, c= ' '; printf("Intentionally provoking SIGSEGV ...\n"); c= *cpt; printf("Strange: The system ignored a SIGSEGV: c= %u\n", (unsigned int) c); } else { printf("killme: %d\n",getpid()); sleep(3600); } Cleanup_set_handlers(NULL,NULL,1); exit(0); } #endif /* Cleanup_standalonE */ libburn-1.4.2/cdrskin/cdrskin_eng.html0000644000175700017510000004606712652646273014747 00000000000000 cdrskin homepage english
cdrskin logo: Doener mit Scharf

Homepage of

cdrskin

Limited cdrecord compatibility wrapper for libburn

Purpose:

Burns preformatted data to CD, DVD, and BD media:
CD-R, DVD-R, DVD-R DL, DVD+R, DVD+R DL, BD-R, CD-RW, DVD-RW, DVD-RAM, DVD+RW, BD-RE


Direct hop to download links ->

Hardware requirements:

About any CD, DVD, or BD recorder produced in the recent ten years.
libburn supports recorders which are compliant to standards MMC-1 for CD and MMC-5 for DVD or BD. Linux, FreeBSD, Solaris, and NetBSD can communicate with drives connected via SCSI, PATA (aka IDE, ATA), USB, or SATA.

Software requirements :

Linux with kernel 2.4 or higher (and libc, of course) :
With kernel 2.4 an ATA drive has to be under ide-scsi emulation.
With kernel 2.6 or higher the drive should not be under ide-scsi.
or FreeBSD (with libc, of course) :
ATA and SATA drives need atapicam running.
libcam has to be installed.
or Solaris (with libc, of course) :
Tested on kernel 5.11, hopefully suitable for older ones too.
or NetBSD (with libc, of course) :
Tested on 6.1.2 and 6.1.3
libpthread
is supposed to be a standard system component.

GPL software included:

libburn-1.4.2
(founded by Derek Foreman and Ben Jansens, developed and maintained since August 2006 by Thomas Schmitt from team of libburnia-project.org)
transfers data to CD, DVD, BD

This program system has been tested on Intel/AMD with Linux, FreeBSD, OpenSolaris, and NetBSD based operating systems.
Ports to other usable systems are appreciated. Reports are welcome.


Special features:

  • Source code is independent of cdrecord

Commands:

The most common options of cdrecord for data and audio on CD media are provided in a compatible way.
On all DVD media, cdrskin is able to perform any recording job which is possible with cdrecord. Other than with cdrecord, option -multi is supported with many DVD types and BD-R. Write mode -tao works with anything but quickly blanked DVD-RW and DVD-R DL, which both support no -multi.


Get an overview of drives and their addresses
# cdrskin -scanbus
# cdrskin dev=ATA -scanbus
# cdrskin --devices
Being superuser avoids permission problems with /dev/srN and /dev/hdX .
Ordinary users should then get granted access to the /dev files as listed by option --devices. Linux, FreeBSD, and NetBSD demand rw-permission. On Solaris it is r-permission and privileges "basic,sys_devices".
 
Get info about a particular drive or loaded media:
$ cdrskin dev=0,1,0 -checkdrive
$ cdrskin dev=ATA:1,0,0 -v -atip
$ cdrskin dev=/dev/hdc -minfo
Prepare CD-RW or DVD-RW for re-use, DVD-RAM or BD-RE for first use:
$ cdrskin -v dev=/dev/sg1 blank=as_needed -eject
Format DVD-RW to avoid need for blanking before re-use:
$ cdrskin -v dev=/dev/sr0 blank=format_overwrite
De-format DVD-RW to make it capable of multi-session again:
$ cdrskin -v dev=/dev/sr0 blank=deformat_sequential
Write ISO-9660 filesystem image as only one to blank or formatted media:
$ cdrskin -v dev=/dev/hdc speed=12 fs=8m \
  blank=as_needed -eject padsize=300k my_image.iso
Write compressed afio archive on-the-fly (not DVD-R DL or minimally blanked DVD-RW):
$ find . | afio -oZ - | \
  cdrskin -v dev=0,1,0 fs=32m speed=8 \
  blank=as_needed padsize=300k -
Write several sessions to the same CD, DVD-R[W] or DVD+R[/DL]:
$ cdrskin dev=/dev/hdc -v padsize=300k -multi 1.iso
$ cdrskin dev=/dev/hdc -v padsize=300k -multi 2.iso
$ cdrskin dev=/dev/hdc -v padsize=300k -multi 3.iso
$ cdrskin dev=/dev/hdc -v padsize=300k 4.iso
Get multi-session info for option -C of program mkisofs:
$ c_values=$(cdrskin dev=/dev/sr0 -msinfo 2>/dev/null)
$ mkisofs ... -C "$c_values" ...
Inquire free space on media for a -multi run:
$ x=$(cdrskin dev=/dev/sr0 -multi \
  --tell_media_space 2>/dev/null)
$ echo "Available: $x blocks of 2048 data bytes"
Accelerate BD-RE writing to full nominal speed after the first 250 MB
$ cdrskin ... stream_recording=250m ...
Write audio tracks to CD:
$ cdrskin -v dev=ATA:1,0,0 speed=48 -sao \
  track1.wav track2.au -audio -swab track3.raw
Get overview of the cdrecord compatible options:
$ cdrskin -help
Get overview of the non-cdrecord options:
$ cdrskin --help
Read the detailed manual page:
$ man cdrskin
Read about the standard for which cdrskin is striving:
$  man cdrecord
Do not bother Joerg Schilling with any cdrskin problems. (Be cursed if you install cdrskin as "cdrecord" without clearly forwarding this "don't bother Joerg" demand.)
Learn to know a more versatile way to burn ISO 9660 formatted data
Standalone ISO 9660 multi-session CD/DVD/BD tool xorriso.


Download as source code (see README):
cdrskin-1.4.2.pl01.tar.gz (1050 KB).
cdrskin-1.4.2.pl01.tar.gz.sig
(detached GPG signature for verification by gpg --verify cdrskin-1.4.2.pl01.tar.gz.sig cdrskin-1.4.2.pl01.tar.gz
after gpg --keyserver keys.gnupg.net --recv-keys ABC0A854).
The cdrskin tarballs are source code identical with libburn releases of the same version number. They get produced via a different procedure, though.
cdrskin is part of libburn - full libburn is provided with cdrskin releases.
Documentation:
README an introduction
cdrskin --help non-cdrecord options
cdrskin -help cdrecord compatible options
man cdrskin the manual page
 
Contact:
Thomas Schmitt, scdbackup@gmx.net
GNU xorriso mailing list where cdrskin and libburn are on topic, too: bug-xorriso@gnu.org
License:
GPL, an Open Source approved license
 


Enhancements towards previous stable version cdrskin-1.4.0:

  • New -toc line "Drive id" tells the drive's individual serial number
Bug fixes towards cdrskin-1.4.0:
  • Media summary session count of blank and closed media was short by 1
  • Endless loop if transport error occured while waiting for drive ready
Bug fixes towards cdrskin-1.4.2 (without .pl01):
  • "failed to attach fifo" when trying to burn from stdin. Regression of 1.4.2.

Development snapshot, version 1.4.3 :

Enhancements towards current stable version 1.4.2.pl01:
  • none yet
Bug fixes towards cdrskin-1.4.2.pl01:
  • none yet
 
README 1.4.3
cdrskin-1.4.3 --help
cdrskin-1.4.3 -help
man cdrskin (as of 1.4.3)
 
Maintainers of cdrskin unstable packages please use SVN of libburnia-project.org
Download: svn co http://svn.libburnia-project.org/libburn/trunk libburn
Build: cd libburn ; ./bootstrap ; ./configure --prefix /usr ; make ; cdrskin/compile_cdrskin.sh
Build of SVN versions needs autotools of at least version 1.7 installed. But after the run of ./bootstrap, only vanilla tools like make and gcc are needed.
 
The following download is intended for adventurous end users or admins with full system sovereignty.
Source (./bootstrap is already applied, build tested, for more see upcoming README ):
cdrskin-1.4.3.tar.gz (1050 KB).


Many thanks to Joerg Schilling for cdrecord,
and to Derek Foreman and Ben Jansens for creating libburn.
Historic versions based on Derek's and Ben's icculus.org/burn :
cdrskin-0.1.2.0.2.ts.tar.gz
cdrskin-0.1.3.0.2.ts.tar.gz
Very special thanks to Andy Polyakov whose dvd+rw-tools provide libburn with invaluable examples on how to deal with DVD and BD media.


Example for a setup of device permissions.
Newer Linux distros enable rw-access for the desktop user automatically. So try as normal user whether all your drives are found. CD devices which offer no rw-permission will stay invisible.
$ cdrskin --devices
If not all desired drives show up, become superuser and do again:
# cdrskin --devices
...
0  dev='/dev/sr0'  rwr-r- :  'TEAC' 'CD-ROM CD-532S'
1  dev='/dev/hdc'  rwrw-- :  'LITE-ON' 'LTR-48125S'
Most simple and most insecure is this equivalent of the usual cdrecord permissions u+s,a+x:
# chmod a+rw /dev/sr0 /dev/hdc
More secure is to put the permitted users into a group like "floppy", to assign /dev/sr0 /dev/hdc to this group, and to allow rw-access only to group members.
# vi /etc/group
...
floppy:x:19:thomas,scdbackup
...
# chgrp floppy /dev/sr0 /dev/hdc
# chmod g+rw /dev/sr0 /dev/hdc


Example how to setup K3b to use cdrskin for burning data CD projects.
(
K3b is a GUI frontend which uses cdrecord for CD burning.)


About the relationship of cdrecord and cdrskin

First of all: this relationship is single sided, as cdrskin has to be aware of cdrecord but not vice versa.

I was a long time user of cdrecord and it worked fine for me. Especially i do appreciate its write mode -tao which can pipe arbitrary data on CD and CD-RW via stdin. cdrecord is reliable, versatile and well maintained. So for me - there would be no problem with using it for burning CDs.
But the author of cdrecord and the Linux kernel people foster a very hostile relationship. Ok, that's their business, not mine (or ours if you are with me). One has to be aware, though, that this relationship might lead to a situation where cdrecord is no longer available for certain Linux kernels.
To have my own project prepared for such a time, i began to implement its cdrecord gestures on top of libburn. From now on i invite other interested users of cdrecord to teach cdrskin the gestures necessary for their cdrecord applications. Contact me. Let's see what we can achieve.

libburn and cdrskin are now mature enough to substitute cdrecord in its major use cases of CD and DVD burning. It is possible to foist cdrskin on various software packages if it gets falsely named "cdrecord". I do not encourage this approach, but of course such a replacement opportunity is the goal of a cdrecord compatibility wrapper.

It is very important to me that this project is not perceived as hostile towards Joerg Schilling and his ongoing work. I owe him much. For cdrecord, for mkisofs, for star. Chapeau.


cdrskin logo: Doener mit Scharf

Enjoying free Open Source hosting by www.webframe.org
100 % Microsoft free
and by sourceforge.net
SourceForge Logo

Links to my other published software projects :
xorriso, a standalone ISO 9660 multi-session CD/DVD/BD burn tool. No mkisofs needed.
(a second source of above)
scdbackup, multi volume CD backup
(a second source of above)
Some Tools for Image Collectors
pppoem, a DSL throughput monitor (mainly for Linux kernel 2.4)


Legal statement: This website does not serve any commercial purpose.
libburn-1.4.2/cdrskin/compile_cdrskin.sh0000755000175700017510000001400612652644223015254 00000000000000#!/bin/sh # compile_cdrskin.sh # Copyright 2005 - 2015 Thomas Schmitt, scdbackup@gmx.net, GPL v2 or later # to be executed within ./libburn-* or./cdrskin-* debug_opts="-O2" def_opts= largefile_opts="-D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE=1" fifo_opts="" libvers="-DCdrskin_libburn_1_4_2" # To be used if Makefile.am uses libburn_libburn_la_CFLAGS # burn="libburn/libburn_libburn_la-" burn="libburn/" cleanup_src_or_obj="$burn"cleanup.o libdax_msgs_o="$burn"libdax_msgs.o libdax_audioxtr_o="$burn"libdax_audioxtr.o do_strip=0 static_opts= warn_opts="-Wall -Wextra -Wno-unused-parameter" libcdio= fifo_source="cdrskin/cdrfifo.c" compile_cdrskin=1 compile_cdrfifo=0 compile_dewav=0 libcam= os=$(uname -s) case $os in *FreeBSD) libcam="-lcam" esac for i in "$@" do if test "$i" = "-compile_cdrfifo" then compile_cdrfifo=1 elif test "$i" = "-compile_dewav" then compile_dewav=1 elif test "$i" = "-libburn_1_4_2" then libvers="-DCdrskin_libburn_1_4_2" libdax_audioxtr_o="$burn"libdax_audioxtr.o libdax_msgs_o="$burn"libdax_msgs.o cleanup_src_or_obj="$burn"cleanup.o elif test "$i" = "-libburn_svn" then libvers="-DCdrskin_libburn_1_4_3" libdax_audioxtr_o="$burn"libdax_audioxtr.o libdax_msgs_o="$burn"libdax_msgs.o cleanup_src_or_obj="$burn"cleanup.o elif test "$i" = "-newapi" -o "$i" = "-experimental" then def_opts="$def_opts -DCdrskin_new_api_tesT" elif test "$i" = "-no_largefile" then largefile_opts= elif test "$i" = "-dvd_obs_64k" then def_opts="$def_opts -DCdrskin_dvd_obs_default_64K" elif test "$i" = "-do_not_compile_cdrskin" then compile_cdrskin=0 elif test "$i" = "-do_diet" then fifo_source= def_opts="$def_opts -DCdrskin_extra_leaN" warn_opts= elif test "$i" = "-do_strip" then do_strip=1 elif test "$i" = "-use_libburn_fifo" then fifo_opts="-DCdrskin_use_libburn_fifO" elif test "$i" = "-use_no_libburn_fifo" then fifo_opts="" elif test "$i" = "-use_no_cdrfifo" then fifo_source= fifo_opts="-DCdrskin_use_libburn_fifO -DCdrskin_no_cdrfifO" elif test "$i" = "-use_libburn_cleanup" then fifo_source= fifo_opts="-DCdrskin_use_libburn_cleanuP -DCdrskin_use_libburn_fifO -DCdrskin_no_cdrfifO" elif test "$i" = "-use_libcdio" then libcdio="-lcdio" elif test "$i" = "-g" then debug_opts="-g" elif test "$i" = "-help" -o "$i" = "--help" -o "$i" = "-h" then echo "cdrskin/compile_cdrskin.sh : to be executed within top level directory" echo "Options:" echo " -compile_cdrfifo compile program cdrskin/cdrfifo." echo " -compile_dewav compile program test/dewav without libburn." echo " -libburn_1_4_2 set macro to match libburn-1.4.2" echo " -libburn_svn set macro to match current libburn-SVN." echo " -dvd_obs_64k 64 KB default size for DVD/BD writing." echo " -use_libcdio link with -lcdio because libburn uses it." echo " -do_not_compile_cdrskin omit compilation of cdrskin/cdrskin." echo " -use_no_libburn_fifo use cdrfifo even for single track non-CD" echo " -use_no_cdrfifo always use fifo of libburn and never cdrfifo" echo " -experimental use newly introduced libburn features." echo " -do_diet produce capability reduced lean version." echo " -do_strip apply program strip to compiled programs." echo " -g produce debuggable programm." echo " -static compile with cc option -static." exit 0 elif test "$i" = "-static" then static_opts="-static" fi done timestamp="$(date -u '+%Y.%m.%d.%H%M%S')" echo "Version timestamp : $(sed -e 's/#define Cdrskin_timestamP "//' -e 's/"$//' cdrskin/cdrskin_timestamp.h)" echo "Build timestamp : $timestamp" if test "$compile_cdrskin" then echo "compiling program cdrskin/cdrskin.c $fifo_source $static_opts $debug_opts $libvers $fifo_opts $def_opts $cleanup_src_or_obj $libcdio $libcam" cc -I. \ $warn_opts \ $static_opts \ $debug_opts \ $libvers \ $largefile_opts \ $fifo_opts \ $def_opts \ \ -DCdrskin_build_timestamP='"'"$timestamp"'"' \ \ -o cdrskin/cdrskin \ \ cdrskin/cdrskin.c \ $fifo_source \ \ $cleanup_src_or_obj \ \ "$burn"async.o \ "$burn"cdtext.o \ "$burn"debug.o \ "$burn"drive.o \ "$burn"file.o \ "$burn"init.o \ "$burn"options.o \ "$burn"source.o \ "$burn"structure.o \ \ "$burn"sg.o \ "$burn"write.o \ "$burn"read.o \ $libdax_audioxtr_o \ $libdax_msgs_o \ \ "$burn"mmc.o \ "$burn"sbc.o \ "$burn"spc.o \ "$burn"util.o \ \ "$burn"sector.o \ "$burn"toc.o \ \ "$burn"crc.o \ "$burn"ecma130ab.o \ \ $libcdio \ $libcam \ -lpthread ret=$? if test "$ret" = 0 then dummy=dummy else echo >&2 echo "+++ FATAL : Compilation of cdrskin failed" >&2 echo >&2 exit 1 fi fi if test "$compile_cdrfifo" = 1 then echo "compiling program cdrskin/cdrfifo.c $static_opts $debug_opts" cc $static_opts $debug_opts \ -DCdrfifo_standalonE \ -o cdrskin/cdrfifo \ cdrskin/cdrfifo.c ret=$? if test "$ret" = 0 then dummy=dummy else echo >&2 echo "+++ FATAL : Compilation of cdrfifo failed" >&2 echo >&2 exit 2 fi fi if test "$compile_dewav" = 1 then echo "compiling program test/dewav.c -DDewav_without_libburN $static_opts $debug_opts" cc $static_opts $debug_opts \ -DDewav_without_libburN \ -o test/dewav \ test/dewav.c \ "$burn"libdax_audioxtr.o \ "$burn"libdax_msgs.o \ \ -lpthread ret=$? if test "$ret" = 0 then dummy=dummy else echo >&2 echo "+++ FATAL : Compilation of test/dewav failed" >&2 echo >&2 exit 2 fi fi if test "$do_strip" = 1 then echo "stripping result cdrskin/cdrskin" strip cdrskin/cdrskin if test "$compile_cdrfifo" = 1 then echo "stripping result cdrskin/cdrfifo" strip cdrskin/cdrfifo fi fi echo 'done.' libburn-1.4.2/cdrskin/cdrfifo.h0000644000175700017510000001665312652644223013347 00000000000000 /* cdrfifo.c , Copyright 2006 Thomas Schmitt A fd-to-fd or fd-to-memory fifo to be used within cdrskin or independently. By chaining of fifo objects, several fifos can be run simultaneously in fd-to-fd mode. Modes are controlled by parameter flag of Cdrfifo_try_to_work(). Provided under GPL license within cdrskin and under BSD license elsewise. */ #ifndef Cdrfifo_headerfile_includeD #define Cdrfifo_headerfile_includeD /** The fifo buffer which will smoothen the data stream from data provider to data consumer. Although this is not a mandatory lifesaver for modern burners any more, a fifo can speed up burning of data which is delivered with varying bandwidths (e.g. compressed archives created on the fly or mkisofs running at its speed limit.). This structure is opaque to applications and may only be used via the Cdrfifo*() methods described in cdrfifo.h . */ struct CdrfifO; /** Create a fifo object. @param ff Returns the address of the new object. @param source_fd Filedescriptor opened to a readable data stream. @param dest_fd Filedescriptor opened to a writable data stream. To work with libburn, it needs to be attached to a struct burn_source object. @param chunk_size Size of buffer block for a single transaction (0=default) @param buffer_size Size of fifo buffer @param flag bit0= Debugging verbosity @return 1 on success, <=0 on failure */ int Cdrfifo_new(struct CdrfifO **ff, int source_fd, int dest_fd, int chunk_size, int buffer_size, int flag); /** Release from memory a fifo object previously created by Cdrfifo_new(). @param ff The victim (gets returned as NULL, call can stand *ff==NULL) @param flag Bitfield for control purposes: bit0= do not close destination fd */ int Cdrfifo_destroy(struct CdrfifO **ff, int flag); /** Close any output fds */ int Cdrfifo_close(struct CdrfifO *o, int flag); /** Close any output fds of o and its chain peers */ int Cdrfifo_close_all(struct CdrfifO *o, int flag); int Cdrfifo_get_sizes(struct CdrfifO *o, int *chunk_size, int *buffer_size, int flag); /** Set a speed limit for buffer output. @param o The fifo object @param bytes_per_second >0 catch up slowdowns over the whole run time <0 catch up slowdowns only over one interval =0 disable speed limit */ int Cdrfifo_set_speed_limit(struct CdrfifO *o, double bytes_per_second, int flag); /** Set a fixed size for input in order to cut off any unwanted tail @param o The fifo object @param idx index for fds attached via Cdrfifo_attach_follow_up_fds(), first attached is 0, <0 directs limit to active fd limit (i.e. first track is -1, second track is 0, third is 1, ...) */ int Cdrfifo_set_fd_in_limit(struct CdrfifO *o, double fd_in_limit, int idx, int flag); int Cdrfifo_set_fds(struct CdrfifO *o, int source_fd, int dest_fd, int flag); int Cdrfifo_get_fds(struct CdrfifO *o, int *source_fd, int *dest_fd, int flag); /** Attach a further pair of input and output fd which will use the same fifo buffer when its predecessors are exhausted. Reading will start as soon as reading of the predecessor encounters EOF. Writing will start as soon as all pending predecessor data are written. @return index number of new item + 1, <=0 indicates error */ int Cdrfifo_attach_follow_up_fds(struct CdrfifO *o, int source_fd, int dest_fd, int flag); /** Attach a further fifo which shall be processed simultaneously with this one by Cdrfifo_try_to_work() in fd-to-fd mode. */ int Cdrfifo_attach_peer(struct CdrfifO *o, struct CdrfifO *next, int flag); /** Obtain buffer state. @param o The buffer object @param fill Returns the number of pending payload bytes in the buffer @param space Returns the number of unused buffer bytes @param flag unused yet @return -1=error , 0=inactive , 1=reading and writing , 2=reading ended (but still writing) */ int Cdrfifo_get_buffer_state(struct CdrfifO *o,int *fill,int *space,int flag); int Cdrfifo_get_counters(struct CdrfifO *o, double *in_counter, double *out_counter, int flag); /** reads min_fill and begins measurement interval for next min_fill */ int Cdrfifo_next_interval(struct CdrfifO *o, int *min_fill, int flag); int Cdrfifo_get_min_fill(struct CdrfifO *o, int *total_min_fill, int *interval_min_fill, int flag); int Cdrfifo_get_cdr_counters(struct CdrfifO *o, double *put_counter, double *get_counter, double *empty_counter, double *full_counter, int flag); /** Inquire the eventually detected size of an eventual ISO-9660 file system @return 0=no ISO size detected, 1=size_in_bytes is valid */ int Cdrfifo_get_iso_fs_size(struct CdrfifO *o, double *size_in_bytes,int flag); /** Take over the eventually memorized blocks 16 to 31 of input (2 kB each). The fifo forgets the blocks by this call. I.e. a second one will return 0. After this call it is the responsibility of the caller to dispose the retrieved memory via call free(). @param pt Will be filled either with NULL or a pointer to 32 kB of data @return 0=nothing is buffered, 1=pt points to valid freeable data */ int Cdrfifo_adopt_iso_fs_descr(struct CdrfifO *o, char **pt, int flag); /** Check for pending data at the fifo's source file descriptor and wether the fifo is ready to take them. Simultaneously check the buffer for existing data and the destination fd for readiness to accept some. If so, a small chunk of data is transfered to and/or from the fifo. This is done for the given fifo object and all members of its next-chain. The check and transactions are repeated until a given timespan has elapsed. libburn applications call this function in the burn loop instead of sleep(). It may also be used instead of read(). Then it returns as soon as an output transaction would be performed. See flag:bit2. @param o The fifo object @param wait_usec The time in microseconds after which the function shall return. @param reply_buffer with bit2: Returns write-ready buffer chunk and must be able to take at least chunk_size bytes @param reply_count with bit2: Returns number of writeable bytes in reply_pt @param flag Bitfield for control purposes: bit0= Enable debug pacifier (same with Cdrfifo_debuG) bit1= Do not write, just fill buffer bit2= fd-to-memory mode (else fd-to-fd mode): Rather than writing a chunk return it and its size. No simultaneous processing of chained fifos. bit3= With bit2: do not check destination fd for readiness @return <0 = error , 0 = idle , 1 = did some work , 2 = all work is done */ int Cdrfifo_try_to_work(struct CdrfifO *o, int wait_usec, char *reply_buffer, int *reply_count, int flag); /** Fill the fifo as far as possible without writing to destination fd. @param size if >=0 : end filling after the given number of bytes @return 1 on success, <=0 on failure */ int Cdrfifo_fill(struct CdrfifO *o, int size, int flag); #endif /* Cdrfifo_headerfile_includeD */ libburn-1.4.2/cdrskin/cleanup.h0000644000175700017510000000223712652644223013353 00000000000000/* cleanup.c , Copyright 2006 Thomas Schmitt A signal handler which cleans up an application and exits. Provided under GPL license within GPL projects, BSD license elsewise. */ #ifndef Cleanup_includeD #define Cleanup_includeD 1 /** Layout of an application provided cleanup function using an application provided handle as first argument and the signal number as second argument. The third argument is a flag bit field with no defined bits yet. If the handler returns 2 or -2 then it has delegated exit() to some other instance and the Cleanup handler shall return rather than exit. */ typedef int (*Cleanup_app_handler_T)(void *, int, int); /** Establish exiting signal handlers on (hopefully) all signals that are not ignored by default or non-catchable. @param handle Opaque object which knows how to cleanup application @param handler Function which uses handle to perform application cleanup @param flag Control Bitfield bit0= reset to default signal handling */ int Cleanup_set_handlers(void *handle, Cleanup_app_handler_T handler, int flag); #endif /* ! Cleanup_includeD */ libburn-1.4.2/cdrskin/cdrskin.10000644000175700017510000021545312652644223013300 00000000000000.\" Hey, EMACS: -*- nroff -*- .\" First parameter, NAME, should be all caps .\" Second parameter, SECTION, should be 1-8, maybe w/ subsection .\" other parameters are allowed: see man(7), man(1) .TH CDRSKIN 1 "Version 1.4.2, Nov 28, 2015" .\" Please adjust this date whenever revising the manpage. .\" .\" Some roff macros, for reference: .\" .nh disable hyphenation .\" .hy enable hyphenation .\" .ad l left justify .\" .ad b justify to both left and right margins .\" .nf disable filling .\" .fi enable filling .\" .br insert line break .\" .sp insert n+1 empty lines .\" for manpage-specific macros, see man(7) .SH NAME cdrskin \- burns preformatted data to CD, DVD, and BD via libburn. .SH SYNOPSIS .B cdrskin .RI [ options | track_source_addresses ] .br .SH DESCRIPTION .PP .\" TeX users may be more comfortable with the \fB\fP and .\" \fI\fP escape sequences to invode bold face and italics, .\" respectively. .PP \fBcdrskin\fP is a program that provides some of cdrecord's options in a compatible way for CD media. With DVD and BD it has its own ways. You do not need to be superuser for its daily usage. .SS .B Overview of features: .br Blanking of CD-RW and DVD-RW. .br Formatting of DVD-RW, DVD+RW, DVD-RAM, BD. .br Burning of data tracks or audio tracks with CD-TEXT to CD, .br either in versatile Track at Once mode (TAO) .br or in Session at Once mode for seamless tracks. .br Multi session on CD (follow-up sessions in TAO only) .br or on DVD-R[W] (in Incremental mode) or DVD+R[/DL] or BD-R. .br Single session Disk-at-once on DVD-RW, DVD-R, DVD-R DL. .br Single session or emulated ISO-9660 multi-session .br on overwriteable DVD+RW, DVD-RW, DVD-RAM, BD-RE .br or on data file or block device. .br Extraction of audio tracks and CD-TEXT to hard disk files. .br Bus scan, burnfree, speed options, retrieving media info, padding, fifo. .br See section EXAMPLES at the end of this text. .SS .B General information paragraphs: .br Track recording model .br Write mode selection .br Recordable CD Media .br Sequentially Recordable DVD or BD Media .br Overwriteable DVD or BD Media .br Drive preparation and addressing .br Emulated drives .SS .B Track recording model: .br The input-output entities which get processed are called tracks. A \fBtrack\fP stores a stream of bytes. .br More than one track can be burned by a single run of cdrskin. In the terms of the MMC standard all tracks written by the same run constitute a \fBsession\fP. .br Normally, each track is initiated by one track source address argument, which may either be "-" for standard input or the address of a readable file. Alternatively, option cuefile= may be used to read a session description from a text file and to read the session content from a single data file. .br If no write mode is given explicitly then one will be chosen which matches the peculiarities of track sources and the state of the output media. .PP Some media types can be kept appendable so that further tracks can be written to them in subsequent runs of cdrskin (see option -multi). Info about the addresses of burned tracks is kept in a table of content (TOC) on media and can be retrieved via cdrskin option -toc. This information is also used by the operating systems' CD-ROM read drivers. .PP In general there are two types of tracks: data and audio. They differ in sector size, throughput and readability via the systems' CD-ROM drivers and by music CD players. With DVD and BD there is only type data. .br If not explicitly option -audio is given, then any track is burned as type data, unless the track source is a file with suffix ".wav" or ".au" and has a header part which identifies it as MS-WAVE or SUN Audio with suitable parameters. Such files are burned as audio tracks by default. .PP While audio tracks just contain a given time span of acoustic vibrations, data tracks may have an arbitray meaning. Nevertheless, ISO-9660 filesystems are established as a format which can represent a tree of directories and files on all major operating systems. Such filesystem images can be produced by programs mkisofs or genisoimage or xorriso. They can also be extended by follow-up tracks if prepared properly. See the man pages of said programs. cdrskin is able to fulfill the needs about their option -C. .br Another type of data track content are archive formats which originally have been developed for magnetic tapes. Only formats which mark a detectable end-of-archive in their data are suitable, though. Well tested are the archivers afio and star. Not suitable seems GNU tar. .SS .B Write mode selection: .br In general there are two approaches for writing media: .br A permissive mode selected by option .B -tao which needs no predicted track size and can use multi-session capabilities if offered by drive and medium. .br A more restrictive mode .B -sao (alias -dao) which usually demands a predictable track size and is not necessarily capable of multi-session. It can be used to write CD-TEXT and it is the only one that works with option cuefile=. .br If none of the options -dao, -tao or -sao is given then the program will try to choose a write mode which matches the defined recording job, the capabilities of the drive and the state of the present media. .br So the mentioning of write modes in the following paragraphs and in the examples is not so much a demand that the user shall choose one explicitly, but rather an illustration of what to expect with particular media types. .SS .B Recordable CD Media: .br CD-R can be initially written only once and eventually extended until they get closed (or are spoiled because they are overly full). After that they are read-only. Closing is done automatically unless option .B -multi is given which keeps the media appendable. .br Write mode -tao is able to use track sources of unpredictable length (like stdin) and to write further sessions to appendable media. -sao produces audio sessions with seamless tracks but needs predicted track sizes and cannot append sessions to media. .br CD-RW media can be blanked to make them re-usable for another round of overwriting. Usually .B blank=fast is the appropriate option. Blanking damages the previous content but does not make it completely unreadable. It is no effective privacy precaution. Multiple cycles of blanking and overwriting with random numbers might be needed. .SS .B Sequentially Recordable DVD or BD Media: .br Currently DVD-RW, DVD-R[DL], DVD+R[DL], and BD-R can be used for the Sequential recording model. It resembles the model of CD media. Only DVD-RW can be blanked and re-used from scratch. .br DVD-RW are sequential media if they are in state "Sequential Recording". The media must be either blank or appendable. Newly purchased DVD-RW and DVD-R media are in this state. Used DVD-RW get into blank sequential state by option .B blank=deformat_sequential . .br With DVD-R[W] two write modes may be available: .br Mode DAO has many restrictions. It does not work with appendable media, cannot do -multi and writes only a single track. The size of the track needs to be known in advance. So either its source has to be a disk file of recognizable size or the size has to be announced explicitly by options .B tsize= or .B tao_to_sao_tsize= . .br DAO is the only mode for DVD-R media which do not offer feature 21h Incremental Streaming (e.g. DVD-R DL). DAO may also be selected explicitly by option .B -sao . Program growisofs uses DAO on sequential DVD-R[W] media for maximum DVD-ROM/-Video compatibility. .br The other mode, Incremental Streaming, is the default write mode if it is available and if the restrictions of DAO would prevent the job. Incremental Streaming may be selected explicitly by option .B -tao as it resembles much CD TAO by accepting track sources of unpredicted length and being able to keep media appendable by option .B -multi . It does not work with DVD-R DL and minimally blanked DVD-RW. The only restriction towards CD-R[W] is the lack of support for -audio tracks. Multiple tracks per session are permissible. .br The write modes for DVD+R[/DL] and BD-R resemble those with DVD-R except that each track gets wrapped in an own session. There is no -dummy writing with DVD+R[/DL] or BD-R. .br Quite deliberately write mode -sao insists in the tradition of a predicted track size and blank media, whereas -tao writes the tracks open ended and can be applied to appendable media. .br BD-R may be formatted before first use to enable the Defect Management which might catch and repair some bad spots at the expense of slow speed even with flawless media. .br .B Note: Option -multi might make DVD media unreadable in some DVD-ROM drives. Best reader compatibility is achieved without it (i.e. by single session media). .SS .B Overwriteable DVD or BD Media: .br Currently types DVD+RW, DVD-RW, DVD-RAM and BD-RE can be overwritten via cdrskin. .br Option -audio is not allowed. Only one track is allowed. Option -multi cannot mark a recognizable end of overwriteable media. Therefore -multi is banned unless ISO-9660 images shall be expandable by help of option .B --grow_overwriteable_iso . Without this option or without an ISO-9660 filesystem image present on media, -toc does not return information about the media content and media get treated as blank regardless whether they hold data or not. .br Currently there is no difference between -sao and -tao. If ever, then -tao will be the mode which preserves the current behavior. .PP DVD+RW and DVD-RAM media need no special initial formatting. They offer a single continuous data area for blockwise random access. BD-RE need explicit formatting before use. See .B blank=as_needed or blank=format_defectmgt . .br DVD-RW are sold in state "Sequential Recording". To become suitable for the Overwriteable DVD recording model they need to get formatted to state "Restricted Overwrite". Then they behave much like DVD+RW. This formatting can be done by option .B blank=format_overwrite . .br Several programs like dvd+rw-format, cdrecord, wodim, or cdrskin can bring a DVD-RW out of overwriteable state so that it has to be formatted again. If in doubt, just give it a try. .SS .B Drive preparation and addressing: .br The drives, CD, DVD, or BD burners, are accessed via addresses which are specific to libburn and the operating system. Those addresses get listed by a run of \fBcdrskin --devices\fP or \fBcdrskin --device_links\fP. .br On Linux, they are device files which traditionally do not offer w-permissions for normal users. Because libburn needs rw-permission, it might be only the .B superuser who is able to get this list without further precautions. .br It is consensus that \fBchmod a+rw /dev/sr0\fP or \fBchmod a+rw /dev/hdc\fP is less security sensitive than chmod u+s,a+x /usr/bin/cdrskin. The risk for the drive is somewhat higher but the overall system is much less at stake. Consider to restrict rw-access to a single group which bundles the users who are allowed to use the burner drive (like group "floppy"). .br For drive permission examples on Linux, FreeBSD, and Solaris, see cdrskin/README. .br .PP If you only got one CD capable drive then you may leave out cdrskin option \fBdev=\fP. Else you should use this option to address the drive you want. .br cdrskin option dev= not only accepts the listed addresses but also traditional cdrecord SCSI addresses which consist of three numbers: Bus,Target,Lun. On Linux there is also a related address family "ATA" which accesses IDE drives not under control of Linux SCSI drivers: ATA:Bus,Target,Lun. .br See option -scanbus for getting a list of cdrecord style addresses. .br Further are accepted: links to libburn-suitable device files, device files which have the same major and minor device number, and device files which have the same SCSI address parameters (e.g. /dev/sg0). .br .SS .B Emulated drives: .br Option .B --allow_emulated_drives enables addressing of pseudo-drives which get emulated on top of filesystem objects. Regular data files and block devices result in pseudo-drives which behave much like DVD-RAM. If the given address does not exist yet but its directory exists, then it gets created as regular file. Other file types like character devices or pipes result in pseudo-drives which behave much like blank DVD-R. The target file address is given after prefix "stdio:". .br E.g.: dev=stdio:/tmp/my_pseudo_drive .br Addresses of the form "stdio:/dev/fd/" are treated special. The number is read literally and used as open file descriptor. With dev="stdio:/dev/fd/1" the normal standard output of the program is redirected to stderr and the stream data of a burn run will appear on stdout. .br Not good for terminals ! Redirect it. .br Pseudo-drives support -dummy. Their reply with --tell_media_space can be utopic. -dummy burn runs touch the file but do not modify its data content. .br Note: --allow_emulated_drives is restricted to stdio:/dev/null if cdrskin is run by the .B superuser or if it has changed user identity via the .B setuid bit of its access permissions. The ban for the superuser can be lifted by a skillfully created file. See section FILES below. .br .SH OPTIONS .TP .BI \-\-help Show non-cdrecord compatible options. .TP .BI \-help Show cdrecord compatible options. .br Note that some of the help texts are quite wrong - for cdrecord as well as for cdrskin (e.g. -format, blank=, -load). They are, nevertheless, traditional indicators for the availability of the listed options. Some frontend programs make decisions after reading them. .TP .BI \-version Print cdrskin id line, compatibility lure line, libburn version, cdrskin version, version timestamp, build timestamp (if available), and then exit. .PP Alphabetical list of options which are intended to be compatible with original cdrecord by Joerg Schilling: .TP .BI \-atip Retrieve some info about media state. With CD-RW print "Is erasable". With DVD media print "book type:" and a media type text. With BD media print "Mounted Media:" and media type text. .TP .BI \-audio Announces that the subsequent tracks are to be burned as audio. The source is supposed to be uncompressed headerless PCM, 44100 Hz, 16 bit, stereo. For little-endian byte order (which is usual on PCs) use option -swab. Unless marked explicitly by option -data, input files with suffix ".wav" are examined whether they have a header in MS-WAVE format confirming those parameters and eventually raw audio data get extracted and burned as audio track. Same is done for suffix ".au" and SUN Audio. .br Option -audio may be used only with CD media and not with DVD or BD. .TP .BI blank= type Blank a CD-RW, DVD-RW, or format a DVD-RW, DVD+RW, DVD-RAM, BD. This is combinable with burning in the same run of cdrskin. The type given with blank= selects the particular behavior: .RS .TP as_needed Try to make the media ready for writing from scratch. If it needs formatting, then format it. If it is not blank, then try to apply blank=fast. It is a reason to abort if the media cannot assume thoroughly writeable state, e.g. if it is non-blank write-once. .br This leaves unformatted DVD-RW in unformatted blank state. To format DVD-RW use blank=format_overwriteable. Blank unformatted BD-R stay unformatted. .br (Note: blank=as_needed is not an original cdrecord option.) .TP The following blank types are specific to particular media familes. Use them if special features are desired. .TP all Blank an entire CD-RW or an unformatted DVD-RW. (See also --prodvd_cli_compatible, --grow_overwriteable_iso) .TP fast Minimally blank an entire CD-RW or blank an unformatted DVD-RW. (See also --prodvd_cli_compatible, --grow_overwriteable_iso) .TP deformat_sequential Like blank=all but with the additional ability to blank overwriteable DVD-RW. This will destroy their formatting and make them sequentially recordable. Another peculiarity is the ability to blank media which appear already blank. This is similar to option -force but does not try to blank media other than recognizable CD-RW and DVD-RW. .br (Note: blank=deformat_* are not original cdrecord options.) .TP deformat_sequential_quickest Like blank=deformat_sequential but blanking DVD-RW only minimally. This is faster than full blanking but may yield media incapable of Incremental Streaming (-tao). .TP format_if_needed Format a media if it is not formatted yet, and if cdrskin supports formatting for the media type, and if formatting will not happen automatically during write. This currently applies to unformatted DVD-RW, DVD-RAM, BD-RE, and blank unformatted BD-R. Eventually the appropriate default formatting is chosen. If other media or states are encountered then nothing happens. .br The following formatting types are more specialized to particular media families. .TP format_overwrite Format a DVD-RW to "Restricted Overwrite". The user should bring some patience. .br (Note: blank=format_* are not original cdrecord options.) .TP format_overwrite_quickest Like format_overwrite without creating a 128 MiB trailblazer session. Leads to "intermediate" state which only supports sequential write beginning from address 0. The "intermediate" state ends after the first session of writing data. .TP format_overwrite_full For DVD-RW this is like format_overwrite but claims full media size rather than just 128 MiB. Most traditional formatting is attempted. No data get written. Much patience is required. .br This option treats already formatted media even if not option -force is given. .br For DVD+RW this is the only supported explicit formatting type. It provides complete "de-icing" so no reader slips on unwritten data areas. .TP format_defectmgt Format DVD-RAM or BD to reserve the default amount of spare blocks for defect management. .br The following format_defectmgt_* enable the user to submit wishes which nevertheless have to match one of the available formats. These formats are offered by the drive after examining the media. .TP format_defectmgt_cert_off Disable the usual media quality certification in order to save time and format to default size. The certification setting persists even if subsequent blank= options override the size of the format selection. .br Whether formatting without certification works properly depends much on the drive. One should check the "Format status:" from --list_formats afterwards. .TP format_defectmgt_cert_on Re-enable the usual media quality certification and format to default size. The certification setting persists like with format_defectmgt_cert_off. .br Whether there happens certification at all depends much on the media state and the actually selected format descriptor. .TP format_defectmgt_max Format DVD-RAM or BD to reserve a maximum number of spare blocks. .TP format_defectmgt_min Format DVD-RAM or BD to reserve a minimum number of spare blocks. It might be necessary to format format_defectmgt_none first in order to get offered the most minmal spare blocks sizes for format_defectmgt_min. .TP format_defectmgt_none Format DVD-RAM or BD-RE to the largest available payload in the hope to disable defect management at all. This may or may not have a speed increasing effect. Unformatted blank BD-R will be left unformatted. .TP format_defectmgt_payload_ Format DVD-RAM or BD. The text after "format_defectmgt_payload_" gives a number of bytes, eventually with suffixes "s", "k", "m". The largest number of spare blocks will be chosen which enables at least the given payload size. .TP format_by_index_ Format DVD-RW, DVD+RW, DVD-RAM or BD. The number after "format_by_index_" is used as index to the list of available format descriptors. This list can be obtained by option --list_formats. The numbers after text "Format idx" are the ones to be used with format_by_index_. Format descriptor lists are volatile. Do neither eject nor write the media between the run of --list_formats and the run of blank=format_by_index_ or else you may get a different format than desired. .TP help Print this list of blanking types. .RE .TP .BI \-checkdrive Retrieve some info about the addressed drive and then exit. Exits with non-zero value if the drive cannot be found and opened. .TP .BI \-copy Create the subsequent tracks with permission for an unlimited number of copies. .TP .BI cuefile= path Read a session description from a cue sheet file in CDRWIN format. Base the tracks on a single file which is given in the sheet by command FILE. To enable CD-TEXT from the cue sheet file, cdrskin option -text has to be present. .br cdrskin currently supports TRACK datatypes AUDIO and MODE1/2048 which may not be mixed. Data source may be of FILE type BINARY, MOTOROLA, or WAVE. .br Non-CDRWIN commands ARRANGER, COMPOSER, MESSAGE are supported. .br Cue sheet file commands CATALOG and ISRC may be overridden by option mcn= and by input_sheet_v07t= purpose specifiers "UPC / EAN" and "ISRC". This does not affect their appearance in CD-TEXT, but only on Q sub-channel. .br The track numbers may be overridden by option cd_start_tno=. .TP .BI \-dao Alias for option -sao. Write CD in Session at Once mode or DVD-R[W] in Disc-at-once mode. .TP .BI \-data Subsequent tracks are data tracks. This option is default and only needed to mark the end of the range of an eventual option -audio or -xa1. .br Options -mode2, -xa, and -xa2 get mapped to -data, not using the desired CD sector formats and thus not taking advantage of eventual higher payload. .BI \-xa1 Subsequent tracks are data tracks with input suitable for CD-ROM XA mode 2 form 1. This differs from -data input by 8 additional header bytes per block. cdrskin will not write CD-ROM XA but rather strip the header bytes and write as -data tracks. .TP .BI dev= target Set the address of the drive to use. Valid are at least the addresses listed with options --devices or --device_links, X,Y,Z addresses listed with option -scanbus, ATA:X,Y,Z addresses listed with options dev=ATA -scanbus, and volatile libburn drive numbers (numbering starts at "0"). Other device file addresses which lead to the same drive might work too. .br If no dev= is given, volatile address "dev=0" is assumed. That is the first drive found being available. Better avoid this ambiguity on systems with more than one drive. .br The special target "help" lists hints about available addressing formats. Be aware that deprecated option --old_pseudo_scsi_adr may change the meaning of Bus,Target,Lun addresses. .TP .BI driveropts= opt Set "driveropts=noburnfree" to disable the drive's eventual protection mechanism against temporary lack of source data (i.e. buffer underrun). A drive that announces no such capabilities will not get them enabled anyway, even if attempted explicitly via "driveropts=burnfree". .TP .BI \-dummy Try to perform the drive operations without actually affecting the inserted media. There is no warranty that this will work with a particular combination of drive, media, and write mode. Blanking is prevented reliably, though. To avoid inadverted real burning, -dummy refuses burn runs on anything but CD-R[W], DVD-R[W], or emulated stdio-drives. .TP .BI \-eject Eject the disc after work is done. .TP .BI \-force Assume that the user knows better in situations when cdrskin or libburn are insecure about drive or media state. This includes the attempt to blank media which are classified as unknown or unsuitable, and the attempt to use write modes which libburn believes they are not supported by the drive. .br Another application is to enforce blanking or re-formatting of media which appear to be in the desired blank or format state already. .br This option enables a burn run with option -dummy even if libburn believes that drive and media will not simulate the write mode but will write for real. .br It enables a burn run where cdrskin expects to exceed the available media capacity. .br .B Caution: Use this only when in urgent need. .TP .BI \-format Same as blank=format_overwrite_full -force but restricted to DVD+RW. .TP .BI fs= size Set the fifo size to the given value. The value may have appended letters which multiply the preceding number: .br "k" or "K" = 1024 , "m" or "M" = 1024k , "g" or "G" = 1024m , "s" or "S" = 2048 .br Set size to 0 in order to disable the fifo (default is "4m"). .br The fifo buffers an eventual temporary surplus of track source data in order to provide the drive with a steady stream during times of temporary lack of track source supply. The larger the fifo, the longer periods of poor source supply can be compensated. But a large fifo needs substantial time to fill up if not curbed via option fifo_start_at=size. .TP .BI gracetime= seconds Set the grace time before starting to write. (Default is 0) .TP .BI -immed Equivalent to: .br modesty_on_drive=1:min_percent=75:max_percent=95 .br The name of this cdrecord option stems from the "Immed" bit which can make some long running drive commands asynchronous and thus eases the load on some wiring hardware types. Regardless of option -immed, cdrskin uses asynchronous commands where possible and appropriate. .TP .BI index= list Set a comma separated list of index start address numbers for the next track. This applies to CD SAO sessions only. .br The addresses count sectors from the start of the next track. The first number is for index 1 and must be 0. The following numbers have to be larger than their respective predecessors. Up to 99 numbers are allowed. .br Sector numbers are computed from Min:Sec:Frame addresses by .br Sector = ((Min*60)+Sec)*75+Frame .br E.g.: "0,7512,20408" sets index 2 to 01:40:12 and index 3 to 04:32:08. .TP .BI -inq Print the identification of the drive and then exit. .TP .BI -isosize The next track following this option will try to obtain its source size from the header information out of the first few blocks of the source data. If these blocks indicate an ISO-9660 filesystem then its declared size will be used under the assumption that it is a single session filesystem. .br If not, then the burn run will be aborted. .br The range of -isosize is exactly one track. Further tracks may be preceded by further -isosize options, though. At least 15 blocks of padding will be added to each -isosize track. But be advised to rather use padsize=300k. .br This option can be performed on track sources which are regular files or block devices. For the first track of the session it can be performed on any type of source if there is a fifo of at least 64 kiB. See option fs= . .TP .BI isrc= text Set the ISRC for the next track source to the given text, which must be exactly 13 characters long. It must comply to the format CCOOOYYSSSSS. .br CC is the country code. OOO is the owner code. Both may consist of capital letters A to Z and of decimal digits 0 to 9. YY depicts the year (00 to 99). SSSSS is the serial number (00000 to 99999). .br This option does not affect CD-TEXT but only the Q sub-channel. .TP .BI -load Load the media and exit. Exit value is 0 if any kind of media was found, non zero else. Note: Option -eject will unload the media even if -load is given. .TP .BI -lock Like option -load but leave the drive's eject button disabled if there is any media found and not option -eject is given. .br Use program "eject" or cdrskin -eject to get the tray out of the drive. Runs of programs like cdrecord, growisofs, wodim, cdrskin will not be hampered and normally enable the drive's eject button when they are done. .TP .BI mcn= text Set the CD Media Catalog Number to text, which must be exactly 13 characters long and should consist of decimal digits. .br This option does not affect CD-TEXT but only the Q sub-channel. .TP .BI minbuf= percentage Equivalent to: .br modesty_on_drive=1:min_percent=:max_percent=95 .br Percentage is permissible between 25 and 95. .TP .BI -minfo Print information about the loaded media. This includes media type, writability state, and a quite readable table of content. .TP .BI msifile= path Run option -msinfo and copy the result line into the file given by path. Unlike -msinfo this option does not redirect all normal output away from standard output. But it may be combined with -msinfo to achieve this. .br Note: msifile=path is actually an option of wodim and not of cdrecord. .TP .BI \-msinfo Retrieve multi-session info for preparing a follow-up session by option -C of programs mkisofs, genisoimage, or xorriso -as mkisofs. Print result to standard output. This option redirects to stderr all message output except the one of option --tell_media_space and its own result string, which consists of two numbers. The result string shall be used as argument of option -C with said programs. It gives the start address of the most recent session and the predicted start address of the next session to be appended. The string is empty if the most recent session was not written with option -multi. .br To have a chance for working on overwriteable media, this option has to be accompanied by option --grow_overwriteable_iso. .TP .BI \-multi This option keeps CD, unformatted DVD-R[W], DVD+R, or BD-R appendable after the current session has been written. Without it the disc gets closed and may not be written any more - unless it is a -RW and gets blanked which causes loss of its content. .br The following sessions can only be written in -tao mode. -multi is prohibited with DVD-R[W] DAO write mode and on DVD-R DL media. Option --prodvd_cli_compatible eventually makes -multi tolerable but cannot make it work. .br In order to have all filesystem content accessible, the eventual ISO-9660 filesystem of a follow-up session needs to be prepared in a special way by the filesystem formatter program. mkisofs and genisoimage expect particular info about the situation which can be retrieved by cdrskin option -msinfo. .br To retrieve an archive file which was written as follow-up session, you may use option -toc to learn about the "lba" of the desired track number. This lba is the address of the 2048 byte block where the archive begins. .br With overwriteable DVD or BD media, -multi cannot mark the end of the session. So when adding a new session this end has to be determined from the payload. Currently only ISO-9660 filesystems can be used that way. See option .B \--grow_overwriteable_iso for lifting the ban on -multi. .br Note: -multi might make DVD media unreadable in some DVD-ROM drives. .TP .BI \-nocopy Create subsequent tracks with permission for a single level of copies. I.e. those copies would then be marked by -scms as offering no permission for further copies. .TP .BI \-nopad Do not add trailing zeros to the data stream. Nevertheless, since there seems to be no use for audio tracks with incomplete last sector, this option applies only to data tracks. There it is default. .TP .BI \-nopreemp Indicate for subsequent tracks that they were mastered without pre-emphasis. .TP .BI \-pad Add 30 kiB of trailing zeros to each data track. (This is not sufficient to avoid problems with various CD-ROM read drivers.) .TP .BI padsize= size Add the given amount of trailing zeros to the next data track. This option gets reset to padsize=0 after that next track is written. It may be set again before the next track argument. About size specifiers, see option fs=. .TP .BI \-preemp Indicate for subsequent tracks that they were mastered with pre-emphasis. .TP .BI \-sao Write CD in Session At Once mode or sequential DVD-R[W] in Disc-at-once (DAO) mode. .br With CD this mode is able to put several audio tracks on media without producing audible gaps between them. .br With DVD-R[W] this mode can only write a single track. No -multi is allowed with DVD-R[W] -sao. .br -sao is permissible with overwriteable DVD, or DVD+R[/DL], or BD but actually only imposes restrictions without providing known advantages. .br -sao can only be used for tracks of fixely predicted size. This implies that track arguments which depict stdin or named pipes need to be preceded by option tsize= or by option tao_to_sao_tsize=. .br -sao cannot be used on appendable media. .TP .BI \-scanbus Scan the system for drives. On Linux the drives at /dev/s* and at /dev/hd* are to be scanned by two separate runs. One without dev= for /dev/s* and one with dev=ATA for /dev/hd* devices. (Option --drives lists all available drives in a single run.) .br Drives which are busy or which offer no rw-permission to the user of cdrskin are not listed. Busy drives get reported in form of warning messages. .br The useful fields in a result line are: .br Bus,Target,Lun Number) 'Vendor' 'Mode' 'Revision' .TP .BI \-scms Create subsequent tracks without permission for being copied. This is usually done for tracks which are copies of tracks that were marked with -nocopy (but not yet with -scms). So copies of copies are prohibited. .br This option gets reset by option -copy. Thus the combination -copy -nocopy means -nocopy surely without -scms. .TP .BI speed= number Set speed of drive. With data CD, 1x speed corresponds to a throughput of 150,000 bytes/second. With DVD, 1x = 1,385,000 bytes/second. With BD 1x = 4,495,625 bytes/second. It is not an error to set a speed higher than is suitable for drive and media. One should stay within a realistic speed range, though. Special speed settings are: .br 0 = minimal speed , -1 = maximal speed (default), text "any" = like -1. .TP .BI \-swab Announce that the raw audio data source of subsequent tracks is byte swapped versus the expectations of cdrecord. This option is suitable for audio where the least significant byte of a 16 bit word is first (little-endian, Intel). Most raw audio data on PC systems are available in this byte order. Less guesswork is needed if track sources are in format MS-WAVE in a file with suffix ".wav". .TP .BI \-tao Write CD in Track At Once (TAO) mode, sequential DVD-R[W] in Incremental Streaming mode, or DVD+R[/DL] without traditional -sao restrictions. This mode also applies pro-forma to overwriteable media .br Mode -tao can be used with track sources of unpredictable size, like standard input or named pipes. It is also the only mode that can be used for writing to appendable media which already hold data. With unformatted DVD-R[W] it is the only mode which can keep media appendable by option -multi. .br Mode -tao is not usable for minimally blanked DVD-RW and for DVD-R DL. .TP .BI \-text Enable writing of CD-TEXT attributes read by option cuefile=. Without option -text, cue sheet file command CDTEXTFILE will be ignored and no CD-TEXT attributes will be read from the file. Nevertheless, CATALOG and ISRC will have the same effect as options mcn= and isrc=. .TP .BI textfile= path Read CD-TEXT packs from the file depicted by path and put them into the Lead-in of the emerging session. This session has to be done by Session At Once (SAO) mode and may only contain audio tracks. .br path must lead to a regular file, which consists of an optional header of four bytes and one or more text packs of 18 bytes each. Suitable would be the file 'cdtext.dat' which gets extracted from CD media by options -vv -toc and shown in human readable form by -vvv -toc. .br The header, if present, must tell the file size minus 2, encoded as big-endian 16 bit word. The other two bytes must be 0. .br If there is no 4-byte header, then a trailing 0-byte, as of Sony specification, is tolerated and ignored. .br A text pack consists of a pack type byte, a track number byte, a counter byte, a Block Number and Character Indicator byte, 12 text characters or data bytes, two optional CRC bytes. For details see libburn documentation file doc/cdtext.txt. .br By default, the input file is checked for correct CRC bytes. If all CRC bytes are 0, then the correct values get silently inserted. If there are non-zero CRC bytes, then a mismatch causes the abort of the burn run. This check can be disabled by option -force. .br Note that this option overrides option input_sheet_v07t= . .TP .BI \-toc Print the table of content (TOC) which describes the tracks recorded on disc. The output contains all info from option -atip plus lines which begin with "track:", the track number, the word "lba:" and a number which gives the start address of the track. Addresses are counted in CD sectors which with SAO or TAO data tracks hold 2048 bytes each. .br If verbosity is set to level 2 (-v -v) then the CD-TEXT packs from the lead-in of an audio CD get extracted and written into file 'cdtext.dat', if that file does not yet exist. Prepended is a 4 byte header, followed by one or more packs of 18 bytes each. .br Verbosity level 3 causes the CD-TEXT packs to be printed as hex numbers to standard output. Bytes 4 to 15 of certain pack types are printed as ASCII characters if they have values in the range of 32 to 126. .br See option textfile= for more information about the text pack format. .RS .TP Example. Retrieve an afio archive from track number 2: .br tracknumber=2 .br lba=$(cdrskin dev=/dev/cdrom -toc 2>&1 | \\ .br grep '^track:[ ]*[ 0-9][0-9]' | \\ .br tail +"$tracknumber" | head -1 | \\ .br awk '{ print $4}' ) .br dd if=/dev/cdrom bs=2048 skip="$lba" | \\ .br afio -t - | less .RE .TP .BI tsize= size Announces the exact size of the next track source. This is necessary with any write mode other than -tao if the track source is not a regular disk file, but e.g. "-" (standard input) or a named pipe. About size specifiers, see option fs=. .br If the track source does not deliver the predicted amount of bytes, the remainder of the track is padded with zeros. This is not considered an error. If on the other hand the track source delivers more than the announced bytes then the track on media gets truncated to the predicted size and cdrskin exits with non-zero value. .TP .BI \-v Increment verbosity level by one. Startlevel is 0 with only few messages. Level 1 prints progress report with long running operations and also causes some extra lines to be put out with info retrieval options. Level 2 additionally reports about option settings derived from arguments or startup files. Level 3 is for debugging and useful mainly in conjunction with somebody who had a look into the program sourcecode. .TP .BI \-V Enable logging of SCSI commands to stderr. This is helpful for expert examination of the interaction between libburn and the drive. The commands are specified in SCSI-3 standards SPC, SBC, MMC. .TP .BI \-waiti Wait until input data is available at stdin or EOF occurs at stdin. Only then begin to access any drives. .br One should use this if cdrskin is working at the end of a pipe where the feeder process reads from the drive before it starts writing its output into cdrskin. Example: .br mkisofs ... -C 0,12800 -M /dev/sr0 | \\ .br cdrskin dev=/dev/sr0 ... -waiti - .br This option works even if stdin is not among the track sources. If no process is piping in, then the Enter key of your terminal will act as trigger for cdrskin. Note that this input line will not be consumed by cdrskin if stdin is not among the track sources. It will end up as shell command, usually. .PP Alphabetical list of options which are genuine to cdrskin and intended for normal use: .TP .BI \--adjust_speed_to_drive Curb explicitly given speed= values to the maximum which is announced by the drive for the loaded media. By default, such an adjustment is only made with pseudo-speeds 0 and -1 whereas speed settings > 0 are sent unchanged to the drive which will then choose an appropriate speed on its own. .TP .BI \--allow_emulated_drives Enable drive addresses of the form dev=stdio:. See above, paragraph "Drive preparation and addressing". .TP .BI \--allow_setuid Disable the loud warning about insecure discrepance between login user and effective user which indicates application of chmod u+s to the program binary. One should not do this chmod u+s , but it is an old cdrecord tradition. .TP .BI \--any_track Allow source_addresses to begin with "-" (plus further characters) or to contain a "=" character. By default such arguments are seen as misspelled options. It is nevertheless not possible to use one of the options listed with --list_ignored_options. .TP .BI assert_write_lba= block_number | byte_address Abort if the write address given with this option is not the same as predicted immediately before the write session starts. This option can ensure that a start address which was presumed by a formatter like mkisofs -C is really used by the drive for writing. assert_write_lba=0 effectively demands blank media and excludes appendables. .br Block numbering is peculiar: If the last character of the option string is a letter [a-zA-Z] then the usual unit scaling by "s", "k", "m", etc. applies and the result is divided by 2048. Else the number value of the string is taken as plain block number with block size 2048 byte. (E.g ...=1000 or ...=1000s means block 1000, ...=1m means block 512, ...=4096b means block number 2) .TP .BI cd_start_tno= number Set the number which shall be written as CD track number with the first track of the session. The following tracks will then get written with consecutive CD track numbers. The resulting number of the last track must not exceed 99. The lowest possible start number is 1, which is also the default. .br This setting applies only to CD SAO writing. It overrides the track number settings caused by options cuefile= or input_sheet_v07t=. .TP .BI cdtext_to_textfile= path Extract the CD-TEXT packs from the lead-in of an audio CD and write them to the file with the given path. If CD-TEXT can be retrieved, then this file will be suitable for option textfile=. .br Not all drives can read CD-TEXT and not all audio CDs bear CD-TEXT. It is not considered an error if no CD-TEXT is available. .TP .BI cdtext_to_v07t= path Extract the CD-TEXT packs from the lead-in of an audio CD and write them as human readable Sony Input Sheet Version 0.7T to the file with the given path. If CD-TEXT can be retrieved, then this file will be suitable for option input_sheet_v07t=. .br If the given path is "-", then the result is printed to standard output. .br Not all drives can read CD-TEXT and not all audio CDs bear CD-TEXT. It is not considered an error if no CD-TEXT is available. .TP .BI \--demand_a_drive Exit with a nonzero value if no drive can be found during a bus scan. .TP .BI \--devices List the device file addresses of all accessible CD drives. In order to get listed, a drive has to offer rw-permission for the cdrskin user and it may not be busy. The superuser should be able to see all idle drives listed and busy drives reported as "SORRY" messages. .br Each available drive gets listed by a line containing the following fields: .br Number dev='Devicefile' rw-Permissions : 'Vendor' 'Model' .br Number and Devicefile can both be used with option dev=, but number is volatile (numbering changes if drives become busy). .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 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 be the only finalization. It is advised to eject the media afterwards because the write operations circumvent the usual system i/o with its caches and buffers. By ejecting, those invalid memory copies get surely discarded. .br Only few media can be written this way: DVD-RAM, BD-RE, RVD+RW and overwriteable DVD-RW. Writing is restricted to the already formatted area of the media. .br Writing starts at byte 0 of the media or at the address given by option .B write_start_address= . Only the first track source is used as input for the write operations. The fifo (fs=) is disabled. .br Parameter .B size controls the amount of data to be written. Size 0 means that the track source shall be used up until EOF. In this case, the last write transaction gets padded up to the necessary size by zeros. Size -1 revokes direct writing and switches back to normal session oriented writing. .br Both, write_start_address and direct_write_amount size must be aligned to a media dependend transaction size. With DVD-RAM, BD-RE, DVD+RW this is 2k, with overwriteable DVD-RW it is 32k. .TP .BI dvd_obs= default|32k|64k Set the number of bytes to be transmitted with each write operation to DVD or BD media. With most write types, tracks get padded up to the next multiple of this write size (see option --obs_pad). A number of 64 KB may improve throughput with systems which show latency problems. The default depends on media type, option stream_recording=, and on compile time options. .TP .BI extract_audio_to= directory_path Extract tracks from an audio CD as separate WAVE audio files into the given directory. This directory has to already exist, but none of the track files may exist. This option will rather fail than overwrite an existing file. .br By default all tracks of the CD are extracted to files with names trackNN.wav, where NN is the track number from 01 to at most 99. .TP .BI extract_basename= name Set a filename which shall be used by extract_audio_to= instead of the default name "track". .TP .BI --extract_dap Enable Digital Audio Play flaw obscuring mechanisms like audio data mute and interpolate. .TP .BI extract_tracks= number[,number[,...]] Set a list of track numbers to define which tracks shall be extracted by extract_audio_to=. If no extract_tracks= is given, then all audio tracks get extracted. It is permissible to have more than one extract_tracks= option in order to split a long list into shorter pieces. .br The lowest permissible track number is 1, the highest is 99. .TP .BI fallback_program= command Set a command name to be executed if cdrskin encounters a known cdrecord option which it does not yet support. If a non-empty command is given with fallback_program=, and if no essential options are given which are specific to cdrskin, then cdrskin will delegate the job to said command. .br The natural commands to be given are cdrecord or wodim but one may well submit the address of an own program. .br The fallback program will get all arguments of cdrskin which do not match the shell patterns --?* or *_*=* . This eventually suppresses path names of track sources which happen to match those patterns. The options from the startup files are not handed to the fallback program. .br Fallback program execution is disabled if cdrskin is run setuid and not option --allow_setuid is given. In general, the drive's device files and the involved programs should be set up so that each program runs under its advised conditions. (E.g. cdrskin as member of group floppy, cdrecord setuid root.) .br Two alias names for cdrskin are predefined with default fallback programs: .br .B unicord implies fallback_program=cdrecord .br .B codim implies fallback_program=wodim .TP .BI --four_channel Indicate for subsequent tracks that they were mastered with four channels. .TP .BI fifo_start_at= size Do not wait for full fifo but start burning as soon as the given number of bytes is read. This option may be helpful to bring the average throughput near to the maximum throughput of a drive. A large fs= and a small fifo_start_at= combine a quick burn start and a large savings buffer to compensate for temporary lack of source data. At the beginning of burning, the software protection against buffer underun is as weak as the size of fifo_start_at= . So it is best if the drive offers hardware protection which is enabled automatically if not driveropts=noburnfree is given. .TP .BI \--grow_overwriteable_iso Enable emulation of multi-session writing on overwriteable media which contain an ISO-9660 filesystem. This emulation is learned from growisofs -M but adapted to the usage model of .br .B cdrskin -msinfo .br .B mkisofs -C -M | cdrskin -waiti [-multi] - .br --grow_overwriteable_iso does not hamper the use of true multi-session media. I.e. it is possible to use the same cdrskin options with both kinds of media and to achieve similar results if ISO-9660 filesystem images are to be written. This option implies option -isosize and therefore demands that the track source is a ISO-9660 filesystem image. .br With overwriteable media and no option blank=fast|all present it expands an eventual ISO-9660 filesystem on media. It is assumed that this image's inner size description points to the end of the valuable data. Overwriteable media with a recognizable ISO-9660 size will be regarded as appendable rather than as blank. I.e. options -msinfo and -toc will work. -toc will always show a single session with its size increasing with every added mkisofs image. .br If not overridden by option write_start_address=, the track with the new image will be placed behind the end of the old one. One may use option assert_write_lba= to make sure that media state and mkisofs job do match. .br --grow_overwriteable_iso causes option blank=fast|all to invalidate an eventual ISO-9660 image by altering the first few bytes of block 16 on overwriteable media. Option -multi is tolerated in order not to hamper true multi-session media. .br An equivalent of growisofs -Z for overwriteable media is: .br .B mkisofs | cdrskin --grow_overwriteable_iso blank=fast [-multi] - .br With multi-session DVD, blank=fast will act like dvd+rw-format -blank=full . .br growisofs -dvd-compat is roughly equivalent to cdrskin without option -multi. .TP .BI input_sheet_v07t= path Read CD-TEXT definitions from a Sony Input Sheet version 0.7T. Up to eight or seven such sheets can be read by multiple input_sheet_v07t= options. Each will define one CD-TEXT language block. .br The first line of a sheet file decides whether more than one sheet may be defined by the file. If it is .br Input Sheet Version = 0.7T .br then each further line with that text switches to the next sheet for the next block. If it is not, then all definitions apply to a single block. .br The information in such a sheet is given by text lines of the following form: .br purpose specifier [whitespace] = [whitespace] content text .br [whitespace] is zero or more ASCII 32 (space) or ASCII 9 (tab) characters. The purpose specifier tells the meaning of the content text. Empty content text does not cause a CD-TEXT attribute to be attached. .br The following purpose specifiers apply to the session as a whole: .br Purpose specifier | Content example .br ------------------------------------------------------------- .br Text Code = 8859 .br Language Code = English .br Album Title = Joyful Nights .br Artist Name = United Cat Orchestra .br Songwriter = Various Songwriters .br Composer = Various Composers .br Arranger = Tom Cat .br Album Message = For all our fans .br Catalog Number = 1234567890 .br Genre Code = Classical .br Genre Information = Feline classic music .br Closed Information = This is not to be shown by CD players .br UPC / EAN = 1234567890123 .br Text Data Copy Protection = OFF .br First Track Number = 1 .br Last Track Number = 3 .br The following purpose specifiers apply to particular tracks: .br Purpose specifier | Content example .br ------------------------------------------------------------- .br Track 01 Title = Song of Joy .br Track 01 Artist = Felix and The Purrs .br Track 01 Songwriter = Friedrich Schiller .br Track 01 Composer = Ludwig van Beethoven .br Track 01 Arranger = Tom Cat .br Track 01 Message = Fritz and Louie once were punks .br ISRC 01 = XYCRR1101234 .br Track numbers are decimal despite the leading 0. There should be as many track definitions as there are track source files given. .br See libburn's doc/cdtext.txt for a detailed definition of 0.7T and the possible values for Text Code, Language Code, Genre Code, Text Data Copy Protection. .br The Q sub-channel settings by "UPC / EAN" and "ISRC" may be overridden by options mcn= and isrc=. This will not affect their appearance as CD-TEXT. They may override cuefile= commands CATALOG and ISRC in the same way. .br If options -text cuefile= are given and if the cue sheet file defines CD-TEXT, then only seven input_sheet_v07t= options may be given. They will then be used as CD-TEXT language blocks 1 to 7. .br This option will get into effect only if no option textfile= is given. The write mode must be SAO on CD. All tracks must be -audio tracks. .br The track numbers may be overridden by option cd_start_tno=. .TP .BI \--list_formats List the available format descriptors as reported by the drive for the loaded media. Each descriptor line begins with "Format idx" and the descriptor's list index, followed by a ":", the format type, the number of payload blocks and that same number converted to MiB. .br The meaning of the format types is defined by the MMC standard with command FORMAT UNIT. A user will more be interested in the sizes than in the types. .TP .BI \--list_ignored_options List all ignored cdrecord options. The "-" options cannot be used as addresses of track sources. No track source address may begin with a text equal to an option which ends by "=". The list is ended by an empty line. .TP .BI \--list_speeds Put out a list of speed values as reported by the output drive with the loaded medium. This does not necessarily mean that the medium is writable or that these speeds are actually achievable. Especially the lists reported with empty drive or with ROM media obviously advertise speeds for other media. .br It is not mandatory to use speed values out of the listed range. The drive is supposed to choose a safe speed that is as near to the desired speed as possible. .br At the end of the list, "Write speed L" and "Write speed H" are the best guesses for lower and upper speed limit. "Write speed l" and "Write speed h" may appear only with CD and eventually override the list of other speed offers. .br Only if the drive reports contradicting speed information there will appear "Write speed 0" or "Write speed-1", which tell the outcome of speed selection by options speed=0 or speed=-1, if it deviates from "Write speed L" or "Write speed H", respectively. .TP .BI \--long_toc Like option -toc but marking each session start by a line "first: X last: Y" and each session end by "track:lout ...". .TP .BI \--no_load When aquiring the optical drive, do not try to load its tray. This yields the same behavior for desktop drives with tray loader as is shown by laptop drives which usually lack a motorized tray loader. .TP .BI \--no_rc Only if used as first command line argument this option prevents reading and interpretation of eventual startup files. See section FILES below. .TP .BI \--pacifier_with_newline Adds a newline character to each pacifier line that would elsewise be overwritten by the next pacifier line. Such lines are emitted during a run of writing, formatting, or blanking if option -v is given. .TP .BI \--prodvd_cli_compatible Activates behavior modifications with some DVD situations which bring cdrskin nearer to the behavior of cdrecord-ProDVD: .br Option -multi with unsuitable media is not an error but simply has no effect. .br Options blank=fast and blank=all deformat overwriteable DVD-RW media. .br Option blank=fast does indeed minmal blanking with DVD-RW. This may yield media which can only do DAO but not Incremental Streaming. .TP .BI \--single_track Accept only the last argument of the command line as track source address. .TP .BI stdio_sync= on|off|number Set the number of bytes after which to force output to drives with prefix "stdio:". This forcing keeps the memory from being clogged with lots of pending data for slow devices. Default "on" is the same as "16m". Forced output can be disabled by "off". .TP .BI stream_recording= on|off|number By setting "on" request that compliance to the desired speed setting is preferred over management of write errors. With DVD-RAM and BD this can bring effective write speed near to the nominal write speed of the media. But it will also disable the automatic use of replacement blocks if write errors occur. It might as well be disliked or ignored by the drive. .br If a number is given, then error management stays enabled for all byte addresses below that number. Any number below 16s is the same as "off". .TP .BI tao_to_sao_tsize= size Set an exact fixed size for the next track to be in effect only if the track source cannot deliver a size prediction and no tsize= was specified and an exact track size prediction is demanded by the write mode. .br This was the fallback from bad old times when cdrskin was unable to burn in mode -tao . It came back with minimally blanked DVD-RW, which cannot do Incremental Streaming (-tao), and with explicitly selected write mode -sao for best DVD-ROM compatibility. .br If the track source delivers less bytes than announced then the missing ones will be filled with zeros. .TP .BI --tell_media_space Prepare a recording session, do not perform it but rather inquire the maximum number of 2048 byte data blocks which may be written in the current state of media with the prepared setup. So this option disables recording of data. It does not disable blanking, though, and will measure space afterwards. .br It is not mandatory to give track sources but their nature may influence the available capacity. So for most realistic results one may set up the full burn session and add --tell_media_space. But if one has to expect a cdrskin version prior to 0.3.3 no track source should be given in order not to start an involuntary burn session. In this case set at least -sao or -tao explicitly. .br The result gets printed to standard output. It is 0 or empty if no writing is possible with the given options. This option redirects to stderr all message output except its own result string and eventual output of -msinfo. .TP .BI textfile_to_v07t= path Read a CD-TEXT pack file (e.g. cdtext.dat from a run with -v -v -toc) and print its content in the human readable format that is described with option input_sheet_v07t=. .br The program run ends immediately thereafter. No drive scan will happen and no drive will be acquired. .br To avoid the cdrskin start message in the output, run: cdrskin textfile_to_v07t=cdtext.dat | grep -v '^cdrskin' .TP .BI --two_channel Indicate for subsequent tracks that they were mastered with two channels. .TP .BI write_start_address= byte_offset Set the address on media where to start writing the track. With DVD+RW, DVD-RAM or BD-RE byte_offset must be aligned to 2 kiB blocks, but better is 32 kiB. With DVD-RW 32 kiB alignment is mandatory. .br Other media are not suitable for this option yet. .TP .BI modesty_on_drive= [:parameter=[:parameter=...]] Mode 1 keeps the program from trying to write to the burner drive while its buffer is in danger to be filled by more than parameter "max_percent". If this filling is exceeded then the program will wait until the filling is at most the value of parameter "min_percent". .br Percentages are permissible in the range of 25 to 100. .br This can ease the load on operating system and drive controller and thus help with achieving better input bandwidth if disk and burner are not on independent controllers (like hda and hdb). Unsufficient input bandwidth is indicated by output "(fifo xy%)" of option -v if xy is lower than 90 for some time. modesty_on_drive= might hamper output bandwidth and cause buffer underruns. .br A new use case is to work around the poor simultaneous performance of multiple burn runs on Linux kernel 3.16 and alike. Here it is not about giving the hard disk enough time to fill the fifo, but about keeping ioctl(SG_IO) from blocking for a longer time and thus blocking all other burn runs. .br To have max_percent larger than the burner's best actual buffer fill has the same effect as min_percent==max_percent. Some burners do not use their full buffer with all media types. Watch output "[buf xy%]" of option -v to get an impression of the actual buffer usage. Some burners are not suitable because they report buffer fill with granularity too large in size or time, or because they go to full speed only when their buffer is full. .br If a write attempt is delayed, the program will wait for a number of microseconds which is given by parameter "min_usec" before inquiring the buffer again. iIf more retries occur, this waiting time between inquiries increases up to the value of parameter "max_usec". .br If the delay lasts longer than the number of seconds given by parameter "timeout_sec", then mode 1 is set 0 and normal burning goes on. .br Mode 0 disables this feature. Mode -1 keeps it unchanged. Default is: .br 0:min_percent=65:max_percent=95:timeout_sec=120: min_usec=10000:max_usec=100000 .br The defaults of cdrskin are good for IDE problems. With concurrent Linux SG_IO problems on modern hardware, higher min_percent and lower usec might yield better buffer fills while still avoiding the problem: .br min_percent=90:max_percent=95:min_usec=5000:max_usec=25000 .PP Alphabetical list of options which are only intended for very special situations and not for normal use: .TP .BI \--abort_handler Establish default signal handling not to leave a drive in busy state but rather to shut it down and to wait until it has ended the final operations. This option is only needed for revoking eventual --ignore_signals or --no_abort_handler. .TP .BI \--allow_untested_media Enable the use of media profiles which have been implemented but not yet tested. Currently this option is without effect because no media types are under test reservation. .br (If you really test experimental media, then please report the outcome on libburn-hackers@pykix.org) .TP .BI \--cdtext_dummy Prepare a burn run, report the effective array of CD-TEXT packs to stdout, and then end the program run without starting to burn the session. A blank CD-R or CD-RW has to be present in the drive, nevertheless. .br The output is formatted in lines which describe 18 bytes as 2-digit hex numbers or as single printable characters. See libburn document doc/cdtext.txt about the format of these records. .TP .BI \--cdtext_verbose Like --cdtext_dummy but without preventing the burn run. Combinable with option -dummy to exercise a CD burn run with no persistent impact on the medium. .TP .BI dev_translation= Set drive address alias. This was necessary before cdrskin-0.2.4 to manually translate cdrecord addresses into cdrskin addresses. .br is a single character which may not occur in the address string . is an address as expected to be given by the user via option dev=. is the address to be used instead whenever is given. More than one translation instruction can be given in one cdrskin run. .br E.g.: dev_translation=+ATA:1,0,0+/dev/sr1 dev_translation=+ATA:1,1,0+/dev/sr2 .TP .BI \--drive_abort_on_busy Linux specific: Abort process if a busy drive is encountered. .TP .BI \--drive_blocking Linux specific: Try to wait for a busy drive to become free. This is not guaranteed to work with all drivers. Some need nonblocking i/o. .TP .BI \--drive_f_setlk Linux specific: Try to get exclusive lock on drive device file via fcntl(2). .TP .BI \--drive_not_exclusive Linux specific: Combine --drive_not_f_setlk and --drive_not_o_excl. .TP .BI \--drive_not_f_setlk Linux specific: Do not try to get exclusive lock on drive device file via fcntl(2). .TP .BI \--drive_not_o_excl Linux specific: Do not ask the operating system to prevent opening busy drives. Whether this leads to senseful behavior depends on operating system and kernel. .TP .BI drive_scsi_dev_family= sr | scd | sg Linux specific: Select a SCSI device file family to be scanned for by options --devices, --device_links and -scanbus. Normally this is /dev/sgN on kernel versions < 2.6 and /dev/srN on kernels >= 2.6 . This option explicitly overrides that default in order to meet other programs at a common device file for each drive. On kernel 2.4 families sr and scd will find no drives. .br Device file family /dev/hdX on kernel >= 2.6 is not affected by this setting. .TP .BI \--drive_scsi_exclusive Linux specific: Try to exclusively reserve device files /dev/srN, /dev/scdM, /dev/sgK of drives. This would be helpful to protect against collisions with program growisofs. Regrettably on Linux kernel 2.4 with ide-scsi emulation this seems not to work. Whether it becomes helpful with new Linux systems has to be evaluated. .TP .BI \--fifo_disable Disable fifo despite any fs=. .TP .BI \--fifo_per_track Use a separate fifo for each track. .TP .BI \--fill_up_media Expand the last track of the session to occupy all remaining free space on the media. .br This option overrides option -multi. It will not fill up media if option -sao is given with CD media. .br .B Caution: With multi-session media this option might increase readatibility on DVD-ROM drives but with some DVD recorders and media types it might also fail to produce readable media at all. "Your mileage may vary". .br You can expect the best possible read compatibility if you do not use -multi at all. .TP .BI grab_drive_and_wait= seconds Open the addressed drive, wait the given number of seconds, release the drive, and do normal work as indicated by the other options used. This option helps to explore the program behavior when faced with busy drives. Just start a second cdrskin with option --devices while grab_drive_and_wait= is still active. .TP .BI \--ignore_signals Try to ignore any signals rather than to abort the program. This is not a very good idea. You might end up waiting a very long time for cdrskin to finish. .TP .BI \--no_abort_handler On signals exit even if the drive is in busy state. This is not a very good idea. You might end up with a stuck drive that refuses to hand out the media. .TP .BI \--no_blank_appendable Refuse to blank appendable CD-RW or DVD-RW. This is a feature that was once builtin with libburn. No information available for what use case it was needed. .TP .BI \--no_convert_fs_adr Do only literal translations of dev=. This prevents cdrskin from test-opening device files in order to find one that matches the given dev= specifier. .br Partly Linux specific: Such opening is needed for Bus,Target,Lun addresses unless option --old_pseudo_scsi_adr is given. It is also needed to resolve device file addresses which are not listed with cdrskin --devices but nevertheless point to a usable drive. (Like /dev/sg0 using the same SCSI address as /dev/sr0.) .TP .BI \--obs_pad Pad the data of last write operation of a DVD-R[W] DAO session or stdio: pseudo-drive up to the full size of an output chunk. This padding has to be applied automatically to the other DVD and BD media types, where it causes e.g. ISO images to have trailing unclaimed blocks. .br Use this option if there is the suspicion that DAO sessions abort with your kernel and/or DVD drive, if their size is not a multiple of 16 blocks. .br This option may also get enabled at compile time of libburn. .TP .BI \--old_pseudo_scsi_adr Linux specific: Use and report literal Bus,Target,Lun addresses rather than real SCSI and pseudo ATA addresses. This method is outdated and was never compatible with original cdrecord. .TP .BI sao_postgap= off|number Define whether a post-gap shall be written at the end of the track and how many sectors this gap shall have. A post-gap occupies the range of an additional index of the track. It contains zeros. No bytes from the track source will be read for writing the post-gap. .br This setting affects only CD SAO write runs. .TP .BI sao_pregap= off|number Define whether a pre-gap shall be written before the track and how many sectors this pre-gap shall have. A pre-gap is written in the range of track index 0 and contains zeros. No bytes from the track source will be read for writing the pre-gap. .br This setting affects only CD SAO write runs. .br The first track automatically gets a pre-gap of at least 150 sectors. Its size can only be enlarged by this call. .TP .BI --xa1-ignore Silently interpret option -xa1 as -data. This may be necessary if a frontent does not prepare -xa1 block headers but insists in using option -xa1. .SH EXAMPLES .SS .B Get an overview of drives and their addresses: .br cdrskin -scanbus .br cdrskin dev=ATA -scanbus .br cdrskin --device_links .SS .B Get info about a particular drive or loaded media: .br cdrskin dev=0,1,0 -checkdrive .br cdrskin dev=ATA:1,0,0 -v -atip .br cdrskin dev=/dev/hdc -minfo .SS .B Prepare CD-RW or DVD-RW for re-use, DVD-RAM or BD-RE for first use: .br cdrskin -v dev=/dev/sg1 blank=as_needed -eject .SS .B Format DVD-RW to avoid need for blanking before re-use: .br cdrskin -v dev=/dev/sr0 blank=format_overwrite .SS .B De-format DVD-RW to make it capable of multi-session again: .br cdrskin -v dev=/dev/sr0 blank=deformat_sequential .SS .B Write ISO-9660 filesystem image as only one to blank or formatted media: .br cdrskin -v dev=/dev/hdc speed=12 fs=8m \\ .br blank=as_needed -eject padsize=300k my_image.iso .SS .B Write compressed afio archive on-the-fly (not possible with minimally blanked DVD-RW or DVD-R DL): .br find . | afio -oZ - | \\ .br cdrskin -v dev=0,1,0 fs=32m speed=8 \\ .br blank=as_needed padsize=300k - .SS .B Write multi-session to the same CD, DVD-R[W], DVD+R[/DL], or BD-R: .br cdrskin dev=/dev/sr0 -v padsize=300k -multi 1.iso .br cdrskin dev=/dev/sr0 -v padsize=300k -multi 2.iso .br cdrskin dev=/dev/sr0 -v padsize=300k -multi 3.iso .br cdrskin dev=/dev/sr0 -v padsize=300k 4.iso .SS .B Get multi-session info for option -C of program mkisofs: .br c_values=$(cdrskin dev=/dev/hdc -msinfo 2>/dev/null) .br mkisofs ... -C "$c_values" ... .SS .B Inquire free space on media for a -multi run: .br x=$(cdrskin dev=/dev/sr0 -multi \\ .br --tell_media_space 2>/dev/null) .br echo "Available: $x blocks of 2048 data bytes" .SS .B Write audio tracks and CD-TEXT to CD: .br cdrskin -v dev=ATA:1,0,0 speed=48 -sao \\ .br input_sheet_v07t=cdtext.v07t \\ .br track1.wav track2.au -audio -swab track3.raw .SS .B Extract audio tracks and CD-TEXT from CD into directory /home/me/my_cd: .br mkdir /home/me/my_cd .br cdrskin -v dev=/dev/sr0 extract_audio_to=/home/me/my_cd \\ .br cdtext_to_v07t=/home/me/my_cd/cdtext.v07t .SH FILES .SS Startup files: .br If not --no_rc is given as the first argument then cdrskin attempts on startup to read the arguments from the following files: .PP .br .B /etc/default/cdrskin .br .B /etc/opt/cdrskin/rc .br .B /etc/cdrskin/cdrskin.conf .br .B $HOME/.cdrskinrc .br .PP The files are read in the sequence given above, but none of them is required for cdrskin to function properly. Each readable line is treated as one single argument. No extra blanks. A first character '#' marks a comment, empty lines are ignored. .br Example content of a startup file: .br # This is the default device .br dev=0,1,0 .br # Some more options .br fifo_start_at=0 .br fs=16m .br .SS Disabling superuser safety precautions: The superuser is normally banned from using any other emulated drive but /dev/null. This ban can be lifted by the existence of file .PP .B /root/cdrskin_permissions/allow_emulated_drives .PP where the directory must be owned by the superuser and must not offer w-permissions for group or others. .br Warning: Superusers must take care not to spoil their hard disk via its raw block device (like stdio:/dev/hda or stdio:/dev/sd0). .SH SEE ALSO .TP Formatting data track sources for cdrskin: .br .BR mkisofs (8), .BR genisoimage (8), .BR xorriso (1), .BR afio (1), .BR star (1) .br .TP Other CD/DVD/BD burn programs: .br .BR cdrecord (1), .BR wodim (1), .BR xorriso (1) .br .TP For DVD/BD burning (also tutor of libburn's DVD/BD capabilities): .br .BR growisofs (1) .br .SH AUTHOR cdrskin was written by Thomas Schmitt . .PP This manual page was started by George Danchev and is now maintained by Thomas Schmitt. libburn-1.4.2/cdrskin/cdrskin_timestamp.h0000644000175700017510000000005612652646312015442 00000000000000#define Cdrskin_timestamP "2016.01.29.100001" libburn-1.4.2/cdrskin/cdrecord_spy.sh0000755000175700017510000000207112652644223014566 00000000000000#!/bin/sh # # Spying on the call to cdrecord. # # Move $(which cdrecord) to $(dirname $(which cdrecord))/real_cdrecord . # Install this sript instead. (Do not forget to revoke this after the test.) # # The report target is set in variable rt. # The default is this file : rt=/tmp/cdrecord_spy_log # To use a bystanding xterm as target i find out the pty address by # executing in that terminal # sleep 12345 # and then running in another terminal # ps -ef | grep 'sleep 12345' # which answers something like # thomas 21303 30518 0 14:02 pts/23 00:00:00 sleep 12345 # thomas 21421 30523 0 14:02 pts/24 00:00:00 grep sleep 12345 # from which i learn that pts/23 is sleeping 12345. Now sleep can be aborted. # # rt=/dev/pts/23 echo '------------------------------------- cdrecord_spy 0.1.0 -------' >>"$rt" date >>"$rt" echo '----------------------------------------------------------------' >>"$rt" echo "$0" >>"$rt" for i in "$@" do echo "$i" >>"$rt" done echo '------------------------------------- cdrecord_spy 0.1.0 - end -' >>"$rt" real_cdrecord "$@" libburn-1.4.2/cdrskin/cdrfifo.c0000644000175700017510000011450412652644223013334 00000000000000/* cdrfifo.c , Copyright 2006 Thomas Schmitt A fd-to-fd or fd-to-memory fifo to be used within cdrskin or independently. By chaining of fifo objects, several fifos can be run simultaneously in fd-to-fd mode. Modes are controlled by parameter flag of Cdrfifo_try_to_work(). Provided under GPL license within cdrskin and under BSD license elsewise. */ /* Compile as standalone tool : cc -g -o cdrfifo -DCdrfifo_standalonE cdrfifo.c */ #include #include #include #include #include #include #include #include #include #include #ifndef Cdrfifo_standalonE /* <<< until release of 0.7.4 : for Libburn_has_open_trac_srC */ #include "../libburn/libburn.h" #endif #include "cdrfifo.h" /* Macro for creation of arrays of objects (or single objects) */ #define TSOB_FELD(typ,anz) (typ *) calloc(anz, sizeof(typ)); #define Cdrfifo_buffer_chunK 2048 /** Number of follow-up fd pairs */ #define Cdrfifo_ffd_maX 100 /* 1= enable , 0= disable status messages to stderr 2= report each */ static int Cdrfifo_debuG= 0; struct CdrfifO { int chunk_size; int source_fd; double in_counter; double fd_in_counter; double fd_in_limit; char *buffer; int buffer_size; int buffer_is_full; int write_idx; int read_idx; int dest_fd; double out_counter; struct timeval start_time; double speed_limit; /* statistics */ double interval_counter; struct timeval interval_start_time; double interval_start_counter; int total_min_fill; int interval_min_fill; double put_counter; double get_counter; double empty_counter; double full_counter; /* eventual ISO-9660 image size obtained from first 64k of input */ double iso_fs_size; char *iso_fs_descr; /* eventually block 16 to 31 of input */ /* (sequential) fd chaining */ /* fds: 0=source, 1=dest */ int follow_up_fds[Cdrfifo_ffd_maX][2]; /* index of first byte in buffer which does not belong to predecessor fd */ int follow_up_eop[Cdrfifo_ffd_maX]; /* if follow_up_eop[i]==buffer_size : read_idx was 0 when this was set */ int follow_up_was_full_buffer[Cdrfifo_ffd_maX]; /* index of first byte in buffer which belongs to [this] fd pair */ int follow_up_sod[Cdrfifo_ffd_maX]; /* values for fd_in_limit */ double follow_up_in_limits[Cdrfifo_ffd_maX]; /* number of defined follow-ups */ int follow_up_fd_counter; /* index of currently active (i.e. reading) follow-up */ int follow_up_fd_idx; /* (simultaneous) peer chaining */ struct CdrfifO *next; struct CdrfifO *prev; /* rank in peer chain */ int chain_idx; }; /** Create a fifo object. @param ff Returns the address of the new object. @param source_fd Filedescriptor opened to a readable data stream. @param dest_fd Filedescriptor opened to a writable data stream. To work with libburn, it needs to be attached to a struct burn_source object. @param chunk_size Size of buffer block for a single transaction (0=default) @param buffer_size Size of fifo buffer @param flag bit0= Debugging verbosity @return 1 on success, <=0 on failure */ int Cdrfifo_new(struct CdrfifO **ff, int source_fd, int dest_fd, int chunk_size, int buffer_size, int flag) { struct CdrfifO *o; struct timezone tz; int i; (*ff)= o= TSOB_FELD(struct CdrfifO,1); if(o==NULL) return(-1); if(chunk_size<=0) chunk_size= Cdrfifo_buffer_chunK; o->chunk_size= chunk_size; if(buffer_size%chunk_size) buffer_size+= chunk_size-(buffer_size%chunk_size); o->source_fd= source_fd; o->in_counter= 0.0; o->fd_in_counter= 0; o->fd_in_limit= -1.0; o->buffer= NULL; o->buffer_is_full= 0; o->buffer_size= buffer_size; o->write_idx= 0; o->read_idx= 0; o->dest_fd= dest_fd; o->out_counter= 0.0; memset(&(o->start_time),0,sizeof(o->start_time)); gettimeofday(&(o->start_time),&tz); o->speed_limit= 0.0; o->interval_counter= 0.0; memset(&(o->interval_start_time),0,sizeof(o->interval_start_time)); gettimeofday(&(o->interval_start_time),&tz); o->interval_start_counter= 0.0; o->total_min_fill= buffer_size; o->interval_min_fill= buffer_size; o->put_counter= 0.0; o->get_counter= 0.0; o->empty_counter= 0.0; o->full_counter= 0.0; o->iso_fs_size= -1.0; o->iso_fs_descr= NULL; for(i= 0; ifollow_up_fds[i][0]= o->follow_up_fds[i][1]= -1; o->follow_up_eop[i]= o->follow_up_sod[i]= -1; o->follow_up_was_full_buffer[i]= 0; o->follow_up_in_limits[i]= -1.0; } o->follow_up_fd_counter= 0; o->follow_up_fd_idx= -1; o->next= o->prev= NULL; o->chain_idx= 0; #ifdef Libburn_has_open_trac_srC o->buffer= burn_os_alloc_buffer((size_t) buffer_size, 0); #else o->buffer= TSOB_FELD(char,buffer_size); #endif /* ! Libburn_has_open_trac_srC */ if(o->buffer==NULL) goto failed; return(1); failed:; Cdrfifo_destroy(ff,0); return(-1); } /** Close any output fds */ int Cdrfifo_close(struct CdrfifO *o, int flag) { int i; if(o->dest_fd!=-1) close(o->dest_fd); o->dest_fd= -1; for(i=0; ifollow_up_fd_counter; i++) { if(o->follow_up_fds[i][1]!=-1) close(o->follow_up_fds[i][1]); o->follow_up_fds[i][1]= -1; } return(1); } /** Release from memory a fifo object previously created by Cdrfifo_new(). @param ff The victim (gets returned as NULL, call can stand *ff==NULL)) @param flag Bitfield for control purposes: bit0= do not close destination fd */ int Cdrfifo_destroy(struct CdrfifO **ff, int flag) /* flag bit0= do not close destination fd */ { struct CdrfifO *o; o= *ff; if(o==NULL) return(0); if(o->next!=NULL) o->next->prev= o->prev; if(o->prev!=NULL) o->prev->next= o->next; if(!(flag&1)) Cdrfifo_close(o,0); /* eventual closing of source fds is the job of the calling application */ if(o->iso_fs_descr!=NULL) free((char *) o->iso_fs_descr); if(o->buffer!=NULL) #ifdef Libburn_has_open_trac_srC burn_os_free_buffer(o->buffer, o->buffer_size, 0); #else free((char *) o->buffer); #endif /* Libburn_has_open_trac_srC */ free((char *) o); (*ff)= NULL; return(1); } int Cdrfifo_get_sizes(struct CdrfifO *o, int *chunk_size, int *buffer_size, int flag) { *chunk_size= o->chunk_size; *buffer_size= o->buffer_size; return(1); } /** Set a speed limit for buffer output. @param o The fifo object @param bytes_per_second >0 catch up slowdowns over the whole run time <0 catch up slowdowns only over one interval =0 disable speed limit */ int Cdrfifo_set_speed_limit(struct CdrfifO *o, double bytes_per_second, int flag) { o->speed_limit= bytes_per_second; return(1); } /** Set a fixed size for input in order to cut off any unwanted tail @param o The fifo object @param idx index for fds attached via Cdrfifo_attach_follow_up_fds(), first attached is 0, <0 directs limit to active fd limit (i.e. first track is -1, second track is 0, third is 1, ...) */ int Cdrfifo_set_fd_in_limit(struct CdrfifO *o, double fd_in_limit, int idx, int flag) { if(idx<0) { o->fd_in_limit= fd_in_limit; return(1); } if(idx >= o->follow_up_fd_counter) return(0); o->follow_up_in_limits[idx]= fd_in_limit; return(1); } int Cdrfifo_set_fds(struct CdrfifO *o, int source_fd, int dest_fd, int flag) { o->source_fd= source_fd; o->dest_fd= dest_fd; return(1); } int Cdrfifo_get_fds(struct CdrfifO *o, int *source_fd, int *dest_fd, int flag) { *source_fd= o->source_fd; *dest_fd= o->dest_fd; return(1); } /** Attach a further pair of input and output fd which will use the same fifo buffer when its predecessors are exhausted. Reading will start as soon as reading of the predecessor encounters EOF. Writing will start as soon as all pending predecessor data are written. @return index number of new item + 1, <=0 indicates error */ int Cdrfifo_attach_follow_up_fds(struct CdrfifO *o, int source_fd, int dest_fd, int flag) { if(o->follow_up_fd_counter>=Cdrfifo_ffd_maX) return(0); o->follow_up_fds[o->follow_up_fd_counter][0]= source_fd; o->follow_up_fds[o->follow_up_fd_counter][1]= dest_fd; o->follow_up_fd_counter++; return(o->follow_up_fd_counter); } /** Attach a further fifo which shall be processed simultaneously with this one by Cdrfifo_try_to_work() in fd-to-fd mode. */ int Cdrfifo_attach_peer(struct CdrfifO *o, struct CdrfifO *next, int flag) { int idx; struct CdrfifO *s; for(s= o;s->prev!=NULL;s= s->prev); /* determine start of o-chain */ for(;o->next!=NULL;o= o->next); /* determine end of o-chain */ for(;next->prev!=NULL;next= next->prev); /* determine start of next-chain */ next->prev= o; o->next= next; for(idx= 0;s!=NULL;s= s->next) s->chain_idx= idx++; return(1); } static int Cdrfifo_tell_buffer_space(struct CdrfifO *o, int flag) { if(o->buffer_is_full) return(0); if(o->write_idx>=o->read_idx) return((o->buffer_size - o->write_idx) + o->read_idx); return(o->read_idx - o->write_idx); } /** Obtain buffer state. @param o The buffer object @param fill Returns the number of pending payload bytes in the buffer @param space Returns the number of unused buffer bytes @param flag Unused yet @return -1=error , 0=inactive , 1=reading and writing , 2=reading ended (but still writing) */ int Cdrfifo_get_buffer_state(struct CdrfifO *o,int *fill,int *space,int flag) /* return : -1=error 0=inactive 1=reading and writing 2=reading ended, still writing */ { *space= Cdrfifo_tell_buffer_space(o,0); *fill= o->buffer_size-(*space); if(o->dest_fd==-1) return(0); if(o->source_fd<0) return(2); return(1); } int Cdrfifo_get_counters(struct CdrfifO *o, double *in_counter, double *out_counter, int flag) { *in_counter= o->in_counter; *out_counter= o->out_counter; return(1); } /** reads min_fill and begins measurement interval for next min_fill */ int Cdrfifo_next_interval(struct CdrfifO *o, int *min_fill, int flag) { struct timezone tz; o->interval_counter++; gettimeofday(&(o->interval_start_time),&tz); o->interval_start_counter= o->out_counter; *min_fill= o->interval_min_fill; o->interval_min_fill= o->buffer_size - Cdrfifo_tell_buffer_space(o,0); return(1); } int Cdrfifo_get_min_fill(struct CdrfifO *o, int *total_min_fill, int *interval_min_fill, int flag) { *total_min_fill= o->total_min_fill; *interval_min_fill= o->interval_min_fill; return(1); } int Cdrfifo_get_iso_fs_size(struct CdrfifO *o, double *size_in_bytes, int flag) { *size_in_bytes= o->iso_fs_size; return(o->iso_fs_size>=2048); } int Cdrfifo_adopt_iso_fs_descr(struct CdrfifO *o, char **pt, int flag) { *pt= o->iso_fs_descr; o->iso_fs_descr= NULL; return(*pt!=NULL); } /** Get counters which are mentioned by cdrecord at the end of burning. It still has to be examined wether they mean what i believe they do. */ int Cdrfifo_get_cdr_counters(struct CdrfifO *o, double *put_counter, double *get_counter, double *empty_counter, double *full_counter, int flag) { *put_counter= o->put_counter; *get_counter= o->get_counter; *empty_counter= o->empty_counter; *full_counter= o->full_counter; return(1); } /** Adjust a given buffer fill value so it will not cross an eop boundary. @param o The fifo to exploit. @param buffer_fill The byte count to adjust. @param eop_idx If eop boundary exactly hit: index of follow-up fd pair @param flag Unused yet. @return 0= nothing changed , 1= buffer_fill adjusted */ int Cdrfifo_eop_adjust(struct CdrfifO *o,int *buffer_fill, int *eop_idx, int flag) { int i,eop_is_near= 0,valid_fill; *eop_idx= -1; valid_fill= *buffer_fill; for(i=0; i<=o->follow_up_fd_idx; i++) { if(o->follow_up_eop[i]>=0 && o->follow_up_eop[i]>=o->read_idx) { eop_is_near= 1; if(o->follow_up_eop[i]buffer_size || o->read_idx>0) { valid_fill= o->follow_up_eop[i]-o->read_idx; o->follow_up_was_full_buffer[i]= 0; } else { /* If an input fd change hit exactly the buffer end then follow_up_eop points to buffer_size and not to 0. So it is time to switch output pipes unless this is immediately after follow_up_eop was set and read_idx was 0 (... if this is possible at all while write_idx is 0). follow_up_was_full_buffer was set in this case and gets invalid as soon as a non-0 read_idx is detected (see above). */ if(o->follow_up_was_full_buffer[i]) valid_fill= o->buffer_size; else valid_fill= 0; /* the current pipe is completely served */ } if(valid_fill==0) *eop_idx= i; else if(valid_fillchunk_size) eop_is_near= 2; /* for debugging. to carry a break point */ break; } } if(*buffer_fill>valid_fill) *buffer_fill= valid_fill; return(!!eop_is_near); } /* Perform pre-select activities of Cdrfifo_try_to_work() */ static int Cdrfifo_setup_try(struct CdrfifO *o, struct timeval start_tv, double start_out_counter, int *still_to_wait, int *speed_limiter, int *ready_to_write, fd_set *rds, fd_set *wts, int *max_fd, int flag) /* flag: bit0= enable debug pacifier (same with Cdrfifo_debuG) bit1= do not write, just fill buffer bit2= fd-to-memory mode (else fd-to-fd mode): rather than writing a chunk return it and its size in reply_* bit3= with bit2: do not check destination fd for readiness */ { int buffer_space,buffer_fill,eop_reached= -1,eop_is_near= 0,was_closed; int fd_buffer_fill, eop_reached_counter= 0; struct timeval current_tv; struct timezone tz; double diff_time,diff_counter,limit,min_wait_time; setup_try:; buffer_space= Cdrfifo_tell_buffer_space(o,0); fd_buffer_fill= buffer_fill= o->buffer_size - buffer_space; #ifdef NIX fprintf(stderr,"cdrfifo_debug: o->write_idx=%d o->read_idx=%d o->source_fd=%d\n",o->write_idx,o->read_idx,o->source_fd); if(buffer_fill>10) sleep(1); #endif if(o->follow_up_fd_idx>=0) eop_is_near= Cdrfifo_eop_adjust(o,&fd_buffer_fill,&eop_reached,0); if(fd_buffer_fill<=0 && (o->source_fd==-1 || eop_reached>=0) ) { was_closed= 0; if(o->dest_fd!=-1 && !(flag&4)) close(o->dest_fd); if(o->dest_fd<0) was_closed= 1; else o->dest_fd= -1; if(eop_reached>=0) { /* switch to next output fd */ o->dest_fd= o->follow_up_fds[eop_reached][1]; if(Cdrfifo_debuG) fprintf(stderr,"\ncdrfifo %d: new fifo destination fd : %d\n", o->chain_idx,o->dest_fd); o->read_idx= o->follow_up_sod[eop_reached]; o->follow_up_eop[eop_reached]= -1; eop_is_near= 0; eop_reached= -1; eop_reached_counter= 0; goto setup_try; } else { /* work is really done */ if((!was_closed) && ((flag&1)||Cdrfifo_debuG)) fprintf(stderr, "\ncdrfifo %d: w=%d r=%d | b=%d s=%d | i=%.f o=%.f (done)\n", o->chain_idx,o->write_idx,o->read_idx,buffer_fill,buffer_space, o->in_counter,o->out_counter); return(2); } } else if(eop_reached>=0) eop_reached_counter++; if(o->interval_counter>0) { if(o->total_min_fill>buffer_fill && o->source_fd>=0) o->total_min_fill= buffer_fill; if(o->interval_min_fill>buffer_fill) o->interval_min_fill= buffer_fill; } *speed_limiter= 0; if(o->speed_limit!=0) { gettimeofday(¤t_tv,&tz); if(o->speed_limit>0) { diff_time= ((double) current_tv.tv_sec)-((double) o->start_time.tv_sec)+ (((double) current_tv.tv_usec)-((double) o->start_time.tv_usec))*1e-6; diff_counter= o->out_counter; limit= o->speed_limit; } else if(flag&4) { if(o->interval_start_time.tv_sec==0) o->interval_start_time= start_tv; diff_time= ((double) current_tv.tv_sec) - ((double) o->interval_start_time.tv_sec) + (((double) current_tv.tv_usec) -((double) o->interval_start_time.tv_usec))*1e-6; diff_counter= o->out_counter - o->interval_start_counter; limit= -o->speed_limit; } else { diff_time= ((double) current_tv.tv_sec) - ((double) start_tv.tv_sec) + (((double) current_tv.tv_usec) -((double)start_tv.tv_usec))*1e-6; diff_counter= o->out_counter - start_out_counter; limit= -o->speed_limit; } if(diff_time>0.0) if(diff_counter/diff_time>limit) { min_wait_time= (diff_counter/limit - diff_time)*1.0e6; if(min_wait_time<*still_to_wait) *still_to_wait= min_wait_time; if(*still_to_wait>0) *speed_limiter= 1; } } if(o->source_fd>=0) { if(buffer_space>0) { FD_SET((o->source_fd),rds); if(*max_fdsource_fd) *max_fd= o->source_fd; } else if(o->interval_counter>0) o->full_counter++; } *ready_to_write= 0; if(o->dest_fd>=0 && (!(flag&2)) && !*speed_limiter) { if(fd_buffer_fill>=o->chunk_size || o->source_fd<0 || eop_is_near) { if((flag&(4|8))==(4|8)) { *still_to_wait= 0; *ready_to_write= 1; } else { FD_SET((o->dest_fd),wts); if(*max_fddest_fd) *max_fd= o->dest_fd; } } else if(o->interval_counter>0) o->empty_counter++; } return(1); } /* Perform post-select activities of Cdrfifo_try_to_work() */ static int Cdrfifo_transact(struct CdrfifO *o, fd_set *rds, fd_set *wts, char *reply_buffer, int *reply_count, int flag) /* flag: bit0= enable debug pacifier (same with Cdrfifo_debuG) bit1= do not write, just fill buffer bit2= fd-to-memory mode (else fd-to-fd mode): rather than writing a chunk return it and its size in reply_* bit3= with bit2: do not check destination fd for readiness return: <0 = error , 0 = idle , 1 = did some work */ { double buffer_space; int can_read,can_write= 0,ret,did_work= 0,idx,sod, eop_idx; buffer_space= Cdrfifo_tell_buffer_space(o,0); if(o->dest_fd>=0) if(FD_ISSET((o->dest_fd),wts)) { can_write= o->buffer_size - buffer_space; if(can_write>o->chunk_size) can_write= o->chunk_size; if(o->read_idx+can_write > o->buffer_size) can_write= o->buffer_size - o->read_idx; if(o->follow_up_fd_idx>=0) { Cdrfifo_eop_adjust(o,&can_write,&eop_idx,0); if(can_write<=0) goto after_write; } if(flag&4) { memcpy(reply_buffer,o->buffer+o->read_idx,can_write); *reply_count= ret= can_write; } else { ret= write(o->dest_fd,o->buffer+o->read_idx,can_write); } if(ret==-1) { /* >>> handle broken pipe */; fprintf(stderr,"\ncdrfifo %d: on write: errno=%d , \"%s\"\n", o->chain_idx,errno, errno==0?"-no error code available-":strerror(errno)); if(!(flag&4)) close(o->dest_fd); o->dest_fd= -1; {ret= -1; goto ex;} } did_work= 1; o->get_counter++; o->out_counter+= can_write; o->read_idx+= can_write; if(o->read_idx>=o->buffer_size) o->read_idx= 0; o->buffer_is_full= 0; } after_write:; if(o->source_fd>=0) if(FD_ISSET((o->source_fd),rds)) { can_read= o->buffer_size - o->write_idx; #ifdef Libburn_has_open_trac_srC /* ts A91115 This chunksize must be aligned to filesystem blocksize. */ #define Cdrfifo_o_direct_chunK 32768 if(o->write_idx < o->read_idx && o->write_idx + can_read > o->read_idx) can_read= o->read_idx - o->write_idx; if(o->fd_in_limit>=0.0) if(can_read > o->fd_in_limit - o->fd_in_counter) can_read= o->fd_in_limit - o->fd_in_counter; /* Make sure to read with properly aligned size */ if(can_read > Cdrfifo_o_direct_chunK) can_read= Cdrfifo_o_direct_chunK; else if(can_read < Cdrfifo_o_direct_chunK) can_read= -1; ret= 0; if(can_read>0) ret= read(o->source_fd,o->buffer+o->write_idx,can_read); if(can_read < 0) { /* waiting for a full Cdrfifo_o_direct_chunK to fit */ if(can_write <= 0 && o->dest_fd >= 0) { fd_set rds,wts,exs; struct timeval wt; FD_ZERO(&rds); FD_ZERO(&wts); FD_ZERO(&exs); FD_SET((o->dest_fd),&wts); wt.tv_sec= 0; wt.tv_usec= 10000; select(o->dest_fd + 1,&rds, &wts, &exs, &wt); } } else #else /* Libburn_has_open_trac_srC */ if(can_read>o->chunk_size) can_read= o->chunk_size; if(o->write_idxread_idx && o->write_idx+can_read > o->read_idx) can_read= o->read_idx - o->write_idx; if(o->fd_in_limit>=0.0) if(can_read > o->fd_in_limit - o->fd_in_counter) can_read= o->fd_in_limit - o->fd_in_counter; ret= 0; if(can_read>0) ret= read(o->source_fd,o->buffer+o->write_idx,can_read); #endif /* ! Libburn_has_open_trac_srC */ if(ret==-1) { /* >>> handle input error */; fprintf(stderr,"\ncdrfifo %d: on read: errno=%d , \"%s\"\n", o->chain_idx,errno, errno==0?"-no error code available-":strerror(errno)); o->source_fd= -1; } else if(ret==0) { /* eof */ /* activate eventual follow-up source fd */ if(Cdrfifo_debuG || (flag&1)) fprintf(stderr,"\ncdrfifo %d: on read(%d,buffer,%d): eof\n", o->chain_idx,o->source_fd,can_read); if(o->follow_up_fd_idx+1 < o->follow_up_fd_counter) { idx= ++(o->follow_up_fd_idx); o->source_fd= o->follow_up_fds[idx][0]; /* End-Of-Previous */ if(o->write_idx==0) { o->follow_up_eop[idx]= o->buffer_size; /* A70304 : can this happen ? */ o->follow_up_was_full_buffer[idx]= (o->read_idx==0); if(Cdrfifo_debuG || (flag&1)) fprintf(stderr,"\ncdrfifo %d: write_idx 0 on eop: read_idx= %d\n", o->chain_idx,o->read_idx); } else o->follow_up_eop[idx]= o->write_idx; /* Start-Of-Data . Try to start at next full chunk */ sod= o->write_idx; if(o->write_idx%o->chunk_size) sod+= o->chunk_size - (o->write_idx%o->chunk_size); /* but do not catch up to the read pointer */ if((o->write_idx<=o->read_idx && o->read_idx<=sod) || sod==o->read_idx) sod= o->write_idx; if(sod>=o->buffer_size) sod= 0; o->follow_up_sod[idx]= sod; o->write_idx= sod; o->fd_in_counter= 0; o->fd_in_limit= o->follow_up_in_limits[idx]; if(Cdrfifo_debuG || (flag&1)) fprintf(stderr,"\ncdrfifo %d: new fifo source fd : %d\n", o->chain_idx,o->source_fd); } else { o->source_fd= -1; } } else { did_work= 1; o->put_counter++; o->in_counter+= ret; o->fd_in_counter+= ret; o->write_idx+= ret; if(o->write_idx>=o->buffer_size) o->write_idx= 0; if(o->write_idx==o->read_idx) o->buffer_is_full= 1; } } ret= !!did_work; ex:; return(ret); } /** Check for pending data at the fifo's source file descriptor and wether the fifo is ready to take them. Simultaneously check the buffer for existing data and the destination fd for readiness to accept some. If so, a small chunk of data is transfered to and/or from the fifo. This is done for the given fifo object and all members of its next-chain. The check and transactions are repeated until a given timespan has elapsed. libburn applications call this function in the burn loop instead of sleep(). It may also be used instead of read(). Then it returns as soon as an output transaction would be performed. See flag:bit2. @param o The fifo object @param wait_usec The time in microseconds after which the function shall return. @param reply_buffer with bit2: Returns write-ready buffer chunk and must be able to take at least chunk_size bytes @param reply_count with bit2: Returns number of writeable bytes in reply @param flag Bitfield for control purposes: bit0= Enable debug pacifier (same with Cdrfifo_debuG) bit1= Do not write, just fill buffer bit2= fd-to-memory mode (else fd-to-fd mode): Rather than writing a chunk return it and its size. No simultaneous processing of chained fifos. bit3= With bit2: do not check destination fd for readiness @return <0 = error , 0 = idle , 1 = did some work , 2 = all work is done */ int Cdrfifo_try_to_work(struct CdrfifO *o, int wait_usec, char *reply_buffer, int *reply_count, int flag) { struct timeval wt,start_tv,current_tv; struct timezone tz; fd_set rds,wts,exs; int ready,ret,max_fd= -1,buffer_space,dummy,still_active= 0; int did_work= 0,elapsed,still_to_wait,speed_limiter= 0,ready_to_write= 0; double start_out_counter; struct CdrfifO *ff; start_out_counter= o->out_counter; gettimeofday(&start_tv,&tz); still_to_wait= wait_usec; if(flag&4) *reply_count= 0; try_again:; /* is there still a destination open ? */ for(ff= o; ff!=NULL; ff= ff->next) if(ff->dest_fd!=-1) break; if(ff==NULL) return(2); FD_ZERO(&rds); FD_ZERO(&wts); FD_ZERO(&exs); for(ff= o; ff!=NULL; ff= ff->next) { ret= Cdrfifo_setup_try(ff,start_tv,start_out_counter, &still_to_wait,&speed_limiter,&ready_to_write, &rds,&wts,&max_fd,flag&15); if(ret<=0) return(ret); else if(ret==2) { /* This fifo is done */; } else still_active= 1; if(flag&2) break; } if(!still_active) return(2); if(still_to_wait>0 || max_fd>=0) { wt.tv_sec= still_to_wait/1000000; wt.tv_usec= still_to_wait%1000000; ready= select(max_fd+1,&rds,&wts,&exs,&wt); } else ready= 0; if(ready<=0) { if(!ready_to_write) goto check_wether_done; FD_ZERO(&rds); } if(ready_to_write) FD_SET((o->dest_fd),&wts); for(ff= o; ff!=NULL; ff= ff->next) { ret= Cdrfifo_transact(ff,&rds,&wts,reply_buffer,reply_count,flag&15); if(ret<0) goto ex; if(ret>0) did_work= 1; if(flag&2) break; } check_wether_done:; if((flag&4) && *reply_count>0) {ret= 1; goto ex;} gettimeofday(¤t_tv,&tz); elapsed= (current_tv.tv_sec-start_tv.tv_sec)*1000000 + (((int) current_tv.tv_usec) - ((int) start_tv.tv_usec)); still_to_wait= wait_usec-elapsed; if(still_to_wait>0) goto try_again; ret= !!did_work; ex:; if(flag&4) { gettimeofday(¤t_tv,&tz); elapsed= (current_tv.tv_sec - o->interval_start_time.tv_sec)*1000000 + (((int) current_tv.tv_usec) - ((int) o->interval_start_time.tv_usec)); } else elapsed= wait_usec; if(elapsed>=wait_usec) { if((flag&1)||Cdrfifo_debuG>=2) { fprintf(stderr,"\n"); for(ff= o; ff!=NULL; ff= ff->next) { buffer_space= Cdrfifo_tell_buffer_space(ff,0); fprintf(stderr, "cdrfifo %d: w=%d r=%d | b=%d s=%d | i=%.f o=%.f\n", ff->chain_idx,ff->write_idx,ff->read_idx, ff->buffer_size-buffer_space,buffer_space, ff->in_counter,ff->out_counter); } } if(flag&4) Cdrfifo_next_interval(o,&dummy,0); } return(ret); } /** Fill the fifo as far as possible without writing to destination fd */ int Cdrfifo_fill(struct CdrfifO *o, int size, int flag) { int ret,fill= 0,space,state; while(1) { state= Cdrfifo_get_buffer_state(o,&fill,&space,0); if(state==-1) { /* >>> handle error */; return(0); } else if(state!=1) break; if(space<=0) break; if(size>=0 && fill>=size) break; ret= Cdrfifo_try_to_work(o,100000,NULL,NULL,2); if(ret<0) { /* >>> handle error */; return(0); } if(ret==2) break; } #ifndef Cdrfifo_standalonE if(fill>=32*2048) { int Scan_for_iso_size(unsigned char data[2048], double *size_in_bytes, int flag); int bs= 16*2048; double size; /* memorize blocks 16 to 31 */ if(o->iso_fs_descr!=NULL) free((char *) o->iso_fs_descr); o->iso_fs_descr= TSOB_FELD(char,bs); if(o->iso_fs_descr==NULL) return(-1); memcpy(o->iso_fs_descr,o->buffer+bs,bs); /* try to obtain ISO-9660 file system size from block 16 */ ret= Scan_for_iso_size((unsigned char *) (o->buffer+bs), &size, 0); if(ret>0) o->iso_fs_size= size; } #endif o->total_min_fill= fill; o->interval_min_fill= fill; return(1); } int Cdrfifo_close_all(struct CdrfifO *o, int flag) { struct CdrfifO *ff; if(o==NULL) return(0); for(ff= o; ff->prev!=NULL; ff= ff->prev); for(; ff!=NULL; ff= ff->next) Cdrfifo_close(ff,0); return(1); } #ifdef Cdrfifo_standalonE /* ---------------------------------------------------------------------- */ /** Application example. See also cdrskin.c */ double Scanf_io_size(char *text, int flag) /* bit0= default value -1 rather than 0 */ { int c; double ret= 0.0; if(flag&1) ret= -1.0; if(text[0]==0) return(ret); sscanf(text,"%lf",&ret); c= text[strlen(text)-1]; if(c=='k' || c=='K') ret*= 1024.0; if(c=='m' || c=='M') ret*= 1024.0*1024.0; if(c=='g' || c=='G') ret*= 1024.0*1024.0*1024.0; if(c=='t' || c=='T') ret*= 1024.0*1024.0*1024.0*1024.0; if(c=='p' || c=='P') ret*= 1024.0*1024.0*1024.0*1024.0*1024.0; if(c=='e' || c=='E') ret*= 1024.0*1024.0*1024.0*1024.0*1024.0*1024.0; if(c=='s' || c=='S') ret*= 2048.0; return(ret); } /* This is a hardcoded test mock-up for two simultaneous fifos of which the one runs with block size 2048 and feeds the other which runs with 2352. Both fifos have the same number of follow_up pipes (tracks) which shall be connected 1-to-1. */ int Test_mixed_bs(char **paths, int path_count, int fs_size, double speed_limit, double interval, int flag) /* bit0= debugging verbousity */ { int fd_in[100],fd_out[100],ret,pipe_fds[100][2]; int i,iv,stall_counter= 0,cycle_counter= 0.0; char target_path[80]; double in_counter, out_counter, prev_in= -1.0, prev_out= -1.0; struct CdrfifO *ff_in= NULL, *ff_out= NULL; if(path_count<1) return(2); Cdrfifo_new(&ff_in,fd_in[0],fd_out[0],2048,fs_size,0); for(i= 0; ichain_idx,ret); if(ret<0) return(-7); break; } cycle_counter++; Cdrfifo_get_counters(ff_in, &in_counter, &out_counter, 0); if(prev_in == in_counter && prev_out == out_counter) stall_counter++; prev_in= in_counter; prev_out= out_counter; } return(1); } /* This is a hardcoded test mock-up for two simultaneous fifos of which the first one simulates the cdrskin fifo feeding libburn and the second one simulates libburn and the burner at given speed. Both have two fd pairs (i.e. tracks). The tracks are read from /u/test/cdrskin/in_[12] and written to /u/test/cdrskin/out_[12]. */ int Test_multi(int fs_size, double speed_limit, double interval, int flag) /* bit0= debugging verbousity */ { int fd_in[4],fd_out[4],ret,pipe_fds[4][2]; int i,iv; struct CdrfifO *ff1= NULL,*ff2= NULL; /* open four pairs of fds */ fd_in[0]= open("/u/test/cdrskin/in_1",O_RDONLY); fd_in[1]= open("/u/test/cdrskin/in_2",O_RDONLY); fd_out[2]= open("/u/test/cdrskin/out_1", O_WRONLY|O_CREAT|O_TRUNC, S_IRUSR|S_IWUSR); fd_out[3]= open("/u/test/cdrskin/out_2", O_WRONLY|O_CREAT|O_TRUNC, S_IRUSR|S_IWUSR); if(pipe(pipe_fds[0])==-1) return(-3); if(pipe(pipe_fds[1])==-1) return(-3); fd_out[0]= pipe_fds[0][1]; fd_out[1]= pipe_fds[1][1]; fd_in[2]= pipe_fds[0][0]; fd_in[3]= pipe_fds[1][0]; for(i=0;i<4;i++) { if(fd_in[i]==-1) return(-1); if(fd_out[i]==-1) return(-2); } /* Create two fifos with two sequential fd pairs each and chain them for simultaneous usage. */ Cdrfifo_new(&ff1,fd_in[0],fd_out[0],2048,fs_size,0); Cdrfifo_new(&ff2,fd_in[2],fd_out[2],2048,2*1024*1024,0); /*burner cache 2 MB*/ if(ff1==NULL || ff2==NULL) return(-3); Cdrfifo_set_speed_limit(ff2,speed_limit,0); ret= Cdrfifo_attach_follow_up_fds(ff1,fd_in[1],fd_out[1],0); if(ret<=0) return(-4); ret= Cdrfifo_attach_follow_up_fds(ff2,fd_in[3],fd_out[3],0); if(ret<=0) return(-4); Cdrfifo_attach_peer(ff1,ff2,0); /* Let the fifos work */ iv= interval*1e6; while(1) { ret= Cdrfifo_try_to_work(ff1,iv,NULL,NULL,flag&1); if(ret<0 || ret==2) { /* <0 = error , 2 = work is done */ fprintf(stderr,"\ncdrfifo %d: fifo ended work with ret=%d\n", ff1->chain_idx,ret); if(ret<0) return(-7); break; } } return(1); } int main(int argc, char **argv) { int i,ret,exit_value= 0,verbous= 1,fill_buffer= 0,min_fill,fifo_percent,fd; double fs_value= 4.0*1024.0*1024.0,bs_value= 2048,in_counter,out_counter; double interval= 1.0,speed_limit= 0.0; char output_file[4096]; struct CdrfifO *ff= NULL; strcpy(output_file,"-"); fd= 1; for(i= 1; i1000.0) interval= 1; } else if(strncmp(argv[i],"of=",3)==0) { if(strcmp(argv[i]+3,"-")==0 || argv[i][3]==0) continue; fd= open(argv[i]+3,O_WRONLY|O_CREAT); if(fd<0) { fprintf(stderr,"cdrfifo: FATAL : cannot open output file '%s'\n", argv[i]+3); fprintf(stderr,"cdrfifo: errno=%d , \"%s\"\n", errno,errno==0?"-no error code available-":strerror(errno)); {exit_value= 4; goto ex;} } } else if(strncmp(argv[i],"sl=",3)==0) { speed_limit= Scanf_io_size(argv[i]+3,0); } else if(strncmp(argv[i],"vb=",3)==0) { sscanf(argv[i]+3,"%d",&verbous); } else if(strcmp(argv[i],"-mixed_bs_test")==0) { ret= Test_mixed_bs(argv+i+1,argc-i-1, (int) fs_value,speed_limit,interval,(verbous>=2)); fprintf(stderr,"Test_mixed_bs(): ret= %d\n",ret); exit(ret<0); } else if(strcmp(argv[i],"-multi_test")==0) { if(speed_limit==0.0) speed_limit= 10*150*1024; ret= Test_multi((int) fs_value,speed_limit,interval,(verbous>=2)); fprintf(stderr,"Test_multi(): ret= %d\n",ret); exit(ret<0); } else { fprintf(stderr,"cdrfifo 0.3 : stdin-to-stdout fifo buffer.\n"); fprintf(stderr,"usage : %s [bs=block_size] [fl=fillfirst]\n",argv[0]); fprintf(stderr," [fs=fifo_size] [iv=interval] [of=output_file]\n"); fprintf(stderr," [sl=bytes_per_second_limit] [vb=verbosity]\n"); fprintf(stderr,"fl=1 reads full buffer before writing starts.\n"); fprintf(stderr,"sl>0 allows catch up for whole run time.\n"); fprintf(stderr,"sl<0 allows catch up for single interval.\n"); fprintf(stderr,"vb=0 is silent, vb=2 is debug.\n"); fprintf(stderr,"example: cdrfifo bs=8k fl=1 fs=32m iv=0.1 sl=-5400k\n"); if(strcmp(argv[i],"-help")!=0 && strcmp(argv[i],"--help")!=0) { fprintf(stderr,"\ncdrfifo: FATAL : option not recognized: '%s'\n", argv[i]); exit_value= 1; } goto ex; } } if(verbous>=1) { fprintf(stderr, "cdrfifo: bs=%.lf fl=%d fs=%.lf iv=%lf of='%s' sl=%.lf vb=%d\n", bs_value,fill_buffer,fs_value,interval,output_file,speed_limit, verbous); } ret= Cdrfifo_new(&ff,0,fd,(int) bs_value,(int) fs_value,0); if(ret<=0) { fprintf(stderr, "cdrfifo: FATAL : creation of fifo object with %.lf bytes failed\n", fs_value); {exit_value= 3; goto ex;} } if(speed_limit!=0.0) Cdrfifo_set_speed_limit(ff,speed_limit,0); if(fill_buffer) { ret= Cdrfifo_fill(ff,0,0); if(ret<=0) { fprintf(stderr, "cdrfifo: FATAL : initial filling of fifo buffer failed\n"); {exit_value= 4; goto ex;} } } while(1) { ret= Cdrfifo_try_to_work(ff,(int) (interval*1000000.0), NULL,NULL,(verbous>=2)); if(ret<0) { fprintf(stderr,"\ncdrfifo: FATAL : fifo aborted. errno=%d , \"%s\"\n", errno,errno==0?"-no error code available-":strerror(errno)); {exit_value= 4; goto ex;} } else if(ret==2) { if(verbous>=1) { double put_counter,get_counter,empty_counter,full_counter; int total_min_fill; Cdrfifo_get_counters(ff,&in_counter,&out_counter,0); fprintf(stderr,"\ncdrfifo: done : %.lf bytes in , %.lf bytes out\n", in_counter,out_counter); Cdrfifo_get_min_fill(ff,&total_min_fill,&min_fill,0); fifo_percent= 100.0*((double) total_min_fill)/fs_value; if(fifo_percent==0 && total_min_fill>0) fifo_percent= 1; Cdrfifo_get_cdr_counters(ff,&put_counter,&get_counter, &empty_counter,&full_counter,0); fprintf(stderr,"cdrfifo: fifo had %.lf puts and %.lf gets.\n", put_counter,get_counter); fprintf(stderr, "cdrfifo: fifo was %.lf times empty and %.lf times full, min fill was %d%%.\n", empty_counter,full_counter,fifo_percent); } break; } Cdrfifo_next_interval(ff,&min_fill,0); } ex:; Cdrfifo_destroy(&ff,0); exit(exit_value); } #endif /* Cdrfifo_standalonE */ libburn-1.4.2/cdrskin/wiki_plain.txt0000644000175700017510000003077712652644223014454 00000000000000-------------------------------------------------------------------------- cdrskin Wiki - plain text copy -------------------------------------------------------------------------- [[Image(source:/libburn/trunk/cdrskin/doener_150x200_tr.png)]] [http://en.wikipedia.org/wiki/D%C3%B6ner_kebab Doener] '''cdrskin is the cdrecord compatibility middleware of libburn.''' Its paragon, cdrecord, is a powerful GPL'ed burn program included in Joerg Schilling's cdrtools. cdrskin strives to be a second source for the services traditionally provided by cdrecord. Currently it does CD-R and CD-RW this way. Overwriteable media DVD-RAM, DVD+RW, DVD-RW, and BD-RE are handled differently than with cdrecord-ProDVD in order to offer TAO-like single track recording. Sequential DVD-R[W], DVD+R, DVD+R DL, BD-R are handled like CD-R[W] with TAO and multi-session. Additionally cdrskin offers cdrecord-ProDVD-like mode DAO with DVD-R[W]. cdrskin does not contain any bytes copied from cdrecord's sources. Many bytes have been copied from the message output of cdrecord runs, though. The most comprehensive technical overview of cdrskin can be found in [http://libburnia-project.org/browser/libburn/trunk/cdrskin/README?format=txt cdrskin/README]. About libburn API for burning CD, DVD, and BD: http://api.libburnia-project.org -------------------------------------------------------------------------- About the command line options of cdrskin: They are described in detail in [http://scdbackup.sourceforge.net/man_1_cdrskin_devel.html#OPTIONS section OPTIONS] of [http://scdbackup.sourceforge.net/man_1_cdrskin_devel.html man cdrskin] There are two families of options: cdrecord-compatible ones and options which are specific to cdrskin. The latter are mostly used to configure cdrskin for its task to emulate cdrecord. There are some, nevertheless, which provide rather exotic unique features of cdrskin. The cdrecord-compatible options are listed in the output of {{{ cdrskin -help }}} where the option "help" has *one* dash. Online: [http://scdbackup.sourceforge.net/cdrskin_help_devel cdrskin -help] For these options you may expect program behavior that is roughly the same as described in original man cdrecord . Online: http://cdrecord.berlios.de/old/private/man/cdrecord-2.0.html The cdrskin-specific options are listed by {{{ cdrskin --help }}} where the option "help" has *two* dashes. Online: [http://scdbackup.sourceforge.net/cdrskin__help_devel cdrskin --help] Some are very experimental and should only be used in coordination with the libburnia developer team. Some are of general user interest, though: -------------------------------------------------------------------------- --devices can be used by the sysadmin to scan the system for possible drives and displays their detected properties. The drives are listed one per line, with fields: libburn-drive-number, sysadmin-device-file, permissions, vendor, type {{{ 0 dev='/dev/sr0' rwrw-- : 'HL-DT-ST' 'DVDRAM GSA-4082B' }}} This feature is valuable since cdrskin -scanbus will not give you the device file name and its current permissions. cdrskin will accept of course the proposed dev= option as address for any usage of the drive. Different from cdrecord, cdrskin is intended to be run without special privileges, i.e. no superuser setuid. It is intended that the sysadmin controls drive accessability by rw-permissions of the drive rather than by x-permission of the burn binary. To be usable with cdrskin, the drive has to offer both, r- and w-permission. -------------------------------------------------------------------------- blank=as_needed applies the suitable blanking or formatting to make any supported type of media ready for writing from scratch. If this is not possible, e.g. because the media is written and not re-usable, then the program run fails. Option blank= offers several specialized blanking and formatting types, which one may use for particular purposes on DVD-RW, DVD-RAM and BD-RE. (See also below: blank=format_overwrite) The drive offers a list of possible formats by cdrskin option --list_formats. One should aquire MMC background information before making use of them. -------------------------------------------------------------------------- cdrskin does not only read from and write to optical drives which comply to the MMC standard but also does the same with regular files or block devices other than optical drives. Because the power to alter a disk file might be a bad surprise for a traditional user of cdrecord, it is necessary to give option --allow_emulated_drives before an emulated drive may be addressed. Eventually one of the startup files would be a good place for it. See man page, section FILES. The addresses of emulated drives begin with the prefix "stdio:". {{{ dev=stdio:/tmp/pseudo_drive dev=stdio:/dev/usbstick }}} Regular files and block devices behave much like DVD-RAM. Other file types may be valid targets for write-only operations. This includes standard output, named pipes, character devices {{{ dev=stdio:/dev/fd/1 dev=stdio:/tmp/named_pipe dev=stdio:/dev/ptyxy }}} These files behave much like blank DVD-R. All files used as pseudo-drives have to offer rw-permission. -------------------------------------------------------------------------- The DVD capabilities of cdrskin differ from those of cdrecord-ProDVD. cdrskin offers TAO-like multi-session with DVD-R[W], DVD+R[ DL] and TAO-like single session with overwriteable DVD media. It also offers DAO on DVD-R[W] which is probably the same as the traditional cdrecord-ProDVD write mode. Non-cdrecord blank mode blank=format_overwrite brings a DVD-RW disc from its initial profile "Sequential Recording" into profile state "Restricted Overwrite". {{{ cdrskin dev=/dev/sr0 -v blank=format_overwrite }}} DVD-RAM, DVD+RW, BD-RE and overwriteable DVD-RW appear to cdrskin as blank media which are capable of taking only a single track. This track may be positioned on a 32KiB aligned address, though. {{{ cdrskin ... write_start_address=2412m ... }}} Non-cdrecord blank mode blank=deformat_sequential brings an overwriteable DVD-RW back into state "Sequential Recording" with the capability of doing multi-session, if the drive is capable of "Incremental Streaming" (MMC feature 21h). Used sequential DVD-RW media may be blanked by blank=fast or blank=all which normally both do full blanking. Thus sequential DVD-RW behave much like large CD-RW with possibly more than 99 tracks. blank=deformat_sequential does minimal blanking of DVD-RW which usually yields media incapable of "Incremental Streaming". Option --prodvd_cli_compatible activates blank=fast and blank=all for overwriteable DVD-RW which normally ignore those two options. It also makes option -multi tolerable with media and write modes which are not suitable for multi-session. (The default behavior of cdrskin deems me to be preferrable.) Option --grow_overwriteable_iso gives cdrskin ISO pseudo-multi-session capabilities on DVD-RAM, DVD+RW, BD-RE similar to growisofs. Associated options blank=, -multi, -msinfo and -toc are available in this case. They either pretend a blank media (if there is no ISO 9660 image) or appendable media with a single session and track on it. blank= invalidates ISO images. -------------------------------------------------------------------------- assert_write_lba= ensures that the start block address which was used with the formatter program (e.g. mkisofs -C) matches the start block address which will be used by the upcoming burn. E.g. cdrskin aborts with an error message if {{{ assert_write_lba=0 }}} is given but an appendable media is to be burned which would start at block 68432. An ISO-9660 file system image must be prepared according to a particular block address on media. If the prepared address and the real address on media do not match then the filesystem will not be mountable or may even cause system trouble. A sequential archive format like afio or star will not necessarily need such a coordination of addresses. It might nevertheless be confusing to a reader if the archive does not start at block 0. -------------------------------------------------------------------------- fifo_start_at= is a throughput enhancer for unsteady data streams like they are produced by a compressing archiver program when piping to CD on-the-fly. It makes better use of the general property of a FIFO buffer to transport surplus bandwidth into the future. Yep. A time machine. One-way, i fear. FIFO originally was introduced by cdrecord's author Joerg Schilling in order to protect mediocre burner hardware from suffering buffer underruns and thus producing misburns (at 1x speed on CD-R media at the price of a DVD-RAM nowadays). This purpose would not justify a fifo any more - given the limited life time of burners and the seamless underrun protection of contemporary consumer drives. With an unsteady data stream the task of the buffer is to soak up peak performance and to release it steadily at the drive's maximum speed. The larger the buffer the more reserves can be built up and the longer input drought can be compensated. Original cdrecord has the historical property, though, to first wait until the buffer is completely filled. Best practice for fighting drive underruns, of course. With a very fat fs=# buffer (128 MB for 12x CD is not unrealistic) this can cause a big delay until burning finally starts and takes its due time. fifo_start_at= makes cdrskin start burning after the given number of bytes is read rather than waiting for the FIFO to be completely full or the data stream to end. It risks a few drive buffer underruns at the beginning of burn - but modern drives stand this. Usage examples: {{{ cdrskin ... fs=128m fifo_start_at=20m ... cdrskin ... fifo_start_at=0 ... }}} Note: no FIFO can give you better average throughput than the average throughput of the data source and the throughput of the burner. It can be used, though, to bring the effective throughput very close to the theoretical limit. Especially with high speed media. -------------------------------------------------------------------------- --no_rc allows you to surely ban influence from systemwide or user specific default settings of cdrskin. Possible locations for such settings: /etc/default/cdrskin /etc/opt/cdrskin/rc /etc/cdrskin/cdrskin.conf $HOME/.cdrskinrc -------------------------------------------------------------------------- dev_translation= may be needed to foist cdrskin to frontend programs of cdrecord which do *not* ask cdrecord -scanbus but which make own assumptions and guesses about cdrecord's device addresses. Normally, cdrskin understands all addresses which are suitable for cdrecord under Linux. See cdrskin/README, "Pseudo-SCSI Adresses". This option is mainly for (yet unknown) exotic configurations or very stubborn frontend programs. If a frontend refuses to work with cdrskin, look into the error protocol of that frontend, look at the output of a run of cdrskin --devices and give cdrskin the necessary hint. Example: Your frontend insists in using "0,0,0" and --devices reported dev='/dev/hdc' resp. cdrskin dev=ATA -scanbus reported "1,0,0" then this would be the appropriate translation: {{{ dev_translation=+0,0,0+/dev/hdc }}} The "+" character is a separator to be choosen by you. Currently i am not aware of the need to choose any other than "+" unless you get playful with custom translations like {{{ dev_translation=-"cd+dvd"-1,0,0 }}} See http://scdbackup.sourceforge.net/k3b_on_cdrskin.html for an illustrated example with K3b 0.10 . -------------------------------------------------------------------------- Advanced multi-session use cases as of dvd+rw-tools: A special feature of dvd+rw-tools is growing of ISO-9660 filesystems on overwriteable media. This is not the same as multi-session writing of cdrskin with CD media, but retrieves additional information from the existing ISO image and finally manipulates the start sectors of this existing image. So, inspired by growisofs, cdrskin can offer DVD multi-session not only with sequential DVD-R[W] and with DVD+R [DL], but also with DVD-RAM, DVD+RW, BD-RE and even regular disk files or block devices other than CD/DVD writers. This is enabled by option --grow_overwriteable_iso. The libburnia project provides an integrated ISO-9660 multi-session tool named [wiki:Xorriso xorriso] which tries to go one step beyond growisofs. It uses [wiki:Libburn libburn] , [wiki:Libisofs libisofs] and [wiki:Libisoburn libisoburn]. See [http://scdbackup.sourceforge.net/man_1_xorriso.html man xorriso]. -------------------------------------------------------------------------- libburn-1.4.2/cdrskin/convert_man_to_html.sh0000755000175700017510000000654412652644223016160 00000000000000#!/bin/sh # # convert_man_to_html.sh - ts A61214 , B50802 # # Generates a HTML version of man page cdrskin.1 # # To be executed within the libburn toplevel directory (like ./libburn-0.2.7) # # set -x man_dir=$(pwd)"/cdrskin" export MANPATH="$man_dir" manpage="cdrskin" raw_html=$(pwd)/"cdrskin/raw_man_1_cdrskin.html" htmlpage=$(pwd)/"cdrskin/man_1_cdrskin.html" if test -r "$man_dir"/"$manpage".1 then dummy=dummy else echo "Cannot find readable man page source $1" >&2 exit 1 fi if test -e "$man_dir"/man1 then dummy=dummy else ln -s . "$man_dir"/man1 fi if test "$1" = "-work_as_filter" then # set -x sed \ -e 's///' \ -e 's///' \ -e 's/CDRSKIN<\/title>/<title>man 1 cdrskin<\/title>/' \ -e 's/<h1 align=center>CDRSKIN<\/h1>/<h1 align=center>man 1 cdrskin<\/h1>/' \ -e 's/<body>/<body BGCOLOR="#F5DEB3" TEXT=#000000 LINK=#0000A0 VLINK=#800000>/' \ -e 's/<b>Overview of features:<\/b>/<b>Overview of features:<\/b><BR>/' \ -e 's/<b>General information paragraphs:<\/b>/<b>General information paragraphs:<\/b><BR>/' \ -e 's/<b>Track recording model:<\/b>/\ <BR><b>Track recording model:<\/b><BR>/' \ -e 's/^In general there are two types of tracks: data and audio./\ <BR>In general there are two types of tracks: data and audio./' \ -e 's/^While audio tracks just contain a given/\ <BR>While audio tracks just contain a given/' \ -e 's/<b>Write mode selection:<\/b>/<b>Write mode selection:<\/b><BR>/' \ -e 's/<b>Recordable CD Media:<\/b>/<b>Recordable CD Media:<\/b><BR>/' \ -e 's/<b>Overwriteable DVD or BD Media:<\/b>/<b>Overwriteable DVD or BD Media:<\/b><BR>/' \ -e 's/<b>Sequentially Recordable DVD or BD Media:<\/b>/<b>Sequentially Recordable DVD or BD Media:<\/b><BR>/' \ -e 's/^The write modes for DVD+R/\ <BR>The write modes for DVD+R/' \ -e 's/<b>Drive preparation and addressing:<\/b>/<b>Drive preparation and addressing:<\/b><BR>/' \ -e 's/^If you only got one CD capable drive/\ <BR>If you only got one CD capable drive/' \ -e 's/<b>Emulated drives:<\/b>/<b>Emulated drives:<\/b><BR>/' \ -e 's/for normal use: <b><br>/for normal use: <b><br><BR>/' \ -e 's/original cdrecord by Joerg Schilling:<\/p>/original cdrecord by Joerg Schilling:<\/p><BR>/' \ -e 's/<\/body>/<BR><HR><FONT SIZE=-1><CENTER>(HTML generated from '"$manpage"'.1 on '"$(date)"' by '$(basename "$0")' )<\/CENTER><\/FONT><\/body>/' \ -e 's/See section FILES/See section <A HREF="#FILES">FILES<\/A>/' \ -e 's/See section EXAMPLES/See section <A HREF="#EXAMPLES">EXAMPLES<\/A>/' \ -e 's/−/-/g' \ <"$2" >"$htmlpage" set +x chmod u+rw,go+r,go-w "$htmlpage" echo "Emerged file:" ls -lL "$htmlpage" else # export BROWSER='cp "%s" '"$raw_html" export BROWSER=$(pwd)/'cdrskin/unite_html_b_line "%s" '"$raw_html" man -H "$manpage" # cp "$raw_html" /tmp/x.html "$0" -work_as_filter "$raw_html" rm "$raw_html" rm "$man_dir"/man1 fi ������������������������������������������������������������������������������������������������������������������������������������������������������������libburn-1.4.2/cdrskin/changelog.txt�����������������������������������������������������������������0000644�0001757�0001751�00001211136�12652646200�014241� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������------------------------------------------------------------------------------ libburnia-project.org scdbackup.sourceforge.net/cdrskin ------------------------------------------------------------------------------ Deliberate deviations of cdrskin from cdrecord compatibility: + cdrskin does drive operations (on its drive 0) without a dev= option (Note: cdrecord meanwhile has a default for missing dev= option.) + gracetime=0 is allowed and set by default + -pad is always set for audio tracks + -sao is default where possible, -tao is default where needed (Note: cdrecord write mode defaults have changed in cdrtools-2.01.01a20) + driveropts=burnfree is default if the drive supports buffer underrun protection. If desired, use driveropts=noburnfree to disable this feature. + premature end of source is not an error and leads to full announced tracksize + -msinfo pushes all other messages to stderr. It works independently of other options which would prevent it with cdrecord (-atip, -scanbus, ...) + DVD track sources get not concateneated to a single track. In general DVD writing is quite different from cdrecord-ProDVD: DVD-R[W] "Disc-at-once" (-sao) is nearest to cdrecord-ProDVD's methods. DVD-R[W] "Incremental Streaming" (-tao) on unformatted media allows multi-session and track sources of unpredictable size. Writing DVD-RAM, DVD+RW and "Restricted Overwrite" DVD-RW is like single track -tao on blank CD. Formatting is done via cdrskin-specific blank=format_overwrite and not with option -format. + DVD-RW get blanked fast only with option blank=deformat_sequential_quickest . Option blank=fast is the same as blank=all in order to achieve media which are capable of Incremental Streaming. + It has not been evaluated how far -isosize is compatible with the original cdrecord option. man cdrecord forbids stdin as source, cdrskin allows it if a fifo is used. ------------------------------------------------------------------------------ Changelog ------------------------------------------------------------------------------ 19 Aug 2006 [committed] README cdrskin/README cdrskin/cdrskin.c cdrskin/add_ts_changes_to_libburn_0_2_1 \ cdrskin/cdrskin_timestamp.h cdrskin/compile_cdrskin.sh cdrskin-0.1.4 "stable" released on base of August 15 2006 version of libburn-svn.pykix.org/trunk after initial merge of libburn and cdrskin-0.1.3 . ------------------------------------------------------------------------------ 19 Aug 2006 [committed 16] cdrskin/changelog.txt cdrskin-0.1.5 development started. Introduced this changelog. ---------------------------------- Format (still emerging): Day Month Year [eventual commit mark with revision number] affected files , naked, one by line, [eventually = internal snapshot tarball] More ore less concise description. ---------------------------------- End of Format 20 Aug 2006 [committed together with next change, i fear] libburn/sg.c Hopefully fixed a file descriptor resource leak in sg_grab(). All scanned drives (seem to) stay open once, the grabbed one got re-opened and its stored first file descriptor got forgotten. Now we try to detect and re-use the still open fd. 21 Aug 2006 [committed] libburn/libburn.h libburn/sg.c libburn/init.c = libburn_cdrskin_A60819.tgz cdrskin/cdrskin.c [committed later as revision 11] O_EXCL experiments imported from cdrskin-0.1.3 In default configuration and on compliant kernels expect that a busy drive is invisible to further cdrskin instances. The user gets hints in case of empty bus scan result resp. busy drive given with dev=... Wether cdrecord and cdrskin respect each other would have to be evaluated. Options to play with: --demand_a_drive exit !=0 on bus scans with empty result --drive_abort_on_busy abort process if busy drive is found (might be triggered by a busy hard disk) --drive_blocking try to wait for busy drive to become free (might be stalled by a busy hard disk) --drive_not_exclusive do not ask kernel to prevent opening busy drives. Effect is kernel dependend. grab_drive_and_wait=<num> grab drive, wait given number of seconds, release drive, and do normal work 21 Aug 2006 [committed] libburn/write.c Rectified non-ANSI-C comment, complained by gcc. 21 Aug 2006 [committed 13] cdrskin/cdrskin_eng.html The homepage moved in from scdbackup's internal doc collection. 21 Aug 2006 [committed with revision 11, i fear] cdrskin/cdrskin.c Removed flaw: Help text of tao_to_sao_tsize= clarified. 21 Aug 2006 [committed 12] cdrskin/wiki_plain.txt The initial filling of the cdrskin wiki on libburn.pykix.org . I am not sure about the future fate of this text. I plan to keep it up to date with the online wiki for now. The online version will be considered the original. 21 Aug 2006 [committed 15] cdrskin/cdrskin_timestamp.h Timestamping the new version. 21 Aug 2006 [committed 14] cdrskin/add_ts_changes_to_libburn_0_2_1 cdrskin/compile_cdrskin.sh Readjusted relationship glue of libburn and cdrskin. --------------------------------------------------------------------- cycled - 27 Aug 2006 [40] libburn/mmc.c libburn/sg.c Inserted prints to see how sg_issue_command() is called (printing is disabled now) 21 Aug 2006 [17] README Reported obvious need for automake >=1.7 21 Aug 2006 [18] cdrskin/cdrskin_eng.html cdrskin/README Reported obvious need for automake >=1.7 22 Aug 2006 [19] libburn/drive.c libburn/drive.h New internal function burn_drive_is_open() 23 Aug 2006 [20] cdrskin/cdrskin.c Implemented Lorenzo Taylor's audio patch manually by copy+paste as i wanted to fully understand it. Hopefully did not break it that way. 24 Aug 2006 [21] libburn/libburn.h libburn/drive.c Introduced API functions burn_drive_scan_and_grab() burn_drive_get_adr() 24 Aug 2006 [22] cdrskin/compile_cdrskin.sh Experimental option cdrskin/compile_cdrskin.sh -newapi 24 Aug 2006 [23] cdrskin/cdrskin.c First test of possibility to obey the self imposed rules of Revison 21 24 Aug 2006 [25] cdrskin/cdrskin.c Fixed undefined track_type introduced by revision 20. (We broke cdrskin, but i did not break the patch. Success.) 24 Aug 2006 [30] libburn/libburn.h Hopefully fixed an unintended line break in API doxygen 25 Aug 2006 [32] cdrskin/cdrskin.c Installed protection against resource leak in Cdrskin_grab_drive() Just to be sure. 25 Aug 2006 [33] libburn/drive.c burn_drive_free() now closes all open drive file descriptors 25 Aug 2006 [34] libburn/libburn.h Adjusted statement at API documention of burn_initialize() 25 Aug 2006 [35] cdrskin/cdrskin.c Worked forth in order to make cdrskin fully newapi compliant 26 Aug 2006 [37] Makefile.am libburn/back_hacks.h libburn/drive.c libburn/init.c Allowed to blank appendable files and installed first back_hacks.h variable ever 26 Aug 2006 [38] test/burniso.c Rewrote it to new API practice, inflated explanation comments, SAO mode 27 Aug 2006 [39] cdrskin/cdrskin.c Implemented Lorenzos blank-appendable patch plus option --no_blank_appendable 27 Aug 2006 [44] test/blank.c Rewrote test/blank.c to new API practice, inflated explanation comments 27 Aug 2006 [41] cdrskin/cdrskin.c Fixed obscure sigsegv introduced with 35 or 39 by obeying libburn.h text (could be a fandango starting in burn_drive_info_free) 27 Aug 2006 [45] test/burniso.c Disabled inner burn_drive_info_free like in cdrskin, polished a bit 27 Aug 2006 [43] libburn/libburn.h Changed some 'release' to 'close' with specs of burn_drive_scan_and_grab 28 Aug 2006 [46] test/burniso.c Polished a bit more for doxygen 28 Aug 2006 [50] libburn/libburn.h cdrskin/cdrskin.c Wrote into API the imperative not to use drive.location but burn_drive_get_adr 28 Aug 2006 [47] test/burniso.c Integrated functionality of test/devices.c into test/burniso.c Proposed to rename it to test/libburner.c 28 Aug 2006 [51] cdrskin/cdrskin.c Closed a pitfall with reading from '-' and no tsize= or tao_to_sao_tsize= Ticket 55 28 Aug 2006 [52] cdrskin/cdrskin.c Added personal commitment to grant BSD license on request. Insisted in GPL for now. 28 Aug 2006 [53] cdrskin/cdrskin.c Forced each track to have a minimum size of 600 kB Ticket 55 29 Aug 2006 [58] test/burniso.c Integrated functionality of test/blank.c into test/burniso.c 29 Aug 2006 [55] cdrskin/cdrskin.c Made cdrskin ready to make good use of now working libburn-eject 29 Aug 2006 [56] cdrskin/cdrskin.c Avoided unwanted tray loading on eject of never grabbed drive 29 Aug 2006 [57] cdrskin/cdrskin.c Disabled unconditionality of eject introduced by 55 or 56 30 Aug 2006 [59] test/burniso.c Repaired SIGSEGV caused by releasing ungrabbed drive after mere bus scan 30 Aug 2006 [60] test/libburner.c Makefile.am My proposal for new souvereign app as API doc and reference for API decisions 31 Aug 2006 [61] libburn/sg.c cdrskin/cdrskin.c Outcommented "experimental:" messages of O_EXCL development 31 Aug 2006 [62] test/libburner.c Added 300 kB of padding to get rid of warning in doc, plus end sector padding 31 Aug 2006 [63] cdrskin/cdrskin.c Promoted "newapi" functionality and libburn-eject from test to standard 31 Aug 2006 [64] cdrskin/cdrskin.c Made cdrskin abort if fifo filling before burn yields 0 bytes (ticket 55) 1 Sep 2006 [65] cdrskin/README cdrskin/cdrskin.c cdrskin/cdrskin_eng.html Updated cdrskin help tests and docs: -audio, obsolete eject_device= 1 Sep 2006 [66] libburn/write.c cdrskin/cdrskin.c Implemented track number patch by bonfire-app@wanadoo.fr, tickets 58 and 9 1 Sep 2006 [67] cdrskin/cdrskin.c Added clarifying URGE to ABORT texts 1 Sep 2006 [71] test/libburner.c Made "read-ahead" comment sufficiently ambigous: "buffer"|"filesystem" == "" 1 Sep 2006 [72] [73] cdrskin/cdrskin.c cdrskin/compile_cdrskin.sh Rowed back from revision 64. Now #ifdef Cdrskin_fifo_abort_on_emptY 1 Sep 2006 [74] cdrskin/cdrskin.c cdrskin/compile_cdrskin.sh Rowed forth from revision 73. Now hopefully compliant to man cdrecord. 1 Sep 2006 [78] cdrskin/cdrskin.c Made -pad behave cdrecord-ly on audio tracks (not tested acousticly) 2 Sep 2006 [85] test/libburner.c Added upcoming clarification of copyright and license aspiration 3 Sep 2006 [86] README Added upcoming clarification of copyright and license aspiration 3 Sep 2006 [87] [88] cdrskin/README cdrskin/cdrskin.c Added upcoming clarification of copyright and license aspiration 3 Sep 2006 [91] cdrskin/changelog.txt cdrskin/cdrskin_timestamp.h Opened new cdrskin-0.1.5 upload cycle. This marks a should-be-stable phase. ---------------------------------------------------- cycled - 2006.09.03.132934 3 Sep 2006 [89] doc/comments_test_ts Made a try to get doxygen portal page readable by html dl lists 4 Sep 2006 [92] cdrskin/README Made changes as reported by Lorenzo on libburn-hackers today 4 Sep 2006 [93] libburn/transport.h libburn/drive.h libburn/drive.c libburn/init.c libburn/libburn.h Integrated elmom patch proposal #3 from ticket #62 /* ts A60904 : ticket 62, contribution by elmom */ 4 Sep 2006 [94] cdrskin/README Removed reference to frontend "burn" (needs a patch to work for .mp3) 5 Sep 2006 [95] doc/comments_test_ts Made a try to get doxygen portal page readable by pre tags and truncation 5 Sep 2006 [96] test/libburner.c Rearranged definitions and header inclusions. Is safer so. 5 Sep 2006 [97] test/libburner.c Re-inserted lost tab. 6 Sep 2006 [trac] closed ticket 55: burn of empty tracks from stdin is now forbidden 6 Sep 2006 [98] libburn/libburn.h libburn/drive.c Added new parameter "force" to API-experimental burn_drive_info_forget() 6 Sep 2006 [99] doc/comments Made doc test portal the official doc portal 6 Sep 2006 [100] cdrskin/cdrfifo.c Added an initial value on proposal by Bart Vanherck 7 Sep 2006 [101] test/libburner.c Changed a macro name from Burniso_ to Libburner_ 7 Sep 2006 [102] [103] libburn/libburn.h libburn/drive.c cdrskin/cdrskin.c Implemented first use of API-experimental burn_drive_info_forget() in cdrskin signal handler 7 Sep 2006 [104] cdrskin/cdrskin.c Tried to make abort messages clearer 7 Sep 2006 [105] Makefile.am test/testburner.c Prepared test bed for burn_drive_info_forget() as regular API call 7 Sep 2006 [106] test/testburner.c Removed a remnant piece of rather unhealthy test code 7 Sep 2006 [106] test/testburner.c Corrected test reciepe 7 Sep 2006 [107] test/libburner.c Added constraint --stdin_size >= 600k, better bus scan behavior 8 Sep 2006 2006 [109] libburn/drive.c test/testburner.c cdrskin/cdrskin.c Hopefully ensured correct burn_disc_erasable() already after first grab 9 Sep 2006 2006 [112] libburn/drive.c cdrskin/cdrskin.c Hunted down the bug which let newapi-cdrskin fail with drive 1 10 Sep 2006 [113] libburn/drive.c test/libburner.c test/testburner.c cdrskin/cdrskin.c Slowed down highspeed loops waiting for drive status changes 10 Sep 2006 [114] cdrskin/compile_cdrskin.sh Aliased switch name -newapi by -experimental 10 Sep 2006 [115] test/libburner.c test/testburner.c cdrskin/cdrskin.c Re-enabled call to burn_drive_info_free() after repair by revision 93 11 Sep 2006 [116] cdrskin/compile_cdrskin.sh Changed -newapi to -experimental in help text 11 Sep 2006 [117] libburn/drive.c Removed a bug introduced with revison 93 11 Sep 2006 [118] libburn/libburn.h test/libburner.c Officialized burn_drive_info_forget() 11 Sep 2006 [119] [120] Makefile.am test/testburner.c Deleted until next occasion: testburner 12 Sep Sep 2006 [124] cdrskin/cdrskin.c Repaired regression of -eject which loaded tray again 12 Sep 2006 [126] cdrskin/cdrskin.c Replaced -experimental method of closing libburn by burn_drive_info_forget() 12 Sep 2006 [129] cdrskin/cdrskin.c Added automated padding to last audio track (ticket 41) 2006.09.13.093350 [130] cdrskin/make_timestamp.sh Prepared for new revision timestamps to mark cdrskin test versions From now on cdrskin/cdrskin_timestamp.h is to be part of any commit. 15 Sep 2006 [135] Makefile.am Replaced a few 8-blanks by tab 15 Sep 2006 [136] README Moved installation instructions in front of overview paragraph 15 Sep 2006 [137] Makefile.am cdrskin/README Made cdrskin an installable program 2006.09.15.092509 [138] cdrskin/cdrskin.c cdrskin/compile_cdrskin.sh Prepared cdrskin-build for version leap ----------------------------- cycled (last cdrskin-0.1.5 ?) - 2006.09.15.101326 2006.09.15.101326 [139] cdrskin/README cdrskin/changelog.txt New upload of scdbackup.sourceforge.net/cdrskin-0.1.5.tar.gz 2006.09.15.174748 [143] cdrskin/cdrskin.c Revoked change of 1 Sep 2006 revision 78 (full -nopad) (ticket 41) 16 Sep 2006 [144] libburn/libburn.h Made doxygen happy with parameter of burn_drive_get_adr 2006.09.16.194730 [145] 000_CAUTION_RELEASE_CANDIDATE zzz_CAUTION_RELEASE_CANDIDATE README Makefile.am cdrskin/README cdrskin/cdrskin.c cdrskin/compile_cdrskin.sh Perfomed version leap in respect to SVN 2006.09.19.124540 [160] [161] cdrskin/cdrskin.c Allowed driveropts=burnproof as alias for burnfree 2006.09.19.140716 [162] [163] cdrskin/cdrskin.c Added error message in case of failed eject 2006.09.20.134219 [175] [176] [177] cdrskin/cdrskin.c Fixed bug with dev=1,1,0 (ticket 75) 21 Sep 2006 [186] configure.ac Makefile.am Forwarded changes from 0.2.2 to 0.2.3 Sep 2006 [187] [188] [189] [190] cdrskin/cdrskin.c cdrskin/compile_cdrskin.sh cdrskin/cdrskin_eng.html cdrskin/README cdrskin/changelog.txt - cdrskin/add_ts_changes_to_libburn_0_2_1 + cdrskin/add_ts_changes_to_libburn_0_2_3 Makefile.am cdrskin/cdrskin_timestamp.h Performed development version leap to cdrskin-0.2.3 ------------------------------------ cycled - cdrskin-0.2.3 - 2006.09.21.082411 21 Sep 2006 [191] README Clarified build from SVN versus tarball 2006.09.21.173012 [192] cdrskin/cdrskin.c cdrskin/compile_cdrskin.sh Gave up compile options -tarball_0_2 , -cvs_A51208 , -libburn_0_2_1 Now standard and therefore no longer needed as macros: Cdrskin_libburn_p_sectoR Cdrskin_libburn_with_fd_sourcE Cdrskin_libburn_largefilE Cdrskin_libburn_padding_does_worK 2006.09.21.185623 [193] cdrskin/cdrskin.c cdrskin/compile_cdrskin.sh Officialized gestures of pre-0.2.3 -experimental, introduced -oldfashioned 2006.09.21.194006 [194] cdrskin/cdrskin.c Investigating failure to open drive on eject 2006.09.22.133027 [195] libburn/libburn.h libburn/sg.c libburn/sg.h libburn/drive.c cdrskin/cdrskin.c Implemented resolving of softlinks (ticket 33) 2006.09.22.170220 [196] libburn/libburn.h libburn/sg.c libburn/sg.h libburn/drive.c cdrskin/cdrskin.c Implemented new API function burn_drive_convert_fs_adr() 2006.09.22.172307 [197] cdrskin/cdrskin.c Fixed SIGSEGV of -eject on non-existent device address 22 Sep 2006 [198] libburn/sg.c libburn/sg.h libburn/drive.c Implemented finding matching /dev/sgN from /dev/srM or /dev/scdK (ioctl(): SCSI_IOCTL_GET_IDLUN) 2006.09.22.195414 [199] cdrskin/cdrskin.c Removed bug prone implementation of link resolving (now only via libburn) 2006.09.22.202631 [200] cdrskin/cdrskin.c Kept new address conversion from hopping on libburn drive numbers 2006.09.22.203939 [201] cdrskin/cdrskin.c Fixed --no_follow_links and renamed to --no_convert_fs_adr 2006.09.23.080015 [202] libburn/drive.c Restructured SCSI search, removed a potential bug with hdX 23 Sep 2006 [203] libburn/libburn.h Made burn_drive_convert_scsi_adr() a new API function 23 Sep 2006 [204] libburn/drive.c libburn/sg.c Changed outdated comments 23 Sep 2006 [205] libburn/libburn.h libburn/drive.c Introduced new API function burn_drive_obtain_scsi_adr() 2006.09.23.100001 [not in libburn-0.2.2 yet] cdrskin-0.2.2/cdrskin/cdrskin.c Backported bug fix of revision 197. Version timestamp : 2006.09.23.100001 23 Sep 2006 [206] [207] libburn/drive.c libburn/sg.c Enabled unused SCSI part of struct burn_drive. Switched persistent address to burn_drive.devname 2006.09.23.114858 [208] cdrskin/cdrskin.c Implemented --no_pseudo_scsi_adr 2006.09.23.132755 [209] cdrskin/cdrskin.c libburn/drive.c Removed a bug with SCSI address of scanned drives without such address 23 Sep 2006 [210] cdrskin/README Explained the new addressing mode 2006.09.23.182444 [211] cdrskin/README cdrskin/cdrskin.c Bus,Target,Lun for dev=ATA and dev=ATAPI, real SCSI addressing by default 2006.09.23.183608 [212] cdrskin/cdrskin.c Made small improvement with debug message 2006.09.24.171706 [214] Makefile.am libburn/libburn.h libburn/libdax_msgs.h libburn/libdax_msgs.c libburn/init.c cdrskin/compile_cdrskin.sh cdrskin/cdrskin.c Added an error message handling facility (ticket 74) 2006.09.24.180836 [215] libburn/init.c libburn/sg.c libburn/libdax_msgs.h libburn/libdax_msgs.c cdrskin/cdrskin.c Made use of new message handling facility and removed first bugs 24 Sep 2006 [216] libburn/libdax_msgs.h Recorded error_code 0x00020001 24 Sep 2006 [217] [218] Makefile.am libburn/libburn.h libburn/write.c libburn/drive.c cdrskin/compile_cdrskin.sh Obsoleted libburn/message.[ch] 25 Sep 2006 [219] libburn/read.c libburn/write.c Removed inclusion of libburn/message.h 2006.09.25.104629 [220] libburn/init.c libburn/drive.c cdrskin/cdrskin.c Converted "libburn_experimental:" messages of address conversion into "DEBUG" 2006.09.25.141035 [221] libburn/libdax_msgs.h libburn/libdax_msgs.c libburn/drive.c libburn/sg.h libburn/sg.c Implemented sg_close_drive_fd (ticket 74) 2006.09.25.144506 [222] libburn/libdax_msgs.c Achieved minimum strerror thread safety (strerror_r is burned by Unix and GNU) 2006.09.26.114552 [223] libburn/libburn.h libburn/init.c libburn/libdax_msgs.c cdrskin/cdrskin.c Made first use of queued messages and fixed several bugs with that 2006.09.26.142824 [224] libburn/sg.c libburn/libdax_msgs.h cdrskin/cdrskin.c Made changes with usage of queued messages 24 Sep 2006 [225] Makefile.am libburn/libburn.h libburn/write.c libburn/drive.c - libburn/message.c - libburn/message.h Removed libburn/message.[ch] 2006.09.26.205504 [227] libburn/drive.c Enhanced softlink resolution 2006.09.26.210711 [228] libburn/drive.c Fixed bug in enhanced softlink resolution 2006.09.27.063147 [229] cdrskin/cdrskin.c Fixed bug with relative device addresses and Cdrpreskin__cdrecord_to_dev() 2006.09.27.074910 [230] cdrskin/cdrskin.c Fixed broken -version and --help (second time for same mistake) 2006.09.27.080826 [231] cdrskin/README cdrskin/cdrskin.c Allowed comments and empty lines in startup files 2006.09.27.082057 [232] cdrskin/cdrskin.c Prevented reading of startup files with first arg -version, -help or --help 2006.09.27.115919 [233] libburn/drive.c libburn/sg.h libburn/sg.c libburn/libdax_msgs.h cdrskin/cdrskin.c Disabled but did not discarded failed attempt to lock against growisofs 2006.09.27.120656 [234] libburn/drive.h libburn/init.c libburn/transport.h libburn/libburn.h Disabled but did not discarded failed attempt to lock against growisofs 2006.09.27.134332 [235] libburn/sg.c Kept /dev/hdX from all having SCSI address 0,0,0 2006.09.27.142312 [236] libburn/drive.c Curbed endless links to 20 hops 2006.09.27.143843 [237] libburn/sg.c Removed obsolete code and comments 2006.09.28.074434 [238] cdrskin/cdrskin.c Enabled optional growisofs lock attempt via --drive_scsi_exclusive 28 Sep 2006 [239] libburn/libburn.h Made official exclusive==2 with burn_preset_device_open() ------------------------------------ cycled - cdrskin-0.2.3 - 2006.09.28.100934 2006.09.28.115152 [240] cdrskin/cdrskin.c Restored vanished line at end of -help text and added a new one 2006.10.01.104140 [243] libburn/drive.c cdrskin/cdrskin.c Enhanced Cdrpreskin__cdrecord_to_dev so it warns of invisible SCSI drive. 2006.10.02.103418 [244] libburn/libburn.h libburn/drive.h libburn/drive.c libburn/libdax_msgs.h libburn/libdax_msgs.c cdrskin/cdrskin.c Implemented burn_abort() and made use of it 2006.10.03.162719 [245] Makefile.am libburn/libburn.h libburn/init.c libburn/cleanup.h libburn/cleanup.c cdrskin/cleanup.h cdrskin/cleanup.c test/libburner.c cdrskin/compile_cdrskin.sh cdrskin/cdrskin.c Implemented new API function burn_set_signal_handling(), libburner uses it 5 Oct 2006 [246] libburn/drive.c Uploaded forgotten part of revision 245 2006.10.05.142628 [247] libburn/libburn.h libburn/transport.h libburn/sg.c libburn/sg.h libburn/drive.c cdrskin/cdrskin.c Made use of SCSI_IOCTL_GET_BUS_NUMBER in hope of cdrecord compatibility 6 Oct 2006 [248] + libburn/asserts.txt Listed findings on assert() within libburn 7 Oct 2006 [249] libburn/async.c libburn/libdax_msgs.h libburn/asserts.txt Got rid by soft means of assert() in async.c 2006.10.07.121234 [250] libburn/libburn.h libburn/async.c libburn/drive.h libburn/drive.c libburn/init.c libburn/libdax_msgs.h libburn/sg.c libburn/asserts.txt Got rid of assert() in drive.c by soft means 2006.10.07.132916 [251] libburn/init.c libburn/async.c Got rid of assert() in init.c by soft means 2006.10.07.142454 [252] libburn/libburn.h libburn/async.c libburn/options.c libburn/sector.c libburn/spc.c libburn/libdax_msgs.h Got rid of assert() in options.c by soft means 7 Oct 2006 [253] libburn/read.c Got rid of assert() in read.c by soft means 2006.10.07.170913 [254] libburn/sg.c libburn/asserts.txt Got rid of some assert() in sg.c by soft means 2006.10.07.175427 [255] libburn/spc.c libburn/async.c libburn/libdax_msgs.h Got rid of assert() in spc.c by soft means 2006.10.08.095016 [256] libburn/structure.c libburn/sector.c libburn/spc.c libburn/libdax_msgs.h libburn/asserts.txt Got rid of assert() in structure.c by soft means 8 Oct 2006 [257] libburn/toc.c Got rid of assert() in toc.c by soft means 8 Oct 2006 [258] libburn/util.c Got rid of assert() in util.c by soft means 2006.10.09.083438 [259] libburn/write.c libburn/structure.c libburn/libdax_msgs.h libburn/asserts.txt Got rid of assert() in write.c by soft means 2006.10.09.123518 [260] libburn/mmc.c libburn/read.c libburn/sector.c libburn/mmc.h libburn/transport.h libburn/asserts.txt Got rid of assert() in mmc.c by soft means 2006.10.10.112545 [261] libburn/sector.h libburn/sector.c libburn/async.c libburn/write.h libburn/write.c libburn/libdax_msgs.h libburn/asserts.txt Got rid of assert() in sector.c by soft means 2006.10.10.175444 [262] libburn/sg.c libburn/libdax_msgs.h Got rid of assert() in sg.c by soft means 10 Oct 2006 [263] libburn/asserts.txt Got rid of assert() in libburn 2006.10.11.191959 [264] cdrskin/cdrskin.c cdrskin/README Changed pseudo-cdrecord addresses: /dev/hdX = ATA:(X-'a')/2,(X-'a')%2,0 13 Oct 2006 [270] Makefile.am libburn/sg.c libburn/cleanup.c libburn/sg-linux.c libburn/read.c libburn/drive.c libburn/sbc.c libburn/transport.h cdrskin/cleanup.c Made libburn and cdrskin build on my Linux again 2006.10.13.114554 [271] cdrskin/cdrskin.c libburn/write.c libburn/sg-linux.c libburn/libdax_msgs.h Removed bug in burn_disc_write_sync(): BURN_DRIVE_IDLE, then d->sync_cache() 2006.10.14.105224 [272] libburn/sg.h libburn/sg-freebsd.c libburn/sg-linux.c libburn/drive.c Introduced burn_drive_enumerator_t to allow more complete sg-freebsd implementation 2006.10.15.133035 [274] cdrskin/cdrskin.c Changed ambigous include statement of libburn.h 15 Oct 2006 2006 [275] Makefile.am libburn/libdax_msgs.h + libburn/libdax_audioxtr.h + libburn/libdax_audioxtr.c Implemented a first attempt of a .wav decapitator (ticket 38) 15 Oct 2006 2006 [276] + test/dewav.c Implemented a first attempt of a .wav decapitator (ticket 38) 15 Oct 2006 2006 [277] test/dewav.c Fixed permissions of eventually created output file 15 Oct 2006 2006 [278] test/dewav.c cdrskin/compile_cdrskin.sh Hunting a malloc/free memory problem 15 Oct 2006 2006 [279] libburn/libdax_audioxtr.c Hopefully fixed memory problem which causes sigabrt on free 15 Oct 2006 2006 [280] libburn/libdax_audioxtr.c Hopefully fixed problem with stdin as audio source 15 Oct 2006 2006 [281] test/dewav.c Made helptext print to stderr rather than stdout 2006.10.17.141053 [283] cdrskin/cdrskin.c cdrskin/compile_cdrskin.sh libburn/libdax_audioxtr.h libburn/libdax_audioxtr.c test/dewav.c Roughly implemented automatic .wav extraction in cdrskin 2006.10.17.164140 [284] cdrskin/cdrskin.c libburn/libdax_audioxtr.h libburn/libdax_audioxtr.c test/dewav.c Implemented some cdrecord pickiness for .wav extraction 18 Oct 2006 [285] test/libburner.c Added --audio and multi-track, removed --verbose, hid --burn_for_real 2006.10.18.174334 [286] cdrskin/cdrskin.c Removed assumption BURN_DRIVE_IDLE==0 18 Oct 2006 [287] cdrskin/README Changed audio statements to reflect new situation 18 Oct 2006 [288] cdrskin/README Removed a typo 19 Oct 2006 [292] test/libburner.c Freed all tracks after burning and not only last one 2006.10.19.094543 [293] cdrskin/cdrskin.c cdrskin/compile_cdrskin.sh Made cdrskin use libburn/cleanup.[oh] by default (not cdrskin/cleanup.[ch]) ------------------------------------ cycled - cdrskin-0.2.3 - 2006.10.19.105730 2006.10.19.162254 [294] cdrskin/cdrskin.c cdrskin/cdrskin_eng.html cdrskin/changelog.txt Updated documentation about cdrskin-0.2.3 2006.10.19.164742 [295] cdrskin/cdrskin.c Corrected -help text 2006.10.20.113421 [297] libburn/libburn.h libburn/mmc.c libburn/sg-linux.c libburn/sg-freebsd.c libburn/drive.c cdrskin/cdrskin.c Made cdrskin produce "ATIP start of lead" (on non-blank media for now) 20 Oct 2006 [298] doc/comments Updated help text of libburner 2006.10.20.151602 [299] libburn/libburn.h libburn/drive.c libburn/mmc.c libburn/libdax_msgs.h cdrskin/cdrskin.c Classified media with TOC read error as unsuitable (rather than as blank) 2006.10.21.103352 [300] libburn/libburn.h libburn/transport.h libburn/drive.c libburn/mmc.c libburn/spc.c libburn/sg-linux.c libburn/sg-freebsd.c libburn/libdax_msgs.h cdrskin/cdrskin.c Implemented some ATIP functionality 2006.10.21.103653 [301] [302] libburn/libburn.h Clarified relation of burn_disc_read_atip() and burn_drive_get_start_end_lba() 2006.10.21.185102 [303] libburn/sg.h libburn/mmc.h libburn/mmc.c libburn/sbc.h libburn/sbc.c libburn/spc.h libburn/spc.c libburn/drive.h libburn/drive.c libburn/transport.h libburn/sg-linux.c libburn/sg-freebsd.c Split enumerate_common() into logic-layer, command-layer, transport-layer 2006.10.22.130341 [304] libburn/libburn.h libburn/mmc.c libburn/drive.c libburn/cleanup.c cdrskin/cleanup.c cdrskin/cdrskin.c Implemented cdrskin -toc 2006.10.22.131452 [305] cdrskin/cdrskin.c Regulated coexistence of options -toc and -atip 23 Oct 2006 [306] libburn/mmc.c Made clarification in remark about atip speed conversion 2006.10.23.074430 [307] cdrskin/cdrskin.c Made use of burn_drive_info.revision as firmware revision text 2006.10.23.113116 [308] libburn/libburn.h libburn/transport.h libburn/mmc.h libburn/mmc.c libburn/write.c cdrskin/cdrskin.c cdrskin/cdrskin_eng.html cdrskin/README Made available drive buffer fill during write 23 Oct 2006 [309] libburn/sg-freebsd.c Updated tangling of FreeBSD code with mmc.c :( 2006.10.23.134719 [310] cdrskin/cdrskin.c Corrected -toc track counter and notified about "hidden" tracks 2006.10.24.075039 [311] libburn/libdax_audioxtr.h libburn/libdax_audioxtr.c test/dewav.c cdrskin/cdrskin.c Introduced extraction of .au (but not its usage within cdrskin) 2006.10.24.102107 [312] libburn/libburn.h libburn/structure.h libburn/structure.c libburn/sector.c cdrskin/cdrskin.c cdrskin/README Enabled byte swapping for audio track sources, added anti option -swab 2006.10.24.130259 [313] test/dewav.c cdrskin/cdrskin.c cdrskin/README Enabled automatic extraction of .au 24 Oct 2006 [314] Makefile.am + test/fake_au.c Introduced temporary test program to produce SUN .au files ------------------------------------ cycled - cdrskin-0.2.3 - 2006.10.24.144650 2006.10.24.165427 [315] libburn/sector.c Closed some loopholes for byte swapping. 2006.10.24.165610 [316] cdrskin/cdrskin.c Enabled audio byte swapping by default (to be disabled via option -swab) ------------------------------------ cycled - cdrskin-0.2.3 - 2006.10.24.173602 25 Oct 2006 [317] cdrskin/README cdrskin/cdrskin_eng.html cdrskin/wiki_plain.txt Announced full -audio compatibility with cdrecord ------------------------------------ cycled - cdrskin-0.2.3 - 2006.10.25.160540 2006.10.27.114326 [319 branch] - cdrskin/add_ts_changes_to_libburn_0_2_3 + cdrskin/add_ts_changes_to_libburn_0_2_4 cdrskin/README cdrskin/cdrskin.c cdrskin/cdrskin_eng.html cdrskin/changelog.txt README Performed cdrskin version leap to cdrskin-0.2.4 2006.10.28.093922 [320 branch] cdrskin/cdrskin_timestamp.h Set final timestamp 2006.10.28.093922 ------------------------------------ cycled - cdrskin-0.2.4 - 2006.10.28.093922 2006.10.28.115213 [321 trunk] [322 trunk] - cdrskin/add_ts_changes_to_libburn_0_2_3 + cdrskin/add_ts_changes_to_libburn_0_2_4 + cdrskin/add_ts_changes_to_libburn_0_2_5 cdrskin/README cdrskin/cdrskin.c cdrskin/cdrskin_eng.html cdrskin/changelog.txt README Performed cdrskin version leap to cdrskin-0.2.5 28 Oct 2006 [323 branch] - cdrskin/add_ts_changes_to_libburn_0_2_3 cdrskin/add_ts_changes_to_libburn_0_2_4 Corrected misnaming of my development directory 28 Oct 2006 [324 trunk] cdrskin/add_ts_changes_to_libburn_0_2_4 cdrskin/add_ts_changes_to_libburn_0_2_5 Corrected misnaming of my development directory 2006.10.28.132532 [325 branch] cdrskin/cdrskin.c Corrected last-minute bug which made every track from file an audio track 2006.10.28.151521 [326 trunk] cdrskin/cdrskin.c Corrected bug which made every track from file an audio track 29 Oct 2006 [327 branch] [328 trunk] + CONTRIBUTORS Copied missing file from libburn-0.2.2 29 Oct 2006 [329 branch] [330 trunk] Makefile.am Added to EXTRA_DIST cdrskin/cleanup.[ch] 29 Oct 2006 [331 branch] [332 trunk] Makefile.am Added to EXTRA_DIST libburn/sg-*.[ch] 29 Oct 2006 [333 branch] [334 trunk] Makefile.am Deleted from to EXTRA_DIST libburn/sg-*.h 30 Oct 2006 [337] libburn/transport.h libburn/mmc.c libburn/sg-freebsd.c Made MMC command CLOSE TRACK/SESSION available to struct burn_drive 2006.10.31.115606 [338] libburn/transport.h libburn/spc.c libburn/mmc.c libburn/write.h libburn/write.c libburn/sector.c libburn/libdax_msgs.h libburn/sg.h libburn/sg-linux.c cdrskin/cdrskin.c Made single track TAO work (sector i/o still wants fixed size, though) 2006.10.31.184736 [339] libburn/sector.c libburn/source.c libburn/structure.h libburn/structure.c libburn/write.c cdrskin/cdrskin.c Made single track TAO work without fixed size (compile -experimental) 2006.11.01.163934 [340] libburn/libburn.h libburn/source.c libburn/write.h libburn/write.c libburn/structure.c libburn/structure.h libburn/sector.c cdrskin/cdrskin.c cdrskin/compile_cdrskin.sh Adapted cdrskin pacifier to possibly unknown track size 2006.11.01.172004 [341] configure.ac bootstrap test/libburner.c Repaired broken macro settings during Linux build 2 Nov 2006 [342] cdrskin/README Mentioned -tao and experimental compile 2006.11.02.211816 [343] libburn/libburn.h libburn/write.c cdrskin/cdrskin.c Installed status communications about closing session ("Fixating") 3 Nov 2006 [344] test/libburner.c Changed status report during blanking (there are no "sectors") 2006.11.03.063307 [345] cdrskin/cdrskin.c Removed some obsolete debugging messages 2006.11.03.151137 [346] libburn/structure.h libburn/structure.c libburn/write.h libburn/write.c libburn/sector.c libburn/libdax_msgs.h Installed decent abort behavior with TAO 2006.11.03.202403 [347] libburn/write.c Enabled TAO for multiple -data tracks (-audio still ends after 0 bytes) 2006.11.04.092909 [348] libburn/spc.c libburn/sector.c Enabled audio tracks with TAO 2006.11.02.140329 (pl01) [351 tags/CdrskinZeroTwoFourPlZeroOne] ../cdrskin-0.2.4.patch01/configure.ac ../cdrskin-0.2.4.patch01/bootstrap ../cdrskin-0.2.4.patch01/cdrskin/README ../cdrskin-0.2.4.patch01/cdrskin/add_ts_changes_to_libburn_0_2_4_patch01 ../cdrskin-0.2.4.patch01/cdrskin/cdrskin_timestamp.h ../cdrskin-0.2.4.patch01/test/libburner.c Revoked autotools aspect of revision 290 2006.11.06.073810 [352] cdrskin/cdrskin.c cdrskin/cdrskin_eng.html cdrskin/changelog.txt Adapted documentation to reflect experimental TAO mode ------------------------------------ cycle - cdrskin-0.2.5 - 2006.11.06.085056 2006.11.06.114159 [353] libburn/libburn.h libburn/spc.c libburn/options.c cdrskin/cdrskin.c New API burn_write_opts_set_multi(). (But libburn cannot burn next session yet) 2006.11.06.121409 [354] cdrskin/cdrskin.c Made -toc on multiple sessions more compatible 2006.11.06.155237 [355] libburn/libburn.h libburn/drive.c libburn/write.c libburn/mmc.c libburn/sg-linux.c cdrskin/cdrskin.c Made CD with unclosed track blankable (by -force) 2006.11.06.195743 [356] libburn/transport.h libburn/mmc.c libburn/spc.c libburn/write.c libburn/sg-linux.c Cared for some SCSI error conditions which were ignored up to now 2006.11.07.114514 [357] cdrskin/cdrskin.c Made -tao default for single track or stdin, -sao for any other multi-track 7 Nov 2006 [358] cdrskin/cdrskin_eng.html cdrskin/changelog.txt Prepared next cdrskin-0.2.5 upload cycle 7 Nov 2006 [359] cdrskin/changelog.txt cdrskin/README cdrskin/wiki_plain.txt Updated documentation about TAO 2006.11.07.152018 [360] cdrskin/cdrskin.c cdrskin/changelog.txt Updated documentation about TAO ------------------------------------ cycle - cdrskin-0.2.5 - 2006.11.07.152018 * Enabled TAO 2006.11.08.165648 [361] cdrskin/cdrfifo.h cdrskin/cdrfifo.c cdrskin/cdrskin.c Avoided error message and nonzero exit with trailing trash on .wav 8 Nov 2006 [362] cdrskin/cdrskin_eng.html Mentioned bug fix about trailing trash 2006.11.08.172918 [363] libburn/write.c Made track write counter of SAO count rather too much than too few bytes 8 Nov 2006 [364] cdrskin/changelog.txt Prepared next cdrskin-0.2.5 upload cycle ------------------------------------ cycle - cdrskin-0.2.5 - 2006.11.08.181016 * Bug fixed: Trailing trash appended to .wav files caused error message and, if exceeding fifo size, could even stall a burn. 2006.11.09.112832 [365] cdrskin/cdrskin.c Check desired write and block type with burn_drive_info.*_block_types 2006.11.09.113729 [366] libburn/sg-linux.c Silenced SCSI error (debugging) messages about missing media 2006.11.09.151431 [367] cdrskin/cdrskin.c Corrected first speed measurement report in TAO mode (which was random) 2006.11.09.193030 [368] libburn/libburn.h libburn/write.c cdrskin/cdrskin.c Experimentally enabled burning to BURN_DISC_APPENDABLE (tested with TAO only) 2006.11.10.093843 [369] cdrskin/cdrskin.c doc/comments Expressing more self-confidence 2006.11.10.172212 [370] cdrskin/cdrskin.c Provisory -msinfo (very verbous on stderr) 2006.11.10.184047 [371] cdrskin/cdrskin.c Made it work with fifos and other non-plain files as track sources 2006.11.10.185209 [372] cdrskin/cdrskin.c Read -msinfo from first track of last session and not from last track 2006.11.11.122402 [373] libburn/libburn.h libburn/transport.h libburn/mmc.h libburn/mmc.c libburn/write.c libburn/drive.c libburn/libdax_msgs.h New API function burn_disc_track_lba_nwa() 2006.11.11.122907 [374] [375] cdrskin/cdrskin.c Implemented not so provisory -msinfo 2006.11.11.124020 [376] [377] cdrskin/cdrskin.c Reacted on some warnings of gcc -O2 2006.11.11.134752 [378] cdrskin/cdrskin.c Implemented handling of unsuitable disk states with -msinfo 2006.11.11.152037 [379] cdrskin/cdrskin.c Demanded (for now) -tao for writing to appendable CDs 2006.11.11.152748 [380] cdrskin/cdrskin.c Generally enabled -multi, -msinfo and writing to appendable CDs in TAO mode 11 Nov 2006 [381] cdrskin/changelog.txt Prepared next cdrskin-0.2.5 cycle 11 Nov 2006 [382] cdrskin/cdrskin_eng.html cdrskin/README Updated docs about multi-session ------------------------------------ cycle - cdrskin-0.2.5 - 2006.11.11.163625 * Multi-session CDs (for now restricted to write mode TAO), -multi, -msinfo * Bug fixed: False speed with first pacifier cycle. Potential SIGFPE by NaN. 2006.11.12.085808 [383] libburn/mmc.c Made speed 0 in burn_drive_set_speed() really maximum speed (i.e. FFFFh) 2006.11.12.113629 [384] cdrskin/cdrskin.c Made SAO preferrable default write mode, kept TAO as default where needed 2006.11.12.152723 [385] libburn/mmc.c libburn/libdax_msgs.h Reacted on error condition during write operation 2006.11.12.185342 [386] cdrskin/cdrskin.c Made -toc on blank CD exit with value 0 (rather than 7 with no media) 13 Nov 2006 [390] README cdrskin/add_ts_changes_to_libburn_0_2_5 cdrskin/cdrskin_eng.html Changed SVN URLs to reflect new structure 13 Nov 2006 [391] README Refered to both libburn and libisofs in SVN description, updated history ------------------------------------ cycle - cdrskin-0.2.5 - 2006.11.13.122418 * Enabled named pipes and other non-plain file types as track sources (actually already in previous cycle) * Bug fixed: Default speed was not highest possible but announced as "MAX" * SAO is preferred default write mode, TAO is default when needed 2006.11.13.122418 [392] cdrskin/changelog.txt Next cdrskin-0.2.5 cycle 13 Nov 2006 [393] cdrskin/cdrskin_eng.html Adjusted description of write mode default 13 Nov 2006 [394] Makefile.am configure.ac Removed references to libisofs 14 Nov 2006 [399] README Changed references to libisofs 14 Nov 2006 [400] cdrskin/README Corrected a typo reported by George Danchev 2006.11.14.104023 [401] cdrskin/cdrskin.c Implemented try to find on restricted drives a suitable write mode as default 14 Nov 2006 [402] libburn/libburn.h Fixed a wrong name in API description 15 Nov 2006 [403] libburn/write.h libburn/write.c Prepared tests for eventual drive which might support SAO to appendable CD 15 Nov 2006 [404] libburn/sg-linux.c Enhanced optional SCSI command logging 2006.11.15.091329 [405] cdrskin/cdrskin.c Adjusted some texts to new multi-session situation 2006.11.15.170927 [406] libburn/sg.h libburn/sg-linux.c libburn/sg-freebsd.c + libburn/sg-freebsd-port.c libburn/spc.h libburn/spc.c libburn/drive.c Made portability clarifications 15 Nov 2006 [407] libburn/sg-linux.c libburn/sg-freebsd-port.c Narrowed system specific part of enumerate_common() 2006.11.16.111656 [408] [409] Makefile.am + libburn/os.h + libburn/os-linux.h + libburn/os-freebsd.h libburn/sg.h libburn/sg.c libburn/transport.h libburn/cleanup.c libburn/sg-linux.c libburn/sg-freebsd-port.c cdrskin/cleanup.c cdrskin/compile_cdrskin.sh Made consolidaed operating system adapters for ease of porting 2006.11.16.133951 [410] libburn/sg-linux.c libburn/sg-freebsd-port.c Polished porting hints and self-compliance to newly established specs 16 Nov 2006 [411] libburn/sg-linux.c libburn/sg-freebsd-port.c Polished porting hints 16 Nov 2006 [412] test/libburner.c Obsoleted --stdin_size by automatic TAO, cared for non-plain track files 16 Nov 2006 [413] doc/comments Updated help text of libburner 17 Nov 2006 [414] Makefile.am + test/telltoc.c Created info retrieval companion for libburner 17 Nov 2006 [415] test/libburner.c Enabled multi-session with libburner 17 Nov 2006 [416] Makefile.am - test/toc.c Obsoleted old test program 17 Nov 2006 [417] [418] test/telltoc.c Shifted a comma 2006.11.18.194606 [419] libburn/transport.h libburn/sbc.h libburn/sbc.c libburn/drive.c Test wether SCSI 1Bh START UNIT would be helpful with ticket 90 2006.11.19.114413 [420] libburn/libburn.h libburn/mmc.c libburn/sector.c libburn/write.c cdrskin/cdrskin.c Implemented libburn builtin fine granulated drive buffer min-fill recording 2006.11.19.162900 [421] cdrskin/cdrskin.c Avoided self contradiction with "Min drive buffer fill" 2006.11.19.163646 [422] cdrskin/cdrskin.c Fixed missing brackets from revison 421 2006.11.20.090207 [423] libburn/sector.c Silenced compiler warnings 2006.11.20.090503 [424] libburn/drive.c Removed a redundant d->start_unit() of revision 419 ------------------------------------ cycle - cdrskin-0.2.5 - 2006.11.20.092808 * libisofs unbundled from libburn+cdrskin * Hints for porting to other operating systems are now in sg-*.c 20 Nov 2006 [425] cdrskin/changelog.txt Next cdrskin-0.2.5 cycle 2006.11.20.132717 [426] cdrskin/cdrskin.c cdrskin/cdrfifo.h cdrskin/cdrfifo.c cdrskin/wiki_plain.txt Implemented new option fifo_start_at= 20 Nov 2006 [427] cdrskin/wiki_plain.txt Updated in respect to multi-session 2006.11.22.122228 [428] libburn/spc.h libburn/spc.c Coordinated scsi_notify_error() and scsi_error() ------------------------------------ cycle - cdrskin-0.2.5 - 2006.11.22.142517 23 Nov 2006 [433] cdrskin/changelog.txt Last cdrskin-0.2.5 cycle 23 Nov 2006 [434] - test/burn.c - test/master.c - test/tree.py - test/tree.pyc - test/rip.c Removed obsolete test programs 2006.11.23.102340 [435] Makefile.am cdrskin/compile_cdrskin.sh cdrskin/cdrskin.c cdrskin/cdrskin_eng.html cdrskin/README cdrskin/wiki_plain.txt + cdrskin/add_ts_changes_to_libburn_0_2_6 + cdrskin/add_ts_changes_to_libburn_0_2_7 - cdrskin/add_ts_changes_to_libburn_0_2_4 - cdrskin/add_ts_changes_to_libburn_0_2_5 Version leap to 0.2.6 24 Nov 2006 Published cdrskin-0.2.6.pl01 on cdrskin home pages ------------------------------- cycle - cdrskin-0.2.6.pl01 - 2006.11.23.114611 * Enabled TAO * Bug fixed: Trailing trash appended to .wav files caused error message and, if exceeding fifo size, could even stall a burn. * Multi-session CDs (for now restricted to write mode TAO), -multi, -msinfo * Bug fixed: False speed with first pacifier cycle. Potential SIGFPE by NaN. * Enabled named pipes and other non-plain file types as track sources (actually already in previous cycle) * Bug fixed: Default speed was not highest possible but announced as "MAX" * SAO is preferred default write mode, TAO is default when needed * libisofs unbundled from libburn+cdrskin * Hints for porting to other operating systems are now in sg-*.c 2006.11.24.121745 [437] Makefile.am configure.ac cdrskin/compile_cdrskin.sh cdrskin/cdrskin.c cdrskin/README Version leap to 0.2.7 24 Nov 2006 [438] doc/comments Mentioned telltoc and dewav as helpers of libburner ------------------------------------ cycle - cdrskin-0.2.7 - 2006.11.24.125445 24 Nov 2006 [439] cdrskin/changelog.txt First cdrskin-0.2.7 cycle 24 Nov 2006 [440] doc/comments Updated libburner helptext copy 24 Nov 2006 [441] doc/comments Made our claim of burning CD more general 2006.11.25.104047 [442] cdrskin/cdrskin.c Disabled old workaround for ticket 8, burn_disc_read_atip() fixed the problem 25 Nov 2006 [443] libburn/drive.h libburn/drive.c libburn/write.c test/libburner.c Ticket 91: update media state model after content change 25 Nov 2006 [444] test/libburner.c test/telltoc.c Made use of libburn device address translation (/dev/sr0, /dev/cdrom, ...) 25 Nov 2006 [445] test/libburner.c Corrected two minor bugs 2006.11.25.170456 [446] libburn/cleanup.c cdrskin/cleanup.c Trying to keep signal handler from repeating messages 2006.11.25.182841 [447] libburn/write.c libburn/drive.c Prevented premature BURN_DRIVE_IDLE introduced with revision 443 2006.11.25.210321 [448] cdrskin/cdrskin.c Enabled options -vv, -vvv and -vvvv 28 Nov 2006 [449] README Mentioned renaming of umbrella project to libburnia 2006.11.29.205136 [450] cdrskin/cdrskin.c Added preliminary support for new cdrecord 1000+ = ATA busses (input only) 2006.12.01.213845 [451] libburn/transport.h libburn/libdax_msgs.h libburn/mmc.c Ticket 21: media type via 46h GET CONFIGURATION , Current Profile 2006.12.02.111701 [452] libburn/libburn.h libburn/mmc.c libburn/drive.c cdrskin/cdrskin.c New API function to obtain media type: burn_disc_get_profile() 2006.12.02.130631 [453] libburn/mmc.c Correction for drives which return empty tray as profile 0x00 rather than error ------------------------------------ cycle - cdrskin-0.2.7 - 2006.12.02.151257 * Improved recognition of unsuitable media types 2 Dec 2006 [454] cdrskin/changelog.txt cdrskin/cdrskin_eng.html Next cdrskin-0.2.7 cycle 2006.12.02.201405 [456] libburn/drive.c libburn/mmc.c Avoided unsuitable media complaint on burn_drive_grab() with load==0 2006.12.02.201529 [457] cdrskin/cdrskin.c Testing wether the after-grab status waiting loops are necessary 3 Dec 2006 [461] cdrskin/doener_150x200_tr.gif cdrskin/doener_150x200_tr_octx.gif cdrskin/cdrskin_eng.html cdrskin is declared honoray Doenerware (burp) 3 Dec 2006 [463] cdrskin/cdrskin_eng.html Have wikipedia explain doenerism ("Eat the rich" and so) 2006.12.03.155703 [464] README doc/comments test/libburner.c cdrskin/cdrskin_eng.html cdrskin/README cdrskin/cdrskin.c Changed URLs and umbrella names to libburnia 3 Dec 2006 [465] cdrskin/wiki_plain.txt Changed URLs and umbrella names to libburnia 3 Dec 2006 [466] cdrskin/wiki_plain.txt Added Doener logo and link 3 Dec 2006 [468] cdrskin/cdrskin_eng.html cdrskin/add_ts_changes_to_libburn_0_2_7 Excluded doener gifs from cdrskin tarballs ------------------------------------ cycle - cdrskin-0.2.7 - 2006.12.03.204709 2006.12.03.204709 [469] cdrskin/changelog.txt Next cdrskin-0.2.7 cycle 4 Dec 2006 [470] cdrskin/cdrskin_eng.html Removed a newline which made the Mozilla family show a "_" 4 Dec 2006 [471] test/telltoc.c Added reporting of current media profile, changed "Media type" to "Media reuse" 2006.12.09.111108 [475] cdrskin/cdrskin.c Replaced setuid blocker by warning. People must know themselves what they do. ------------------------------------ cycle - cdrskin-0.2.7 - 2006.12.09.141837 * Replaced ban of chmod u+s by loud warning 11 Dec 2006 [484] cdrskin/cdrskin_eng.html cdrskin/changelog.txt Next cdrskin-0.2.7 cycle 2006.12.11.095230 [485] cdrskin/cdrskin_timestamp.h Belated timestamp for changes in cdrskin 11 Dec 2006 [486] Makefile.am Unified mix of tab an blanks which looks ugly in diff 2006.12.11.100021 [487] libburn/sg-linux.c Prepared experiments for new Linux SCSI adventures 2006.12.11.101350 [488] cdrskin/README cdrskin/cdrskin.c cdrskin/wiki_plain.txt Consequences from newly introduces startup file 11 Dec 2006 [489] cdrskin/wiki_plain.txt Repaired README link and planted helptext links 2006.12.11.115802 [490] libburn/sg-linux.c Silenced a compiler warning. Worked further on /dev/srM test. Not done yet. 2006.12.11.125222 [491] libburn/mmc.c libburn/structure.c Prevented SIGSEGVs when using -atip with my SCSI CD-ROM (sr,sg: no matter) 2006.12.11.134452 [492] libburn/sg-linux.c Enabled correct SCSI address parameter registration for /dev/srM. 2006.12.11.145332 [493] libburn/sg-linux.c Removed ban on linux_sg_device_family, warning now of linux_sg_accept_any_type 2006.12.11.161952 [494] libburn/sg-linux.c Reacted better on failing ioctl(SG_GET_SCSI_ID) 2006.12.11.191826 [495] libburn/sg-linux.c cdrskin/cdrskin.c Trying to identfy CD device via ioctl(CDROM_DRIVE_STATUS) 2006.12.11.215017 [496] libburn/libburn.h Appeased doxygen warnings 2006.12.13.170319 [497] cdrskin/cdrskin.c Updated dev=help to versions >= 0.2.4, new option --list_ignored_options 13 Dec 2006 [498] + cdrskin/cdrskin.1 Detailed man page for cdrskin. Based on work of George Danchev. 2006.12.13.195441 [499] Makefile.am Trying to get new man page into release tarball and installation. 13 Dec 2006 [500] cdrskin/README Took care for man page 13 Dec 2006 [501] cdrskin/cdrskin.1 Clarified track content meaning. Corrected some typos and beauty flaws 13 Dec 2006 [502] cdrskin/README cdrskin/cdrskin_eng.html Took more care for man page ------------------------------------ cycle - cdrskin-0.2.7 - 2006.12.13.221921 * detailed man page for cdrskin 13 Dec 2006 [503] cdrskin/changelog.txt Next cdrskin-0.2.7 cycle 13 Dec 2006 [504] cdrskin/cdrskin.1 Explained recordable CD media. Removed a typo. 14 Dec 2006 [505] cdrskin/cdrskin.1 Unified some nomenclature. Removed an error with dev_translation= 14 Dec 2006 [506] CONTRIBUTORS Mentioned George Danchev for his merits about cdrskin man page 2006.12.14.102857 [507] Makefile.am cdrskin/cdrskin_eng.html + cdrskin/convert_man_to_html.sh cdrskin/add_ts_changes_to_libburn_0_2_7 Publishing cdrskin.1 as man_1_cdrskin.html 14 Dec 2006 [508] - doc/comments_test_ts Removed outdated experiment ------------------------------------ cycle - cdrskin-0.2.7 - 2006.12.14.111807 2006.12.14.140001 + cdrskin-0.2.6/cdrskin/cdrskin.1 cdrskin-0.2.6/cdrskin/README cdrskin-0.2.6/cdrskin/cdrskin_eng.html cdrskin-0.2.6/cdrskin/changelog.txt Backported manpage to cdrskin-0.2.6 -> pl02 and libburn-0.2.6 -> 0.2.6.2 14 Dec 2006 [509] cdrskin/cdrskin_eng.html Re-arranged examples of documentation commands 14 Dec 2006 [510] cdrskin/cdrskin.1 Corrected alphabetical sorting error 14 Dec 2006 [511] cdrskin/changelog.txt Next cdrskin-0.2.7 cycle 14 Dec 2006 [512] cdrskin/convert_man_to_html.sh Added some meta info to the document header, changed title to "man 1 cdrskin" 14 Dec 2006 [513] cdrskin/wiki_plain.txt Adapted to existence of man page 15 Dec 2006 [514] cdrskin/cdrskin.1 Clarified drives and their addresses 15 Dec 2006 [515] cdrskin/convert_man_to_html.sh Adapted to changes in cdrskin.1 15 Dec 2006 [516] cdrskin/cdrskin.1 Introduced term "session" 2006.12.16.090001 [518] cdrskin-0.2.6/Makefile.am + cdrskin-0.2.6/cdrskin/cdrskin.1 cdrskin-0.2.6/cdrskin/README cdrskin-0.2.6/cdrskin/cdrskin_eng.html cdrskin-0.2.6/cdrskin/changelog.txt cdrskin-0.2.6/cdrskin/cdrskin_timestamp.h Backported manpage to libburn-0.2.6.1 -> libburn-0.2.6.2 18 Dec 2006 [519] cdrskin/cdrskin.1 Made several minor clarifications 2006.12.18.123242 [520] libburn/mmc.c Noted some insight about necessity of OPC gained from growisofs_mmc.cpp 2006.12.20.111932 [522] libburn/transport.h libburn/options.h libburn/options.c libburn/write.c libburn/sector.c libburn/mmc.c libburn/libdax_msgs.h Prepared experiments for writing to DVD (most easy: DVD+RW) 2006.12.20.142301 [523] libburn/write.c libburn/libdax_msgs.h Refuse to burn audio tracks to DVD 2006.12.20.145222 [524] libburn/drive.c libburn/mmc.c Avoid undefined 43h commands (TOC/ATIP) with non-CD 2006.12.20.170502 [525] libburn/mmc.c Corrected DVD+RW track number and nwa with 52h READ TRACK INFORMATION 2006.12.20.171230 [526] libburn/mmc.c Corrected bug reported by gcc -O2 2006.12.20.174016 [527] yylibburn/write.c Corrected bug reported by gcc -O2 2006.12.20.180214 [528] cdrskin/cdrskin.c With -atip report "booktype" for DVD media and no questionable ATIP info 2006.12.20.195421 [529] cdrskin/cdrskin.c With -atip on DVD report no RAW/RAW96R among "Supported modes" 2006.12.21.122301 [530] libburn/write.c Removed some debugging messages 2006.12.21.122533 [531] cdrskin/cdrskin.c DVD speed reporting (and setting for drives which obey BBh SET CD SPEED) 2006.12.21.200556 [532] libburn/mmc.c libburn/libdax_msgs.h DVD speed setting via B6h SET STREAMING, DVD+RW now enabled in vanilla build 2006.12.21.205702 [533] libburn/write.c Disallowed multi flag with DVD+RW (nurses wrong hopes for now) 21 Dec 2006 [534] test/libburner.c Report media type, avoid self contradicting messages with DVD+RW --multi 2006.12.21.214641 [535] cdrskin/cdrskin.c cdrskin/cdrskin.1 cdrskin/README cdrskin/cdrskin_eng.html doc/comments Some bragging about DVD+RW ------------------------------------ cycle - cdrskin-0.2.7 - 2006.12.22.120854 * Burning of DVD+RW media as single-track TAO-like initial session 2006.12.23.102056 [536] libburn/libburn.h libburn/options.h libburn/options.c libburn/write.c Adjustable write position for DVD+RW: burn_write_opts_set_start_byte() 2006.12.23.102201 [537] cdrskin/cdrskin.c New option write_start_address= 23 Dec 2006 [538] cdrskin/cdrskin.1 cdrskin/README cdrskin/convert_man_to_html.sh Added more info about DVD+RW 2006.12.23.141315 [539] libburn/libburn.h libburn/drive.c libburn/write.c cdrskin/cdrskin.c New API function to inquire burn success (and avoid confusing messages) 2006.12.23.184353 [540] libburn/libburn.h libburn/write.c cdrskin/cdrskin.c More appropriate drive status during format and close of DVD+RW 2006.12.24.140904 [547] cdrskin/cdrskin.c libburn/write.c Fixed a bug with speed measurement at end of DVD+RW burning 2006.12.24.142512 [548] libburn/options.h libburn/options.c libburn/write.c Made DVD 32k end padding controllable 2006.12.24.154455 [549] cdrskin/cdrskin.c Made DVD ignore CD write modes of drive. Made TAO default for DVD+RW. 2006.12.24.182307 [550] libburn/write.c Bugfix with DVD+RW : progress indicators were initialized too late 2006.12.24.182410 [551] libburn/options.c Bugfix after changes for DVD+RW: start_byte was initialized 0, but must be -1 24 Dec 2006 [552] test/libburner.c test/telltoc.c Removed unnecessary waiting loops after grab, mentioned DVD+RW 2006.12.25.113534 [553] libburn/libburn.h libburn/spc.c libburn/drive.c Ticket 93: write speeds from mode page 2Ah descriptors 25 Dec 2006 [554] test/telltoc.c Adjusted to new (still immature) speed info semantics 2006.12.25.185747 [555] cdrskin/cdrskin.c Corrected CD speed conversion factor to 2352*75/1000 = 176.4 kB/s 2006.12.25.190055 [556] libburn/spc.c libburn/mmc.h libburn/mmc.c libburn/write.c libburn/libdax_msgs.h Ticket 93: write speeds from ACh GET PERFORMANCE, Type 03h, DVD media capacity 25 Dec 2006 [557] test/telltoc.c Adjusted to new (more mature) speed info semantics 2006.12.25.190811 [558] libburn/transport.h Completed revision 556 2006.12.26.170459 [559] libburn/libburn.h libburn/transport.h libburn/drive.h libburn/drive.c libburn/mmc.c libburn/spc.c New API calls burn_drive_get_speedlist() , burn_drive_free_speedlist() 26 Dec 2006 [560] test/telltoc.c Enabled report of speed descriptor list 2006.12.26.184321 [561] libburn/libburn.h test/telltoc.c Minor corrections to revisions 559 and 560 2006.12.27.125948 [562] libburn/drive.c Disabled obsolete drive-media-state workaround. (Spinoff of ticket 93 :)) 2006.12.27.130125 [563] libburn/mmc.c Corrected kB conversion factor to 176.4 with ATIP speed codes 2006.12.27.130239 [564] cdrskin/cdrskin.c Defended against a race condition on SuSE 9.3 after -atip (hald et.al. ?) 2006.12.27.132653 [565] libburn/mmc.c Avoided self contradicting result of ATIP speed inquiry 2006.12.27.162846 [566] cdrskin/cdrskin.c cdrskin/cdrskin.1 Emulated wodim option -msifile=path 2006.12.27.213729 [567] cdrskin/cdrskin.c Followed revision 644 of wodim (msifile output without newline) 27 Dec 2006 [568] cdrskin/cdrskin_eng.html cdrskin/cdrskin.1 Updated about msifile=path ------------------------------------ cycle - cdrskin-0.2.7 - 2006.12.27.214424 * New option -msifile=path from cdrkit/wodim 2006.12.29.143734 [569] libburn/mmc.c Corrected DVD-RW sequential profile name 2006.12.30.001343 [570] libburn/mmc.h libburn/mmc.c libburn/spc.c libburn/write.c libburn/libdax_msgs.h cdrskin/cdrskin.c Prepared support for DVD-RW in mode Restricted Overwrite 29 Dec 2006 [571] cdrskin/changelog.txt Next cdrskin-0.2.7 cycle 2007.01.01.170824 [572] libburn/libburn.h libburn/transport.h libburn/spc.c libburn/mmc.h libburn/mmc.c libburn/async.c libburn/drive.h libburn/drive.c libburn/write.c libburn/libdax_msgs.h Prepared formatting of DVD-RW 2007.01.01.171725 [573] cdrskin/cdrskin.c cdrskin/README cdrskin/cdrskin.1 cdrskin/wiki_plain.txt cdrskin/cdrskin_eng.html Made use of formatting of DVD-RW 2 Jan 2007 [574] cdrskin/wiki_plain.txt Added links to cdrskin help texts 2007.01.02.090530 [575] COPYRIGHT README cdrskin/cdrskin.c Greeting the new year ------------------------------------ cycle - cdrskin-0.2.7 - 2007.01.02.101027 * Formatting and then burning to DVD-RW like to DVD+RW 2 Jan 2007 [576] cdrskin/changelog.txt Next cdrskin-0.2.7 cycle 2 Jan 2007 [577] cdrskin/wiki_plain.txt cdrskin/README Some DVD-RW statements 2 Jan 2007 [578] test/libburner.c doc/comments Made use of formatting of DVD-RW 2 Jan 2007 [579] cdrskin/cdrskin.1 Some DVD-RW statements 2007.01.03.163026 [583] libburn/mmc.c Made formatting report progress (as good as the drive does) 2007.01.03.164716 [584] libburn/async.c libburn/drive.c Moved blanking suitability test before eventual spwaning of threads 2007.01.05.125715 [587] libburn/mmc.c libburn/write.c Comments and name changes from new findings out of reading MMC-5 2007.01.06.120551 [591] libburn/libburn.h libburn/transport.h libburn/mmc.h libburn/mmc.c libburn/async.c libburn/drive.h libburn/drive.c libburn/write.c cdrskin/cdrskin.c test/libburner.c New formatting parameter "size". Sorry for changing API. Function is a week old. 8 Jan 2007 [592] libburn/os-linux.h libburn/os-freebsd.h Added note that buffer may not be smaller than 32768 2007.01.08.104222 [593] libburn/libburn.h libburn/drive.c libburn/write.c libburn/mmc.c Introduced size parameter to DVD-RW formatting plus writing of zeros. 2007.01.08.104407 [594] cdrskin/cdrskin.1 cdrskin/cdrskin.c Using 128 MB of size plus writing of zeros with blank=format_overwrite 2007.01.09.140302 [595] libburn/drive.c Fixed a SIGFPE with formatting via libburner 9 Jan 2007 [596] libburn/libburn.h libburn/transport.h libburn/libdax_msgs.h libburn/drive.c libburn/write.c libburn/mmc.c Enhanced DVD-RW formatting 2007.01.09.211152 [597] cdrskin/README cdrskin/cdrskin.1 cdrskin/cdrskin.c Now available: "quickest" and "full" formatting for DVD-RW ------------------------------------ cycle - cdrskin-0.2.7 - 2007.01.10.101406 10 Jan 2007 [598] cdrskin/cdrskin_eng.html Updated size estimation of development downloads 10 Jan 2007 [599] cdrskin/changelog.txt Next cdrskin-0.2.7 cycle 2007.01.10.152350 [600] libburn/libburn.h libburn/mmc.c libburn/drive.c libburn/async.c cdrskin/cdrskin.c Option -force enables re-formatting 2007.01.10.152520 [601] libburn/mmc.c Switched full formatting from type 10h to 00h which includes lead-out 2007.01.10.152812 [602] cdrskin/cdrskin.c cdrskin/cdrskin.1 cdrskin/README Removed writing of dummy data with blank=format_overwrite_full 2007.01.10.204839 [603] libburn/mmc.c libburn/async.c cdrskin/cdrskin.c cdrskin/cdrskin.1 Enabled explicit full formatting of DVD+RW ("de-icing") 11 Jan 2007 [604] cdrskin/README Removed outdated option from startup file example 2007.01.11.131106 [605] libburn/mmc.c With full formatting prefer format 10h over 13h or 15h 2007.01.11.131302 [606] libburn/os-linux.h libburn/os-freebsd.h libburn/cleanup.c cdrskin/cleanup.c Kept SIGWINCH from spoiling a burn. 2007.01.11.131615 [607] libburn/init.c Sketched better handling of self-inflicted SIGs 2007.01.11.131716 [608] libburn/drive.c Removed surplus newlines from messages 2007.01.12.162239 [609] libburn/write.c libburn/spc.c libburn/mmc.c cdrskin/cdrskin.c cdrskin/cdrskin.1 Enabled writing to DVD-RAM 2007.01.13.140812 [610] [611] libburn/sg-linux.c Implemented debugging messages for ATA enumeration 13 Jan 2007 [612] cdrskin/cdrskin_eng.html cdrskin/README Documentation updates about DVD-RAM 2007.01.13.211425 [613] libburn/transport.h libburn/mmc.c Load array of format capacities into struct burn_drive 2007.01.13.211639 [614] libburn/libburn.h libburn/drive.c libburn/async.c Introduced API for inspection and selection of format capacities 13 Jan 2007 [615] test/telltoc.c Added printing of list of available formats 13 Jan 2007 [616] test/libburner.c Mentioned DVD-RAM where appropriate 2007.01.13.214259 [617] cdrskin/cdrskin.c Shifted fifo reporting to new 4-times -v verbosity level 2007.01.14.101742 [618] cdrskin/cdrskin.c Corrected bug with debug messages for fifo 2007.01.14.115347 [619] libburn/write.c Added missing cache sync in case of aborted DVD-RW burns 2007.01.14.133951 [620] libburn/transport.h libburn/mmc.c libburn/write.c Avoided closing of 0x13-DVD-RW sessions which are not intermediate 15 Jan 2007 [621] cdrskin/wiki_plain.txt Updated about overwriteable DVD and pointer to dvd+rw-tools ------------------------------------ cycle - cdrskin-0.2.7 - 2007.01.15.131357 * Burning to DVD-RAM 15 Jan 2007 [623] cdrskin/changelog.txt Next cdrskin-0.2.7 cycle 2007.01.16.120001 [tag 624] Makefile.am configure.ac README cdrskin/cdrskin.c cdrskin/README cdrskin/compile_cdrskin.sh cdrskin/cdrskin_timestamp.h cdrskin/changelog.txt Made version number transition to 0.3.0 15 Jan 2007 [tag 625] - cdrskin/add_ts_changes_to_libburn_0_2_6 - cdrskin/add_ts_changes_to_libburn_0_2_7 + cdrskin/add_ts_changes_to_libburn_0_3_0 Updated cdrskin tarball generator 16 Jan 2007 [tag 626] README Corrected statement about restriction to CD 16 Jan 2007 [tag 627] cdrskin/cdrskin.c Silenced a compiler warning 16 Jan 2007 [tag 628] cdrskin/README Corrected name of tarball 16 Jan 2007 [tag 632] test/telltoc.c Corrected old libburn.pykix.org URL 16 Jan 2007 [tag 634] cdrskin/cdrskin_eng.html Updated web page ------------------------------- cycle - cdrskin-0.3.0.pl00 - 2007.01.16.120001 * Improved recognition of unsuitable media types * Replaced ban of chmod u+s by loud warning * detailed man page for cdrskin * Burning of DVD+RW and DVD-RAM media as single-track TAO-like initial session * Formatting and then burning to DVD-RW like to DVD+RW * New option -msifile=path from cdrkit/wodim 16 Jan 2007 [629] - cdrskin/add_ts_changes_to_libburn_0_2_6 - cdrskin/add_ts_changes_to_libburn_0_2_7 + cdrskin/add_ts_changes_to_libburn_0_3_0 + cdrskin/add_ts_changes_to_libburn_0_3_1 Updated cdrskin tarball generator 2007.01.16.151041 [630] Makefile.am configure.ac cdrskin/cdrskin.c cdrskin/README cdrskin/compile_cdrskin.sh Made version number transition to 0.3.1 16 Jan 2007 [631] test/telltoc.c Corrected old libburn.pykix.org URL 16 Jan 2007 [633] cdrskin/cdrskin_eng.html Corrected typo ------------------------------------ cycle - cdrskin-0.3.1 - 2007.01.16.152345 16 Jan 2007 [635] cdrskin/changelog.txt Next cdrskin-0.3.1 cycle 17 Jan 2007 [636] cdrskin/wiki_plain.txt Removed paragraph about obsoleted tao_to_sao_tsize= 18 Jan 2007 [637] + doc/cookbook.txt Wrote down what i learned from implementing support for overwriteable DVD 18 Jan 2007 [638] doc/cookbook.txt More info about Current/Maximum Capacity Descriptor 18 Jan 2007 [639] doc/cookbook.txt Made clarification about formatting state recognition 2007.01.18.211740 [640] libburn/transport.h libburn/mmc.c libburn/write.c Kept DVD+RW from stopping BG formatting if it was not started at all 2007.01.19.110510 [641] libburn/mmc.c Removed forgotten debug message printed to stderr 19 Jan 2007 [642] doc/cookbook.txt Began to describe TAO multi-session CD writing 20 Jan 2007 [643] doc/cookbook.txt Changes with CD part. Especially explanation of TOC. 2007.01.21.190928 [644] cdrskin/cdrskin.c Removed unnecessary after-grab loops 2007.01.21.191058 [645] libburn/write.c Comments learned from studying MMC-3 and MMC-5 for SAO CD cookbook 21 Jan 2007 [646] doc/cookbook.txt Clarification about TAO and mode page 05h per track 2007.01.22.114245 [647] libburn/libburn.h libburn/write.c libburn/async.c libburn/libdax_msgs.h cdrskin/cdrskin.c Bug fix: Banned mixed mode SAO (because broken in libburn and unclear in MMC) 23 Jan 2007 [648] doc/cookbook.txt Added SAO CD Cookbook 23 Jan 2007 [649] doc/cookbook.txt Corrections of typos and text debris 2007.01.25.145846 [652] libburn/structure.c Bug fix: DVD tracks of defined size >=2GB suffered 32-bit integer wraparound 2007.01.25.185214 [655] libburn/libburn.h libburn/write.c libburn/structure.h libburn/structure.c libburn/file.h libburn/file.c Enforce minimum track length with SAO 2007.01.25.180001 [tag 656] libburn_0_3_0_1/libburn/structure.c libburn_0_3_0_1/cdrskin/cdrskin_timestamp.h libburn_0_3_0_1/cdrskin/README Bug fix: DVD tracks of defined size >=2GB suffered 32-bit integer wraparound 26 Jan 2007 [tag 657] libburn_0_3_0_1/cdrskin/cdrskin_eng.html Mentioned new cdrskin patch level 01 26 Jan 2007 [658] cdrskin/cdrskin_eng.html Now offering cdrskin-0.3.0.pl01 for download ------------------------------------ cycle - cdrskin-0.3.1 - 2007.01.26.111920 2007.01.26.173236 [659] libburn/file.h libburn/file.c Unified burn_file_source and burn_fd_source 27 Jan 2007 [660] libburn/null.c Initialized member set_size of burn_source within burn_null_source_new() 27 Jan 2007 [tag 661] libburn_0_3_0_1/libburn/file.c Removed 1.3 GB curbs for sources created by burn_file_source_new() 29 Jan 2007 [662] doc/cookbook.txt Added a statement about blanking of DVD-RW 2007.01.29.175822 [663] libburn/transport.h libburn/drive.c libburn/write.c libburn/mmc.c Experiments about list of features and profiles 2007.01.30.165317 [664] libburn/write.c libburn/mmc.c Preparations for DVD-R[W] Sequential Recording 2007.01.30.191740 [665] libburn/write.c libburn/mmc.c First successful multi-session write to a sequential DVD-RW 30 Jan 2007 [666] doc/cookbook.txt Added snapshot of emerging sequential DVD-R[W] cookbook 2007.01.30.220220 [667] cdrskin/cdrskin.c cdrskin/cdrskin.1 Enabled Burnfree buffer underrun protection by default 2007.01.31.130100 [668] libburn/async.c cdrskin/cdrskin.c cdrskin/cdrskin.1 Blank sequential DVD-RW, deformat overwriteable DVD-RW 2007.01.31.173611 [669] libburn/libburn.h libburn/transport.h libburn/drive.c libburn/mmc.c cdrskin/cdrskin.c cdrskin/cdrskin.1 Provisorily obtain multi-session -C parameters (violates MMC specs but works) 2007.02.01.161634 [670] libburn/libburn.h libburn/transport.h libburn/mmc.c test/telltoc.c cdrskin/cdrskin.c cdrskin/cdrskin.1 Obtain TOC from non-CD via 52h READ TRACK INFORMATION 2007.02.01.163511 [671] cdrskin/cdrskin.c Reacted on justified compiler warning about unitialized sessions variable 2007.02.01.191638 [672] libburn/mmc.c cdrskin/cdrskin.c Allow blanking of DVD-RW which offer no Incremental Streaming 1 Feb 2007 [673] cdrskin/cdrskin_eng.html cdrskin/README cdrskin/cdrskin.1 Prepared next cdrskin-0.3.1 cycle 1 Feb 2007 [674] cdrskin/changelog.txt Prepared next cdrskin-0.3.1 cycle 1 Feb 2007 [675] [676] cdrskin/cdrskin.1 Mentioned DVD-RW multi-session in overview of features ------------------------------------ cycle - cdrskin-0.3.1 - 2007.02.01.203057 * Burnfree enabled by default * Multi-session recording on sequential DVD-RW, including -toc, -msinfo 2 Feb 2007 [677] cdrskin/convert_man_to_html.sh Some sed expressions for beautification 2 Feb 2007 [678] doc/cookbook.txt Updated about DVD-R[W] blanking, multi-session info and TOC 2007.02.02.151327 [679] libburn/mmc.c test/telltoc.c Make mmc_read_multi_session_c1 use TOC if available 2007.02.02.173345 [680] libburn/mmc.c cdrskin/cdrskin.c Improved classification and TOC of finalized DVD-R[W] media ------------------------------------ cycle - cdrskin-0.3.1 - 2007.02.02.183755 3 Feb 2007 [681] cdrskin/cdrskin.1 cdrskin/wiki_plain.txt Mentioned DVD-RW multi-session 2007.02.03.205526 (comitted 4 Feb 2007) [682] libburn/libburn.h libburn/mmc.c libburn/drive.c libburn/async.c test/telltoc.c New in API : struct burn_multi_caps and burn_disc_get_multi_caps() 2007.02.05.132335 [683] libburn/transport.h libburn/mmc.c Preparations for DVD-R[W] DAO 2007.02.06.130410 [684] libburn/libburn.h libburn/mmc.c libburn/write.c libburn/drive.c libburn/libdax_msgs.h Implemented DVD-R[W] DAO as BURN_WRITE_SAO 2007.02.06.170621 [685] libburn/write.c libburn/mmc.c Beautification of debugging messages 2007.02.06.174320 [686] cdrskin/cdrskin.c tao_to_sao_tsize= for DVD-R[W] DAO 2007.02.06.185534 [687] libburn/async.c cdrskin/cdrskin.c Enabled fast blank for DVD-R[W] 6 Feb 2007 [688] cdrskin/cdrskin.1 Clarified CD and DVD peculiarities 6 Feb 2007 [689] doc/cookbook.txt Described DVD-R[W] DAO mode ------------------------------------ cycle - cdrskin-0.3.1 - 2007.02.06.200802 * DVD-R[W] Disk-at-once writing 6 Feb 2007 [690] cdrskin/README cdrskin/changelog.txt cdrskin/cdrskin_eng.html Next cdrskin-0.3.1 cycle 2007.02.07.162836 [691] libburn/libburn.h libburn/drive.h libburn/drive.c libburn/options.c libburn/libdax_msgs.h New API function burn_write_opts_auto_write_type() 7 Feb 2007 [692] test/libburner.c Made use of burn_write_opts_auto_write_type() 7 Feb 2007 [693] test/libburner.c doc/comments Updated documentation aspects 8 Feb 2007 [694] README doc/comments cdrskin/cdrskin.1 cdrskin/README Finally made tests with DVD-R. They burn indeed like DVD-RW. 2007.02.08.210744 [695] cdrskin/cdrskin.c cdrskin/cdrskin.1 New option --prodvd_cli_compatible 8 Feb 2007 [696] cdrskin/wiki_plain.txt cdrskin/cdrskin_eng.html Mentioned DVD-R 2007.02.08.225208 [697] cdrskin/cdrskin.c Silenced compiler warning ------------------------------------ cycle - cdrskin-0.3.1 - 2007.02.09.074058 9 Feb 2006 [698] cdrskin/cdrskin_eng.html Added special thanks towards Andy Polyakov 9 Feb 2006 [699] cdrskin/cdrskin.1 doc/cookbook.txt Small corrections in documentation 10 Feb 2007 [tag 701] [705] - cdrskin/add_ts_changes_to_libburn_0_3_0 - cdrskin/add_ts_changes_to_libburn_0_3_1 + cdrskin/add_ts_changes_to_libburn_0_3_2 + cdrskin/add_ts_changes_to_libburn_0_3_3 Updated cdrskin tarball generator 2007.02.10.120001 [tag 702] [704] Makefile.am configure.ac README cdrskin/cdrskin.c cdrskin/README cdrskin/compile_cdrskin.sh cdrskin/cdrskin_timestamp.h cdrskin/wiki_plain.txt cdrskin/cdrskin_eng.html Made number transition and activated development documentation 10 Feb 2007 [tag 703] [707] cdrskin/changelog.txt Documented changes and 0.3.2 release timestamp ----------------------------- release - cdrskin-0.3.2.pl00 - 2007.02.10.120001 * Burnfree enabled by default * Multi-session recording on sequential DVD-R[W], including -toc, -msinfo * DVD-R[W] Disk-at-once recording 10 Feb 2007 [706] libburn/mmc.c Added a comment about DVD-R ------------------------------------ cycle - cdrskin-0.3.3 - 2007.02.10.190528 12 Feb 2007 [708] cdrskin/cdrskin.1 Being exacting about on-the-fly and DVD-RW 12 Feb 2007 [709] cdrskin/cdrskin_eng.html Updated list of keywords 2007.02.12.142245 [710] libburn/mmc.c Made profile 0010h DVD-ROM suitable,full,not erasable. So it delivers a TOC. 2007.02.13.115459 [711] libburn/spc.c Set a suitable page 05h after spc_probe_write_modes() 2007.02.13.143718 [712] libburn/libburn.h libburn/transport.h libburn/mmc.c libburn/spc.c libburn/drive.c Mew API function burn_disc_available_space() 13 Feb 2007 [713] test/libburner.c Removed or updated outdated restriction statements 13 Feb 2007 [714] test/telltoc.c Applied new API function burn_disc_available_space() 2007.02.14.120213 [715] libburn/spc.c Removed outdated ifdef 14 Feb 2007 [716] test/telltoc.c Set the advised write mode before inquiring media space 2007.02.14.121440 [717] libburn/libdax_msgs.h libburn/mmc.c Handle eventual ridiculously high d->last_track_no 2007.02.14.122218 [718] libburn/mmc.h Forgotten part of revision 718 2007.02.14.202944 [719] libburn/libburn.h libburn/options.h libburn/options.c libburn/structure.h libburn/structure.c libburn/write.c libburn/drive.c Optional padding up to full media size when closing (incomplete yet) 2007.02.14.203635 [720] cdrskin/cdrskin.c cdrskin/cdrskin.1 New options --fill_up_media and --tell_media_space 2007.02.15.201506 [722] libburn/options.c libburn/drive.c cdrskin/cdrskin.c libburn/write.c Took fill_up_media into respect with automatic write mode decisions 2007.02.15.201651 [723] libburn/transport.h libburn/mmc.c libburn/libdax_msgs.h Installed a guardian for predicted track end 2007.02.15.201757 [724] libburn/structure.c Corrected bug about open_ended filluped tracks 15 Feb 2007 [725] libburn/libburn.h cdrskin/cdrskin.1 Clarifications about current state of fillup 2007.02.15.203448 [726] libburn/write.c Repaired debugging message spoiled by uninitialized variable 2007.02.16.111941 [728] libburn/write.c Corrected CD TAO bug introduced with DVD bug fix 724 and CD SAO change 655 2007.02.17.085118 [729] libburn/structure.c Another bug fix for revision 724 2007.02.17.085533 [730] libburn/async.c cdrskin/cdrskin.c cdrskin/cdrskin.1 test/libburner.c Allowed forceful blanking of blank media in burn_disc_erase() 17 Feb 2007 [731] test/libburner.c Removed unprecise unnecessary comment ------------------------------------ cycle - cdrskin-0.3.3 - 2007.02.17.121238 * New option --tell_media_space tells the maximum size for the next burn 2007.02.18.094414 [732] libburn/libburn.h Clarified usage comment with burn_drive_info_free() (see ticket 98) 18 Feb 2007 [733] cdrskin/cdrskin.1 cdrskin/cdrskin_eng.html cdrskin/changelog.txt Next cdrskin-0.3.3 cycle 2007.02.18.094858 [734] libburn/mmc.h Adjusted maximum realistic number of tracks to MMC specs 2007.02.19.184132 [735] cdrskin/cdrskin.c Repaired slightly broken pacifier track size display with -audio 2007.02.19.225102 [736] libburn/libburn.h libburn/async.c libburn/structure.h libburn/structure.c libburn/write.h libburn/write.c libburn/drive.h libburn/drive.c libburn/options.c libburn/libdax_msgs.h Re-arranged checking and defaulting of write parameters = New API function burn_track_set_default_size() New API function burn_precheck_write() Make wide use of burn_disc_write_mode_demands() 2007.02.21.205244 [737] libburn/libburn.h libburn/async.c libburn/drive.c libburn/options.c libburn/structure.c libburn/write.c libburn/libdax_msgs.h cdrskin/cdrskin.c Moved tao_to_sao_tsize into libburn, let cdrskin use auto_write_type and precheck 21 Feb 2007 [738] cdrskin/add_ts_changes_to_libburn_0_3_3 cdrskin/add_ts_changes_to_libburn_0_3_2 Added -O2 to binary production 2007.02.22.072700 [739] libburn/libburn.h libburn/drive.c libburn/options.c Re-enabled overwriteable pseudo-pseudo-SAO with unpredicted track size 2007.02.22.073157 [740] libburn/mmc.c Disabled debugging messages about format descriptors 2007.02.22.094939 [741] libburn/libburn.h libburn/options.c libburn/write.c libburn/async.c test/libburner.c cdrskin/cdrskin.c Macro for length of rejection reasons string (old size is still safe) 2007.02.22.113016 [742] libburn/libburn.h libburn/drive.c Made burn_disc_available_space() take into respect burn_write_opts_set_start_byte() 2007.02.23.190937 [743] libburn/libburn.h libburn/drive.c libburn/mmc.c libburn/write.c doc/cookbook.txt Enabled DVD-R/DL Sequential via burn_allow_untested_profiles() 2007.02.23.191117 [744] cdrskin/cdrskin.c cdrskin/cdrskin.1 Enabled DVD-R/DL Sequential via --allow_untested_media_types 2007.02.23.193427 [745] libburn/init.c Forgotten source file for revision 743 ------------------------------------ cycle - cdrskin-0.3.3 - 2007.02.24.102731 2007.02.25.112733 [746] libburn/write.h libburn/write.c libburn/drive.c cdrskin/cdrskin.1 Took into respect deliberate lack of DVD-R/DL multi session capability 2007.03.01.120945 [747] libburn/drive.c libburn/mmc.c libburn/write.c cdrskin/cdrskin.c doc/cookbook.txt Preparations for supporting DVD+R[/DL] 3 Mar 2007 [748] cdrskin/cdrskin.1 Updated DVD-R[W] write mode description 2007.03.03.141240 [749] libburn/transport.h libburn/mmc.c Determine physical interface SCSI,ATA,SATA,USB,... (for future use) 2007.03.03.141435 [750] libburn/libburn.h libburn/write.c libburn/options.h libburn/options.c cdrskin/cdrskin.c Re-enabled -force with write modes which seem unavailable 2007.03.03.151812 [751] libburn/options.c Fixed bug introduced with rev 736ff which prevented audio CD burning 2007.03.04.184720 [752] cdrskin/cdrskin.c cdrskin/cdrfifo.c Fifo got stuck if sum of processed track sizes was exactly aligned to fifo size ------------------------------------ cycle - cdrskin-0.3.3 - 2007.03.04.185202 * Bug fix: Multi-track runs with fifo could stall in rare cases 5 Mar 2007 [753] cdrskin/cdrskin_eng.html cdrskin/add_ts_changes_to_libburn_0_3_2 Released cdrskin-0.3.2.pl01 2007.03.06.195203 [754] libburn/mmc.c libburn/write.c Enabled DVD+R, DVD+R DL via --allow_untested_media_types, always -multi for now 2007.03.06.205312 [755] libburn/mmc.c cdrskin/cdrskin.1 doc/cookbook.txt doc/comments Enabled DVD+R as tested media (-multi is still always on) 2007.03.07.151514 [756] libburn/write.c cdrskin/cdrskin.1 cdrskin/README doc/cookbook.txt Some adjustments for DVD+R recording 2007.03.07.151514 [756] cdrskin/cdrskin_eng.html cdrskin/changelog.txt Next cdrskin-0.3.3 cycle ------------------------------------ cycle - cdrskin-0.3.3 - 2007.03.07.155750 * Multi-session burning to DVD+R 8 Mar 2007 [757] cdrskin/cdrskin.1 cdrskin/convert_man_to_html.sh cdrskin/wiki_plain.txt Polished documentation 2007.03.09.134622 [758] cdrskin/cdrskin.c cdrskin/cdrskin.1 New option assert_write_lba= 10 Mar 2007 [759] cdrskin/cdrskin.1 cdrskin/wiki_plain.txt Polished documentation ------------------------------------ cycle - cdrskin-0.3.3 - 2007.03.10. * New option assert_write_lba= 2007.03.12.110001 [tag 761] Makefile.am configure.ac README cdrskin/cdrskin.c cdrskin/README cdrskin/compile_cdrskin.sh cdrskin/cdrskin_timestamp.h cdrskin/cdrskin_eng.html Made number transition to 0.3.4 and activated development documentation 12 Mar 2007 [tag 762] - cdrskin/add_ts_changes_to_libburn_0_3_2 - cdrskin/add_ts_changes_to_libburn_0_3_3 + cdrskin/add_ts_changes_to_libburn_0_3_4 + cdrskin/add_ts_changes_to_libburn_0_3_5 Updated cdrskin tarball generator 12 Mar 2007 [tag 763] cdrskin/changelog.txt Documented most recent changes 12 Mar 2007 [tag 764] README Removed redundant sentence ----------------------------- release - cdrskin-0.3.4.pl00 - 2007.03.12.110001 * Multi-session burning to DVD+R * New option --tell_media_space tells the maximum size for the next burn * New option assert_write_lba= * Bug fix: Multi-track runs with fifo could stall in rare cases 2007.03.12.155600 [765] Makefile.am configure.ac README cdrskin/cdrskin.c cdrskin/README cdrskin/compile_cdrskin.sh cdrskin/cdrskin_timestamp.h cdrskin/cdrskin_eng.html Made number transition to 0.3.5 12 Mar 2007 [766] - cdrskin/add_ts_changes_to_libburn_0_3_2 - cdrskin/add_ts_changes_to_libburn_0_3_3 + cdrskin/add_ts_changes_to_libburn_0_3_4 + cdrskin/add_ts_changes_to_libburn_0_3_5 Updated cdrskin tarball generator ------------------------------------ cycle - cdrskin-0.3.5 - 2007.03.12.160658 14 Mar 2007 [767] cdrskin/cdrskin_eng.html Corrected truncated sentence and file sizes 14 Mar 2007 [768] cdrskin/changelog.txt Next cdrskin-0.3.5 cycle 2007.03.14.133618 [769] libburn/libburn.h libburn/init.c libburn/sg-linux.c cdrskin/cdrskin.c cdrskin/cdrskin.1 New option drive_scsi_dev_family=sr|scd|sg 2007.03.15.194531 [770] libburn/drive.c React properly on drive stating that it cannot write any media 2007.03.15.195005 [771] libburn/spc.h libburn/spc.c libburn/sbc.c After loading tray wait for unit to become ready or to report some clear error 2007.03.15.195251 [772] cdrskin/cdrskin.c Moved manual device family decision to a sufficiently early stage 2007.03.15.195428 [773] libburn/mmc.c Kept mmc_get_configuration() from believing the announcement of 1 GB reply 2007.03.15.195534 [774] libburn/sg-linux.c Trying to recognize kernel >= 2.6 and use /dev/sr by default 15 Mar 2007 [775] cdrskin/cdrskin.1 Updated drive_scsi_dev_family= 15 Mar 2007 [776] cdrskin/changelog.txt Next cdrskin-0.3.5 cycle ------------------------------------ cycle - cdrskin-0.3.5 - 2007.03.16.001311 * Usage of /dev/srN rather than /dev/sgN on Linux >= 2.6 * New option drive_scsi_dev_family=sr|scd|sg 18 Mar 2007 [777] cdrskin/cdrskin_eng.html Mentioned new sr behavior 2007.03.24.093238 [785] libburn/drive.c Fixed bug with burn_disc_available_space(...,NULL) 2007.03.24.093623 [786] cdrskin/cdrskin.c Warning of very small tsize= settings. (Proposal by Eduard Bloch) 2007.03.27.213543 [787] cdrskin/cdrskin.c cdrskin/cdrfifo.h cdrskin/cdrfifo.c Preparations for option -isosize via fifo (only a debug message yet) 2007.03.28.100934 [788] libburn/libburn.h libburn/structure.c cdrskin/cdrskin.c Enabled -isosize for first track by help of fifo and without seeking 2007.03.28.111739 [789] cdrskin/cdrskin.c Silenced error condition about -sao with stdin and -isosize 2007.03.28.160503 [790] cdrskin/cdrskin.c Enabled -isosize with S_IFREG or S_IFBLK files and without fifo 2007.03.28.182419 [791] cdrskin/cdrskin.c cdrskin/cdrskin.1 Made fifo based -isosize read 64k first and the rest only at normal stage 2007.03.28.202802 [792] cdrskin/cdrskin.c Silenced error message if tsize= is smaller than source is willing to deliver ------------------------------------ cycle - cdrskin-0.3.5 - 2007.03.28.212322 * Option -isosize is supported now 29 Mar 2007 [793] cdrskin/cdrskin_eng.html cdrskin/changelog.txt Next cdrskin-0.3.5 cycle 2007.03.30.201034 [794] libburn/write.c cdrskin/cdrskin.1 Allowed finalizing of DVD+R 2007.03.30.214657 [795] libburn/write.c Avoided unconditional finalizing of DVD+R 2007.04.03.140356 [796] libburn/sg-linux.c Added fcntl() locking to O_EXCL locking 2007.04.03.145637 [797] cdrskin/cdrskin.c Make --old_pseudo_scsi_adr -scanbus work with any drive_scsi_dev_family= 2007.04.03.145806 [798] libburn/libdax_msgs.h Added fcntl() locking to O_EXCL locking 2007.04.04.184341 [799] libburn/libburn.h libburn/init.c libburn/sg-linux.c cdrskin/cdrskin.c cdrskin/cdrskin.1 New cdrskin options --drive_not_f_setlk and --drive_not_o_excl 6 Apr 2007 [801] test/libburner.c Updated media list in introduction comment 2007.04.09.105543 [802] libburn/transport.h libburn/os-linux.h libburn/sg-linux.c cdrskin/cdrskin.1 Cleaned up scsi sibling management, sketched grafting of DDLP 2007.04.09.111215 [803] libburn/sg-linux.c Reacted on compiler warning about last_rdev, fixed fresh typo bug ------------------------------------ cycle - cdrskin-0.3.5 - 2007.04.09.112127 * DVD+R now get finalized (if not -multi is given) 10 Apr 2007 [804] cdrskin/changelog.txt Next cdrskin-0.3.5 cycle 2007.04.10.081855 [805] libburn/init.c Fixed bug with drive_scsi_dev_family= introduced by revision 796 (fcntl lock) 2007.04.10.082229 [806] libburn/sg-linux.c Used O_EXCL|O_RDWR and fcntl() even within sg_obtain_scsi_adr() 2007.04.10.083119 [807] libburn/sg-linux.c Fixed bug in sg_open_scsi_siblings() introduced with revision 802 2007.04.10.144840 [808] libburn/spc.c libburn/libdax_msgs.h Avoided SIGSEGV with an old SCSI CD-ROM drive and its wild replies 12 Apr 2007 [810] README Clarified license. People who object shall please come forward now. 2007.04.13.171347 [815] libburn/sg-linux.c libburn/libdax_msgs.h Switched from O_NONBLOCK to O_NDELAY (see http://lkml.org/lkml/2007/4/11/141) 2007.04.13.173008 [816] cdrskin/cdrskin.c cdrskin/cdrskin.1 Made use of fcntl(F_SETLK) switchable (and thus became more free with default) 15 Apr 2007 [819] + libburn/ddlpa.h + libburn/ddlpa.c Began test implementation of DDLP-A 15 Apr 2007 [820] libburn/ddlpa.h libburn/ddlpa.c Implemented ddlpa_lock_btl() 16 Apr 2007 [821] doc/cookbook.txt Finalized DVD+R cookbook 16 Apr 2007 [822] + doc/ddlp.txt Emerging description of DDLP 16 Apr 2007 [823] doc/ddlp.txt libburn/ddlpa.h libburn/ddlpa.c Polished txt and finally threw out getter functions 16 Apr 2007 [824] libburn/ddlpa.h Corrected description of return values 18 Apr 2007 [825] + test/open-cd-excl.c Program for probing access to device files. By Ted Ts'o with modifications by me. 18 Apr 2007 [826] doc/ddlp.txt Allowed for Friendly Programs: O_EXCL | O_RDONLY 18 Apr 2007 [827] libburn/ddlpa.h libburn/ddlpa.c Progress due to tests with test/open-cd-excl 2007.04.18.103734 [828] libburn/mmc.c Updated comments about DVD+R 18 Apr 2007 [829] test/open-cd-excl.c libburn/ddlpa.c doc/ddlp.txt Polished messages, comments and description of DDLP-A 18 Apr 2007 [830] test/open-cd-excl.c doc/ddlp.txt Adaptations to new test results and discussions 18 Apr 2007 [831] doc/ddlp.txt Corrected a list of standard paths 19 Apr 2007 [832] [833] doc/ddlp.txt Clarifications about motivation and duties of the participants 20 Apr 2007 [834] doc/ddlp.txt Beginning to develop DDLP-B 21 Apr 2007 [835] doc/ddlp.txt Declared failure of DDLP to entirely solve the concurrency problem ------------------------------------ cycle - cdrskin-0.3.5 - 2007.04.22.112236 22 Apr 2007 [836] cdrskin/changelog.txt Next cdrskin-0.3.5 cycle 22 Apr 2007 [837] cdrskin/add_ts_changes_to_libburn_0_3_5 cdrskin/add_ts_changes_to_libburn_0_3_4 Repaired autotools bootstrap bug by help of sed 22 Apr 2007 [838] cdrskin/cdrskin.1 Changed many /dev/sg to /dev/sr 2007.04.23.130001 [tag 841] Makefile.am configure.ac README cdrskin/cdrskin.c cdrskin/README cdrskin/compile_cdrskin.sh cdrskin/cdrskin_timestamp.h cdrskin/wiki_plain.txt cdrskin/cdrskin_eng.html doc/comments Made number transition and activated development documentation 23 Apr 2007 [tag 842] - cdrskin/add_ts_changes_to_libburn_0_3_4 - cdrskin/add_ts_changes_to_libburn_0_3_5 + cdrskin/add_ts_changes_to_libburn_0_3_6 + cdrskin/add_ts_changes_to_libburn_0_3_7 Updated cdrskin tarball generator 23 Apr 2007 [tag 844] cdrskin/README Corrected false info about outdated addressing method 2007.04.23.154600 [843] Makefile.am configure.ac README cdrskin/cdrskin.c cdrskin/README cdrskin/compile_cdrskin.sh cdrskin/wiki_plain.txt cdrskin/cdrskin_eng.html doc/comments Made number transition and activated development documentation 23 Apr 2007 [845] - cdrskin/add_ts_changes_to_libburn_0_3_4 - cdrskin/add_ts_changes_to_libburn_0_3_5 + cdrskin/add_ts_changes_to_libburn_0_3_6 + cdrskin/add_ts_changes_to_libburn_0_3_7 Updated cdrskin tarball generator ----------------------------- release - cdrskin-0.3.6.pl00 - 2007.04.23.130001 * Usage of /dev/srN rather than /dev/sgN on Linux >= 2.6 * New option drive_scsi_dev_family=sr|scd|sg * Option -isosize is supported now * DVD+R now get finalized (if not -multi is given) 2007.04.23.171735 [846] cdrskin/changelog.txt Next cdrskin-0.3.7 cycle ------------------------------------ cycle - cdrskin-0.3.7 - 2007.04.24.113310 2007.05.21.184334 [853] libburn/sg-linux.c Prepared fflushing and stderr output of SCSI command log 2007.05.21.185450 [854] libburn/sbc.c libburn/spc.h libburn/spc.c libburn/mmc.c libburn/toc.c libburn/transport.h For Linux 2.4, USB : Carefully avoided to inquire more data than available 2007.05.21.185644 [855] libburn/sector.c libburn/write.c For Linux 2.4, USB audio : Reduced CD output buffer size to 32 kiB 21 May 2007 [856] cdrskin/cdrskin_eng.html cdrskin/changelog.txt Next cdrskin-0.3.7 cycle ------------------------------------ cycle - cdrskin-0.3.7 - 2007.05.21.201501 * Now able to cope with the peculiarities of Linux 2.4 USB 2007.05.22.154407 [857] libburn/sg-linux.c Report eventual sg_io_hdr_t host_status,driver_status as debug messages 2007.05.22.154504 [858] cdrskin/cdrskin.c Disabled macro Cdrskin_debug_libdax_msgS. Thus getting unqueued error messages. 2007.05.22.164850 [859] libburn/sg-linux.c Added SCSI opcode to output of revision 857 2007.05.28.132412 [860] libburn/os-linux.h libburn/write.c Moved general 32 kiB buffer restriction from write.c to os-linux.h 2007.05.28.165630 [861] libburn/libburn.h libburn/drive.c test/telltoc.c Extended struct burn_multi_caps by .might_simulate 28 May 2007 [862] libburn/libdax_msgs.h Forgotten update of error list with revison 857 2007.05.28.170243 [863] libburn/options.c cdrskin/cdrskin.1 Added check for .might_simulate to burn_write_opts_auto_write_type() 2007.05.28.192421 [864] libburn/sector.c Fixed low transaction size introduced by cooperation of revisions 855 and 860 ------------------------------------ cycle - cdrskin-0.3.7 - 2007.05.28.192853 * Refusal to perform -dummy runs on media which cannot simulate burning 29 May 2007 [865] cdrskin/cdrskin_eng.html cdrskin/changelog.txt Next cdrskin-0.3.7 cycle 8 Jun 2007 [873] - cdrskin/doener_150x200_tr.gif - cdrskin/doener_150x200_tr_octx.gif + cdrskin/doener_150x200_tr.png + cdrskin/doener_150x200_tr_octx.png cdrskin/cdrskin_eng.html Changed logo graphics format from GIF to PNG 8 Jun 2007 [874] cdrskin/wiki_plain.txt cdrskin/add_ts_changes_to_libburn_0_3_6 cdrskin/add_ts_changes_to_libburn_0_3_7 Took into respect change of logo graphics format 8 Jun 2007 [875] cdrskin/cdrskin.1 Prevented macro interpretation of text snippet ".wav" 10 Jun 2007 [876] cdrskin/README cdrskin/cdrskin.1 Clarified MB to MiB if compatibility allows it (ticket 100) 10 Jun 2007 [877] cdrskin/cdrskin.1 doc/cookbook.txt test/libburner.c Changed "KB" to "kiB" ------------------------------------ cycle - cdrskin-0.3.7 - 2007.06.10.081025 2007.07.12.162856 [882] libburn/transport.h libburn/mmc.c libburn/write.c libburn/libdax_msgs.h Preparations to avoid writing which will not fit in drive buffer 2007.07.12.171727 [883] libburn/libburn.h libburn/drive.c New API-Function burn_drive_set_buffer_waiting() 2007.07.12.171832 [884] cdrskin/cdrskin.c cdrskin/cdrskin.1 New options modesty_on_drive= and minbuf= 2007.07.14.111614 [885] libburn/libburn.h libburn/drive.c New API function burn_drive_get_best_speed() 2007.07.14.112029 [886] libburn/mmc.c Only set realistic maximum DVD speeds (for my LG GSA which fails otherwise) 2007.07.14.112326 [887] cdrskin/cdrskin.c Experimental option --adjust_speed_to_drive. Caution: May vanish soon. 17 Jul 2007 [888] cdrskin/cdrskin.1 Clarification on option speed= 2007.07.17.085823 [889] libburn/libburn.h libburn/drive.c libburn/mmc.c cdrskin/cdrskin.c Implemented minimum speed in burn_drive_set_speed() 2007.07.19.072434 [890] libburn/libburn.h cdrskin/cdrskin.c cdrskin/cdrskin.1 Removed ban against speed 0 with burn_drive_set_buffer_waiting() 2007.07.19.143139 [891] cdrskin/cdrskin.c Trying to prevent usage of burn drive as track source 2007.07.19.171947 [892] cdrskin/cdrskin.c Avoided new track-drive test with option --no_convert_fs_adr 19 Jul 2007 [893] cdrskin/cdrskin.1 Documented option --adjust_speed_to_drive (i.e. it will stay) 19 Jul 2007 [894] cdrskin/changelog.txt Next cdrskin-0.3.7 cycle 19 Jul 2007 [895] cdrskin/cdrskin_eng.html Next cdrskin-0.3.7 cycle ------------------------------------ cycle - cdrskin-0.3.7 - 2007.07.19.174859 * New option modesty_on_drive= may help with hda -> hdb burns * New option minbuf= , cdrecord compatible frontend of modesty_on_drive= * New option --adjust_speed_to_drive * Precautions against using the burner drive as track source 2007.07.20.120001 [branch 897] Makefile.am configure.ac README cdrskin/cdrskin.c cdrskin/README cdrskin/compile_cdrskin.sh cdrskin/cdrskin_timestamp.h cdrskin/cdrskin_eng.html Made number transition to 0.3.8 20 Jul 2007 [branch 898] - cdrskin/add_ts_changes_to_libburn_0_3_6 - cdrskin/add_ts_changes_to_libburn_0_3_7 + cdrskin/add_ts_changes_to_libburn_0_3_8 + cdrskin/add_ts_changes_to_libburn_0_3_9 Updated cdrskin tarball generators 20 Jul 2007 [branch 899] cdrskin/changelog.txt Documented changes and release timestamp 2007.07.20.210001 [900] Makefile.am configure.ac README cdrskin/cdrskin.c cdrskin/README cdrskin/compile_cdrskin.sh cdrskin/cdrskin_timestamp.h cdrskin/cdrskin_eng.html Made number transition to 0.3.9 20 Jul 2007 [901] - cdrskin/add_ts_changes_to_libburn_0_3_6 - cdrskin/add_ts_changes_to_libburn_0_3_7 + cdrskin/add_ts_changes_to_libburn_0_3_8 + cdrskin/add_ts_changes_to_libburn_0_3_9 Updated cdrskin tarball generators 20 Jul 2007 [902] cdrskin/changelog.txt Documented changes ----------------------------- release - cdrskin-0.3.8.pl00 - 2007.07.20.120001 * Now able to cope with the peculiarities of Linux 2.4 USB * Refusal to perform -dummy runs on media which cannot simulate burning * New option modesty_on_drive= may help with hda -> hdb burns * New option minbuf= , cdrecord compatible frontend of modesty_on_drive= * New option --adjust_speed_to_drive * Precautions against using the burner drive as track source ------------------------------------ cycle - cdrskin-0.3.9 - 2007.07.20.200422 2 Aug 2007 [917] cdrskin/cdrskin_eng.html Corrected a harmless typo 2 Aug 2007 [918] doc/cookbook.txt cdrskin/cdrskin.1 Took into respect new info from Andy Polyakov about closing DVD+-R 9 Aug 2007 [920] cdrskin/cdrskin_eng.html Corrected a dead link 2007.08.09.133137 [921] cdrskin/cdrskin.c cdrskin/cdrskin.1 Allowed speed=any 2007.08.09.133259 [922] libburn/transport.h Changed "unsigned" to "unsigned int" 2007.08.09.133420 [923] libburn/libdax_msgs.h Corrected a typo 9 Aug 2007 [924] + doc/libdax_model.txt + doc/libdax_overview.gif + doc/libdax_equip.gif + doc/libdax_job.gif Obscure backup of my unripe model ideas about libcevap (former libdax) 10 Aug 2007 [936] doc/libdax_model.txt Fiddled on the model attributes 2007.08.10.201450 [937] libburn/libburn.h Updated comments about supported profiles and media types 2007.08.10.203040 [938] configure.ac Changed "libburn-1.pc" to "libburn-5.pc" to re-enable ./bootstrap ; ./configure 2007.08.11.075330 [941] cdrskin/README cdrskin/add_ts_changes_to_libburn_0_3_9 cdrskin/cdrskin.c cdrskin/cdrskin_eng.html cdrskin/wiki_plain.txt doc/comments doc/cookbook.txt test/libburner.c test/telltoc.c Reflected recent URL changes to libburnia-project.org 2007.08.11.202027 [942] libburn/libburn.h libburn/write.c libburn/libdax_msgs.h New API function burn_random_access_write() 2007.08.11.202627 [943] cdrskin/cdrskin.c cdrskin/cdrskin.1 New option direct_write_amount= using new API call burn_random_access_write() 12 Aug 2007 [944] libburn/libburn.h Clarifications about burn_random_access_write() 2007.08.12.095446 [945] libburn/write.c libburn/libdax_msgs.h Checked in burn_random_access_write() wether drive is grabbed 2007.08.12.095623 [946] cdrskin/cdrskin.c Debug message explaining why burn_drive_convert_fs_adr() acts on track source 2007.08.12.152937 [947] libburn/libburn.h libburn/transport.h libburn/mmc.h libburn/mmc.c libburn/write.c libburn/read.c libburn/libdax_msgs.h New API function burn_read_data() 12 Aug 2007 [948] test/telltoc.c Testing burn_read_data() by option --read_and_print ------------------------------------ cycle - cdrskin-0.3.9 - 2007.08.12.161808 * New option direct_write_amount= 13 Aug 2007 [949] cdrskin/changelog.txt Next cdrskin-0.3.9 cycle 13 Aug 2007 [950] cdrskin/cdrskin.1 cdrskin/cdrskin_eng.html Some polishing about option direct_write_amount= 13 Aug 2007 [951] doc/libdax_model.txt Beautified implementation names and added some more attributes 15 Aug 2007 [952] doc/libdax_model.txt Added more attributes and distinguished read-write, read-only, private ones 2007.08.17.081901 [953] libburn/transport.h Corrected harmless type declaration flaws 17 Aug 2007 [954] doc/libdax_model.txt Added more attributes and comments 19 Aug 2007 [955] + libcevap/ + libcevap/cgen.c + libcevap/cgen.h + libcevap/ctyp.c + libcevap/ctyp.h + libcevap/smem.c + libcevap/smem.h + libcevap/cgen.txt The C code generator mentioned in doc/libdax_model.txt. See there. 19 Aug 2007 [956] doc/libdax_model.txt More comments, new capabilities of C code generator 19 Aug 2007 [957] + libcevap/libcevap_gen.sh + libcevap/extract_cgen_input.sh + libcevap/main.c doc/libdax_model.txt Generator frontend scripts (./libcevap_gen.sh to be run in libcevap/) 19 Aug 2007 [958] doc/libdax_model.txt Corrected description of compiling and generating 20 Aug 2007 [959] libcevap/cgen.c Corrected a bug about inclusion of cevap*.h files 21 Aug 2007 [960] libcevap/smem.h Added some function type declarations 2007.08.22.134731 [961] libburn/mmc.c Corrected dangerous typo with error message production of mmc_read_10() 22 Aug 2007 [962] test/telltoc.c Retrieving my old backups which are hit by the Linux Read-Ahead-Bug 22 Aug 2007 [963] libburn/read.c test/telltoc.c Avoiding libburn read-ahead-bug 22 Aug 2007 [964] test/telltoc.c Avoided locked drive with interrupted telltoc read. (eject unlocks anyway) 2007.08.22.173459 [965] libburn/libburn.h libburn/drive.c libburn/read.c libburn/write.c Taking synchronous read/write into respect with abort handling 2007.08.23.150423 [966] libburn/libburn.h libburn/mmc.c libburn/read.c Allowed to suppress error message from failed burn_read_data() 23 Aug 2007 [967] test/telltoc.c Try to read last 2 blocks of CD track without eventual error message 2007.08.25.085709 [968] libburn/libburn.h libburn/mmc.c libburn/file.c libburn/source.c libburn/structure.c Corrected memory management flaws found by Joris Dobbelsteen 25 Aug 2007 [969] test/telltoc.c Reacted on false compiler warning about potentially unused variable 2007.08.25.155931 [970] libburn/mmc.c libburn/file.c More memory management changes proposed by Joris Dobbelsteen 2007.08.26.200829 [971] cdrskin/cdrskin.c cdrskin/cdrfifo.h cdrskin/cdrfifo.c cdrskin/cdrskin.1 New cdrskin option --grow_overwriteable_iso 2007.08.28.143057 [974] cdrskin/cdrskin.c cdrskin/cdrskin.1 Made program behavior with --grow_overwriteable_iso more consistent 28 Aug 2007 [975] cdrskin/README Mentioned --grow_overwriteable_iso 29 Aug 2007 [976] doc/libdax_model.txt Work goes on 29 Aug 2007 [977] cdrskin/cdrskin_eng.html cdrskin/changelog.txt Next cdrskin-0.3.9 cycle ------------------------------------ cycle - cdrskin-0.3.9 - 2007.08.29.124057 * New option --grow_overwriteable_iso 29 Aug 2007 [978] cdrskin/compile_cdrskin.sh Added missing file to link list: read.o 29 Aug 2007 [979] - doc/libdax_model.txt - doc/libdax_overview.gif - doc/libdax_job.gif - doc/libdax_equip.gif + libcevap/libdax_model.txt + libcevap/libdax_overview.gif + libcevap/libdax_job.gif + libcevap/libdax_equip.gif Moved libdax-libcevap model stuff to libcevap/ 29 Aug 2007 [980] libcevap/libcevap_gen.sh Adapted C code generator script to new address of libdax_model.txt 2007.09.01.182319 [984] libburn/libburn.h libburn/options.c New API function burn_write_opts_get_drive() 2007.09.04.224905 [987] libburn/libburn.h libburn/transport.h libburn/async.c libburn/drive.c libburn/write.c libburn/read.c libburn/options.c libburn/spc.c libburn/libdax_msgs.h New API calls burn_drive_grab_dummy(), burn_drive_get_drive_role() 5 Sep 2007 [988] test/telltoc.c test/libburner.c Testing new API functions via --drive stdio:<path> 2007.09.04.225558 [989] libburn/write.c libburn/read.c Reacted on compiler warnings 2007.09.05.194124 [991] libburn/libburn.h libburn/drive.c test/libburner.c test/telltoc.c burn_drive_grab_dummy() becomes invisible part of burn_drive_scan_and_grab() 2007.09.05.195248 [992] libburn/write.c Fixed a bug with failed opening of pseudo-drive 2007.09.06.094402 [995] libburn/drive.c Added forgotten handling of pseudo-drives in burn_drive_grab() 2007.09.06.095954 [996] libburn/write.c Added forgotten read/write counters in burn_stdio_write_track() 2007.09.06.100100 [997] cdrskin/cdrskin.c Removed obstacles for use of stdio-drives 2007.09.06.120844 [999] libburn/libburn.h libburn/drive.c Promoted burn_drive_raw_get_adr() to API function burn_drive_d_get_adr() 2007.09.07.102728 [1002] libburn/write.c Corrected write counter in burn_stdio_write_track() 2007.09.07.123748 [1003] libburn/libburn.h libburn/async.c libburn/drive.c libburn/libdax_msgs.h Made burn_drive_info_free() only delete the drive of its parameter 7 Sep 2007 [1004] test/telltoc.c Reacted on changed media profile of stdio-drives 2007.09.07.154951 [1005] libburn/drive.h libburn/drive.c libburn/async.c libburn/init.c Made burn_drive_scan() refuse work on non-empty drive list. 2007.09.07.163949 [1006] libburn/async.c libburn/drive.c Corrected memory leak introduced by revision 1005 2007.09.07.164532 [1007] libburn/drive.h Forgotten file for revision 1006 2007.09.07.184631 [1008] libburn/init.c libburn/libdax_msgs.h Avoided locked tray after failed burn_finish() because of busy drive 7 Sep 2007 [1009] test/telltoc.c Lowered report severity to LIBDAX_MSGS_SEV_WARNING. 2007.09.07.190916 [1010] libburn/libburn.h libburn/drive.c libburn/libdax_msgs.h Made burn_drive_scan_and_grab() extend the drive list rather than replacing it 2007.09.07.234122 [1011] libburn/drive.c cdrskin/cdrskin.c Report media profile in cdrskin blank, format, burn runs 2007.09.07.234704 [1012] libburn/drive.c Bug fix about stdio:<charcter device> 2007.09.08.102151 [1013] libburn/drive.c Fixed memory leak and possible SIGSEGV with pseudo-drives 2007.09.08.102620 [1014] cdrskin/cdrskin.c Made cdrskin work with null-drive (which it mistook for something like ATA:) 2007.09.08.132058 [1015] libburn/drive.c libburn/write.c Allowed -dummy burns with stdio-drives (because /dev/null is no block device) 2007.09.08.132206 [1016] cdrskin/cdrskin.c Changed speed measurement of stdio-drives to DVD 1x units 8 Sep 2007 [1017] libburn/libburn.h Documentation of stdio-drives 2007.09.08.164924 [1018] cdrskin/cdrskin.c cdrskin/cdrskin.1 cdrskin/convert_man_to_html.sh New option --allow_emulated_drives 2007.09.08.174757 [1019] libburn/libburn.h libburn/async.c libburn/write.c Made Libburn_precheck_write_ruleS unconditional code 8 Sep 2007 [1020] cdrskin/cdrskin_eng.html cdrskin/changelog.txt Next cdrskin-0.3.9 cycle ------------------------------------ cycle - cdrskin-0.3.9 - 2007.09.08.212130 * New option --allow_emulated_drives dev=stdio:<path> 2007.09.09.093535 [1021] libburn/drive.c libburn/libdax_msgs.h cdrskin/cdrskin.1 Called statvfs() for size estimation of regular stdio-files. 2007.09.09.093637 [1022] cdrskin/cdrskin.c Fixed bug with dev=stdio: where path contains a digit 2007.09.09.133136 [1023] libburn/init.c libburn/sg.h libburn/sg-linux.c libburn/sg-freebsd-port.c libburn/sg-freebsd.c Enabled os dependend stdio size estimation 2007.09.09.133922 [1024] libburn/drive.c Made use of os dependend stdio size estimation 2007.09.09.182827 [1026] libburn/async.c libburn/mmc.c Ended falsely alleged erasability of DVD-RAM and DVD+RW 2007.09.10.110050 [1028] libburn/drive.c Added forgotten return 0 to an error case 2007.09.12.104626 [1032] libburn/transport.h libburn/libdax_msgs.h libburn/write.c libburn/drive.c libburn/spc.c libburn/sbc.c libburn/mmc.c libburn/sg-linux.c libburn/sg-freebsd.c Brought burn_stdio_write_track() onto sector_data() for outmost realism 2007.09.12.115850 [1033] libburn/mmc.c libburn/spc.c Reacted on compiler -O2 warnings 2007.09.12.115946 [1034] libburn/write.c Implemented realistic speed simulation with stdio-drives 2007.09.12.195206 [1039] libburn/write.c Implemented cache syncing for stdio-drives in burn_random_access_write() 2007.09.12.200106 [1040] cdrskin/cdrskin.c Fixed bug with direct_write_amount=0 2007.09.14.122437 [1063] libburn/write.c Took into respect time granularity with stdio speed control 2007.09.14.122531 [1064] libburn/libburn.h Documented burn_write_opts_set_multi @param opts 14 Sep 2007 [1065] src/burn_wrap.c Changed include form of libisofs.h and libburn.h 2007.09.15.112311 [1066] libburn/libdax_msgs.h libburn/libdax_msgs.c Imported Range "vreixo" into libburn/libdax_msgs.h 2007.09.15.171844 [1067] libburn/libdax_msgs.h Prepared for neat sed translation. Explained concept of libdax_msgs variants. 15 Sep 2007 [1068] libburn/libdax_msgs_to_xyz_msgs.sh A sed converter which creates libiso_msgs.[ch] from libdax_msgs.[ch] 2007.09.15.172141 [1069] libburn/libburn.h libburn/init.c New API function burn_set_messenger() 2007.09.15.204320 [1070] libburn/libburn.h libburn/libdax_msgs.h libburn/libdax_msgs.c libburn/init.c Equipped libdax_msgs with reference counter. Completed its mutex protection. ------------------------------------ cycle - cdrskin-0.3.9 - 2007.09.15.205752 16 Sep 2007 [1071] cdrskin/changelog.txt Next cdrskin-0.3.9 cycle 2007.09.17.163735 [1072] cdrskin/cdrskin.c cdrskin/cdrskin.1 Implemented emulation for cdrecord options -inq , -format , -load 2007.09.18.072234 [1073] cdrskin/cdrskin.c cdrskin/cdrskin.1 Learned helptexts for -inq, -format, -load from cdrecord (they are wrong, btw) 2007.09.18.090713 [1074] libburn/libburn.h libburn/drive.c New API function burn_drive_leave_locked() 2007.09.18.090839 [1075] cdrskin/cdrskin.c cdrskin/cdrskin.1 Implemented emulation for cdrecord option -lock 2007.09.18.130344 [1076] libburn/mmc.c Made use of Immed bit with 5Bh CLOSE TRACK/SESSION 2007.09.18.200343 [1077] libburn/mmc.c libburn/spc.h libburn/spc.c libburn/sbc.c libburn/libdax_msgs.h Made use of Immed bit with 1Bh START STOP UNIT and 35h SYNCHRONIZE CACHE 2007.09.18.200454 [1078] cdrskin/cdrskin.c Corrected an outdated HINT text 2007.09.18.201556 [1079] libburn/sbc.c libburn/spc.c Changed some comments, reacted on harmless compiler warning 2007.09.18.204043 [1080] cdrskin/cdrskin.c cdrskin/cdrskin.1 Implemented emulation for cdrecord option -immed 2007.09.19.094046 [1081] cdrskin/cdrskin.c Implemented emulation for cdrecord option -waiti 19 Sep 2007 [1082] cdrskin/cdrskin.1 Did a little overhaul of general paragraphs, mentioned new option -waiti ------------------------------------ cycle - cdrskin-0.3.9 - 2007.09.19.112330 * More cdrecord options supported: -format, -inq, -load, -lock, -immed, -waiti 19 Sep 2007 [1083] cdrskin/changelog.txt cdrskin/cdrskin_eng.html Next cdrskin-0.3.9 cycle 2007.09.19.141650 [1084] cdrskin/cdrskin.c Made cdrskin/compile_cdrskin.sh -do_diet work again 19 Sep 2007 [1085] cdrskin/cdrskin.1 Made minor corrections 2007.09.19.212659 [1086] cdrskin/cdrskin.c cdrskin/cdrskin.1 New option fallback_program= 2007.09.20.125854 [1087] cdrskin/cdrskin.c cdrskin/cdrskin.1 Triggered fallback by unsuitable media, made -version report fallback program 2007.09.21.120333 [1088] libburn/sbc.c libburn/spc.c Had to revoke Immed bit on load command. LG GSA-4082B : premature "no media" 2007.09.22.140613 [1096] cdrskin/cdrskin.c Updated list of unsupported cdrecord and wodim options 2007.09.22.151712 [1097] libburn/libburn.h libburn/init.c New API function burn_msgs_submit() 2007.09.22.151712 [1101] libburn/sbc.c Reacted on compiler warning 2007.09.23.163301 [1107] libburn/libburn.h libburn/drive.c New API function burn_drive_equals_adr() 2007.09.23.163419 [1108] cdrskin/cdrskin.c Made use of burn_drive_equals_adr() 2007.09.23.163529 [1109] libburn/sbc.c Updated a comment about Immed and a debug message with tray loading 2007.09.24.062354 [1110] libburn/drive.c Added forgotten handling of "sdtio:" with burn_drive_equals_adr() 2007.09.24.135440 [1113] libburn/libburn.h libburn/transport.h libburn/drive.h libburn/drive.c libburn/read.c libburn/write.c Implemented drive role 3, sequential write-only stdio drives (e.g. stdout) 2007.09.24.135845 [1114] cdrskin/cdrskin.c cdrskin/cdrskin.1 Took into respect new drive role 3 2007.09.24.181340 [1115] libburn/sg-linux.c libburn/drive.c Made stdio-drives work on readonly CD block devices 24 Sep 2007 [1116] test/libburner.c Blocked against file descriptor drives. Too dangerous for a demo. 2007.09.26.155301 [1123] cdrskin/cdrskin.c cdrskin/cdrskin.1 Disabled --allow_emulated_drives in setuid runs 26 Sep 2007 [1124] cdrskin/README Streamlined and moved legal stuff to end of text 2007.09.26.173840 [1125] cdrskin/compile_cdrskin.sh Made -O2 default if not -g is given 2007.09.27.083351 [1126] cdrskin/cdrskin.c cdrskin/cdrskin.1 cdrskin/convert_man_to_html.sh cdrskin/README Disallowed emulated drives for superuser, allowed stdio:/dev/null for all 2007.09.27.093129 [1127] cdrskin/cdrskin.c Corrected announcement with dev=help about stdio: "Open via UNIX device" ------------------------------------ cycle - cdrskin-0.3.9 - 2007.09.27.093301 * New option fallback_program= 27 Sep 2007 [1128] cdrskin/changelog.txt Next cdrskin-0.3.9 cycle 28 Sep 2007 [1129] libisofs libisofs/libiso_msgs.h Removed apostrophes which my compiler does not like 2007.09.29.185007 [1131] libburn/transport.h libburn/init.h libburn/init.c libburn/drive.h libburn/drive.c libburn/async.c Trying to catch signals from within the writer thread 2007.09.29.191558 [1132] libburn/init.c Added forgotten handling of non-writer-non-control threads 2007.09.30.212517 [1135] libburn/libburn.h libburn/async.h libburn/async.c libburn/file.h libburn/file.c Implemented a simple fifo to decouple from burn_source signals 30 Sep 2007 [1136] test/telltoc.c Disallowed --read_and_print raw:- , allowed to write to chardev+pipe+socket 2007.10.02.120659 [1145] libburn/write.c Moved minimum tracksize padding out of TAO track closing. Now done before sync. 2007.10.02.135538 [1146] libburn/libburn.h Clarified role of burn_source 2007.10.02.180003 [1148] libburn/write.c Corrected error with revision 1145 2007.10.03.084206 [1150] libburn/libburn.h More documentation for burn_source 2007.10.03.112547 [1151] libburn/transport.h libburn/mmc.c libburn/write.c libburn/drive.c Ensured synchronize cache before release 2007.10.03.115550 [1153] libburn/libburn.h More documentation for burn_source 2007.10.03.223649 [1155] libburn/file.h libburn/file.c libburn/async.c Implemented the ring buffer of burn_fifo_source_new() object 2007.10.03.223851 [1156] libburn/libburn.h More documentation for burn_source, new API call burn_fifo_inquire_status() 3 Oct 2007 [1157] test/libburner.c Made use of 4 MB fifo 2007.10.04.200221 [1158] libburn/libburn.h libburn/file.h libburn/file.c libburn/libdax_msgs.h Inserted the necessary error messages and magic numbers 4 Oct 2007 [1159] test/libburner.c Adjusted pacifier messages and change with burn_fifo_inquire_status() 2007.10.04.210245 [1160] libburn/libburn.h Minor adjustments with comment text 2007.10.04.213107 [1161] libburn/drive.c Corrected abort preventing bug introduced with revision 1131 2007.10.05.085929 [1162] libburn/libburn.h libburn/file.c Revoked urge to have a magic[4] in burn_source (free_data is magic enough) 2007.10.05.231712 [1163] libburn/file.c Fixed data spoiling bug with ring buffer introduced with rev 1155 2007.10.07.110506 [1164] libburn/file.c Corrected status reply for unstarted fifo 2007.10.07.110644 [1165] libburn/file.c Corrected status reply for unstarted fifo (2nd try) 7 Oct 2007 [1166] test/libburner.c Minor changes with waiting for drive and fifo status display 2007.10.15.115448 [1179] cdrskin/cdrskin.c Corrected 4-byte buffer overflow (which did no detectable harm) 2007.10.15.115728 [1180] libburn/read.c Made possible to silence error message about missing pseudo drive 2007.10.15.115851 [1181] libburn/drive.c Corrected SIGSEGV with changing from one drive to the other 2007.10.15.144050 [1182] libburn/drive.c Activated re-usal of disposed global drive_array slots 2007.10.16.212205 [1189] libburn/libburn.h libburn/init.c New API function burn_text_to_sev() 18 Oct 2007 [1209] test/telltoc.c Calmed down hyperactive sleep interval with drive scanning 2007.10.18.200336 [1210] libburn/init.c Prevented SIGSEGV with burn_msgs_obtain() on non-initialized library 2007.10.19.115326 [1215] libburn/async.c libburn/libdax_msgs.h Starting threads detached, providing two alternatives. But zombies still there. 2007.10.19.132821 [1216] libburn/init.c Small change with debug verbosity of abort handler 2007.10.19.133310 [1217] libburn/async.c Removed useless alternative after zombies turned out to be caused by gdb ------------------------------------ cycle - cdrskin-0.3.9 - 2007.10.23.150436 2007.10.23.150436 [1240] cdrskin/changelog.txt Next cdrskin-0.3.9 cycle 23 Oct 2007 [1241] libcevap/main.c Preparations for lowercase class and function names 23 Oct 2007 [1242] libcevap/libdax_model.txt Work goes on 23 Oct 2007 [1243] libcevap/cgen.c libcevap/ctyp.c Fixed a bug about arrays 2007.10.24.184233 [1248] branch/ZeroFourZero Makefile.am configure.ac README cdrskin/cdrskin.c cdrskin/README cdrskin/compile_cdrskin.sh cdrskin/cdrskin_timestamp.h cdrskin/wiki_plain.txt cdrskin/cdrskin_eng.html doc/comments Made number transition to 0.4.0 25 Oct 2007 [1249] branch/ZeroFourZero - cdrskin/add_ts_changes_to_libburn_0_3_8 - cdrskin/add_ts_changes_to_libburn_0_3_9 + cdrskin/add_ts_changes_to_libburn_0_4_0 + cdrskin/add_ts_changes_to_libburn_0_4_1 Updated cdrskin tarball generator 2007.10.25.091106 [1250] Makefile.am configure.ac README cdrskin/cdrskin.c cdrskin/README cdrskin/compile_cdrskin.sh cdrskin/cdrskin_timestamp.h cdrskin/wiki_plain.txt cdrskin/cdrskin_eng.html doc/comments Made number transition to 0.4.1 25 Oct 2007 [1251] - cdrskin/add_ts_changes_to_libburn_0_3_8 - cdrskin/add_ts_changes_to_libburn_0_3_9 + cdrskin/add_ts_changes_to_libburn_0_4_0 + cdrskin/add_ts_changes_to_libburn_0_4_1 Updated cdrskin tarball generator 25 Oct 2007 [1252] branch/ZeroFourZero cdrskin/cdrskin.c Added forgotten help text lines 2007.10.25.131841 [1253] cdrskin/cdrskin.c Added forgotten help text lines 2007.10.27.090421 [1254] [1256] branch/ZeroFourZero libburn/sg-linux.c Reacted on cdwrite@ message about INT_MAX in cdrom.h of kernel 2.6.23 2007.10.27.075309 [1255] libburn/sg-linux.c Reacted on cdwrite@ message about INT_MAX in cdrom.h of kernel 2.6.23 29 Oct 2007 [1272] - cdrskin/add_ts_changes_to_libburn_0_3_9 + cdrskin/add_ts_changes_to_libburn_0_4_0 Updated cdrskin release generator scripts ----------------------------- release - cdrskin-0.4.0.pl00 - 2007.10.27.090421 * New option direct_write_amount= * New option --grow_overwriteable_iso * New option --allow_emulated_drives dev=stdio:<path> * More cdrecord options supported: -format, -inq, -load, -lock, -immed, -waiti * New option fallback_program= ------------------------------------ cycle - cdrskin-0.4.1 - 2007.10.27.114207 2007.11.18.093952 [1307] libburn/libburn.h Marked loss of binary backward compatibility back in rev 655, libburn-0.3.1 18 Nov 2007 [1308] cdrskin/cdrskin.1 Corrected a typo in cdrskin man page 2007.11.18.094209 [1309] cdrskin/cdrskin.c Reacted on build warnings on a 64 Bit system 2007.11.26.154817 [1310] libburn/libdax_audioxtr.c Reacted on build warnings on another system ------------------------------------ cycle - cdrskin-0.4.1 - 2007.11.27.214003 2007.11.29.185342 [1312] libburn/drive.c libburn/mmc.c libburn/spc.c libburn/libdax_msgs.h Enabled reading of TOC from ROM drives (direly needed for xorriso) 29 Nov 2007 [1313] test/telltoc.c Adjusted meaning of --read_and_print count= -1 2007.12.07.185030 [1323] configure.ac An attempt to rectify .so numbering: SONAME=10, REV=1, AGE=6 2007.12.07.185206 [1324] libburn/async.c Made postponed change in thread management 8 Dec 2007 [1325] configure.ac Some changes in the comments 24 Dec 2008 [1338] libburn/libburn.h libburn/source.h libburn/source.c libburn/file.c libburn/write.c libburn/sector.c Implemented burn_source.cancel() in a binary backwards compatible way 2008.01.17.185051 [1383] libburn/libdax_msgs.h libburn/libdax_msgs.c Changed meaning of .driveno to .origin, introduced LIBDAX_MSGS_ORIGIN_* macros 17 Jan 2008 [1384] cdrskin/README Removed a reference to future GPL versions 2008.01.19.201702 [1396] libburn/read.c Fixed small bug about error messages with burn_read_data 2008.01.23.193345 [1405] libburn/read.c Made burn_read_data() issue messages about hopeless drive access errors 2008.01.23.193843 [1406] libburn/libburn.h libburn/libdax_msgs.h libburn/libdax_msgs.c Introduced message severity "FAILURE" 2008.01.23.211731 [1408] cdrskin/cdrskin.c configure.ac Implemented run time check of libburn version. 2008.01.23.213607 [1409] Makefile.am Dynamic cdrskin linking patch by Simon Huggins. 26 Jan 2008 [1420] cdrskin/convert_man_to_html.sh Adapted to man -H on my new system 2008.01.26.123054 [1421] libburn/libdax_msgs.h Ported change in vreixo message range from isoburn_msgs 2008.01.26.131519 [1422] libburn/drive.c Made a sudden end to all stdio drives in burn_abort() 2008.01.26.180241 [1426] [branch 1427] libburn/async.c Disabled debugging messages about thread properties 2008.01.26.200001 [branch 1428] Makefile.am configure.ac libburn-5.pc.in README cdrskin/cdrskin.c cdrskin/README cdrskin/compile_cdrskin.sh cdrskin/cdrskin_timestamp.h cdrskin/wiki_plain.txt cdrskin/cdrskin_eng.html Made number transition to 0.4.2 , libburn.so.4.7.0 27 Jan [branch 1429] cdrskin/cdrskin.c cdrskin/cdrskin_eng.html cdrskin/changelog.txt Adjustments after first round of testing 27 Jan [branch 1430] cdrskin/README cdrskin/cdrskin_eng.html Adjustments after testing 2008.01.27.143022 [1431] Makefile.am configure.ac libburn-5.pc.in README cdrskin/cdrskin.c cdrskin/README cdrskin/compile_cdrskin.sh cdrskin/cdrskin_timestamp.h cdrskin/wiki_plain.txt cdrskin/cdrskin_eng.html cdrskin/changelog.txt Made number transition to 0.4.3 , still libburn.so.4.7.0 27 Jan 2008 [branch 1433] [1432] - cdrskin/add_ts_changes_to_libburn_0_4_0 - cdrskin/add_ts_changes_to_libburn_0_4_1 + cdrskin/add_ts_changes_to_libburn_0_4_2 + cdrskin/add_ts_changes_to_libburn_0_4_3 Updated cdrskin tarball generator 2008.01.29.210821 [1442] configure.ac libburn/libburn.h Moving the major.minor.micro definition from configure.ac to libburn.h 2008.01.28.213001 [branch 1444] libburn/libburn.h Introduced copy of major.minor.micro definition in libburn.h of version 0.4.2 29 Jan 2008 [branch 1445] [branch 1447] Corrected description of major.minor.micro definition in libburn.h of version 0.4.2 2008.01.29.214110 [1446] libburn/libburn.h Corrected description of major.minor.micro definition in libburn.h 2008.01.31.111057 [1448] cdrskin/cdrskin.c Introduced compile time check of libburn header version 2008.02.01.100302 [1451] [branch 1453] - libburn-5.pc.in + libburn-1.pc.in configure.ac Makefile.am Renamed libburn-5.pc to libburn-1.pc 2008.02.01.100530 [1452] cdrskin/cdrskin.c Changed "libburn interface :" version message to libburn.h macros [branch ] cdrskin/cdrskin_timestamp.h cdrskin/changelog.txt Updated changelog before release ----------------------------- release - cdrskin-0.4.2.pl00 - 2008.02.01.100001 * Safe dynamic linking possible with libburn.so.4 ------------------------------------ cycle - cdrskin-0.4.3 - 2008.02.01.225039 2008.02.03.092013 [1463] libburn/libdax_msgs.h Registered error code range "libisofs-xorriso" 2008.02.03.092134 [1464] configure.ac Incremented LT_* to get libburn.so.4.8.0 (forgot to do 4.7.1 anyway) 2008.02.03.092509 [1465] libburn/libburn.h libburn/init.c New API call burn_sev_to_text() 4 Feb 2008 [1473] README Announced deprecation of libisofs-0.2.x, temporory employment of libisofs-0.6.1 2008.02.04.175209 [1474] libburn/libdax_msgs.h Registered range "libisoburn" 0x00060000 to 0x00006ffff 2008.02.06.174009 [1482] libburn/libdax_msgs.h Re-instated range "vreixo" with old and new codes, adjusted severity definitions 2008.02.06.182222 [1483] libburn/libburn.h Copied usage discussion about *_header_version_* from libisoburn 2008.02.06.230041 [1488] libburn/read.c Installed a simple address logger in burn_read_data 2008.02.07.232820 [1492] libburn/read.c Added debug message in case of burn_read_data() return 0 2008.02.08.073414 [1493] libburn/mmc.c Allowed DVD +/- DL for reading 2008.02.11.190802 [1518] libburn/libdax_msgs.h libburn/libdax_msgs.c Introduced LIBDAX_MSGS_SEV_MISHAP 2008.02.14.074108 [1522] libburn/libburn.h Micro corrections in comment text 14 Feb 2008 [1523] COPYRIGHT Updated year 14 Feb 2008 [1524] cdrskin/README Pointed to ldconfig 2008.02.16.121102 [1541] configure.ac Corrected typo in comment 16 Feb 2008 [1542] doc/comments README cdrskin/wiki_plain.txt Updated project interrelations 2008.02.21.200956 [1554] libburn/sg-linux.c Testwise inquiry of ioctl(CDROM_MEDIA_CHANGED) (disabled by default) 21 Feb 2008 [1555] test/libburner.c Directed error message to proper output channel 2008.02.21.201238 [1556] libburn/libdax_msgs.h libburn/libdax_msgs.c Introduced severity ERRFILE 2008.02.21.202216 [1557] libburn/libdax_msgs.c Mapped unknown severity text to ALL rather than NEVER 2008.02.21.215250 [1560] libburn/libdax_msgs.h Weakened demand to print file path in following message 2008.02.22.150939 [1562] libburn/libdax_msgs.h libburn/init.c New error code 0x00040008 2008.02.22.213527 [1563] libburn/libdax_msgs.h libburn/libdax_msgs.c Imported changes from libiso_msgs.h 2008.02.22.213726 [1564] libburn/init.c Changed meaning of unrecognized severity texts from FATAL to ALL 2008.02.28.123152 [1565] libburn/libburn.h libburn/spc.c libburn/mmc.c libburn/write.c cdrskin/cdrskin.1 Made support for DVD+R DL official, enabled untested support for BD-RE 2008.02.28.132325 [1586] libburn/mmc.c cdrskin/README cdrskin/cdrskin.c cdrskin/cdrskin_eng.html cdrskin/wiki_plain.txt test/libburner.c Mentioned support for DVD+R/DL. ------------------------------------ cycle - cdrskin-0.4.3 - 2008.03.01.154319 * Support for DVD+R/DL media is now official * Experimental code for BD-RE with --allow_untested_media 1 Mar 2008 [1595] cdrskin/changelog.txt Updated changelog 2008.03.03.202930 [1598] libburn/libburn.h libburn/drive.c libburn/read.c Got rid of a cumbersome open-close cycle with burn_read_data() on stdio: 2 Apr 2008 [1654] COPYRIGHT Corrected GPL version ------------------------------------ cycle - cdrskin-0.4.3 - 2008.04.07.152331 * libburn: Improved read performance from stdio: pseudo-drives 2008.04.08.100001 [ZeroFourFour 1669] Makefile.am configure.ac README libburn/libburn.h (burn_header_version_*) cdrskin/cdrskin.c cdrskin/README cdrskin/compile_cdrskin.sh cdrskin/cdrskin_timestamp.h cdrskin/wiki_plain.txt cdrskin/cdrskin_eng.html doc/comments Made number transition and activated development documentation 8 Apr 2008 [ZeroFourFour 1670] - cdrskin/add_ts_changes_to_libburn_0_4_2 - cdrskin/add_ts_changes_to_libburn_0_4_3 + cdrskin/add_ts_changes_to_libburn_0_4_4 + cdrskin/add_ts_changes_to_libburn_0_4_5 Updated cdrskin tarball generator 8 Apr 2008 [ZeroFourFour 1671] cdrskin/changelog.txt Documented changes and release timestamp 2008.04.08.100001 [ZeroFourFour 1672] libburn/util.c Switched from configure.ac versioning to libburn.h versioning 8 Apr 2008 [ZeroFourFour 1673] cdrskin/changelog.txt Documented last minute changes ----------------------------- release - cdrskin-0.4.4.pl00 - 2008.04.08.100001 * Support for DVD+R/DL media is now official * Experimental code for BD-RE with --allow_untested_media * libburn: Improved read performance from stdio: pseudo-drives 2008.04.08.132344 [1674] Makefile.am configure.ac README libburn/libburn.h (burn_header_version_*) cdrskin/cdrskin.c cdrskin/README cdrskin/compile_cdrskin.sh cdrskin/cdrskin_timestamp.h cdrskin/wiki_plain.txt cdrskin/cdrskin_eng.html doc/comments cdrskin/changelog.txt Made number transition 8 Apr 2008 [1675] - cdrskin/add_ts_changes_to_libburn_0_4_2 - cdrskin/add_ts_changes_to_libburn_0_4_3 + cdrskin/add_ts_changes_to_libburn_0_4_4 + cdrskin/add_ts_changes_to_libburn_0_4_5 Updated cdrskin tarball generator 2008.04.08.133452 [1676] libburn/util.c Switched from configure.ac versioning to libburn.h versioning ------------------------------------ cycle - cdrskin-0.4.5 - 2008.04.08.134413 2008.04.10.211529 [1681] libburn/mmc.c libburn/drive.c cdrskin/cdrskin.c Trying to fix bugs about BD-RE, macro for simulating BD-RE on DVD-RAM ------------------------------------ cycle - cdrskin-0.4.5 - 2008.04.10.211529 2008.04.12.164244 [1683] libburn/libburn.h libburn/transport.h libburn/options.h libburn/options.c libburn/write.c libburn/drive.c libburn/mmc.c New API call burn_write_opts_set_stream_recording() 2008.04.12.164606 [1684] cdrskin/cdrskin.c cdrskin/cdrskin.1 cdrskin/cdrskin_eng.html New option stream_recording=on|off ------------------------------------ cycle - cdrskin-0.4.5 - 2008.04.12.164930 * New option stream_recording=on can speed up DVD-RAM 2008.04.15.094133 [1685] libburn/os-linux.h libburn/write.c Enforced tail padding with stream_recording, enlarged transport buffer 15 Apr 2008 [1686] cdrskin/cdrskin.1 Some adjustments of cdrskin man page ------------------------------------ cycle - cdrskin-0.4.5 - 2008.04.15.094545 2008.04.16.082208 [1687] libburn/read.c Made burn_read_data() obey its flag bit1 2008.04.18.092715 [1688] libburn/libburn.h libburn/async.c libburn/drive.c libburn/mmc.c Began to implement formatting of DVD-RAM and experimentally of BD-RE 2008.04.18.092816 [1689] cdrskin/cdrskin.c cdrskin/cdrskin.1 Began to implement formatting of DVD-RAM and experimentally of BD-RE 2008.04.18.194602 [1691] libburn/mmc.c Adjustments with DVD-RAM formatting 2008.04.22.161139 [1695] libburn/libburn.h libburn/transport.h libburn/mmc.c libburn/drive.c cdrskin/cdrskin.c cdrskin/cdrskin.1 Adjustments with DVD-RAM formatting 2008.04.22.200949 [1696] cdrskin/cdrskin.c cdrskin/cdrskin.1 New option --list_formats 2008.04.23.110116 [1697] libburn/mmc.c cdrskin/cdrskin.c cdrskin/cdrskin.1 New blank type blank=format_by_index_<number> 24 Apr 2008 [1698] doc/cookbook.txt Wrote down what was learned about DVD-RAM formatting 24 Apr 2008 [1699] cdrskin/cdrskin_eng.html Mentioned new features 2008.04.25.131531 [1700] libburn/mmc.c Preparations for formatting BD-RE 2008.04.25.132353 [1701] cdrskin/cdrskin.c cdrskin/cdrskin.1 Documented experimental support for BD-RE formatting 25 Apr 2008 [1702] configure.ac Incremented LT_CURRENT and LT_AGE to reflect API enhancements 25 Apr 2008 [1703] cdrskin/cdrskin_eng.html Documented newest enhancements ------------------------------------ cycle - cdrskin-0.4.5 - 2008.04.25.134438 * New blank type blank=format_defectmgt for DVD-RAM * New option --list_formats * New blank type blank=format_by_index_<number> * Experimental support for formatting BD-RE 2008.04.26.150646 [1704] libburn/libburn.h libburn/mmc.c libburn/drive.c doc/cookbook.txt Enabled quick formatting with DVD-RAM, made slow formatting default with BD-RE 2008.04.26.150945 [1705] cdrskin/cdrskin.c cdrskin/cdrskin.1 New blank subtypes format_defectmgt_cert_[on|off], on is default 2008.04.27.084704 [1706] cdrskin/cdrskin.c cdrskin/cdrskin.1 New blank type format_if_needed 2008.04.27.140144 [1707] cdrskin/cdrskin.c cdrskin/cdrskin.1 New blank type as_needed 27 Apr 2008 [1708] cdrskin/cdrskin_eng.html Documented newest enhancements ------------------------------------ cycle - cdrskin-0.4.5 - 2008.04.27.163625 * New blank type blank=as_needed for automatic handling of media type and state 3 May 2008 [1723] README Updated project history 2008.05.06.082429 [1729] libburn/drive.c Avoided to report negative burn_multi_caps.start_range_high with DVD-RW 2008.05.06.084156 [1730] libburn/mmc.c Mapped undefined size to 0 with burn_disc_get_formats() and DVD-RW 2008.05.06.180813 [1733] libburn/libburn.h libburn/drive.c libburn/mmc.c doc/cookbook.txt doc/comments test/libburner.c Declared BD-RE to be supported 2008.05.06.181100 [1734] cdrskin/cdrskin.c cdrskin/cdrskin.1 cdrskin/wiki_plain.txt Declared BD-RE to be supported 2008.05.06.181723 [1735] libburn/mmc.c Declared BD-RE to be supported 6 May 2008 [1736] cdrskin/cdrskin_eng.html cdrskin/cdrskin.1 Declared BD-RE to be supported ------------------------------------ cycle - cdrskin-0.4.5 - 2008.05.06.183436 * Support for BD-RE media is now official 2008.05.09.143130 [1748] libburn/libburn.h Documented read-only profiles CD-ROM and DVD-ROM 2008.05.09.145205 [1749] libburn/mmc.c Allowed BD-ROM and BD-R for read-only purposes 9 May 2008 [1750] cdrskin/cdrskin.1 Changed blank examples to blank=as_needed ------------------------------------ cycle - cdrskin-0.4.5 - 2008.05.09.151327 2008.05.10.080001 [1754] Makefile.am configure.ac README libburn/libburn.h cdrskin/cdrskin.c cdrskin/README cdrskin/compile_cdrskin.sh cdrskin/cdrskin_timestamp.h cdrskin/wiki_plain.txt cdrskin/cdrskin_eng.html doc/comments cdrskin/cdrskin.1 Made number transition to 0.4.6 and activated development documentation 10 May 2008 [1755] cdrskin/README Made number transition to 0.4.6 and activated development documentation 10 May 2008 [1756] - cdrskin/add_ts_changes_to_libburn_0_4_4 - cdrskin/add_ts_changes_to_libburn_0_4_5 + cdrskin/add_ts_changes_to_libburn_0_4_6 + cdrskin/add_ts_changes_to_libburn_0_4_7 Updated cdrskin tarball generator 10 May 2008 [1757] cdrskin/changelog.txt Documented changes and release timestamp ----------------------------- release - cdrskin-0.4.6.pl00 - 2008.05.10.080001 * Support for BD-RE media is now official * New option stream_recording=on can speed up DVD-RAM and BD-RE * New option --list_formats * New blank types for expert formatting of DVD-RAM and BD-RE * New blank type blank=as_needed for automatic handling of media type and state 2008.05.10.132543 [1758] Makefile.am configure.ac README libburn/libburn.h (burn_header_version_*) cdrskin/cdrskin.c cdrskin/README cdrskin/compile_cdrskin.sh cdrskin/cdrskin_timestamp.h cdrskin/wiki_plain.txt cdrskin/cdrskin_eng.html doc/comments cdrskin/cdrskin.1 Made number transition to 0.4.7 10 May 2008 [1759] - cdrskin/add_ts_changes_to_libburn_0_4_4 - cdrskin/add_ts_changes_to_libburn_0_4_5 + cdrskin/add_ts_changes_to_libburn_0_4_6 + cdrskin/add_ts_changes_to_libburn_0_4_7 Updated cdrskin tarball generator 10 May 2008 [1760] cdrskin/changelog.txt Documented changes and release timestamp ------------------------------------ cycle - cdrskin-0.4.7 - 2008.05.10.132543 2008.05.14.165025 [1776] libburn/write.c Bug fix: random access addressing for DVD-RAM and BD-RE did not work 2008.05.14.165157 [1777] libburn/libburn.h Added format types 0x30 and 0x32 to list in API comments 2008.05.14.165258 [1778] cdrskin/cdrskin.c Made inability to get format list a reason to abort the program ------------------------------------ cycle - cdrskin-0.4.7 - 2008.05.14.165258 * Bug fix: random access addressing for DVD-RAM and BD-RE did not work 2008.05.17.080001 [1788] Makefile.am configure.ac README libburn/libburn.h cdrskin/cdrskin.c cdrskin/README cdrskin/compile_cdrskin.sh cdrskin/cdrskin_timestamp.h cdrskin/cdrskin_eng.html cdrskin/cdrskin.1 Made number transition to 0.4.8 and activated development documentation 17 May 2008 [1789] - cdrskin/add_ts_changes_to_libburn_0_4_6 - cdrskin/add_ts_changes_to_libburn_0_4_7 + cdrskin/add_ts_changes_to_libburn_0_4_8 + cdrskin/add_ts_changes_to_libburn_0_4_9 Updated cdrskin tarball generator 17 May 2008 [1792] cdrskin/changelog.txt Documented changes and release timestamp ----------------------------- release - cdrskin-0.4.8.pl00 - 2008.05.17.080001 * Bug fix: random access addressing for DVD-RAM and BD-RE did not work 2008.05.17.115434 [1790] Makefile.am configure.ac README libburn/libburn.h cdrskin/cdrskin.c cdrskin/README cdrskin/compile_cdrskin.sh cdrskin/cdrskin_timestamp.h cdrskin/cdrskin_eng.html cdrskin/cdrskin.1 Made number transition to 0.4.9 17 May 2008 [1791] - cdrskin/add_ts_changes_to_libburn_0_4_6 - cdrskin/add_ts_changes_to_libburn_0_4_7 + cdrskin/add_ts_changes_to_libburn_0_4_8 + cdrskin/add_ts_changes_to_libburn_0_4_9 Updated cdrskin tarball generator 17 May 2008 [1793] cdrskin/changelog.txt Documented changes and release timestamp ------------------------------------ cycle - cdrskin-0.4.9 - 2008.05.17.121250 14 Jun 2008 [1852] README Updated release history 2008.06.14.140711 [1853] libburn/libburn.h Inserted @since tags for all functions older than 0.2.0 2008.07.02.093933 [1882] libburn/sg-linux.c With auto device family: scd is now fallback if sr does not exist ------------------------------------ cycle - cdrskin-0.4.9 - 2008.07.12.164045 * Ability to use /dev/scd as fallback if /dev/sr does not exist * Bug fix: option drive_scsi_dev_family=scd lead to buffer overflow 2008.07.14.112935 [1914] libburn/sg-linux.c libburn/libdax_msgs.h Trying to avoid SORRY messages when hitting busy hard disk /dev/hdX 2008.07.14.113050 [1915] cdrskin/cdrskin.c Making visible the new NOTE and HINT about busy alleged hard disks 2008.07.14.113152 [1916] configure.ac Did LT_CURRENT++, LT_AGE++ because of new API call 2008.07.14.113903 [1917] libburn/libburn.h libburn/file.c libburn/async.c New API call burn_fifo_peek_data() 2008.07.14.164528 [1922] libburn/sg-linux.c Followed hint of Giulio Orsero to recognize disk by /proc/ide/hdX/media ------------------------------------ cycle - cdrskin-0.4.9 - 2008.07.14.164906 * New API call burn_fifo_peek_data() 2008.07.16.070001 [1927] Makefile.am configure.ac README libburn/libburn.h cdrskin/cdrskin.c cdrskin/README cdrskin/compile_cdrskin.sh cdrskin/cdrskin_timestamp.h cdrskin/cdrskin_eng.html Made number transition to 0.5.0 and activated development documentation 16 Jul 2008 [1928] - cdrskin/add_ts_changes_to_libburn_0_4_8 - cdrskin/add_ts_changes_to_libburn_0_4_9 + cdrskin/add_ts_changes_to_libburn_0_5_0 + cdrskin/add_ts_changes_to_libburn_0_5_1 Updated cdrskin tarball generator 16 Jul 2008 [1929] cdrskin/changelog.txt Documented changes and release timestamp ------------------------------ release - cdrskin-0.5.0.pl00 - 2008.07.16.070001 * Ability to use /dev/scd as fallback if /dev/sr does not exist * Bug fix: option drive_scsi_dev_family=scd lead to buffer overflow * New API call burn_fifo_peek_data() 2008.07.16.090816 [1930] Makefile.am configure.ac README libburn/libburn.h cdrskin/cdrskin.c cdrskin/README cdrskin/compile_cdrskin.sh cdrskin/cdrskin_timestamp.h cdrskin/cdrskin_eng.html Made number transition to 0.5.1 and activated development documentation 16 Jul 2008 [1931] - cdrskin/add_ts_changes_to_libburn_0_4_8 - cdrskin/add_ts_changes_to_libburn_0_4_9 + cdrskin/add_ts_changes_to_libburn_0_5_0 + cdrskin/add_ts_changes_to_libburn_0_5_1 Updated cdrskin tarball generator 16 Jul 2008 [1932] cdrskin/changelog.txt Documented changes and release timestamp ------------------------------------ cycle - cdrskin-0.5.1 - 2008.07.14.164528 2008.08.01.101053 [1954] libburn/drive.h libburn/drive.c libburn/sg-linux.c Avoiding drive scan if single drive is given 2008.08.05.175930 [1963] libburn/os-linux.h libburn/drive.h libburn/drive.c libburn/sg-linux.c libburn/libdax_msgs.h cdrskin/cdrskin.1 Taking into respect drive list from /proc/sys/dev/cdrom/info 5 Aug 2008 [1964] cdrskin/cdrskin_eng.html Updated for next 0.5.1 cycle ------------------------------------ cycle - cdrskin-0.5.1 - * Larger set of possibly acceptable drive device file names 2008.08.09.071742 [1975] libburn/mmc.c libburn/structure.h libburn/structure.c CD burn_toc_entries now bear extension_valid data 2008.08.09.071854 [1976] libburn/libburn.h libburn/read.c New flag bit2 with burn_read_data() 2008.08.19.122535 [1991] libburn/libburn.h API clarification about CD burn_toc_entries 2008.08.19.123513 [1992] libburn/structure.c Reacted on harmless compiler warning ------------------------------------ cycle - cdrskin-0.5.1 - 2008.08.19.123513 2008.08.20.080001 [1994] Makefile.am configure.ac README libburn/libburn.h cdrskin/cdrskin.c cdrskin/README cdrskin/compile_cdrskin.sh cdrskin/cdrskin_timestamp.h cdrskin/cdrskin_eng.html Made number transition to 0.5.2 and activated development documentation 20 Aug 2008 [1995] - cdrskin/add_ts_changes_to_libburn_0_5_0 - cdrskin/add_ts_changes_to_libburn_0_5_1 + cdrskin/add_ts_changes_to_libburn_0_5_2 + cdrskin/add_ts_changes_to_libburn_0_5_3 Updated cdrskin tarball generator 20 Aug 2008 [1996] cdrskin/changelog.txt Documented changes and release timestamp ------------------------------ release - cdrskin-0.5.2.pl00 - 2008.08.20.080001 * Larger set of possibly acceptable drive device file names 2008.08.20.100045 [1997] Makefile.am configure.ac README libburn/libburn.h cdrskin/cdrskin.c cdrskin/README cdrskin/compile_cdrskin.sh cdrskin/cdrskin_timestamp.h cdrskin/cdrskin_eng.html Made number transition to 0.5.3 20 Aug 2008 [1998] - cdrskin/add_ts_changes_to_libburn_0_5_0 - cdrskin/add_ts_changes_to_libburn_0_5_1 + cdrskin/add_ts_changes_to_libburn_0_5_2 + cdrskin/add_ts_changes_to_libburn_0_5_3 Updated cdrskin tarball generator 20 Aug 2008 [1999] cdrskin/changelog.txt Documented changes and release timestamp ------------------------------------ cycle - cdrskin-0.5.3 - 2008.08.20.110457 30 Aug 2008 [2023] README Mentioned release of libisoburn-0.2.4 2008.08.30.104339 [2024] libburn/mmc.c libburn/spc.c Issueing many SCSI error messages in cleartext now 2008.09.09.131915 [2039] libburn/sg-linux.c Trying to avoid unnecessary access to sibling device objects 12 Sep 2008 [2043] doc/cookbook.txt Described ISO 9660 multi-session on overwriteable media 2008.09.14.174344 [2048] libburn/util.c Gave up problematic and unused version.h 2008.09.16.060250 [2052] cdrskin/cdrskin.c Corrected pacifier text (Ticket 141) 24 Sep 2008 [2079] README Mentioned recent releases of libisofs and libisoburn 2008.09.28.193802 [2086] libburn/spc.c Bug fix: Potential buffer overflow introduced with revision 2024 2008.09.28.211741 [2087] libburn/sg-linux.c Bug fix: /dev/sr0 was accepted as enumerable address on Linux 2.4 2008.10.04.072657 [2096] libburn/write.c libburn/read.c libburn/drive.c Prevented SIGSEGV after illegal drive operations during sync write 2008.10.04.072657 [2097] cdrskin/cdrskin.1 Mentioned new xorriso capabilities in man cdrskin 2008.10.04.073814 [2098] configure.ac Incremented LT_CURRENT and LT_AGE to get libburn.so.4.18.0 ------------------------------------ cycle - cdrskin-0.5.3 - 2008.10.04.072657 * Bug fix: /dev/sr0 was accepted as enumerable address on Linux 2.4 2008.10.05.073001 [2102] Makefile.am configure.ac README libburn/libburn.h cdrskin/cdrskin.c cdrskin/README cdrskin/compile_cdrskin.sh cdrskin/cdrskin_timestamp.h cdrskin/cdrskin_eng.html Made number transition 5 Oct 2008 [2103] - cdrskin/add_ts_changes_to_libburn_0_5_2 - cdrskin/add_ts_changes_to_libburn_0_5_3 + cdrskin/add_ts_changes_to_libburn_0_5_4 + cdrskin/add_ts_changes_to_libburn_0_5_5 Updated cdrskin tarball generator 5 Oct 2008 [2104] cdrskin/changelog.txt Documented changes and release timestamp ------------------------------ release - cdrskin-0.5.4.pl00 - 2008.10.06.073001 * Bug fix: /dev/sr0 was accepted as enumerable address on Linux 2.4 * Issueing many SCSI error messages in cleartext now 2008.10.05.123737 [2106] Makefile.am configure.ac README libburn/libburn.h cdrskin/cdrskin.c cdrskin/README cdrskin/compile_cdrskin.sh cdrskin/cdrskin_timestamp.h cdrskin/cdrskin_eng.html Made number transition to next development cycle 5 Oct 2008 [2107] - cdrskin/add_ts_changes_to_libburn_0_5_2 - cdrskin/add_ts_changes_to_libburn_0_5_3 + cdrskin/add_ts_changes_to_libburn_0_5_4 + cdrskin/add_ts_changes_to_libburn_0_5_5 Updated cdrskin tarball generator 5 Oct 2008 [2108] cdrskin/changelog.txt Documented changes and release timestamp ------------------------------------ cycle - cdrskin-0.5.5 - 2008.10.05.130109 2008.10.15.103224 [2126] libburn/libburn.h A clarification in comment about burn_disc_format() 15 Oct 2008 [2127] cdrskin/cdrskin.1 Fixed incomplete sentence in man cdrskin 2008.11.01.121240 [2157] libburn/libburn.h libburn/async.c Bug fix: Unsuitable write modes were caught silently and later than desired ------------------------------------ cycle - cdrskin-0.5.5 - 2008.11.01.121445 2008.11.08.134828 [2173] libburn/libburn.h Clarified behavior of burn_source with pipes 2008.11.08.141734 [2174] libburn/file.h libburn/file.c libburn/async.c Cancelling libburn fifo thread before freeing the fifo object 2008.11.08.202456 [2175] libburn/async.c Disabling the sigsegv provoking new debug message 2008.11.12.075111 [2180] libburn/async.h Avoiding warning message about implicitely declared burn_fifo_abort() ------------------------------------ cycle - cdrskin-0.5.5 - 2008.11.12.075411 * Bug fix: libburn fifo thread was not aborted when burn run was aborted 12 Nov 2008 [2181] svn copy http://svn.libburnia-project.org/libburn/trunk http://svn.libburnia-project.org/libburn/branches/ZeroFiveSix Preparing for libburn-0.5.6 12 Nov 2008 [2182] svn delete http://svn.libburnia-project.org/libburn/branches/ZeroFourSix Removing obsolete libburn branch ZeroFourSix 2008.11.12.120001 [2183] Makefile.am configure.ac README libburn/libburn.h cdrskin/cdrskin.c cdrskin/README cdrskin/compile_cdrskin.sh cdrskin/cdrskin_timestamp.h cdrskin/cdrskin_eng.html Made number transition to 0.5.6 12 Nov 2008 [2184] - cdrskin/add_ts_changes_to_libburn_0_5_4 - cdrskin/add_ts_changes_to_libburn_0_5_5 + cdrskin/add_ts_changes_to_libburn_0_5_6 + cdrskin/add_ts_changes_to_libburn_0_5_7 Updated cdrskin tarball generator 12 Nov 2008 [2185] cdrskin/changelog.txt Documented changes and release timestamp 12 Nov 2008 [2186] cdrskin/cdrskin.c Corrected wrong version number of cdrskin ------------------------------ release - cdrskin-0.5.6.pl00 - 2008.11.12.120001 * Bug fix: libburn fifo thread was not aborted when burn run was aborted which could lead to use of freed memory 2008.11.12.121832 [2187] Makefile.am configure.ac README libburn/libburn.h cdrskin/cdrskin.c cdrskin/README cdrskin/compile_cdrskin.sh cdrskin/cdrskin_timestamp.h cdrskin/cdrskin_eng.html Made number transition to 0.5.7 12 Nov 2008 [2188] - cdrskin/add_ts_changes_to_libburn_0_5_4 - cdrskin/add_ts_changes_to_libburn_0_5_5 + cdrskin/add_ts_changes_to_libburn_0_5_6 + cdrskin/add_ts_changes_to_libburn_0_5_7 Updated cdrskin tarball generator 12 Nov 2008 [2189] cdrskin/changelog.txt Documented changes and release timestamp ------------------------------------ cycle - cdrskin-0.5.7 - 2008.11.12.130026 12 Nov 2008 [2191] svn move \ http://svn.libburnia-project.org/libburn/"$svn_name" \ http://svn.libburnia-project.org/libburn/"$tag_name" libburn release 0.5.6 is ready 2008.11.15.220652 [2197] libburn/sg-freebsd.c libburn/sg-freebsd-port.c Removed remark that use of statvfs() was untested with FreeBSD 21 Nov 2008 [2208] README cdrskin/README cdrskin/cdrskin_eng.html Mentioned FreeBSD peculiarities in our docs 2008.11.26.210608 [2213] libburn/structure.c Added tests against the SIGSEGV of ticket 146 2008.11.27.081027 [2214] libburn/libdax_msgs.h libburn/structure.c Truncating eventually detected damaged CD table-of-content ------------------------------------ cycle - cdrskin-0.5.7 - 2008.11.27.081027 * Bug fix: Session without leadout entry on CD caused SIGSEGV 2008.11.27.172124 [2215] libburn/libdax_msgs.h libburn/structure.c Changed error severity with TOC truncation to MISHAP 2008.11.29.140115 [2217] libburn/spc.c Translating ASC=0x31 formatting error messages, reporting command names 2008.11.29.140404 [2218] libburn/mmc.c Circumventing BD-RE Quick Certification refusal of LG GGW-H20L YL03 ------------------------------------ cycle - cdrskin-0.5.7 - 2008.11.29.140404 2008.12.03.085219 [2239] libburn/mmc.c libburn/structure.c libburn/libdax_msgs.h Defaulting sessions without leadout entry ------------------------------------ cycle - cdrskin-0.5.7 - 2008.12.03.085219 Dec 07 2008 [2248] svn copy http://svn.libburnia-project.org/libburn/trunk http://svn.libburnia-project.org/libburn/branches/ZeroFiveEight Preparing for libburn-0.5.8 2008.12.07.140001 [2249] Makefile.am configure.ac README libburn/libburn.h cdrskin/cdrskin.c cdrskin/README cdrskin/compile_cdrskin.sh cdrskin/cdrskin_timestamp.h cdrskin/cdrskin_eng.html Made number transition to 0.5.8 Dec 07 2008 [2250] - cdrskin/add_ts_changes_to_libburn_0_5_6 - cdrskin/add_ts_changes_to_libburn_0_5_7 + cdrskin/add_ts_changes_to_libburn_0_5_8 + cdrskin/add_ts_changes_to_libburn_0_5_9 Updated cdrskin tarball generator Dec 07 2008 [2251] cdrskin/changelog.txt Documented changes and release timestamp ------------------------------ release - cdrskin-0.5.8.pl00 - 2008.12.07.140001 * Bug fix: A session without leadout entry on CD caused a SIGSEGV by NULL * Improvements about BD-RE formatting 2008.12.07.155219 [2252] Makefile.am configure.ac README libburn/libburn.h cdrskin/cdrskin.c cdrskin/README cdrskin/compile_cdrskin.sh cdrskin/cdrskin_timestamp.h cdrskin/cdrskin_eng.html Made number transition to 0.5.9 Dec 07 2008 [2253] - cdrskin/add_ts_changes_to_libburn_0_5_6 - cdrskin/add_ts_changes_to_libburn_0_5_7 + cdrskin/add_ts_changes_to_libburn_0_5_8 + cdrskin/add_ts_changes_to_libburn_0_5_9 Updated cdrskin tarball generator Dec 07 2008 [2254] cdrskin/changelog.txt Documented changes and release timestamp Dec 07 2008 [2255] svn move -m "libburn release 0.5.8 is ready" \ http://svn.libburnia-project.org/libburn/branches/ZeroFiveEigh \ http://svn.libburnia-project.org/libburn/tags/ZeroFiveEight svn delete -m 'Deleted obsolete branch' \ http://svn.libburnia-project.org/libburn/branches/"$svn_name" ------------------------------------ cycle - cdrskin-0.5.9 - 2008.12.07.155219 2008.12.09.123314 [2264] libburn/libburn.h libburn/drive.c libburn/async.c libburn/write.c libburn/mmc.c Beginning to implement write code for BD-R SRM without POW 2008.12.09.123558 [2265] cdrskin/cdrskin.c Beginning to implement write code for BD-R SRM without POW 2008.12.10.092535 [2271] libburn/transport.h libburn/async.c libburn/mmc.h libburn/mmc.c Formatting of BD-R SRM to default size and by index 2008.12.10.114241 [2273] cdrskin/cdrskin.c Formatting of BD-R SRM to default size and by index 10 Dec 2008 [2274] README cdrskin/README cdrskin/cdrskin.1 cdrskin/wiki_plain.txt Mentioning BD-R in documentation 2008.12.11.072308 [2276] libburn/libdax_msgs.h libburn/async.c Rejecting unformattable BD-R more early 2008.12.11.092204 [2278] libburn/libdax_msgs.h libburn/async.c libburn/mmc.c cdrskin/cdrskin.1 Catching BD-R zero spare formatting with NOTE rather than SORRY 2008.12.12.112129 [2279] libburn/libburn.h libburn/async.c libburn/mmc.c Making format size of BD-RE and BD-R quite freely adjustable 2008.12.12.214013 [2280] libburn/transport.h libburn/async.c libburn/mmc.c Interpreting feature 0023h for BD formatting capabilities 2008.12.13.144909 [2284] configure.ac Now producing libburn.so.4.24.0 ------------------------------------ cycle - cdrskin-0.5.9 - 2008.12.13.144909 * Formatting and writing of BD-R media 14 Dec 2008 [2289] test/libburner.c Updated libburner to BD-R 14 Dec 2008 [2290] cdrskin/cdrskin_eng.html Updated cdrskin web page 2008.12.17.091905 [2297] libburn/libburn.h libburn/drive.c New API function burn_get_read_capacity() 17 Dec 2008 [2298] [2302] doc/comments Removed project overview and references to libisofs and libisoburn ------------------------------------ cycle - cdrskin-0.5.9 - 2008.12.19.070912 * New API function burn_get_read_capacity() 2008.12.19.203523 [2306] libburn/libburn.h Clarified blank, appendable, closed burn_disc_status 2008.12.22.130527 [2323] libburn/async.c Fixed denial of fast formatting with BD-RE introduced by revision 2280 ------------------------------------ cycle - cdrskin-0.5.9 - 2008.12.23.144853 2008.12.29.105341 [2342] libburn/libburn.h test/libburner.c Cosmetic changes Jan 02 2009 [2346] svn copy http://svn.libburnia-project.org/libburn/trunk http://svn.libburnia-project.org/libburn/branches/ZeroSixZero Preparing for libburn-0.6.0 02 Jan 2009 [2347] COPYRIGHT libburn/libdax_msgs.c libburn/libdax_msgs.h test/libburner.c Updated copyright claims to year 2009 2009.01.02.160001 [2348] Makefile.am configure.ac README libburn/libburn.h cdrskin/cdrskin.c cdrskin/README cdrskin/compile_cdrskin.sh cdrskin/cdrskin_timestamp.h cdrskin/cdrskin_eng.html Made number transition to 0.6.0 02 Jan 2009 [2349] - cdrskin/add_ts_changes_to_libburn_0_5_8 - cdrskin/add_ts_changes_to_libburn_0_5_9 + cdrskin/add_ts_changes_to_libburn_0_6_0 + cdrskin/add_ts_changes_to_libburn_0_6_1 Updated cdrskin tarball generator 02 Jan 2009 [2350] cdrskin/changelog.txt Documented changes and release timestamp ------------------------------ release - cdrskin-0.6.0.pl00 - 2009.01.02.160001 * Formatting and writing of BD-R media * New API function burn_get_read_capacity() 2009.01.04.112716 [2351] COPYRIGHT libburn/libdax_msgs.c libburn/libdax_msgs.h test/libburner.c Updated copyright claims to year 2009 2009.01.04.113401 [2352] Makefile.am configure.ac README libburn/libburn.h cdrskin/cdrskin.c cdrskin/README cdrskin/compile_cdrskin.sh cdrskin/cdrskin_timestamp.h cdrskin/cdrskin_eng.html Made number transition to 0.6.1 04 Jan 2009 [2353] - cdrskin/add_ts_changes_to_libburn_0_5_8 - cdrskin/add_ts_changes_to_libburn_0_5_9 + cdrskin/add_ts_changes_to_libburn_0_6_0 + cdrskin/add_ts_changes_to_libburn_0_6_1 Updated cdrskin tarball generator 03 Jan 2009 [2354] cdrskin/changelog.txt Documented changes and release timestamp ------------------------------------ cycle - cdrskin-0.6.1 - 2009.01.04.113401 04 Jan 2009 [2356] svn move http://svn.libburnia-project.org/libburn/branches/ZeroSixZero http://svn.libburnia-project.org/libburn/tags/ZeroSixZero libburn release 0.6.0 is ready 2009.01.06.122534 [2366] libburn/spc.c Error texts for ASC 73 : power calibration and program memory 2009.01.06.122808 [2367] [2369] libburn/async.c libburn/libdax_msgs.h Complaining and refusing more early with unformatted BD-RE 7 Jan 2009 [2370] cdrskin/cdrskin.1 Clarification about one-time DVD and BD media 2009.01.07.154414 [2371] libburn/write.c Bug fix: BD-R were not correctly finalized 7 Jan 2009 [2372] cdrskin/cdrskin_eng.html Mentioned bug fix and pl01 ------------------------------------ cycle - cdrskin-0.6.1 - 2009.01.07.154414 7 Jan 2009 [2373] svn copy -m "Branching for libburn bugfix release 0.6.0.pl01" \ http://svn.libburnia-project.org/libburn/ \ http://svn.libburnia-project.org/libburn/ 7 Jan 2009 [2374] svn rm -m 'Removing falsly copied tag' \ http://svn.libburnia-project.org/libburn/libburn 7 Jan 2009 [2375] svn copy -m "Branching for libburn bugfix release 0.6.0.pl01" \ http://svn.libburnia-project.org/libburn/tags/ZeroSixZero \ http://svn.libburnia-project.org/libburn/branches/ZeroSixZeroPl01 2009.01.07.140001 [branch 2376] README cdrskin/README cdrskin/cdrskin_eng.html cdrskin/cdrskin_timestamp.h Mentioned bug fix and pl01 2009.01.07.140001 [branch 2377] libburn/write.c Bug fix: BD-R were not correctly finalized 7 Jan 2009 [2378] svn move -m 'libburn bugfix release 0.6.0.pl01 is ready' \ http://svn.libburnia-project.org/libburn/branches/ZeroSixZeroPl01 \ http://svn.libburnia-project.org/libburn/tags/ZeroSixZeroPl01 ------------------------------------ cycle - cdrskin-0.6.1 - 2009.01.07.154414 2009.01.09.095943 [2381] libburn/transport.h libburn/write.c libburn/mmc.c libburn/libdax_msgs.h Recognizing BD-R media spoiled by the close bug and handling them as appendable ------------------------------------ cycle - cdrskin-0.6.1 - 2009.01.09.100210 2009.01.09.161704 [2383] libburn/write.c Preventing a possible bug with a burn run of more than one session at once 2009.01.11.102711 [2390] libburn/write.c libburn/libdax_msgs.h Prepared eventual closing of spoiled BD-R media by a pseudo write run 11 Jan 2009 [2391] doc/cookbook.txt Updated cookbook about BD-R media 27 Jan 2009 [2431] README libburn/libburn.h Mentioned the need for 64 bit file i/o 2009.02.04.102822 [2447] Makefile.am Linking with $LIBBURN_ARCH_LIBS to get -lcam on FreeBSD 4 Feb 2009 [2448] README cdrskin/README Mentioned hald as possibly conflicting service 2009.02.19.192801 [2479] libburn/spc.c Human readable error messages with asynchronous SCSI errors 20 Feb 2009 [2482] svn copy http://svn.libburnia-project.org/libburn/trunk http://svn.libburnia-project.org/libburn/branches/ZeroSixZero Preparing for libburn-0.6.0 2009.02.20.090001 [2483] Makefile.am configure.ac README libburn/libburn.h cdrskin/cdrskin.c cdrskin/README cdrskin/compile_cdrskin.sh cdrskin/cdrskin_timestamp.h cdrskin/cdrskin_eng.html Made number transition to 0.6.2 20 Feb 2009 [2484] - cdrskin/add_ts_changes_to_libburn_0_6_0 - cdrskin/add_ts_changes_to_libburn_0_6_1 + cdrskin/add_ts_changes_to_libburn_0_6_2 + cdrskin/add_ts_changes_to_libburn_0_6_3 Updated cdrskin tarball generator ------------------------------ release - cdrskin-0.6.2.pl00 - 2009.02.20.090001 * Improvements with build system for FreeBSD 2009.02.20.124909 [2485] Makefile.am configure.ac README libburn/libburn.h cdrskin/cdrskin.c cdrskin/README cdrskin/compile_cdrskin.sh cdrskin/cdrskin_timestamp.h cdrskin/cdrskin_eng.html Made number transition to 0.6.3 20 Feb 2009 [2486] - cdrskin/add_ts_changes_to_libburn_0_6_0 - cdrskin/add_ts_changes_to_libburn_0_6_1 + cdrskin/add_ts_changes_to_libburn_0_6_2 + cdrskin/add_ts_changes_to_libburn_0_6_3 Updated cdrskin tarball generator ------------------------------------ cycle - cdrskin-0.6.3 - 2009.02.20.132535 20 Feb 2009 [2489] svn move -m libburn release 0.6.2 is ready http://svn.libburnia-project.org/libburn/branches/ZeroSixTwo http://svn.libburnia-project.org/libburn/tags/ZeroSixTwo 2009.02.27.143100 [2500] libburn/libburn.h libburn/transport.h libburn/drive.c libburn/options.c libburn/write.c libburn/mmc.c New API function burn_drive_set_stream_recording() 2009.02.27.211707 [2501] cdrskin/cdrskin.c cdrskin/cdrskin.1 New stream_recording mode with start number 2009.03.02.170126 [2513] libburn/os.h libburn/libdax_msgs.h libburn/sg.c + libburn/os-dummy.h + libburn/sg-dummy.c New operating system adapter "dummy" for stdio on POSIX-like systems 2009.03.02.193353 [2514] libburn/drive.c Fixed a race condition on abort with stdio writing which could cause SIGSEGV 2009.03.02.200132 [2515] libburn/sg.c Added a dummy function with loud compiler warning to sg.c dummy case 2009.03.03.092057 [2516] configure.ac libburn/sg-dummy.c Making optional use of statvfs() in sg-dummy ------------------------------------ cycle - cdrskin-0.6.3 - 2009.03.03.092057 * New API function burn_drive_set_stream_recording() * New stream recording mode with start number 2009.03.05.145309 [2520] acinclude.m4 Lifted the ban on operating systems other than Linux and FreeBSD ------------------------------------ cycle - cdrskin-0.6.3 - 2009.03.05.145309 * New operating system adapter "dummy" for stdio on POSIX-like systems 2009.03.08.140120 [2522] libburn/cleanup.c Reacted on compiler warnings of SchilliX-0.6.7 (based on Solaris 5.11) 13 Mar 2009 [2529] svn copy -m "Branching for libburn release 0.6.4" \ http://svn.libburnia-project.org/libburn/trunk \ http://svn.libburnia-project.org/libburn/branches/ZeroSixFour 2009.03.13.080001 [2530] Makefile.am configure.ac README libburn/libburn.h cdrskin/cdrskin.c cdrskin/README cdrskin/compile_cdrskin.sh cdrskin/cdrskin_timestamp.h cdrskin/cdrskin_eng.html Made libburn number transition to 0.6.4 13 Mar 2009 [2531] - cdrskin/add_ts_changes_to_libburn_0_6_2 - cdrskin/add_ts_changes_to_libburn_0_6_3 + cdrskin/add_ts_changes_to_libburn_0_6_4 + cdrskin/add_ts_changes_to_libburn_0_6_5 Updated cdrskin tarball generator 13 Mar 2009 [2534] cdrskin/changelog.txt Documented changes and release timestamp ------------------------------ release - cdrskin-0.6.4.pl00 - 2009.03.13.080001 * New operating system adapter "dummy" for stdio on general X/Open systems * New API function burn_drive_set_stream_recording() * New stream recording mode with start address 2009.03.13.135818 [2532] Makefile.am configure.ac README libburn/libburn.h cdrskin/cdrskin.c cdrskin/README cdrskin/compile_cdrskin.sh cdrskin/cdrskin_timestamp.h cdrskin/cdrskin_eng.html Made libburn number transition to 0.6.5 13 Mar 2009 [2533] - cdrskin/add_ts_changes_to_libburn_0_6_2 - cdrskin/add_ts_changes_to_libburn_0_6_3 + cdrskin/add_ts_changes_to_libburn_0_6_4 + cdrskin/add_ts_changes_to_libburn_0_6_5 Updated cdrskin tarball generator 13 Mar 2009 [2535] cdrskin/changelog.txt Documented changes and release timestamp ------------------------------------ cycle - cdrskin-0.6.5 - 2009.03.13.162355 13 Mar 2009 [2538] svn move -m "libburn release 0.6.4 is ready" \ http://svn.libburnia-project.org/libburn/branches/ZeroSixFour \ http://svn.libburnia-project.org/libburn/tags/ZeroSixFour 2009.03.16.190745 [2547] configure.ac acinclude.m4 Makefile.am Get on FreeBSD pkgconfigdir=.../libdata , on Linux and others: .../lib 2009.03.18.124558 [2553] libburn/spc.c Human readable error messages for asc=08 "Logical unit communication failure" 2009.03.18.172512 [2554] libburn/drive.c Bug fix: burn_abort() did not work with broken output pipe (since rev 2514) 2009.04.30.065653 [2623] libburn/write.c Marked alleged use of uninitialized memory reported by valgrind 2009.04.30.065918 [2624] libburn/write.c Replaced 8 blanks by a tab 2009.04.30.070813 [2625] libburn/sg-freebsd.c Bug fix: Device scan stalled on FreeBSD. Ticket 148 jwehle ------------------------------------ cycle - cdrskin-0.6.5 - 2009.04.30.070813 Bug fix: burn_abort() did not work with broken output pipe (since rev 2514) Bug fix: Device scan stalled on FreeBSD. Ticket 148 jwehle 7 May 2009 [2628] svn copy -m "Branching for libburn release 0.6.6" http://svn.libburnia-project.org/libburn/trunk http://svn.libburnia-project.org/libburn/branches/ZeroSixSix 7 May 2009 [2629] cdrskin/cdrskin.1 Mentioned BD were it was missing 2009.05.07.100001 [2630] Makefile.am configure.ac README libburn/libburn.h cdrskin/cdrskin.c cdrskin/README cdrskin/compile_cdrskin.sh cdrskin/cdrskin_timestamp.h cdrskin/cdrskin_eng.html Made number transition and activated development documentation 7 May 2009 [2631] - cdrskin/add_ts_changes_to_libburn_0_6_4 - cdrskin/add_ts_changes_to_libburn_0_6_5 + cdrskin/add_ts_changes_to_libburn_0_6_6 + cdrskin/add_ts_changes_to_libburn_0_6_7 Updated cdrskin tarball generator 7 May 2009 [2632] cdrskin/changelog.txt Documented changes and release timestamp ------------------------------ release - cdrskin-0.6.6.pl00 - 2009.05.07.100001 Bug fix: burn_abort() did not work with broken output pipe (since rev 2514) Bug fix: Device scan stalled on FreeBSD. Ticket 148 jwehle 7 May 2009 [2633] cdrskin/cdrskin.1 Mentioned BD were it was missing 2009.05.07.181034 [2634] Makefile.am configure.ac README libburn/libburn.h cdrskin/cdrskin.c cdrskin/README cdrskin/compile_cdrskin.sh cdrskin/cdrskin_timestamp.h cdrskin/cdrskin_eng.html Made number transition and activated development documentation 7 May 2009 [2635] - cdrskin/add_ts_changes_to_libburn_0_6_4 - cdrskin/add_ts_changes_to_libburn_0_6_5 + cdrskin/add_ts_changes_to_libburn_0_6_6 + cdrskin/add_ts_changes_to_libburn_0_6_7 Updated cdrskin tarball generator 7 May 2009 [2636] cdrskin/changelog.txt Documented changes and release timestamp ------------------------------------ cycle - cdrskin-0.6.7 - 2009.05.07.181034 8 May 2009 [2637] svn move -m libburn release 0.6.6 is ready http://svn.libburnia-project.org/libburn/branches/ZeroSixSix http://svn.libburnia-project.org/libburn/tags/ZeroSixSix 2009.05.17.144304 [2645] cdrskin/cdrskin.c Made -scanbus work with SCSI bus numbers like 85 (USB, kernel 2.6.18.2) 2009.06.02.162841 [2655] libburn/drive.c libburn/async.c libburn/options.c libburn/spc.c libburn/libdax_msgs.h Rectified use of burn_drive.mdata->valid 2 Jun 2009 [2656] test/libburner.c Avoided SIGSEGV if no drives were found by scan 2009.06.02.172201 [2657] libburn/drive.c Avoided to enumerate faulty drive objects 2009.06.03.085637 [2658] libburn/spc.c Bug fix: Old MMC-1 drives were rejected because of mode page 2Ah length 2009.06.03.185118 [2659] libburn/transport.h libburn/drive.c libburn/spc.c libburn/mmc.c Bug fix: No usable media was detected with old MMC-1 drives 2009.06.14.095004 [2669] libburn/sg-linux.c Retrying 3 times on EBUSY drives with generous usleep intervals ------------------------------------ cycle - cdrskin-0.6.7 - 2009.06.14.095833 Made -scanbus work with high SCSI bus numbers Bug fix: Old MMC-1 drives were rejected because of mode page 2Ah length Bug fix: No usable media was detected with old MMC-1 drives 7 Jul 2009 [2691] acinclude.m4 configure.ac configure options --enable-libdir-pkgconfig and --enable-pkgconfig-path=DIR 2009.07.07.191134 [2692] Timestamp for revision 2691 14 Jul 2009 [2894] svn copy -m "Branching for libburn release 0.6.8" http://svn.libburnia-project.org/libburn/trunk http://svn.libburnia-project.org/libburn/branches/ZeroSixEight 2009.07.14.100001 [2695] Makefile.am configure.ac README libburn/libburn.h cdrskin/cdrskin.c cdrskin/README cdrskin/compile_cdrskin.sh cdrskin/cdrskin_timestamp.h cdrskin/cdrskin_eng.html Made number transition and activated development documentation 14 Jul 2009 [2696] - cdrskin/add_ts_changes_to_libburn_0_6_6 - cdrskin/add_ts_changes_to_libburn_0_6_7 + cdrskin/add_ts_changes_to_libburn_0_6_8 + cdrskin/add_ts_changes_to_libburn_0_6_9 Updated cdrskin tarball generator 14 Jul 2009 [2697] cdrskin/changelog.txt Documented changes and release timestamp ------------------------------ release - cdrskin-0.6.8.pl00 - 2009.07.14.100001 Made -scanbus work with high SCSI bus numbers Bug fix: Old MMC-1 drives were rejected because of mode page 2Ah length Bug fix: No usable media was detected with old MMC-1 drives 2009.07.14.133159 [2698] Makefile.am configure.ac README libburn/libburn.h cdrskin/cdrskin.c cdrskin/README cdrskin/compile_cdrskin.sh cdrskin/cdrskin_timestamp.h cdrskin/cdrskin_eng.html Made number transition and activated development documentation 14 Jul 2009 [2699] - cdrskin/add_ts_changes_to_libburn_0_6_6 - cdrskin/add_ts_changes_to_libburn_0_6_7 + cdrskin/add_ts_changes_to_libburn_0_6_8 + cdrskin/add_ts_changes_to_libburn_0_6_9 Updated cdrskin tarball generator 14 Jul 2009 [2700] cdrskin/changelog.txt Documented changes and release timestamp ------------------------------------ cycle - cdrskin-0.6.9 - 2009.07.14.133159 14 Jul 2009 [2702] svn move -m libburn release 0.6.8 is ready http://svn.libburnia-project.org/libburn/branches/ZeroSixEight http://svn.libburnia-project.org/libburn/tags/ZeroSixEight 2009.08.15.133055 [2721] libburn/write.c Added test code about output blocks size as comment. 2009.08.15.133332 [2722] libburn/libburn.h libburn/transport.h libburn/drive.c libburn/mmc.h libburn/mmc.c New API calls burn_drive_get_all_profiles(), burn_obtain_profile_name() 2009.08.15.133744 [2723] cdrskin/cdrskin.c Listing all profiles with cdrskin -v -atip 2009.08.23.130326 [2735] libburn/drive.c libburn/spc.c libburn/mmc.c Adapted to pitfalls of U3 memory sticks which appear as CD-ROM drives ------------------------------------ cycle - cdrskin-0.6.9 - 2009.08.23.132942 New API calls burn_drive_get_all_profiles(), burn_obtain_profile_name() Adapted to pitfalls of U3 memory sticks which appear as CD-ROM drives 2009.08.24.131146 [2736] libburn/libburn.h libburn/transport.h libburn/drive.c libburn/sbc.c New API call burn_drive_snooze() 2009.08.24.161646 [2737] libburn/libburn.h libburn/drive.c Made burn_drive_snooze() safe for emulated drives 2009.08.24.202517 [2740] libburn/transport.h libburn/sbc.c libburn/mmc.c Implemented automatic START UNIT after STOP UNIT before any other SCSI command 2009.08.27.123001 [2746] Makefile.am configure.ac README libburn/libburn.h cdrskin/cdrskin.c cdrskin/README cdrskin/compile_cdrskin.sh cdrskin/cdrskin_timestamp.h cdrskin/cdrskin_eng.html Made number transition and activated development documentation 27 Aug 2009 [2747] - cdrskin/add_ts_changes_to_libburn_0_6_8 - cdrskin/add_ts_changes_to_libburn_0_6_9 + cdrskin/add_ts_changes_to_libburn_0_7_0 + cdrskin/add_ts_changes_to_libburn_0_7_1 Updated cdrskin tarball generator 27 Aug 2009 [2748] cdrskin/changelog.txt Documented changes and release timestamp ------------------------------ release - cdrskin-0.7.0.pl00 - 2009.08.27.123001 New API calls burn_drive_get_all_profiles(), burn_obtain_profile_name() New API call burn_drive_snooze() Adapted to pitfalls of U3 memory sticks which appear as CD-ROM drives Listing all supported profiles with option -atip 2009.08.27.143351 [2749] Makefile.am configure.ac README libburn/libburn.h cdrskin/cdrskin.c cdrskin/README cdrskin/compile_cdrskin.sh cdrskin/cdrskin_timestamp.h cdrskin/cdrskin_eng.html Made number transition to development version 0.7.1 27 Aug 2009 [2750] - cdrskin/add_ts_changes_to_libburn_0_6_8 - cdrskin/add_ts_changes_to_libburn_0_6_9 + cdrskin/add_ts_changes_to_libburn_0_7_0 + cdrskin/add_ts_changes_to_libburn_0_7_1 Updated cdrskin tarball generator 27 Aug 2009 [2751] cdrskin/changelog.txt Documented changes and release timestamp ------------------------------------ cycle - cdrskin-0.7.1 - 2009.08.27.143351 2009.09.01.082602 [2773] cdrskin/cdrskin.c cdrskin/cdrskin.1 Disabled write mode -raw96r 2009.09.01.095750 [2774] [2775] libburn/libburn.h libburn/sector.h libburn/sector.c libburn/lec.h libburn/lec.c libburn/read.c libburn/write.c Disabled code using libburn/lec.c 2009.09.01.113957 [2777] cdrskin/cdrskin.c Aligned the output columns of cdrskin --devices 2009.09.01.133520 [2778] cdrskin/cdrskin.c cdrskin/cdrskin.1 New option --long_toc, now printing media summary at end of TOC 2009.09.02.131514 [2779] Makefile.am libburn/sector.c - libburn/lec.h - libburn/lec.c cdrskin/compile_cdrskin.sh Removed lec.c from libburn 2009.09.02.133307 [2780] libburn/libburn.h libburn/util.c + doc/mediainfo.txt cdrskin/cdrskin.c New API call burn_guess_cd_manufacturer() 2009.09.04.202255 [2781] libburn/libburn.h libburn/drive.c libburn/util.c libburn/spc.c libburn/mmc.h libburn/mmc.c New API calls burn_get_media_product_id() and burn_guess_manufacturer() 2009.09.04.202357 [2782] cdrskin/cdrskin.c Option -atip now reports Product Id and Manufacturer for most CD, DVD, BD types 4 Sep 2009 [2783] doc/mediainfo.txt Updated media info documentation 2009.09.04.204432 [2784] cdrskin/cdrskin.c Adjusted column width of media info messages 2009.09.05.072512 [2785] cdrskin/cdrskin.c Adjusted column width of media summary message ------------------------------------ cycle - cdrskin-0.7.1 - 2009.09.05.072659 * New option --long_toc, now printing media summary at end of TOC * New API call burn_guess_cd_manufacturer() * New API calls burn_get_media_product_id() and burn_guess_manufacturer() 2009.09.05.113043 [2786] libburn/util.h libburn/util.c libburn/mmc.c Made product ID surely a single printable word 2009.09.05.114326 [2787] libburn/sg-linux.c Silenced a valgrind warning caused by not recognizing side effects of a ioctl 2009.09.05.115112 [2788] cdrskin/cdrskin.c Closed a small memory leak with drive inquiry 2009.09.05.120947 [2789] cdrskin/cdrskin.c Made cdrskin/compile_cdrskin.sh -libburn_0_7_0 work again ------------------------------------ cycle - cdrskin-0.7.1 - 2009.09.05.121334 2009.09.05.131859 [2790] cdrskin/cdrskin.c Re-enabled output of product id and manufacturer ------------------------------------ cycle - cdrskin-0.7.1 - 2009.09.05.132208 2009.09.05.165127 [2791] libburn/libburn.h libburn/drive.c libburn/util.c libburn/mmc.c Introduced flag bit0 for API call burn_get_media_product_id() 2009.09.05.165257 [2792] cdrskin/cdrskin.c "Manufacturer:", "Media type:" as cdrecord, own "Product Id:" and "Producer:" ------------------------------------ cycle - cdrskin-0.7.1 - 2009.09.05.172818 * New -atip report lines "Product Id:" and "Producer:" 2009.09.06.092330 [2793] libburn/util.c Made recognition of CD media codes work in burn_guess_manufacturer() 2009.09.06.092654 [2794] libburn/libburn.h libburn/drive.c cdrskin/cdrskin.c Changed new API call burn_get_media_product_id() to burn_disc_get_media_id() 06 Sep 2009 [2795] doc/mediainfo.txt Corrected misformatted manufacturer strings of DVD- media 2009.09.06.112121 [2796] libburn/mmc.c doc/mediainfo.txt Avoided to read third sixpack of manufacturer bytes with DVD-R media ------------------------------------ cycle - cdrskin-0.7.1 - 2009.09.06.115138 2009.09.09.125305 [2801] libburn/libburn.h libburn/transport.h libburn/drive.c libburn/mmc.c New API call burn_disc_get_cd_info() 2009.09.09.134030 [2802] libburn/transport.h libburn/drive.c libburn/mmc.c Correction with erasable bit of burn_disc_get_cd_info() 2009.09.09.153951 [2803] libburn/libburn.h libburn/mmc.c New struct burn_toc_entry extension for Last Recorded Address 2009.09.09.173452 [2804] cdrskin/cdrskin.c cdrskin/cdrskin.1 Emulation of some -minfo output 2009.09.09.174337 [2805] cdrskin/cdrskin.c Silenced compiler warning ------------------------------------ cycle - cdrskin-0.7.1 - 2009.09.09.174446 * New API call burn_disc_get_cd_info() * Emulation of some -minfo output 2009.09.10.071253 [2806] cdrskin/cdrskin.c Removed Media summary from -minfo because of incompatible counting rules ------------------------------------ cycle - cdrskin-0.7.1 - 2009.09.10.084912 2009.09.11.112528 [2807] libburn/libburn.h libburn/transport.h libburn/structure.h libburn/structure.c libburn/sector.c New API call burn_track_set_cdxa_conv() 2009.09.11.120959 [2808] cdrskin/cdrskin.c cdrskin/cdrskin.1 Interpreting options -mode2, -xa, -xa1, -xa2 but producing CD-ROM Mode 1 tracks 12 Sep 2009 [2809] cdrskin/cdrskin_eng.html Updated cdrskin web page ------------------------------------ cycle - cdrskin-0.7.1 - 2009.09.12.134510 * New API call burn_track_set_cdxa_conv() * Better interpretation of options -mode2, -xa, -xa1, -xa2 * New option --xa1-ignore 2009.09.13.095055 [2810] libburn/drive.c Evaluating read capacity with role 2 drives (regular files and block devices) 2009.09.18.161214 [2815] libburn/sector.c Fixing SIGSEGV with CD SAO introduced with revision 2807 2009.09.18.161944 [2816] libburn/read.c libburn/libdax_msgs.h Refusing to read beyond media_read_capacity ------------------------------------ cycle - cdrskin-0.7.1 - 2009.09.18.164446 2009.09.20.111911 [2820] libburn/libburn.h Mentioned need for 2056 byte fifo chunks with burn_track_set_cdxa_conv() 2009.09.22.192545 [2822] libburn/sbc.c Revoked instruction to retry STOP UNIT 2009.09.22.192802 [2823] libburn/sg-linux.c Restricted retry to the timeout for single SCSI commands (200 seconds) 2009.10.04.151239 [2830] libburn/write.c libburn/libdax_msgs.h Fixed CD TAO multi-track -dummy bug reported by Philippe Rouquier ------------------------------------ cycle - cdrskin-0.7.1 - 2009.10.08.174136 * Bug fix: CD TAO sessions with multiple tracks did not work in -dummy mode 2009.10.09.123651 [2847] libburn/mmc.c Determining read capacity for DVD-RAM 2009.10.09.123840 [2848] cdrskin/cdrskin.c Made -minfo stupidly report overwriteable media as "erasable" and "complete" 2009.10.09.200411 [2849] libburn/read.c Made read_capacity error message of burn_read_data() depending on flag bit1 2009.10.09.200730 [2850] cdrskin/cdrskin.c Made -minfo subtract 2 from track size if "Data" and last 2 blocks unreadable 12 Oct 2009 [2854] svn copy -m "Branching for libburn release 0.7.2" \ http://svn.libburnia-project.org/libburn/trunk \ http://svn.libburnia-project.org/libburn/branches/ZeroSevenTwo 2009.10.12.080001 [2855] Makefile.am configure.ac README libburn/libburn.h cdrskin/cdrskin.c cdrskin/README cdrskin/compile_cdrskin.sh cdrskin/cdrskin_timestamp.h cdrskin/cdrskin_eng.html Made number transition and activated development documentation 12 Oct 2009 [2856] - cdrskin/add_ts_changes_to_libburn_0_7_0 - cdrskin/add_ts_changes_to_libburn_0_7_1 + cdrskin/add_ts_changes_to_libburn_0_7_2 + cdrskin/add_ts_changes_to_libburn_0_7_3 Updated cdrskin tarball generator 12 Oct 2009 [2867] cdrskin/changelog.txt Documented changes and release timestamp ------------------------------ release - cdrskin-0.7.2.pl00 - 2009.10.12.080001 * Bug fix: CD TAO sessions with multiple tracks did not work in -dummy mode * Better interpretation of options -mode2, -xa, -xa1, -xa2 * New option --xa1-ignore * Emulation of some -minfo output * New -atip report lines "Product Id:" and "Producer:" * New API call burn_guess_cd_manufacturer() * New API calls burn_get_media_product_id() and burn_guess_manufacturer() * New API call burn_disc_get_cd_info() * New API call burn_track_set_cdxa_conv() 2009.10.12.103503 [2858] Makefile.am configure.ac README libburn/libburn.h cdrskin/cdrskin.c cdrskin/README cdrskin/compile_cdrskin.sh cdrskin/cdrskin_timestamp.h cdrskin/cdrskin_eng.html Made number transition to 0.7.3 12 Oct 2009 [2859] - cdrskin/add_ts_changes_to_libburn_0_7_0 - cdrskin/add_ts_changes_to_libburn_0_7_1 + cdrskin/add_ts_changes_to_libburn_0_7_2 + cdrskin/add_ts_changes_to_libburn_0_7_3 Updated cdrskin tarball generator 12 Oct 2009 [2860] cdrskin/changelog.txt Documented changes and release timestamp 12 Oct 2009 [2861] svn move -m "libburn release 0.7.2 is ready" \ http://svn.libburnia-project.org/libburn/branches/ZeroSevenTwo \ http://svn.libburnia-project.org/libburn/tags/ZeroSevenTwo ------------------------------------ cycle - cdrskin-0.7.3 - 2009.10.12.105750 2009.10.17.131852 [2865] [2864] Makefile.am libburn/libburn.h libburn/sector.c + libburn/ecma130ab.h + libburn/ecma130ab.c cdrskin/compile_cdrskin.sh Re-implemented ECMA-130 P-parity, Q-parity and scrambling for BURN_WRITE_RAW ------------------------------------ cycle - cdrskin-0.7.3 - * Re-implemented ECMA-130 P-parity, Q-parity and scrambling for BURN_WRITE_RAW 2009.10.19.115722 [2867] libburn/ecma130ab.c Optimizations with parity computation, clarification about nature of logarithms 2009.10.20.160131 [2868] libburn/libburn.h libburn/ecma130ab.c More optimizations with parity computation ------------------------------------ cycle - cdrskin-0.7.3 - 2009.10.20.160131 2009.10.27.100637 [2871] libburn/mmc.c Bug fix: burn_drive->disc_id or burn_drive->disc_app_code altered by stray 0. Thanks to George Danchev. 2009.10.27.101031 [2872] libburn/sg-freebsd.c Bug fix: Closed memory leak with failure to open device file under FreeBSD. Thanks to George Danchev. 2009.10.30.134640 [2880] libburn/libburn.h libburn/spc.c libburn/mmc.c libburn/sg-linux.c Test macros for finding reason of stall problem with Pioneer DVD-216D on DVD-R ------------------------------------ cycle - cdrskin-0.7.3 - 2009.10.30.134640 2009.11.03.184626 [2881] libburn/libburn.h libburn/mmc.c Test macro for SL_V in mode page 05 2009.11.04.084506 [2882] libburn/libburn.h libburn/write.c Test macro for SEND OPC INFORMATION before DVD-R track 2009.11.05.170409 [2883] libburn/libburn.h libburn/transport.h libburn/write.c libburn/sbc.c libburn/mmc.c Test macros for double START UNIT and SET CD SPEED 2009.11.08.120917 [2884] libburn/mmc.c Corrected allocation length with GET CONFIGURATION 2009.11.08.121334 [2885] libburn/spc.h libburn/spc.c libburn/mmc.h libburn/sg-linux.c Made SCSI command log more complete and more readable 2009.11.10.132154 [2886] libburn/mmc.c Avoiding START UNIT before the drive gets released 2009.11.10.203412 [2887] libburn/libburn.h libburn/write.c libburn/spc.c libburn/sbc.c libburn/mmc.c libburn/sg-linux.c Hopefully solved the endless burn problem with Pioneer DVR-216D 2009.11.11.100714 [2888] libburn/write.c Increased stdio flush interval from 1 MB to 16 MB 2009.11.11.100822 [2889] cdrskin/cdrskin.c Reporting number of pending bytes while thanking for patience in -vvv mode 2009.11.11.105028 [2890] cdrskin/cdrskin.c Silenced a compiler warning about potentially uninitialized variable ------------------------------------ cycle - cdrskin-0.7.3 - 2009.11.11.105159 * Workaround for Pioneer DVR-216D which got stuck on DVD-R burns 11 Nov 2009 [2891] cdrskin/cdrskin_eng.html Updated cdrskin home page about DVR-216D workaround 2009.11.12.175514 [2892] libburn/libburn.h libburn/init.c libburn/write.c libburn/sg-linux.c Made SCSI logger permanent and controllable via API call 2009.11.12.175735 [2893] libburn/spc.c libburn/sbc.c libburn/mmc.c Workaround for Pioneer DVR-216D refusal to eject 2009.11.12.180048 [2894] libburn/drive.c Macro Libburn_pioneer_dvr_216d_dummy_probe_wM for omitting write mode probe 2009.11.12.180241 [2895] cdrskin/cdrskin.c Implemented option -V for logging of SCSI commands 2009.11.12.193617 [2896] cdrskin/cdrskin.c cdrskin/cdrskin.1 Man page entry and help text for option -V ------------------------------------ cycle - cdrskin-0.7.3 - 2009.11.12.194644 * Implemented option -V for logging of SCSI commands * Workaround for Pioneer DVR-216D refusal to eject 13 Nov 2009 [2898] svn copy -m Branching for libburn bugfix release 0.7.2.pl01 \ http://svn.libburnia-project.org/libburn/tags/ZeroSevenTwo \ http://svn.libburnia-project.org/libburn/branches/ZeroSevenTwoPl01 2009.11.12.230001 [2899] README libburn/write.c libburn/sbc.c cdrskin/README cdrskin/cdrskin_eng.html cdrskin/cdrskin_timestamp.h libburn-0.7.2.pl01 : Workarounds for Pioneer DVR-216D rev 1.09 13 Nov 2009 [2900] svn move -m libburn bugfix release 0.7.2.pl01 is ready \ http://svn.libburnia-project.org/libburn/branches/ZeroSevenTwoPl01 \ http://svn.libburnia-project.org/libburn/tags/ZeroSevenTwoPl01 -------------------------------- patch - cdrskin-0.7.2.pl01 - 2009.11.12.230001 * Workaround for Pioneer DVR-216D which got stuck on DVD-R burns * Workaround for Pioneer DVR-216D refusal to eject 2009.11.15.115923 [2901] libburn/file.c Corrected an outdated remark 2009.11.15.152541 [2902] cdrskin/cdrskin.c cdrskin/cdrfifo.c cdrskin/compile_cdrskin.sh New compile_cdrskin.sh option -o_direct (Linux only) 2009.11.15.153140 [2903] libburn/libburn.h libburn/options.h libburn/options.c libburn/write.c New API calls burn_write_opts_set_dvd_obs(), burn_write_opts_set_stdio_fsync() 2009.11.15.165016 [2904] cdrskin/cdrskin.c cdrskin/cdrskin.1 New options dvd_obs= and stdio_fsync= 2009.11.16.165420 [2905] configure.ac Makefile.am libburn/write.c cdrskin/cdrskin.c cdrskin/cdrfifo.h cdrskin/cdrfifo.c cdrskin/cdrskin.1 Configure options --enable-cdrskin-fifo-odirect, --enable-dvd-obs-64k 16 Nov 2009 [2906] cdrskin/compile_cdrskin.sh New compile_cdrskin.sh option -dvd_obs_64k, adapted to new .o names of libburn 16 Nov 2009 [2907] README cdrskin/README cdrskin/cdrskin_eng.html Updated build instructions of libburn and cdrskin ------------------------------------ cycle - cdrskin-0.7.3 - 2009.11.16.180334 * New API calls burn_write_opts_set_dvd_obs(), burn_write_opts_set_stdio_fsync() * New options dvd_obs= and stdio_fsync= * Configure option --enable-dvd-obs-64k * New compile_cdrskin.sh option -dvd_obs_64k 2009.11.17.093602 [2908] configure.ac Makefile.am cdrskin/compile_cdrskin.sh Revoked usage of libburn_libburn_la_CFLAGS in Makefile.am (ugly .o names) ------------------------------------ cycle - cdrskin-0.7.3 - 2009.11.17.100248 17 Nov 2009 [2912] cdrskin/compile_cdrskin.sh Corrected help text of cdrskin static compile script 2009.11.18.122713 [2913] libburn/drive.c libburn/spc.c libburn/mmc.h libburn/mmc.c Split automatic drive start function from mmc_function_spy() 2009.11.18.185733 [2914] libburn/write.c Reserving enough track space for 64 kB write chunks ------------------------------------ cycle - cdrskin-0.7.3 - 2009.11.18.190403 2009.11.20.134952 [2915] libburn/libburn.h libburn/write.c libburn/sg-linux.c Experiment about SG_FLAG_DIRECT_IO 2009.11.20.175854 [2916] cdrskin/cdrfifo.c Avoided use of uninitialized variable ------------------------------------ cycle - cdrskin-0.7.3 - 2009.11.21.122202 2009.11.21.191516 [2917] libburn/write.c Longer READ BUFFER CAPACITY interval with DVD/BD writing 2009.11.21.191717 [2918] cdrskin/cdrskin.c Enabled cdrskin O_DIRECT with fs=0 2009.11.22.115227 [2919] libburn/write.c Bug fix: DVD DAO track size was rounded up much too generously 2009.11.23.185725 [2920] configure.ac Makefile.am README libburn/libburn.h libburn/file.h libburn/file.c libburn/async.c libburn/write.c libburn/sg-linux.c libburn/sg-freebsd.c libburn/sg-freebsd-port.c libburn/sg-dummy.c New API calls burn_os_open_track_src() , burn_os_alloc_buffer() 2009.11.23.193252 [2921] cdrskin/cdrskin.c cdrskin/cdrfifo.c cdrskin/compile_cdrskin.sh cdrskin/README Gave up cdrskin specific O_DIRECT compile option 2009.11.25.122233 [2920] libburn/libburn.h libburn/sg-linux.c libburn/sg-freebsd.c libburn/sg-freebsd-port.c libburn/sg-dummy.c Gave up call burn_os_close_track_src() introduced by rev 2920 2009.11.25.160153 [2923] libburn/libburn.h libburn/file.c libburn/libdax_msgs.h New API call burn_fifo_fill() 2009.11.26.144452 [2924] libburn/libburn.h libburn/file.h libburn/file.c New API calls burn_fifo_get_statistics(), burn_fifo_next_interval() 2009.11.26.211418 [2925] cdrskin/cdrskin.c cdrskin/compile_cdrskin.sh Compiler option -use_libburn_fifo to switch non-CD from cdrfifo to libburn fifo 2009.11.28.122436 [2926] libburn/sg-linux.c Using mmap() by default for allocating read buffers ------------------------------------ cycle - cdrskin-0.7.3 - 2009.11.28.165658 * Bug fix: DVD DAO track size was rounded up much too generously * New API call burn_fifo_fill() * New API calls burn_fifo_get_statistics(), burn_fifo_next_interval() * Configure option --enable-track-src-odirect 2009.11.30.100152 [2929] libburn/sbc.c Documented meaning of START/STOP UNIT bits 2009.12.02.103036 [2930] libburn/write.c Gave up CLOSE TRACK with CD TAO burn runs 2009.12.05.111822 [2931] libburn/mmc.c Bug fix: SIGSEGV with LG GH22LS30 when inquiring media product id ------------------------------------ cycle - cdrskin-0.7.3 - 2009.12.05.112623 * Bug fix: SIGSEGV from NULL pointer with media product id inquiry on LG GH22LS30 2009.12.05.142309 [2932] libburn/libburn.h libburn/write.c Made effect of macro Libburn_pioneer_dvr_216d_read_buf_caP unconditional 2009.12.05.143707 [2933] libburn/mmc.c libburn/sg-linux.c Converted stderr experiment messages to DEBUG messages 2009.12.06.073404 [2934] libburn/mmc.c Some clarifications about the GH22LS30 problem 2009.12.06.074622 [2935] libburn/write.c Some clarifications about the Linux throughput problem 2009.12.06.093847 [2936] cdrskin/compile_cdrskin.sh Now default in cdrskin: use of libburn fifo with DVD and BD single track 06 Dec 2009 [2937] svn copy -m Branching for libburn release 0.7.4 http://svn.libburnia-project.org/libburn/trunk http://svn.libburnia-project.org/libburn/branches/ZeroSevenFour 2009.12.06.160001 [2938] Makefile.am configure.ac README libburn/libburn.h cdrskin/cdrskin.c cdrskin/README cdrskin/compile_cdrskin.sh cdrskin/cdrskin_timestamp.h cdrskin/cdrskin_eng.html Made number transition to 0.7.4 06 Dec 2009 [2939] - cdrskin/add_ts_changes_to_libburn_0_7_2 - cdrskin/add_ts_changes_to_libburn_0_7_3 + cdrskin/add_ts_changes_to_libburn_0_7_4 + cdrskin/add_ts_changes_to_libburn_0_7_5 Updated cdrskin tarball generator 06 Dec 2009 [2940] cdrskin/changelog.txt Documented changes and release timestamp ------------------------------ release - cdrskin-0.7.4.pl00 - 2009.12.06.160001 * Configure options --enable-dvd-obs-64k, --enable-track-src-odirect * New API calls burn_write_opts_set_dvd_obs(), burn_write_opts_set_stdio_fsync() * New API call burn_set_scsi_logging() * New API calls burn_fifo_get_statistics(), burn_fifo_next_interval(), burn_fifo_fill() * Re-implemented ECMA-130 P-parity, Q-parity and scrambling for BURN_WRITE_RAW * Workaround for Pioneer DVR-216D which got stuck on DVD-R burns * Workaround for Pioneer DVR-216D refusal to eject * Bug fix: SIGSEGV from NULL pointer with media product id inquiry on LG GH22LS30 * Bug fix: DVD DAO track size was rounded up much too generously * cdrskin option -V for logging of SCSI commands * New cdrskin options dvd_obs= and stdio_fsync= * New compile_cdrskin.sh option -dvd_obs_64k 2009.12.07.070029 [2941] Makefile.am configure.ac README libburn/libburn.h cdrskin/cdrskin.c cdrskin/README cdrskin/compile_cdrskin.sh cdrskin/cdrskin_timestamp.h cdrskin/cdrskin_eng.html Made number transition to 0.7.5 07 Dec 2009 [2942] - cdrskin/add_ts_changes_to_libburn_0_7_2 - cdrskin/add_ts_changes_to_libburn_0_7_3 + cdrskin/add_ts_changes_to_libburn_0_7_4 + cdrskin/add_ts_changes_to_libburn_0_7_5 Updated cdrskin tarball generator 07 Dec 2009 [2943] cdrskin/changelog.txt Documented changes and release timestamp 07 Dec 2009 [2946] svn move -m libburn release 0.7.4 is ready http://svn.libburnia-project.org/libburn/branches/ZeroSevenFour http://svn.libburnia-project.org/libburn/tags/ZeroSevenFour ------------------------------------ cycle - cdrskin-0.7.5 - 2009.12.07.083850 16 Dec 2009 [2955] doc/cookbook.txt Mentioned in cookbook the change about TAO close track 2009.12.19.140015 [2957] libburn/spc.c Corrected CDB length of command 55h MODE SELECT from 12 to 10 2009.12.19.142456 [2958] libburn/spc.h libburn/sg-linux.c Moved sg_log_cmd() to spc.c scsi_log_cmd() 2009.12.19.142456 [2959] configure.ac Makefile.am libburn/os.h libburn/sg.c libburn/sg-freebsd-port.c + libburn/os-libcdio.h + libburn/sg-libcdio.c Experimental SCSI transport adapter via GNU libcdio 2009.12.24.170601 [2960] configure.ac libburn/spc.h libburn/spc.c libburn/sg-linux.c libburn/sg-libcdio.c Making use of libcdio function mmc_get_cmd_scsi_sense() 25 Dec 2009 [2961] cdrskin/compile_cdrskin.sh Option -use_libcdio for cdrskin development compile script 2009.12.25.101433 [2962] libburn/libdax_msgs.h Commited file forgotten with rev 2960 2009.12.25.143326 [2963] libburn/sg-libcdio.c Resolving symbolic links in libcdio drive list 2009.12.25.144122 [2964] configure.ac Added PKG_CHECK_MODULES for libcdio-0.82 (must become 0.83 when released) 2009.12.25.205704 [2965] configure.ac libburn/sg-libcdio.c Adapted to libcdio-0.83 and its runtime version telling 2009.12.25.223915 [2966] libburn/init.c libburn/sg.h libburn/sg-freebsd.c libburn/sg-freebsd-port.c libburn/sg-libcdio.c libburn/sg-linux.c New internal sg-API function sg_initialize() 2009.12.26.080301 [2967] libburn/init.c libburn/sg-dummy.c libburn/sg-freebsd.c libburn/sg-freebsd-port.c libburn/sg-libcdio.c libburn/sg-linux.c New API function burn_scsi_transport_id() 26 Dec 2009 [2968] Makefile.am Added os-dummy.h and sg-dummy.h to libburn tarball 26 Dec 2009 [2969] svn copy -m Branching for libburn bugfix release 0.7.4.pl01 http://svn.libburnia-project.org/libburn/tags/ZeroSevenTwo http://svn.libburnia-project.org/libburn/branches/ZeroSevenTwoPl01 26 Dec 2009 [2970] svn mv -m Branching for libburn bugfix release 0.7.4.pl01 http://svn.libburnia-project.org/libburn/branches/ZeroSevenTwoPl01 http://svn.libburnia-project.org/libburn/branches/ZeroSevenFourPl01 26 Dec 2009 [2971] svn rm -m Branching for libburn bugfix release 0.7.4.pl01 http://svn.libburnia-project.org/libburn/branches/ZeroSevenFourPl01 26 Dec 2009 [2972] svn copy -m Branching for libburn bugfix release 0.7.4.pl01 http://svn.libburnia-project.org/libburn/tags/ZeroSevenFour http://svn.libburnia-project.org/libburn/branches/ZeroSevenFourPl01 2009.12.26.110001 [2973] README Makefile.am cdrskin/cdrskin_timestamp.h Bug fix: Added missing system adapter for generic X/Open to libburn release tarball 26 Dec 2009 [2974] svn move -m libburn bugfix release 0.7.4.pl01 is ready http://svn.libburnia-project.org/libburn/branches/ZeroSevenFourPl01 http://svn.libburnia-project.org/libburn/tags/ZeroSevenFourPl01 2009.12.26.193707 [2975] cdrskin/cdrskin.c Reporting burn_scsi_transport_id() in cdrskin as debug message 2009.12.26.222656 [2976] libburn/libburn.h doc/comments Reacted on some doxygen warnings of Debian hurd build 2009.12.27.092057 [2979] libburn/os-libcdio.h libburn/sg-libcdio.c Showing libburn users drive name link targets, using in libcdio its own names 2009.12.27.102342 [2981] libburn/sg-libcdio.c Shorter sg_initialize message with sg-libcdio 2009.12.27.144620 [2982] libburn/init.c libburn/drive.c libburn/sg.h libburn/os-libcdio.h libburn/sg-dummy.c libburn/sg-freebsd.c libburn/sg-freebsd-port.c libburn/sg-libcdio.c libburn/sg-linux.c Extended sg-API by sg_shutdown(), sg_dispose_drive(), sg_id_string() 2009.12.27.144733 [2983] cdrskin/cdrskin.c Reporting system adapter id with cdrskin -version 2009.12.29.115717 [2984] configure.ac Incremented middle .so number 2009.12.29.115854 [2985] libburn/spc.c Corrected a mode page size computation error which for now had no bad effect 2009.12.29.132537 [2986] acinclude.m4 libburn/os.h libburn/sg.c Experimentally enabled FreeBSD system adapter for Debian kfreebsd ------------------------------------ cycle - cdrskin-0.7.5 - 2009.12.29.134637 * Experimental SCSI transport adapter via GNU libcdio * Experimentally using FreeBSD system adapter for Debian kfreebsd * Bug fix: System adapter for generic X/Open was missing in libburn release tarball 2009.12.29.224506 [2987] acinclude.m4 Adaptions for Debian kfreebsd requested by Petr Salinger 2009.12.30.154140 [2988] libburn/drive.c libburn/sg-libcdio.c Making use of new libcdio capability to obtain SCSI address tuple on Linux 2009.12.30.201025 [2990] libburn/sg-libcdio.c Silenced libcdio warnings 2010.01.01.124042 [2994] libburn/drive.c Bug fix: with non-Linux adapters there were 0 readable bytes on block devices 2010.01.01.124415 [2995] libburn/sg-libcdio.c Enabled block device size recognition with sg-libcdio on Linux ------------------------------------ cycle - cdrskin-0.7.5 - 2010.01.01.143104 * Bug fix: with non-Linux adapters there were 0 readable bytes on block devices 2010.01.04.134949 [3001] libburn/write.c libburn/libdax_msgs.h Avoiding stream recording on BD if not 64 kB buffer 2010.01.04.135427 [3002] libburn/os-libcdio.h Enlarged buffer size of libcdio adapter on Linux to 64k 2010.01.09.142027 [3004] libburn/sg-libcdio.c Forgot to forward sense reply to higher levels 2010.01.09.142642 [3005] libburn/spc.c Better error message with unknown SCSI error codes 2010.01.09.143428 [3006] libburn/spc.c libburn/sbc.c Revoked asynchronous eject, as we cannot distinguish out from unready 2010.01.12.165214 [3009] libburn/sg-dummy.c libburn/sg-freebsd-port.c libburn/sg-libcdio.c libburn/sg-linux.c Corrected free capacity measurement of stdio: drives in regular files 12 Jan 2010 [3010] doc/cookbook.txt Fixed typos in MMC cookbook 2010.01.13.074028 [3011] libburn/drive.c Experimentally regard FreeBSD /dev/da[0-9] and /dev/cd[0-9] as block device 2010.01.13.074640 [3012] libburn/sg-freebsd.c Adaptions after encounter with FreeBSD 8.0 2010.01.13.171546 [3013] libburn/libburn.h Carified that apps must use 64 bit off_t or the lib must be tweaked. 14 Jan 2010 [3014] 14 Jan 2010 [3015] test/libburner.c Carified in libburner.c that apps must use 64 bit off_t. 2010.01.14.160633 [3016] libburn/libburn.h libburn/drive.c Giving up drive probing by mode page sending 2010.01.14.160748 [3017] libburn/sg-libcdio.c Provisory rejection of FreeBSD ATAPI drives in sg-libcdio 2010.01.15.182615 [3018] libburn/os-freebsd.h libburn/sg-freebsd.c Implemented adivisory FreeBSD drive locking via flock(2) 2010.01.16.125258 [3019] libburn/drive.c libburn/sg.h libburn/sg-dummy.c libburn/sg-freebsd.c libburn/sg-freebsd-port.c libburn/sg-libcdio.c libburn/sg-linux.c New OS adapter burn_os_is_2k_seekrw() replaces S_ISBLK() with pseudo-drives 2010.01.18.103410 [3023] libburn/sg-linux.c Changed a comment in sg-linux.c ------------------------------------ cycle - cdrskin-0.7.5 - 2010.01.18.104011 * Made FreeBSD system adapter safe from mutal burn spoiling and drive deadlock 21 Jan 2010 [3028] cdrskin/cdrskin.1 Changed man page example from -toc to -minfo 2010.01.21.104741 [3029] libburn/sg-freebsd.c libburn/sg-libcdio.c Learned how to inquire size of disk-like FreeBSD devices 22 Jan 2010 [3030] svn copy -m "Branching for libburn release 0.7.6" \ http://svn.libburnia-project.org/libburn/trunk \ http://svn.libburnia-project.org/libburn/branches/ZeroSevenSix 2010.01.22.130001 [] Makefile.am configure.ac README libburn/libburn.h cdrskin/cdrskin.c cdrskin/README cdrskin/compile_cdrskin.sh cdrskin/cdrskin_timestamp.h cdrskin/cdrskin_eng.html Made number transition to 0.7.6 22 Jan 2010 [3032] COPYRIGHT cdrskin/cdrskin.c doc/cookbook.txt libburn/libdax_msgs.h libburn/libdax_msgs.c test/libburner.c test/telltoc.c Lifted ban to derive GPLv3, extended copyright range to 2010 22 Jan 2009 [3033] - cdrskin/add_ts_changes_to_libburn_0_7_4 - cdrskin/add_ts_changes_to_libburn_0_7_5 + cdrskin/add_ts_changes_to_libburn_0_7_6 + cdrskin/add_ts_changes_to_libburn_0_7_7 Updated cdrskin tarball generator 22 Jan 2009 [3034] cdrskin/changelog.txt Documented changes and release timestamp ------------------------------ release - cdrskin-0.7.6.pl00 - 2010.01.22.130001 * Bug fix: System adapter for generic X/Open was missing in libburn release tarball * Bug fix: with non-Linux adapters there were 0 readable bytes on block devices * Made FreeBSD system adapter safe from mutal burn spoiling and drive deadlock * Enabled FreeBSD system adapter for Debian kfreebsd * Experimental SCSI transport adapter via GNU libcdio 0.83git 2010.01.23.103338 [3035] Makefile.am configure.ac README libburn/libburn.h cdrskin/cdrskin.c cdrskin/README cdrskin/compile_cdrskin.sh cdrskin/cdrskin_timestamp.h cdrskin/cdrskin_eng.html Made number transition to 0.7.7 2010.01.23.104423 [3036] COPYRIGHT doc/cookbook.txt libburn/libdax_msgs.h libburn/libdax_msgs.c test/libburner.c test/telltoc.c Lifted ban to derive GPLv3, extended copyright range to 2010 23 Jan 2010 [3037] - cdrskin/add_ts_changes_to_libburn_0_7_4 - cdrskin/add_ts_changes_to_libburn_0_7_5 + cdrskin/add_ts_changes_to_libburn_0_7_6 + cdrskin/add_ts_changes_to_libburn_0_7_7 Updated cdrskin tarball generator ------------------------------------ cycle - cdrskin-0.7.7 - 2010.01.23.104423 23 Jan 2010 [3038] svn move -m 'libburn release 0.7.6 is ready' http://svn.libburnia-project.org/libburn/branches/ZeroSevenSix http://svn.libburnia-project.org/libburn/tags/ZeroSevenSix 2010.02.04.083315 [3054] acinclude.m4 configure.ac Forcing use of /usr/local on FreeBSD by LDFLAGS and CPPFLAGS 2010.02.12.173236 [3063] libburn/os-linux.h libburn/sg-linux.c Changed system adapter id and some remarks from "Linux" to "GNU/Linux" 2010.02.12.212818 [3064] libburn/libburn.h libburn/sg.c libburn/mmc.c libburn/drive.c libburn/init.c libburn/cleanup.c libburn/os-linux.h libburn/sg-linux.c libburn/write.c libburn/read.c libburn/sg-libcdio.c libburn/os-libcdio.h libburn/os.h libburn/toc.c Changed docs and comments to "GNU/Linux" where appropriate 2010.02.14.084452 [3066] libburn/sbc.c libburn/file.h libburn/os-libcdio.h libburn/os-dummy.h libburn/cleanup.h libburn/sector.h libburn/libiso_msgs.c libburn/async.c libburn/libdax_audioxtr.h libburn/ecma130ab.c libburn/back_hacks.h libburn/libdax_msgs.h libburn/drive.h libburn/read.c libburn/source.c libburn/util.h libburn/cleanup.c libburn/sg.c libburn/init.c libburn/write.c libburn/transport.h libburn/write.h libburn/libburn.h libburn/options.c libburn/mmc.h libburn/sg.h libburn/sbc.h libburn/sg-dummy.c libburn/ecma130ab.h libburn/null.c libburn/structure.c libburn/mmc.c libburn/spc.h libburn/drive.c libburn/sg-linux.c libburn/options.h libburn/os-linux.h libburn/sg-libcdio.c libburn/os-freebsd.h libburn/sg-freebsd-port.c libburn/sector.c libburn/debug.c libburn/util.c libburn/toc.h libburn/file.c libburn/libdax_audioxtr.c libburn/libdax_msgs.c libburn/toc.c libburn/sg-freebsd.c libburn/spc.c libburn/structure.h Added or adjusted copyright and license statements in single files 2010.02.14.171833 [3069] libburn/write.c libburn/read.c libburn/sector.c libburn/crc.h Created opportunity to omit source module libburn/crc.c 2010.02.15.125922 [3071] libburn/crc.h Changed a comment in libburn/crc.h 2010.02.16.194147 [3073] libburn/file.c Bug fix on FreeBSD: Piped input was falsely attributed a small fixed size 2010.02.17.141409 [3075] libburn/async.c libburn/drive.c libburn/write.c Avoided random percentage display at start of blanking 2010.02.22.134904 [3080] libburn/init.c Made burn_set_signal_handling() more suitable for cdrskin 2010.02.25.070635 [3090] libburn/write.c Corrected optional speed curb for stdio: drives. Was damaged by revision 2903. 2010.02.28.104003 [3091] cdrskin/cdrskin.c Added forgotten initialization of a variable 2010.02.28.110749 [3092] cdrskin/cdrskin.c Bug fix: cdrskin fs=0 lead to SIGSEGV. Regression introduced by revision 2936. 28 Feb 2010 [3093] cdrskin/cdrskin.1 Corrected spelling errors in cdrskin man page 2010.03.03.140639 [3096] libburn/drive.c Enabled patience 0 within burn_abort() 2010.03.03.141407 [3097] cdrskin/cdrskin.c cdrskin/cdrfifo.c Adapted cdrskin abort handler to FreeBSD peculiarities 3 Mar 2010 [3098] [3099] cdrskin/compile_cdrskin.sh Enabled static compile script compile_cdrskin.sh for FreeBSD 2010.03.04.121441 [3100] libburn/sg-linux.c Showing more patience with temporarily busy drives on Linux 2010.03.04.180102 [3101] cdrskin/cdrskin.c Changed burn_abort(0) to burn_abort(-1) 2010.03.05.090948 [3102] libburn/libburn.h libburn/transport.h libburn/drive.h libburn/drive.c libburn/init.h libburn/init.c libburn/async.c libburn/write.c libburn/sector.c libburn/libdax_msgs.h libburn/libdax_msgs.c Introduced alternative signal handling actions 2010.03.05.091432 [3103] cdrskin/cdrskin.c Enabled optional use of new signal action 2 with libburn built-in handler 2010.03.05.111712 [3104] libburn/init.c libburn/drive.h libburn/drive.c Removed some debugging printing ------------------------------------ cycle - cdrskin-0.7.7 - 2010.03.05.111954 Bug fix on FreeBSD: Piped input was falsely attributed a small fixed size Bug fix: cdrskin fs=0 led to SIGSEGV. Regression introduced by revision 2936. 2010.03.05.190110 [3105] libburn/async.c Protected blanker and formatter thread from signals 06 Mar 2010 [3106] test/libburner.c Adapted libburner to new advise about signal handling 07 Mar 2010 [3107] libburn/libburn.h test/libburner.c Changed examples burn_set_signal_handling(...,48) to (...,0x30) 2010.03.08.092608 [3108] libburn/libburn.h libburn/init.c Prevented potential memory fault with burn_set_signal_handling() 2010.03.09.140341 [3111] libburn/libburn.h Clarifications in API description of burn_set_signal_handling() 10 Mar 2010 [3112] svn copy -m "Branching for libburn release 0.7.8" \ http://svn.libburnia-project.org/libburn/trunk \ http://svn.libburnia-project.org/libburn/branches/ZeroSevenEight 2010.03.10.120001 [3113] Makefile.am configure.ac README libburn/libburn.h cdrskin/cdrskin.c cdrskin/README cdrskin/compile_cdrskin.sh cdrskin/cdrskin_timestamp.h cdrskin/cdrskin_eng.html Made number transition to 0.7.8 10 Mar 2010 [3114] - cdrskin/add_ts_changes_to_libburn_0_7_6 - cdrskin/add_ts_changes_to_libburn_0_7_7 + cdrskin/add_ts_changes_to_libburn_0_7_8 + cdrskin/add_ts_changes_to_libburn_0_7_9 Updated cdrskin tarball generator 10 Mar 2010 [3115] cdrskin/cdrskin.c Removed unused variable 10 Mar 2010 [3116] cdrskin/changelog.txt Documented changes and release timestamp ------------------------------ release - cdrskin-0.7.8.pl00 - 2010.03.10.120001 Bug fix on FreeBSD: Piped input was falsely attributed a small fixed size Bug fix: cdrskin fs=0 led to SIGSEGV. Regression introduced by version 0.7.4. 2010.03.10.134802 [3117] Makefile.am configure.ac README libburn/libburn.h cdrskin/cdrskin.c cdrskin/README cdrskin/compile_cdrskin.sh cdrskin/cdrskin_timestamp.h cdrskin/cdrskin_eng.html Made number transition to 0.7.9 10 Mar 2010 [3118] - cdrskin/add_ts_changes_to_libburn_0_7_6 - cdrskin/add_ts_changes_to_libburn_0_7_7 + cdrskin/add_ts_changes_to_libburn_0_7_8 + cdrskin/add_ts_changes_to_libburn_0_7_9 Updated cdrskin tarball generator 10 Mar 2010 [3119] cdrskin/changelog.txt Documented changes and release timestamp 10 Mar 2010 [3120] svn move -m 'libburn release 0.7.8 is ready' http://svn.libburnia-project.org/libburn/branches/ZeroSevenEight http://svn.libburnia-project.org/libburn/tags/ZeroSevenEight ------------------------------------ cycle - cdrskin-0.7.9 - 2010.03.10.143607 2010.03.17.185222 [3123] cdrskin/cdrskin.c Small bug fix about track size with cdrskin -minfo 17 Mar 2010 [3124] configure.ac Corrected initialization of configure option --enable-dvd-obs-64k 2010.03.25.113536 [3131] libburn/spc.c libburn/sg-freebsd.c Changed sg-freebsd.c to work with ahci, advise by Alexander Motin 2010.03.26.083158 [3132] libburn/sg-freebsd.c Had to make ahci change conditional for now: -DLibburn_for_freebsd_ahcI 2010.03.27.155659 [3133] libburn/mmc.c Avoiding to inquire NWA of unwritable media or states 2010.03.27.172644 [3134] libburn/os-freebsd.h libburn/sg-freebsd.c Trying to detect FreeBSD ahci devices and to handle others the old way ------------------------------------ cycle - cdrskin-0.7.9 - 2010.03.27.184614 * Now able to work with ahci driver of FreeBSD 8-STABLE 2010.03.29.103141 [3135] libburn/spc.c libburn/sg-linux.c libburn/sg-freebsd.c libburn/sg-libcdio.c Adjusted libcdio system adapter to FreeBSD peculiarities 2010.04.04.181237 [3146] test/libburner.c Let libburner warn programmers if they forget to set 64 bit off_t 2010.04.09.090645 [3155] libburn/sg-linux.c Reporting eventual SCSI sense in sg-linux repeat loop 9 Apr 2010 [3156] svn copy -m "Branching for libburn release 0.8.0" \ http://svn.libburnia-project.org/libburn/trunk \ http://svn.libburnia-project.org/libburn/branches/ZeroEightZero 2010.04.09.100001 [3157] Makefile.am configure.ac README libburn/libburn.h cdrskin/cdrskin.c cdrskin/README cdrskin/compile_cdrskin.sh cdrskin/cdrskin_timestamp.h cdrskin/cdrskin_eng.html Made number transition to 0.8.0 09 Apr 2010 [3158] - cdrskin/add_ts_changes_to_libburn_0_7_8 - cdrskin/add_ts_changes_to_libburn_0_7_9 + cdrskin/add_ts_changes_to_libburn_0_8_0 + cdrskin/add_ts_changes_to_libburn_0_8_1 Updated cdrskin tarball generator 09 Apr 2010 [3159] cdrskin/changelog.txt Documented changes and release timestamp ------------------------------ release - cdrskin-0.8.0.pl00 - 2010.04.09.100001 * Now able to work with ahci driver of FreeBSD 8-STABLE 2010.04.09.104907 [3160] Makefile.am configure.ac README libburn/libburn.h cdrskin/cdrskin.c cdrskin/README cdrskin/compile_cdrskin.sh cdrskin/cdrskin_timestamp.h cdrskin/cdrskin_eng.html Made number transition to 0.8.1 09 Apr 2010 [3161] - cdrskin/add_ts_changes_to_libburn_0_7_8 - cdrskin/add_ts_changes_to_libburn_0_7_9 + cdrskin/add_ts_changes_to_libburn_0_8_0 + cdrskin/add_ts_changes_to_libburn_0_8_1 Updated cdrskin tarball generator 09 Apr 2010 [3162] cdrskin/changelog.txt Documented changes and release timestamp 09 Apr 2009 [3163] svn move -m libburn release 0.8.0 is ready http://svn.libburnia-project.org/libburn/branches/ZeroEightZero http://svn.libburnia-project.org/libburn/tags/ZeroEightZero ------------------------------------ cycle - cdrskin-0.8.1 - 2010.04.09.110341 2010.04.30.180350 [3206] libburn/mmc.c Avoided to create track without toc_entry from "hidden first track" on CD ------------------------------------ cycle - cdrskin-0.8.1 - 2010.04.30.182846 * Bug fix: CD TOC was not read if the first track did not start at LBA 0 2010.05.01.082808 [3207] libburn/util.c libburn/mmc.c Bug fix: CD-ROM media got attributed random lead-in and lead-out adresses ------------------------------------ cycle - cdrskin-0.8.1 - 2010.05.01.083316 * Bug fix: CD-ROM media got attributed random lead-in and lead-out adresses 2010.05.16.090624 [3219] libburn/async.c libburn/cleanup.c libburn/crc.c libburn/ddlpa.c libburn/debug.c libburn/drive.c libburn/ecma130ab.c libburn/file.c libburn/init.c libburn/libdax_audioxtr.c libburn/libdax_msgs.c libburn/mmc.c libburn/null.c libburn/options.c libburn/read.c libburn/sbc.c libburn/sector.c libburn/sg.c libburn/sg-dummy.c libburn/sg-freebsd.c libburn/sg-freebsd-port.c libburn/sg-libcdio.c libburn/sg-linux.c libburn/source.c libburn/spc.c libburn/structure.c libburn/toc.c libburn/util.c libburn/write.c Eventually including ../config.h generated by autotools 2010.05.29.074318 [3237] libburn/sg-libcdio.c Bug fix: SIGSEGV of libcdio system adapter if drive list is empty 2010.06.07.171552 [3239] libburn/sg-libcdio.c Avoiding to resolve /dev/rdsk/cXtYdZs2 drive addresses on Solaris libcdio 2010.06.07.171706 [3240] libburn/init.c cdrskin/cdrskin.c Reacted on harmless compiler warnings on Solaris 2010.06.07.172925 [3241] README cdrskin/README Makefile.am libburn/os.h libburn/sg.c + libburn/os-solaris.h + libburn/sg-solaris.c libburn/libdax_msgs.h cdrskin/cdrskin_eng.html New system adapter for Solaris uscsi (tested on snv134, kernel 5.11) 2010.06.08.173156 [3244] libburn/os-solaris.h Corrected comment 2010.06.08.174946 [3245] libburn/sg-solaris.c Handled SCSI status "BUSY" on Solaris ------------------------------------ cycle - cdrskin-0.8.1 - 2010.06.08.175125 * Bug fix: SIGSEGV of libcdio system adapter if drive list is empty * New system adapter for Solaris uscsi (tested on snv134, kernel 5.11) 2010.06.08.200313 [3246] libburn/sg-libcdio.c libburn/sg-solaris.c Implemented block device capacity determination fo Solaris 2010.06.10.170901 [3247] libburn/sg-solaris.c Removed obsolete development remark 2010.06.10.171018 [3248] README cdrskin/README cdrskin/cdrskin.1 Mentioned Solaris and system dependent drive permission settings [] svn copy -m "Branching for libburn release 0.8.2" \ http://svn.libburnia-project.org/libburn/trunk \ http://svn.libburnia-project.org/libburn/branches/ZeroEightTwo 2010.06.11.080001 [3251] Makefile.am configure.ac README libburn/libburn.h cdrskin/cdrskin.c cdrskin/README cdrskin/compile_cdrskin.sh cdrskin/cdrskin_timestamp.h cdrskin/cdrskin_eng.html Made number transition to 0.8.2 11 Jun 2010 [3252] - cdrskin/add_ts_changes_to_libburn_0_8_0 - cdrskin/add_ts_changes_to_libburn_0_8_1 + cdrskin/add_ts_changes_to_libburn_0_8_2 + cdrskin/add_ts_changes_to_libburn_0_8_3 Updated cdrskin tarball generator 11 Jun 2010 [3253] cdrskin/changelog.txt Documented changes and release timestamp ------------------------------ release - cdrskin-0.8.2.pl00 - 2010.06.11.080001 * Bug fix: CD TOC was not read if the first track did not start at LBA 0 * Bug fix: CD-ROM media got attributed random lead-in and lead-out adresses * Bug fix: SIGSEGV of experimental libcdio system adapter if drive list is empty * New system adapter for Solaris uscsi (tested on snv134, kernel 5.11) 2010.06.11.104830 [3254] Makefile.am configure.ac README libburn/libburn.h cdrskin/cdrskin.c cdrskin/README cdrskin/compile_cdrskin.sh cdrskin/cdrskin_timestamp.h cdrskin/cdrskin_eng.html Made number transition to 0.8.3 11 Jun 2010 [3255] - cdrskin/add_ts_changes_to_libburn_0_8_0 - cdrskin/add_ts_changes_to_libburn_0_8_1 + cdrskin/add_ts_changes_to_libburn_0_8_2 + cdrskin/add_ts_changes_to_libburn_0_8_3 Updated cdrskin tarball generator 11 Jun 2010 [3256] cdrskin/changelog.txt Documented changes and release timestamp 11 Jun 2010 [3257] svn move -m libburn release 0.8.2 is ready http://svn.libburnia-project.org/libburn/branches/ZeroEightTwo http://svn.libburnia-project.org/libburn/tags/ZeroEightTwo ------------------------------------ cycle - cdrskin-0.8.3 - 2010.06.11.104830 2010.06.13.190707 [3267] libburn/sg-solaris.c New less obtrusive implementation of sg_is_enumerable_adr for Solaris 2010.06.15.155423 [3272] libburn/sg-libcdio.c Avoided compiler warning about unused variable on non-Solaris systems 2010.06.15.155625 [3273] libburn/os-dummy.h libburn/os-libcdio.h Let general POSIX system adapters ignore SIGWINCH and SIGURG if defined 2010.06.15.155739 [3274] configure.ac Incremented LT_CURRENT and LT_AGE of libburn 2010.06.16.082457 [3277] libburn/os-solaris.h libburn/os-libcdio.h libburn/os-freebsd.h Allowed 64 kB max output buffer size on all OSes 30 Jun 2010 [3307] svn copy -m "Branching for libburn release 0.8.4" \ http://svn.libburnia-project.org/libburn/trunk \ http://svn.libburnia-project.org/libburn/branches/ZeroEightFour 2010.06.30.100001 [3308] Makefile.am configure.ac README libburn/libburn.h cdrskin/cdrskin.c cdrskin/README cdrskin/compile_cdrskin.sh cdrskin/cdrskin_timestamp.h cdrskin/cdrskin_eng.html Made number transition to 0.8.4 30 Jun 2010 [3309] - cdrskin/add_ts_changes_to_libburn_0_8_2 - cdrskin/add_ts_changes_to_libburn_0_8_3 + cdrskin/add_ts_changes_to_libburn_0_8_4 + cdrskin/add_ts_changes_to_libburn_0_8_5 Updated cdrskin tarball generator 30 Jun 2010 [3310] cdrskin/changelog.txt Documented changes and release timestamp ------------------------------ release - cdrskin-0.8.4.pl00 - 2010.06.30.100001 * Let general POSIX system adapters ignore SIGWINCH and SIGURG if defined * Allowed 64 kB max output buffer size on all OSes 2010.06.30.112709 [3311] Makefile.am configure.ac README libburn/libburn.h cdrskin/cdrskin.c cdrskin/README cdrskin/compile_cdrskin.sh cdrskin/cdrskin_timestamp.h cdrskin/cdrskin_eng.html Made number transition to 0.8.5 30 Jun 2010 [3312] - cdrskin/add_ts_changes_to_libburn_0_8_2 - cdrskin/add_ts_changes_to_libburn_0_8_3 + cdrskin/add_ts_changes_to_libburn_0_8_4 + cdrskin/add_ts_changes_to_libburn_0_8_5 Updated cdrskin tarball generator 30 Jun 2010 [3313] cdrskin/changelog.txt Documented changes and release timestamp 30 Jun 2010 [3314] svn move -m libburn release 0.8.4 is ready \ http://svn.libburnia-project.org/libburn/branches/ZeroEightFour \ http://svn.libburnia-project.org/libburn/tags/ZeroEightFour ------------------------------------ cycle - cdrskin-0.8.5 - 2010.06.30.112709 2010.07.04.131219 [3323] libburn/libburn.h libburn/libdax_audioxtr.h libburn/libdax_audioxtr.c cdrskin/cdrskin.c test/dewav.c Moved public part of libdax_audioxtr.h to libburn.h 2010.07.04.170035 [3325] configure.ac Makefile.am + libburn/libburn.ver Hiding all non-API symbols from the linker by use of --version-script 04 Jul [3326] README Mentioned new configure option --disable-versioned-libs 2010.07.06.113304 [3329] configure.ac acinclude.m4 Let configure perform linker test with --version-script if enabled 2010.07.06.113356 [3330] libburn/libburn.h Mentioned that public API calls must be in libisofs/libisofs.ver 2010.07.12.193201 [3334] cdrskin/cdrskin.c cdrskin/cdrfifo.c Changed all malloc() to calloc() 2010.07.12.193644 [3335] libburn/async.c libburn/drive.c libburn/file.c libburn/libdax_audioxtr.c libburn/libdax_msgs.c libburn/mmc.c libburn/null.c libburn/options.c libburn/read.c libburn/sg-freebsd.c libburn/sg-freebsd-port.c libburn/util.c libburn/write.c Changed all malloc() to calloc() 2010.07.29.083453 [3336] libburn/spc.h libburn/spc.c libburn/mmc.c libburn/sg-freebsd.c libburn/sg-solaris.c libburn/sg-libcdio.c Recognizing sense data format 0x72 if given instead of 0x70 2010.07.29.164100 [3337] Makefile.am Detached make target "doc" from target "all". 30 Jul 2010 [3341] doc/doxygen.conf.in Removed problematic DETAILS_AT_TOP to silence warning of Debian buildd 2010.08.02.100630 [3345] libburn/spc.h libburn/spc.c libburn/sg-linux.c libburn/sg-freebsd.c libburn/sg-libcdio.c Reporting sense data with burn_set_scsi_logging() 2010.08.02.131946 [3346] libburn/sg-linux.c Added error simulation code to Linux system adapter 2010.08.02.141233 [3347] libburn/sg-solaris.c Committed Solaris system adapter which was forgotten with rev 3345 ------------------------------------ cycle - cdrskin-0.8.5 - 2010.08.02.141233 * Hiding all non-API symbols from the linker by use of --version-script 2010.08.03.191151 [3348] libburn/sg-linux.c libburn/sg-freebsd.c libburn/sg-libcdio.c libburn/sg-solaris.c Obeying burn_set_scsi_logging() with errors of class RETRY 2010.08.08.091224 [3349] libburn/spc.h libburn/spc.c libburn/sg-linux.c libburn/sg-freebsd.c libburn/sg-libcdio.c libburn/sg-solaris.c New SCSI comand response "GO_ON" 2010.08.08.091317 [3350] libburn/libburn.h Hopefully silenced a warning of doxygen on Debian buildd 2010.08.13.114139 [3352] libburn/libdax_msgs.h libburn/libdax_audioxtr.h Corrected typo in macro names (which shall never be defined anyway) 2010.08.21.095456 [3356] libburn/libburn.h libburn/mmc.c cdrskin/cdrskin.1 cdrskin/cdrskin_eng.html Lifted test reservation on DVD-R DL media. Thanks to Kevin Kieffer for testing. 28 Aug 2010 [3358] test/libburner.c Clarified the meaning of 0x0 and 0x30 signal handlers 2010.09.14.124934 [3368] libburn/spc.h libburn/spc.c libburn/sg-linux.c libburn/sg-libcdio.c libburn/sg-freebsd.c libburn/sg-solaris.c Centralized interpretation of SCSI command outcome ------------------------------------ cycle - cdrskin-0.8.5 - 2010.09.14.135405 * Lifted test reservation on DVD-R DL media. 15 Sep 2010 [3369] ChangeLog Meaningful change log file derived by George Danchev from web site 16 Sep 2010 [3373] svn copy -m Branching for libburn release 0.8.6 http://svn.libburnia-project.org/libburn/trunk http://svn.libburnia-project.org/libburn/branches/ZeroEightSix 2010.09.16.113001 [3374] Makefile.am configure.ac README libburn/libburn.h cdrskin/cdrskin.c cdrskin/README cdrskin/compile_cdrskin.sh cdrskin/cdrskin_timestamp.h cdrskin/cdrskin_eng.html Made number transition to 0.8.6 16 Sep 2010 [3375] - cdrskin/add_ts_changes_to_libburn_0_8_4 - cdrskin/add_ts_changes_to_libburn_0_8_5 + cdrskin/add_ts_changes_to_libburn_0_8_6 + cdrskin/add_ts_changes_to_libburn_0_8_7 Updated cdrskin tarball generator 16 Sep 2010 [3376] ChangeLog cdrskin/changelog.txt Documented changes and release timestamp ------------------------------ release - cdrskin-0.8.6.pl00 - 2010.09.16.113001 * Lifted test reservation on DVD-R DL media. * Hiding all non-API symbols from the linker by use of --version-script 2010.09.17.073827 [3377] Makefile.am configure.ac README libburn/libburn.h cdrskin/cdrskin.c cdrskin/README cdrskin/compile_cdrskin.sh cdrskin/cdrskin_timestamp.h cdrskin/cdrskin_eng.html Made number transition to 0.8.7 17 Sep 2010 [3378] - cdrskin/add_ts_changes_to_libburn_0_8_4 - cdrskin/add_ts_changes_to_libburn_0_8_5 + cdrskin/add_ts_changes_to_libburn_0_8_6 + cdrskin/add_ts_changes_to_libburn_0_8_7 Updated cdrskin tarball generator 17 Sep 2010 [3379] ChangeLog cdrskin/changelog.txt Documented changes and release timestamp 17 Sep 2010 [3381] svn move -m libburn release 0.8.6 is ready http://svn.libburnia-project.org/libburn/branches/ZeroEightSix http://svn.libburnia-project.org/libburn/tags/ZeroEightSix ------------------------------------ cycle - cdrskin-0.8.7 - 2010.09.17.082926 2010.09.22.105426 [3395] acinclude.m4 configure.ac Makefile.am README On Linux: Run ldconfig during make install,if not --disable-ldconfig-at-install 2010.09.22.175054 [3397] libburn/libburn.h libburn/libburn.ver libburn/libdax_msgs.h libburn/file.h libburn/file.c libburn/source.h libburn/source.c New API call burn_offst_source_new() 2010.09.22.180921 [3398] Makefile.am + test/offst_source.c Temporarily added test program for burn_offst_source_new() 22 Sep 2010 [3399] test/offst_source.c Better default input file for test/offst_source.c 2010.09.24.090631 [3401] libburn/libburn.h libburn/drive.c libburn/mmc.h libburn/mmc.c ChangeLog New API call burn_disc_get_bd_spare_info() 2010.09.24.090731 [3402] cdrskin/cdrskin.c Displaying eventual BD spare area information with -minfo 2010.09.24.091902 [3403] cdrskin/cdrskin.c Displaying eventual BD spare area information with --list_formats 2010.09.24.092535 [3404] libburn/libburn.ver Making new API call available in dynamic library 2010.09.24.100255 [3405] cdrskin/cdrskin.c Polished appearance of BD spare info with --list_formats ------------------------------------ cycle - cdrskin-0.8.7 - 2010.09.24.100255 * New API call burn_offst_source_new() * New API call burn_disc_get_bd_spare_info() 2010.09.28.101043 [3408] libburn/mmc.c Avoiding to inquire spare area of unsuitable media 2010.10.15.191717 [3445] libburn/write.c libburn/libdax_msgs.h Issue warning after writing a BD-R with more than 300 sessions 2010.10.19.165908 [3450] libburn/async.c libburn/write.c libburn/libdax_msgs.h Issueing messages with all cases of burn canceling 20 Oct 2010 [3453] svn copy -m Branching for libburn release 0.8.8 http://svn.libburnia-project.org/libburn/trunk http://svn.libburnia-project.org/libburn/branches/ZeroEightEight 2010.10.20.120001 [3454] Makefile.am configure.ac README libburn/libburn.h cdrskin/cdrskin.c cdrskin/README cdrskin/compile_cdrskin.sh cdrskin/cdrskin_timestamp.h cdrskin/cdrskin_eng.html Made number transition to 0.8.8 20 Oct 2010 [3455] - cdrskin/add_ts_changes_to_libburn_0_8_6 - cdrskin/add_ts_changes_to_libburn_0_8_7 + cdrskin/add_ts_changes_to_libburn_0_8_8 + cdrskin/add_ts_changes_to_libburn_0_8_9 Updated cdrskin tarball generator 20 Oct 2010 [3456] ChangeLog cdrskin/changelog.txt Documented changes and release timestamp ------------------------------ release - cdrskin-0.8.8.pl00 - 2010.10.20.120001 * New API call burn_offst_source_new() * New API call burn_disc_get_bd_spare_info() 2010.10.20.125207 [3457] Makefile.am configure.ac README libburn/libburn.h cdrskin/cdrskin.c cdrskin/README cdrskin/compile_cdrskin.sh cdrskin/cdrskin_timestamp.h cdrskin/cdrskin_eng.html Made number transition to 0.8.9 20 Oct 2010 [3458] - cdrskin/add_ts_changes_to_libburn_0_8_6 - cdrskin/add_ts_changes_to_libburn_0_8_7 + cdrskin/add_ts_changes_to_libburn_0_8_8 + cdrskin/add_ts_changes_to_libburn_0_8_9 Updated cdrskin tarball generator 20 Oct 2010 [3459] ChangeLog cdrskin/changelog.txt Documented changes and release timestamp 20 Oct 2010 svn move -m libburn release 0.8.8 is ready http://svn.libburnia-project.org/libburn/branches/ZeroEightEight http://svn.libburnia-project.org/libburn/tags/ZeroEightEight ------------------------------------ cycle - cdrskin-0.8.9 - 2010.10.20.134102 2010.10.29.164059 [3474] libburn/mmc.c libburn/libdax_msgs.h Issueing error messages if cache syncing or closing fails 2010.10.29.174455 [3476] libburn/spc.c Regression fix: SCSI reply data logging was disabled in rev 3368, 0.8.6 2010.11.16.131221 [3483] libburn/sg-linux.c libburn/sg-freebsd.c libburn/sg-libcdio.c libburn/sg-solaris.c Removed outdated development macros 08 Dec 2010 [3502] svn copy -m Branching for libburn release 0.9.0 http://svn.libburnia-project.org/libburn/trunk http://svn.libburnia-project.org/libburn/branches/ZeroNineZero 2010.12.08.133001 [3503] Makefile.am configure.ac README libburn/libburn.h cdrskin/cdrskin.c cdrskin/README cdrskin/compile_cdrskin.sh cdrskin/cdrskin_timestamp.h cdrskin/cdrskin_eng.html Made number transition to 0.9.0 08 Dec 2010 [3504] - cdrskin/add_ts_changes_to_libburn_0_8_8 - cdrskin/add_ts_changes_to_lisburn_0_8_9 + cdrskin/add_ts_changes_to_libburn_0_9_0 + cdrskin/add_ts_changes_to_libburn_0_9_1 Updated cdrskin tarball generator 08 Dec 2010 [3505] ChangeLog cdrskin/changelog.txt Documented changes and release timestamp ------------------------------ release - cdrskin-0.9.0.pl00 - 2010.12.08.133001 Regression fix: SCSI reply data logging was disabled in release 0.8.6 2010.12.08.131934 [3506] Makefile.am configure.ac README libburn/libburn.h cdrskin/cdrskin.c cdrskin/README cdrskin/compile_cdrskin.sh cdrskin/cdrskin_timestamp.h cdrskin/cdrskin_eng.html Made number transition to 0.9.1 08 Dec 2010 [3507] - cdrskin/add_ts_changes_to_libburn_0_8_8 - cdrskin/add_ts_changes_to_lisburn_0_8_9 + cdrskin/add_ts_changes_to_libburn_0_9_0 + cdrskin/add_ts_changes_to_libburn_0_9_1 Updated cdrskin tarball generator 08 Dec 2010 [3508] ChangeLog cdrskin/changelog.txt Documented changes and release timestamp 08 Dec 2010 [3509] svn move -m libburn release 0.9.0 is ready http://svn.libburnia-project.org/libburn/branches/ZeroNineZero http://svn.libburnia-project.org/libburn/tags/ZeroNineZero ------------------------------------ cycle - cdrskin-0.9.1 - 2010.12.08.154833 2010.12.13.075956 [3522] configure.ac Prepending ./configure generated options to CFLAGS rather than appending them 23 Dec 2010 [3528] doc/comments Updated API introduction 2010.12.28.071904 [3537] libburn/write.c Allowed umask to create stdio-drive files with rw-permissions for all 2011.01.03.195125 [3542] libburn/write.c libburn/sector.c libburn/structure.h libburn/structure.c Allowed stdio tracks of known size to end in TAO mode on premature EOF 2011.01.09.135915 [3546] cdrskin/cdrskin.c cdrskin/cdrskin.1 Refusing to burn if foreseeable size exceeds media capacity ------------------------------------ cycle - cdrskin-0.9.1 - 2011.01.09.140240 * Allowed umask to create stdio-drive files with rw-permissions for all * cdrskin now refuses to burn if the foreseeable size exceeds media capacity 09 Jan 2011 [3547] cdrskin/cdrskin_eng.html ChangeLog Updated change log and web page 16 Jan 2011 [3548] svn copy -m "Branching for libburn release 1.0.0" \ http://svn.libburnia-project.org/libburn/trunk \ http://svn.libburnia-project.org/libburn/1.0.0" 2011.01.16.123001 [3549] [3550] Makefile.am configure.ac README libburn/libburn.h cdrskin/cdrskin.c cdrskin/README cdrskin/compile_cdrskin.sh cdrskin/cdrskin_timestamp.h cdrskin/cdrskin_eng.html Made number transition to 1.0.0 16 Jan 2011 [3551] - cdrskin/add_ts_changes_to_libburn_0_9_0 - cdrskin/add_ts_changes_to_libburn_0_9_1 + cdrskin/add_ts_changes_to_libburn_1_0_0 + cdrskin/add_ts_changes_to_libburn_1_0_1 Updated cdrskin tarball generator 16 Jan 2011 [3552] ChangeLog cdrskin/changelog.txt Documented changes and release timestamp ------------------------------ release - cdrskin-1.0.0.pl00 - 2011.01.16.123001 * Allowed umask to create stdio-drive files with rw-permissions for all * cdrskin now refuses to burn if the foreseeable size exceeds media capacity 2011.01.16.140456 [3553] Makefile.am configure.ac README libburn/libburn.h cdrskin/cdrskin.c cdrskin/README cdrskin/compile_cdrskin.sh cdrskin/cdrskin_timestamp.h cdrskin/cdrskin_eng.html Made number transition to 1.0.1 16 Jan 2011 [3554] - cdrskin/add_ts_changes_to_libburn_0_9_0 - cdrskin/add_ts_changes_to_libburn_0_9_1 + cdrskin/add_ts_changes_to_libburn_1_0_0 + cdrskin/add_ts_changes_to_libburn_1_0_1 Updated cdrskin tarball generator 16 Jan 2011 [3555] ChangeLog cdrskin/changelog.txt Documented changes and release timestamp 16 Jan 2011 [3556] svn move -m "libburn release 1.0.0 is ready" \ http://svn.libburnia-project.org/libburn/branches/1.0.0 \ http://svn.libburnia-project.org/libburn/tags/1.0.0 ------------------------------------ cycle - cdrskin-1.0.1 - 2011.01.16.152923 2011.01.18.162859 [3570] libburn/file.c Using usleep() instead of nanosleep() which is not available on Solaris 9 2011.02.09.114311 [3586] libburn/write.c libburn/drive.c Forced role 3 on drives which stem from open file descriptors without O_RDWR 2011.02.14.085951 [3589] libburn/drive.c Reacted on compiler warnings about uninitialized variables 2011.02.18.165542 [3592] libburn/drive.c libburn/sector.c DEBUG message with burn_drive_cancel, FAILURE with premature end-of-input 23 Feb 2011 [3604] svn copy -m Branching for libburn release 1.0.2 http://svn.libburnia-project.org/libburn/trunk http://svn.libburnia-project.org/libburn/branches/1.0.2 2011.02.23.130001 [3605] Makefile.am configure.ac README libburn/libburn.h cdrskin/cdrskin.c cdrskin/README cdrskin/compile_cdrskin.sh cdrskin/cdrskin_timestamp.h cdrskin/cdrskin_eng.html Made number transition to 1.0.2 23 Feb 2011 [3606] - cdrskin/add_ts_changes_to_libburn_1_0_0 - cdrskin/add_ts_changes_to_libburn_1_0_1 + cdrskin/add_ts_changes_to_libburn_1_0_2 + cdrskin/add_ts_changes_to_libburn_1_0_3 Updated cdrskin tarball generator 23 Feb 2011 [3607] ChangeLog cdrskin/changelog.txt Documented changes and release timestamp ------------------------------ release - cdrskin-1.0.2.pl00 - 2011.02.23.130001 * Removed compilation obstacles on Solaris 9. * Improved recognition of non-seekable stdio pseudo-drives. 2011.02.23.193502 [3611] Makefile.am configure.ac README libburn/libburn.h cdrskin/cdrskin.c cdrskin/README cdrskin/compile_cdrskin.sh cdrskin/cdrskin_timestamp.h cdrskin/cdrskin_eng.html Made number transition to 1.0.3 23 Feb 2011 [3612] - cdrskin/add_ts_changes_to_libburn_1_0_0 - cdrskin/add_ts_changes_to_libburn_1_0_1 + cdrskin/add_ts_changes_to_libburn_1_0_2 + cdrskin/add_ts_changes_to_libburn_1_0_3 Updated cdrskin tarball generator 23 Feb 2011 [3613] ChangeLog cdrskin/changelog.txt Documented changes and release timestamp ------------------------------------ cycle - cdrskin-1.0.3 - 2011.02.23.193502 23 Feb 2011 [3614] svn move -m libburn release 1.0.2 is ready http://svn.libburnia-project.org/libburn/branches/1.0.2 http://svn.libburnia-project.org/libburn/tags/1.0.2 2011.02.23.195650 [3615] libburn/libdax_msgs.h Registered new error code 2011.02.24.191718 [3619] libburn/async.c Corrected a flaw found by George Danchev with cpp 2011.03.01.144625 [3625] libburn/drive.c Bug fix: Read-only file descriptors were classified as write-only pseudo drives svn copy -m Branching for libburn release 1.0.4 http://svn.libburnia-project.org/libburn/trunk http://svn.libburnia-project.org/libburn/branches/1.0.4 2011.03.10.080001 [3651] Makefile.am configure.ac README libburn/libburn.h cdrskin/cdrskin.c cdrskin/README cdrskin/compile_cdrskin.sh cdrskin/cdrskin_timestamp.h cdrskin/cdrskin_eng.html Made number transition to 1.0.4 10 Mar 2011 [3652] - cdrskin/add_ts_changes_to_libburn_1_0_2 - cdrskin/add_ts_changes_to_libburn_1_0_3 + cdrskin/add_ts_changes_to_libburn_1_0_4 + cdrskin/add_ts_changes_to_libburn_1_0_5 Updated cdrskin tarball generator 10 Mar 2011 [3653] ChangeLog cdrskin/changelog.txt Documented changes and release timestamp ------------------------------ release - cdrskin-1.0.4.pl00 - 2011.03.10.080001 * Bug fix: Read-only file descriptors were classified as write-only pseudo drives 2011.03.10.132603 [3657] Makefile.am configure.ac README libburn/libburn.h cdrskin/cdrskin.c cdrskin/README cdrskin/compile_cdrskin.sh cdrskin/cdrskin_timestamp.h cdrskin/cdrskin_eng.html Made number transition to 1.0.5 10 Mar 2011 [3659] - cdrskin/add_ts_changes_to_libburn_1_0_2 - cdrskin/add_ts_changes_to_libburn_1_0_3 + cdrskin/add_ts_changes_to_libburn_1_0_4 + cdrskin/add_ts_changes_to_libburn_1_0_5 Updated cdrskin tarball generator 10 Mar 2011 [3660] ChangeLog cdrskin/changelog.txt Documented changes and release timestamp 10 Mar 2011 [3658] svn move -m libburn release 1.0.4 is ready http://svn.libburnia-project.org/libburn/branches/1.0.4 http://svn.libburnia-project.org/libburn/tags/1.0.4 ------------------------------------ cycle - cdrskin-1.0.5 - 2011.03.10.132603 12 Mar 2011 [3664] COPYRIGHT Updated copyright year 2011.03.12.093520 [3665] libburn/write.c libburn/mmc.c Burning DVD-R DAO with 2 kB size granularity rather than 32 kB 2011.03.13.130746 [3666] libburn/libburn.h libburn/init.c libburn/drive.c libburn/async.c libburn/write.c libburn/libdax_msgs.h libburn/libburn.ver New API call burn_allow_drive_role_4() 2011.03.13.130850 [3667] cdrskin/cdrskin.c Using burn_allow_drive_role_4() in cdrskin 2011.03.13.192627 [3671] libburn/read.c libburn/libdax_msgs.h Changed severity of "Read attempt on write-only drive" from FATAL to FAILURE 2011.03.18.093128 [3672] cdrskin/cdrskin.c Prepared cdrskin for drive role 5 2011.03.18.093410 [3673] libburn/transport.h libburn/drive.c libburn/async.c libburn/write.c libburn/read.c libburn/libdax_msgs.h Provisory introduction of drive role 5, random access write-only 2011.03.18.153326 [3674] libburn/async.c libburn/mmc.c Enabled BD formatting by index on Pioneer BDR-205 which offers no Cert or QCert 2011.03.19.222152 [3675] libburn/sector.c Silenced an error message with input that is not aligned to 2 kB 2011.03.21.090313 [3676] libburn/drive.c Corrected nwa computation for drive role 5 2011.03.21.090430 [3677] libburn/write.c Adjustments for drive role 5, random access write-only 2011.03.21.092220 [3678] libburn/async.c Enabled blanking of drive with role 5 2011.03.22.085956 [3685] libburn/libburn.h libburn/init.c libburn/drive.c Avoiding appendable role 5 if not explicitely enabled 2011.03.24.182148 [3687] libburn/libburn.h libburn/read.c libburn/libdax_msgs.h Better handling of read attempt on pseudo-drive without read-permission 8 Apr 2011 [3712] svn copy -m Branching for libburn release 1.0.6 http://svn.libburnia-project.org/libburn/trunk http://svn.libburnia-project.org/libburn/branches/1.0.6 2011.04.08.180001 [3713] Makefile.am configure.ac README libburn/libburn.h cdrskin/cdrskin.c cdrskin/README cdrskin/compile_cdrskin.sh cdrskin/cdrskin_timestamp.h cdrskin/cdrskin_eng.html Made number transition to 1.0.6 08 Apr 2011 [3714] - cdrskin/add_ts_changes_to_libburn_1_0_4 - cdrskin/add_ts_changes_to_libburn_1_0_5 + cdrskin/add_ts_changes_to_libburn_1_0_6 + cdrskin/add_ts_changes_to_libburn_1_0_7 Updated cdrskin tarball generator 08 Apr 2011 [3715] ChangeLog cdrskin/changelog.txt Documented changes and release timestamp ------------------------------ release - cdrskin-1.0.6.pl00 - 2011.04.08.180001 * Burning DVD-R DAO with 2 kB size granularity rather than 32 kB * New API call burn_allow_drive_role_4() 2011.04.09.090001 [3719] Makefile.am configure.ac README libburn/libburn.h cdrskin/cdrskin.c cdrskin/README cdrskin/compile_cdrskin.sh cdrskin/cdrskin_timestamp.h cdrskin/cdrskin_eng.html Made number transition to 1.0.7 09 Apr 2011 [3720] - cdrskin/add_ts_changes_to_libburn_1_0_4 - cdrskin/add_ts_changes_to_libburn_1_0_5 + cdrskin/add_ts_changes_to_libburn_1_0_6 + cdrskin/add_ts_changes_to_libburn_1_0_7 Updated cdrskin tarball generator 09 Apr 2011 [3721] ChangeLog cdrskin/changelog.txt Documented changes and release timestamp 09 Apr 2011 [3722] svn move -m libburn release 1.0.6 is ready http://svn.libburnia-project.org/libburn/branches/1.0.6 http://svn.libburnia-project.org/libburn/tags/1.0.6 ------------------------------------ cycle - cdrskin-1.0.7 - 2011.04.09.090001 15 Apr 2011 [3735] doc/doxygen.conf.in Disabled HAVE_DOT in doxygen.conf 2011.05.01.144546 [3743] libburn/init.c Closed tiny memory leak found by valgrind 2011.05.12.120503 [3791] libburn/drive.h Including header pthread.h on request of Mats Andersson for OpenBSD 2011.05.12.134723 [3792] libburn/init.c libburn/drive.c libburn/structure.c libburn/mmc.c libburn/sg-linux.c Reacted on -Wsign-compare warnings of gcc 2011.05.12.135008 [3793] cdrskin/cdrskin.c Reacted on -Wsign-compare warnings of gcc 2011.05.12.135116 [3794] test/libburner.c Reacted on -Wsign-compare warnings of gcc 2011.05.12.135217 [3795] test/telltoc. Reacted on -Wsign-compare warnings of gcc 12 May 2011 [3796] test/poll.c Reacted on -Wsign-compare warnings of gcc 14 May 2011 [3803] Makefile.am doc/cookbook.txt doc/mediainfo.txt Added cookbook.txt and mediainfo.txt to tarball on request of George Danchev 2011.05.15.104727 [3804] libburn/init.h Macros BURN_ALLOC_MEM, BURN_FREE_MEM for replaceing local variables 2011.05.15.104926 [3805] libburn/async.c Replaced some large local variables by other means in libburn/async.c 2011.05.15.181724 [3806] libburn/init.h Polished macro BURN_ALLOC_MEM 2011.05.15.191420 [3807] libburn/drive.c Replaced some large local variables by other means in libburn/drive.c 2011.05.15.203140 [3808] libburn/init.h libburn/async.c Added forgotten return value to BURN_ALLOC_MEM 22 May 2011 [3830] doc/mediainfo.txt Added a DVD+RW product id to the list 22 May 2011 [3831] configure.ac Added options -Wextra -Wno-unused-parameter for gcc 2011.05.23.154011 [3834] libburn/mmc.c Replaced some large local variables by other means in libburn/mmc.c 2011.05.23.155217 [3835] libburn/read.c Replaced some large local variables by other means in libburn/read.c 2011.05.23.163506 [3836] libburn/sg-dummy.c Replaced some large local variables by other means in libburn/sg-dummy.c 2011.05.23.174016 [3837] libburn/sg-freebsd.c Replaced some large local variables by other means in libburn/sg-freebsd.c 2011.05.23.182627 [3838] libburn/sg-freebsd-port.c Replaced some large local variables by other means in libburn/sg-freebsd-port.c 2011.05.26.145626 [3839] libburn/transport.h libburn/libdax_msgs.h libburn/mmc.c Improved reaction on Damage Bit and missing NWA_V of READ TRACK INFORMATION 2011.05.26.150020 [3840] libburn/libburn.h libburn/drive.c libburn/libburn.ver New API call burn_disc_next_track_is_damaged() 2011.05.31.103124 [3846] libburn/write.h libburn/write.c libburn/libdax_msgs.h libburn/libburn.ver New API call burn_disc_close_damaged() 2011.06.02.083808 [3848] libburn/sg-freebsd.c libburn/sg-freebsd-port.c Gave up use of bzero() in FreeBSD system adapters 2011.06.02.132554 [3849] libburn/sg-libcdio.c Replaced some large local variables by other means in libburn/sg-libcdio.c 2011.06.05.170431 [3850] libburn/sg-linux.c Replaced some large local variables by other means in libburn/sg-linux.c 2011.06.06.104404 [3851] libburn/sg-solaris.c Replaced some large local variables by other means in libburn/sg-solaris.c 2011.06.06.105052 [3852] libburn/sg-solaris.c Reacted on warnings of gcc about mixed sign comparison 2011.06.06.173021 [3853] libburn/spc.c Replaced some large local variables by other means in libburn/spc.c 2011.06.06.173611 [3854] libburn/init.h libburn/init.c Leaner implementation of macro BURN_ALLOC_MEM 2011.06.07.084343 [3855] libburn/write.c Closed a small memory leak with CD SAO found by valgrind 2011.06.07.143930 [3856] libburn/transport.h libburn/spc.c libburn/sbc.c libburn/mmc.c Consolidated several local struct command to a new member of struct burn_drive 2011.06.08.081338 [3858] libburn/structure.c Replaced some large local variables by other means in libburn/structure.c 2011.06.08.082201 [3859] libburn/toc.c Replaced some large local variables by other means in libburn/toc.c 2011.06.08.181204 [3860] libburn/mmc.c Bug fix: burn_disc_format() on DVD-RW issued wrong block size with type 00h 08 Jun 2011 [3861] configure.ac Makefile.am Introduced AC_CONFIG_MACRO_DIR() and ACLOCAL_AMFLAGS on advise of George Danchev 2011.06.08.200329 [3863] libburn/write.c Replaced some large local variables by other means in libburn/write.c 09 Jun 2011 [3864] bootstrap Added option -I . to aclocal in bootstrap script on advise of George Danchev 2011.06.14.152832 [3866] libburn/spc.c libburn/mmc.c Reporting SCSI error if command RESERVE TRACK fails Release 1.0.8 was skipped to get back in sync with libisofs and libisoburn. 18 Jun 2011 [3868] svn copy -m Branching for libburn release 1.1.0 http://svn.libburnia-project.org/libburn/trunk http://svn.libburnia-project.org/libburn/branches/1.1.1 2011.06.18.100001 [3869] Makefile.am configure.ac README libburn/libburn.h cdrskin/cdrskin.c cdrskin/README cdrskin/compile_cdrskin.sh cdrskin/cdrskin_timestamp.h cdrskin/cdrskin_eng.html Made number transition to 1.1.0 18 Jun 2011 [3870] - cdrskin/add_ts_changes_to_libburn_1_0_6 - cdrskin/add_ts_changes_to_libburn_1_0_7 + cdrskin/add_ts_changes_to_libburn_1_1_0 + cdrskin/add_ts_changes_to_libburn_1_1_1 Updated cdrskin tarball generator 18 Jun 2011 [3871] ChangeLog cdrskin/changelog.txt Documented changes and release timestamp ----------------------------------- release - cdrskin-1.1.0 - 2011.06.18.100001 * New API call burn_disc_next_track_is_damaged() * New API call burn_disc_close_damaged() * Bug fix: burn_disc_format() on DVD-RW issued wrong block size with type 00h 2011.06.18.154942 [3875] Makefile.am configure.ac README libburn/libburn.h cdrskin/cdrskin.c cdrskin/README cdrskin/compile_cdrskin.sh cdrskin/cdrskin_timestamp.h cdrskin/cdrskin_eng.html Made number transition to 1.1.1 18 Jun 2011 [3876] - cdrskin/add_ts_changes_to_libburn_1_0_6 - cdrskin/add_ts_changes_to_libburn_1_0_7 + cdrskin/add_ts_changes_to_libburn_1_1_0 + cdrskin/add_ts_changes_to_libburn_1_1_1 Updated cdrskin tarball generator 18 Jun 2011 [3877] ChangeLog cdrskin/changelog.txt Documented changes and release timestamp 18 Jun 2011 [3878] svn move -m libburn release 1.1.0 is ready http://svn.libburnia-project.org/libburn/branches/1.1.0 http://svn.libburnia-project.org/libburn/tags/1.1.0 ------------------------------------ cycle - cdrskin-1.1.1 - 2011.06.18.154942 2011.06.19.203515 [3882] libburn/sg-dummy.c Bug fix: libburn-1.1.0 did only compile on Linux, FreeBSD, and Solaris 20 Jun 2011 [3883] svn copy -m Branching for libburn release 1.1.0.pl01 http://svn.libburnia-project.org/libburn/tags/1.1.0 http://svn.libburnia-project.org/libburn/branches/1.1.0.pl01 2011.06.20.110001 [3884] [3885] (branch 1.0.0.pl01) libburn/sg-dummy.c ChangeLog cdrskin/cdrskin_timestamp.h Bug fix: libburn-1.1.0 did only compile on Linux, FreeBSD, and Solaris 20 Jun 2011 [3886] svn move -m "libburn bugfix release 1.0.0.pl01 is ready" http://svn.libburnia-project.org/libburn/branches/1.1.0.pl01 http://svn.libburnia-project.org/libburn/tags/1.1.0.pl01 ------------------------------ release - libburn-1.1.0.pl01 - 2011.06.20.110001 * Bug fix: libburn-1.1.0 compiled only on Linux, FreeBSD, and Solaris 2011.06.22.093127 [3888] libburn/sg-libcdio.c Silenced compiler warnings about signedness 22 Jun 2011 [3889] releng/releng_build_os Beginning to create a test suite for libburn and cdrskin 2011.07.04.143922 [4041] libburn/spc.c Avoiding to load speed descriptor list twice 2011.07.04.171649 [4047] libburn/file.c Reacted on warnings of -Wunused-but-set-variable 2011.07.06.142532 [4071] libburn/init.h libburn/async.c Reacted on warnings of -Wunused-but-set-variable 2011.07.06.143104 [4072] libburn/mmc.c Reacted on warnings of -Wunused-but-set-variable 2011.07.06.143313 [4073] libburn/spc.c Reacted on warnings of -Wunused-but-set-variable 2011.07.06.143441 [4074] libburn/toc.c Reacted on warnings of -Wunused-but-set-variable 2011.07.06.143536 [4075] libburn/write.c Reacted on warnings of -Wunused-but-set-variable 2011.07.06.143724 [4076] cdrskin/cdrskin.c Reacted on warnings of -Wtype-limits and -Wunused-but-set-variable 2011.07.06.143904 [4077] cdrskin/cdrfifo.c Reacted on warnings of -Wunused-but-set-variable 2011.07.07.114911 [4083] libburn/mmc.c Silenced warning of cppcheck 2011.07.07.115006 [4084] libburn/sg-linux.c Silenced warning of cppcheck 2011.07.07.120719 [4085] libburn/util.c Reacted on warning of cppcheck 2011.07.11.143934 [4133] libburn/sg.c Implemented macro Libburn_use_sg_freebsd_porT 2011.07.12.095936 [4138] cdrskin/cdrfifo.c Reacted on warning of cppcheck about cdrskin/cdrfifo.c 2011.07.12.105955 [4139] cdrskin/cleanup.c Reacted on warning of cppcheck about cdrskin/cleanup.c 2011.07.12.110131 [4140] libburn/async.c Reacted on warning of cppcheck about libburn/async.c 2011.07.12.110223 [4142] libburn/cleanup.c Reacted on warning of cppcheck about libburn/cleanup.c 2011.07.12.110306 [4143] libburn/drive.c Reacted on warning of cppcheck about libburn/drive.c 2011.07.12.110405 [4144] libburn/read.c Reacted on warning of cppcheck about libburn/read.c 2011.07.12.110453 [4145] test/poll.c Reacted on warning of cppcheck about test/poll.c 2011.07.12.141659 [4147] libburn/sg.c Improved intentional compiler warning about lack of suitable system adapter 2011.07.12.141838 [4148] libburn/sg-dummy.c Reacted on warning of cppcheck about libburn/sg-dummy.c 2011.07.12.141932 [4149] libburn/sg-freebsd-port.c Reacted on warning of cppcheck about libburn/sg-freebsd-port.c 2011.07.12.142018 [4150] libburn/sg-freebsd.c Reacted on warning of cppcheck about libburn/sg-freebsd.c 2011.07.12.142141 [4151] libburn/sg-libcdio.c Reacted on warning of cppcheck about libburn/sg-libcdio.c 2011.07.12.155335 [4152] cdrskin/cdrskin.c Improved -atip and -minfo with empty drive 2011.07.12.155417 [4153] libburn/drive.c Bug fix: Empty ROM drive was mistaken to hold an unsuitable disc 2011.07.12.173727 [4154] libburn/sg-solaris.c Reacted on warning of cppcheck about libburn/sg-solaris.c 2011.07.14.162150 [4164] cdrskin/cdrskin.c Fixed possible uninitialized variable use introduced by rev 4152 2011.07.15.081325 [4170] libburn/sg-freebsd.c Reacted on warning of cppcheck about libburn/sg-freebsd.c 2011.07.28.191202 [4222] libburn/libburn.h libburn/drive.c libburn/libburn.ver New API call burn_lookup_device_link() 2011.07.28.191536 [4223] cdrskin/cdrskin.c cdrskin/cdrskin.1 New option --device_links 2011.07.31.080152 [4227] libburn/transport.h libburn/drive.h libburn/drive.c libburn/spc.c libburn/mmc.c Bug fix: Some drives returned wrong CD sizes after having burnt DVD-R 2011.07.31.083046 [4228] libburn/spc.c libburn/mmc.c Bug fix: Some drives return -150 as NWA of blank CD, rather than 0 2011.08.01.125405 [4232] libburn/libburn.h libburn/drive.c libburn/mmc.c libburn/libburn.ver New API call burn_disc_get_phys_format_info() 2011.08.01.153305 [4237] libburn/mmc.h Forgot to upload the header which defines mmc_get_phys_format_info Release 1.1.2 was skipped to get back in sync with libisoburn. 07 Aug 2011 [4247] copy -m Branching for libburn release 1.1.4 http://svn.libburnia-project.org/libburn/trunk http://svn.libburnia-project.org/libburn/branches/1.1.4 2011.08.07.100001 [4249] Makefile.am configure.ac README libburn/libburn.h cdrskin/cdrskin.c cdrskin/README cdrskin/compile_cdrskin.sh cdrskin/cdrskin_timestamp.h cdrskin/cdrskin_eng.html Made number transition to 1.1.4 07 Aug 2011 [4250] - cdrskin/add_ts_changes_to_libburn_1_1_0 - cdrskin/add_ts_changes_to_libburn_1_1_1 + cdrskin/add_ts_changes_to_libburn_1_1_4 + cdrskin/add_ts_changes_to_libburn_1_1_5 Updated cdrskin tarball generator 07 Aug 2011 [4251] ChangeLog cdrskin/changelog.txt Documented changes and release timestamp 07 Aug 2011 [4255] cdrskin/cdrskin_eng.html ChangeLog cdrskin/changelog.txt Forgot to mention cdrskin option --device_links ----------------------------------- release - cdrskin-1.1.4 - 2011.08.07.100001 * 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 2011.08.08.121355 [4259] Makefile.am configure.ac README libburn/libburn.h cdrskin/cdrskin.c cdrskin/README cdrskin/compile_cdrskin.sh cdrskin/cdrskin_timestamp.h cdrskin/cdrskin_eng.html Made number transition to 1.1.5 08 Aug 2011 [4260] - cdrskin/add_ts_changes_to_libburn_1_1_0 - cdrskin/add_ts_changes_to_libburn_1_1_1 + cdrskin/add_ts_changes_to_libburn_1_1_4 + cdrskin/add_ts_changes_to_libburn_1_1_5 Updated cdrskin tarball generator 08 Aug 2011 [4261] ChangeLog cdrskin/changelog.txt Documented changes and release timestamp ------------------------------------ cycle - cdrskin-1.1.5 - 2011.08.08.121355 08 Aug 2011 [4262] svn move -m libburn release 1.1.4 is ready http://svn.libburnia-project.org/libburn/branches/1.1.4 http://svn.libburnia-project.org/libburn/tags/1.1.4 2011.08.17.160854 [4280] libburn/libburn.h libburn/transport.h libburn/drive.c Bug fix: stdio sizes > 4 TB - 32 kB caused integer rollover 2011.08.17.162201 [4281] libburn/drive.c Reacted on compiler warning about previous revision 2011.08.29.213339 [4302] libburn/write.c More generous ignoring of failure of fsync() on inappropriate fd 2011.09.20.131602 [4306] libburn/sg-linux.c Simulation of large disks 2011.09.20.131843 [4307] libburn/sg-linux.c Working around collision with udev by closing and re-opening device file 2011.09.20.132438 [4308] libburn/spc.c Slowing down test cycle while waiting for drive to become ready 2011.09.21.133344 [4310] README cdrskin/README libburn/sg-linux.c Improved and documented workaround for udev 21 Sep 2011 [4311] README cdrskin/README Corrected outdated sentence in documented workaround for udev 26 Sep 2011 [4321] svn copy -m Branching for libburn release 1.1.6 http://svn.libburnia-project.org/libburn/trunk http://svn.libburnia-project.org/libburn/branches/1.1.6 2011.09.27.060001 [4322] Makefile.am configure.ac README libburn/libburn.h cdrskin/cdrskin.c cdrskin/README cdrskin/compile_cdrskin.sh cdrskin/cdrskin_timestamp.h cdrskin/cdrskin_eng.html Made number transition to 1.1.6 27 Sep 2011 [4323] - cdrskin/add_ts_changes_to_libburn_1_1_4 - cdrskin/add_ts_changes_to_libburn_1_1_5 + cdrskin/add_ts_changes_to_libburn_1_1_6 + cdrskin/add_ts_changes_to_libburn_1_1_7 Updated cdrskin tarball generator 27 Sep 2011 [4324] ChangeLog cdrskin/changelog.txt Updated change log ----------------------------------- release - libburn-1.1.6 - 2011.09.27.060001 * Bug fix: stdio sizes > 4 TB - 32 kB caused integer rollover * Worked around a collision with Linux udev which lets links vanish 2011.09.27.124555 [4329] Makefile.am configure.ac README libburn/libburn.h cdrskin/cdrskin.c cdrskin/README cdrskin/compile_cdrskin.sh cdrskin/cdrskin_timestamp.h cdrskin/cdrskin_eng.html Made number transition to 1.1.7 27 Sep 2011 [4330] - cdrskin/add_ts_changes_to_libburn_1_1_4 - cdrskin/add_ts_changes_to_libburn_1_1_5 + cdrskin/add_ts_changes_to_libburn_1_1_6 + cdrskin/add_ts_changes_to_libburn_1_1_7 Updated cdrskin tarball generator 27 Sep 2011 [4331] ChangeLog cdrskin/changelog.txt Updated change log 27 Sep 2011 [4332] svn move -m libburn release 1.1.6 is ready http://svn.libburnia-project.org/libburn/branches/1.1.6 http://svn.libburnia-project.org/libburn/tags/1.1.6 ------------------------------------ cycle - cdrskin-1.1.7 - 2011.09.27.124555 2011.10.02.134037 [4336] libburn/sg-linux.c Avoided open()-close() cycles during drive scan and grab on Linux 2011.10.02.172004 [4337] libburn/sg-linux.c Avoided one more open()-close() cycles during drive scan and grab on Linux 2011.10.05.075531 [4339] libburn/libburn.h libburn/drive.h libburn/drive.c libburn/write.c libburn/libburn.ver New API call burn_drive_re_assess() 2011.10.06.082649 [4344] cdrskin/cdrskin.c Now unconditional: Cdrskin_libburn_has_stream_recordinG 2011.10.06.082934 [4345] cdrskin/cdrskin.c Now unconditional: Cdrskin_libburn_has_drive_equals_adR 2011.10.06.083228 [4346] cdrskin/cdrskin.c Now unconditional: Cdrskin_libburn_has_get_drive_rolE 2011.10.06.084026 [4347] cdrskin/cdrskin.c Now unconditional: Cdrskin_libburn_has_random_access_rW 2011.10.06.085426 [4348] cdrskin/cdrskin.c Now unconditional: Cdrskin_libburn_has_get_best_speeD 2011.10.06.085713 [4349] cdrskin/cdrskin.c Now unconditional: Cdrskin_libburn_has_set_waitinG 2011.10.06.085848 [4350] cdrskin/cdrskin.c Now unconditional: Cdrskin_libburn_has_track_set_sizE 2011.10.06.090207 [4351] cdrskin/cdrskin.c Now unconditional: Cdrskin_libburn_preset_device_familY 2011.10.06.090422 [4352] cdrskin/cdrskin.c Now unconditional: Cdrskin_libburn_has_set_forcE 2011.10.06.090557 [4353] cdrskin/cdrskin.c Now unconditional: Cdrskin_libburn_has_allow_untested_profileS 2011.10.06.091334 [4554] cdrskin/cdrskin.c Now unconditional: Cdrskin_libburn_write_mode_ruleS 2011.10.06.091641 [4355] cdrskin/cdrskin.c Now unconditional: Cdrskin_libburn_has_get_spacE 2011.10.06.091949 [4356] [4357] cdrskin/cdrskin.c Now unconditional: Cdrskin_libburn_has_set_filluP 2011.10.06.092242 [4358] cdrskin/cdrskin.c Now unconditional: Cdrskin_libburn_has_get_multi_capS 2011.10.06.095055 [4359] cdrskin/cdrskin.c Now unconditional: Cdrskin_libburn_has_toc_entry_extensionS 2011.10.06.095322 [4360] cdrskin/cdrskin.c Now unconditional: Cdrskin_libburn_has_get_msc1 2011.10.06.100025 [4361] cdrskin/cdrskin.c Now unconditional: Cdrskin_libburn_has_burn_disc_formaT 2011.10.06.101239 [4362] cdrskin/cdrskin.c Now unconditional: Cdrskin_libburn_has_bd_formattinG 2011.10.06.101442 [4363] cdrskin/cdrskin.c Now unconditional: Cdrskin_libburn_has_wrote_welL 2011.10.06.101918 [4364] cdrskin/cdrskin.c Now unconditional: Cdrskin_libburn_has_set_start_bytE 2011.10.06.102127 [4365] cdrskin/cdrskin.c Now unconditional: Cdrskin_libburn_has_get_profilE 2011.10.06.102557 [4366] cdrskin/cdrskin.c Now unconditional: Cdrskin_atip_speed_is_oK 2011.10.06.102816 [4367] cdrskin/cdrskin.c Now unconditional: Cdrskin_libburn_has_buffer_min_filL 2011.10.06.103102 [4368] cdrskin/cdrskin.c Now unconditional: Cdrskin_libburn_has_multI 2011.10.06.103325 [4369] cdrskin/cdrskin.c Now unconditional: Cdrskin_libburn_has_pretend_fulL 2011.10.06.103445 [4370] cdrskin/cdrskin.c Now unconditional: Cdrskin_libburn_has_buffer_progresS 2011.10.06.103619 [4371] cdrskin/cdrskin.c Now unconditional: Cdrskin_libburn_has_read_atiP 2011.10.06.103832 [4372] cdrskin/cdrskin.c Now unconditional: Cdrskin_libburn_has_burn_disc_unsuitablE 2011.10.06.104012 [4373] cdrskin/cdrskin.c Now unconditional: Cdrskin_libburn_has_get_start_end_lbA 2011.10.06.104233 [4374] cdrskin/cdrskin.c Now unconditional: Cdrskin_libburn_has_audioxtR 2011.10.06.104519 [4375] cdrskin/cdrskin.c Now unconditional: Cdrskin_libburn_has_cleanup_handleR 2011.10.06.104908 [4376] cdrskin/cdrskin.c Now unconditional: Cdrskin_libburn_has_burn_aborT 2011.10.06.105627 [4377] cdrskin/cdrskin.c Now unconditional: Cdrskin_libburn_has_burn_msgS 2011.10.06.105922 [4378] cdrskin/cdrskin.c Now unconditional: Cdrskin_libburn_has_convert_scsi_adR 2011.10.06.111115 [4379] cdrskin/cdrskin.c Now unconditional: Cdrskin_libburn_has_convert_fs_adR 2011.10.06.111245 [4380] cdrskin/cdrskin.c Now unconditional: Cdrskin_libburn_has_is_enumerablE 2011.10.06.111758 [4381] cdrskin/cdrskin.c Now unconditional: Cdrskin_allow_libburn_taO 2011.10.06.112031 [4382] cdrskin/cdrskin.c Now unconditional: Cdrskin_grab_abort_does_worK 2011.10.06.112239 [4383] cdrskin/cdrskin.c Now unconditional: Cdrskin_is_erasable_on_load_does_worK 2011.10.06.112456 [4384] cdrskin/cdrskin.c Now unconditional: Cdrskin_progress_track_does_worK 2011.10.06.112732 [4385] cdrskin/cdrskin.c Now unconditional: Cdrskin_libburn_has_drive_get_adR 2011.10.06.113103 [4386] cdrskin/cdrskin.c Now unconditional: Cdrskin_libburn_does_ejecT 2011.10.06.113315 [4387] cdrskin/cdrskin.c Now unconditional: Cdrskin_all_tracks_with_sector_paD 2011.10.06.114009 [4388] cdrskin/cdrskin.c Removed obsolete macro case 2011.10.06.120014 [4389] cdrskin/cdrskin.c cdrskin/compile_cdrskin.sh Removed outdated code and Cdrskin_oldfashioned_api_usE 2011.10.06.121140 [4390] cdrskin/cdrskin.c Now unconditional: Cdrskin_libburn_from_pykix_svN 2011.10.07.075117 [4391] libburn/drive.h libburn/drive.c Avoided to release drive prematurely if interrupted while grabbing drive 08 Oct 2011 [4392] cdrskin/convert_man_to_html.sh Replaced HTML minus by a flat ASCII minus in HTML man page generator 2011.10.09.155415 [4394] libburn/drive.c Reacted on warning of cppcheck about burn_disc_get_cd_info() 2011.10.09.162355 [4395] libburn/drive.c Reacted on nitpicking of cppcheck 2011.10.10.125950 [4397] libburn/libburn.h Changed term "persistent address" to "device file address" 2011.10.10.130029 [4398] libburn/drive.c Changed debug message which called "stdio:" addresses enumerable 2011.10.11.141313 [4399] [4400] cdrskin/cdrskin.c Avoided release-grab cycle in cdrskin -msinfo 2011.10.11.163842 [4401] cdrskin/cdrskin.c Avoided release-grab cycles between tasks of a cdrskin run 2011.10.12.100050 [4402] libburn/libburn.h libburn/libdax_msgs.h libburn/drive.c libburn/write.c libburn/structure.c libburn/read.c libburn/debug.c libburn/mmc.c libburn/spc.c libburn/sg-solaris.c libburn/sg-linux.c libburn/sg-libcdio.c libburn/sg-freebsd-port.c libburn/sg-freebsd.c Gave up use of burn_print() in libburn 2011.10.12.100155 [4403] test/structest.c Added madatory library initialization to test/structest.c 2011.10.27.091014 [4413] libburn/sg-libcdio.c Silenced a warnings in libcdio adapter 2011.10.27.094705 [4414] libburn/sg-libcdio.c Enabled optional reporting of drive replies in libcdio adapter 2011.10.27.094705 [4415] libburn/sg-solaris.c Enabled optional reporting of drive replies in Solaris adapter 2011.10.31.164236 [4416] libburn/spc.c libburn/mmc.c Enabled recognition of QEMU DVD-ROM 0.12 as ATAPI drive 2011.11.01.221713 [4417] libburn/spc.c Small correction of rev 4416 2011.11.02.074334 [4418] libburn/sg-linux.c Avoiding on Linux to list drives from /proc if device family is non-default 2011.11.02.130735 [4419] libburn/mmc.c Corrected a bug with obtaining Physical Interface Standard information 2011.11.03.130710 [4422] libburn/spc.c Bug fix: Misinterpreted mode page 2A if block descriptors are present 2011.11.09.111408 [4424] libburn/sg-linux.c Enabled recognition of CD drive at /dev/vda of Linux guest on qemu virtio 2011.11.10.134432 [4430] libburn/libburn.h Removed remark about SCSI logging being restricted to Linux system adapter 2011.11.10.153659 [4431] libburn/spc.h libburn/spc.c libburn/sg-linux.c Logging of early SCSI commands of Linux system adapter to stderr 2011.11.14.170612 [4435] libburn/sg-linux.c Clarified a remark in libburn/sg-linux.c 2011.11.16.094244 [4336] libburn/libdax_msgs.h Clarified a remark in libburn/libdax_msgs.h 2011.11.16.094436 [4437] libburn/write.c Distinguished failure messages about write(2) and fsync(2) 2011.11.18.155410 [4440] libburn/sg-libcdio.c Bug fix: licdio adapter reacted inconsistently on symbolic links to drives 20 Nov 2011 [4441] svn copy -m Branching for libburn release 1.1.8 http://svn.libburnia-project.org/libburn/trunk http://svn.libburnia-project.org/libburn/branches/1.1.8 2011.11.20.100001 [4442] Makefile.am configure.ac README libburn/libburn.h cdrskin/cdrskin.c cdrskin/README cdrskin/compile_cdrskin.sh cdrskin/cdrskin_timestamp.h cdrskin/cdrskin_eng.html Made number transition to 1.1.8 20 Nov 2011 [4443] - cdrskin/add_ts_changes_to_libburn_1_1_6 - cdrskin/add_ts_changes_to_libburn_1_1_7 + cdrskin/add_ts_changes_to_libburn_1_1_8 + cdrskin/add_ts_changes_to_libburn_1_1_9 Updated cdrskin tarball generator 20 Nov 2011 [4444] ChangeLog cdrskin/changelog.txt Updated change log ----------------------------------- release - libburn-1.1.8 - 2011.11.20.100001 * New API call burn_drive_re_assess() * Enabled recognition of QEMU DVD-ROM 0.12 as ATAPI drive * Bug fix: Misinterpreted mode page 2A if block descriptors are present 2011.11.20.214751 [4448] Makefile.am configure.ac README libburn/libburn.h cdrskin/cdrskin.c cdrskin/README cdrskin/compile_cdrskin.sh cdrskin/cdrskin_timestamp.h cdrskin/cdrskin_eng.html Made number transition to 1.1.9 20 Nov 2011 [4449] - cdrskin/add_ts_changes_to_libburn_1_1_6 - cdrskin/add_ts_changes_to_libburn_1_1_7 + cdrskin/add_ts_changes_to_libburn_1_1_8 + cdrskin/add_ts_changes_to_libburn_1_1_9 Updated cdrskin tarball generator 20 Nov 2011 [4450] ChangeLog cdrskin/changelog.txt Updated change log 21 Nov 2011 [4451] svn move -m libburn release 1.1.8 is ready http://svn.libburnia-project.org/libburn/branches/1.1.8 http://svn.libburnia-project.org/libburn/tags/1.1.8 ------------------------------------ cycle - cdrskin-1.1.9 - 2011.11.20.220318 2011.11.22.191621 [4455] libburn/sg-linux.c Reacted on compiler warning of Debian buildd 2011.11.23.104948 [4458] libburn/libdax_msgs.h libburn/sg-linux.c Reporting about failure to open existing /dev/sr or /dev/scd on Linux 2011.11.26.153142 [4460] libburn/sg-solaris.c Bug fix: Solaris adapter mishandled write commands which failed on first try 2011.11.30.081130 [4462] libburn/transport.h libburn/libdax_msgs.h libburn/spc.h libburn/spc.c libburn/sbc.c libburn/mmc.c libburn/sg-linux.c libburn/sg-freebsd.c libburn/sg-libcdio.c libburn/sg-solaris.c Made SCSI timeout settable at level of SPC, SBC, MMC functions 2011.11.30.131608 [4463] libburn/mmc.c Improved debugging of drive feature list 2011.12.02.100148 [4464] libburn/drive.c libburn/spc.c Bug fix: Interrupting libburn while drive tray is loading led to endless loop 2011.12.02.171436 [4466] libburn/libburn.h libburn/drive.c libburn/mmc.h libburn/mmc.c libburn/libburn.ver New API call burn_disc_get_leadin_text() 2011.12.02.171710 [4467] cdrskin/cdrskin.c cdrskin/cdrskin.1 Storing CD-TEXT as cdtext.dat with cdrskin option -toc -vv, reporting with -vvv 2011.12.02.204513 [4468] libburn/libburn.h Clarified meaning of Character Position byte of burn_disc_get_leadin_text() 2011.12.03.113345 [4469] libburn/mmc.c Corrected a style deviation in code of mmc.c 03 Dec 2011 [4470] Makefile.am Removing cdrskin/.libs and test/.libs witch make clean 03 Dec 2011 [4471] Makefile.am Added ./bootstrap script to release tarball 2011.12.05.203600 [4475] libburn/libburn.h libburn/libdax_msgs.h libburn/options.h libburn/options.c libburn/mmc.c libburn/write.c libburn/libburn.ver doc/cookbook.txt New API call burn_write_opts_set_leadin_text() 2011.12.05.203821 [4476] cdrskin/cdrskin.c cdrskin/cdrskin.1 Implemented cdrskin option textfile= 2011.12.06.134651 [4477] libburn/write.c Reacted on compiler warning about uninitialized variable in rev 4476 06 Dec 2011 [4478] doc/cookbook.txt Documented CD-TEXT pack type 0x8f 2011.12.07.075031 [4479] Makefile.am Removed version.h from list of source files because generated by configure 08 Dec 2011 [4481] doc/cookbook.txt Updated documentation of CD-TEXT pack types 0x87 and 0x8f 08 Dec 2011 [4482] doc/cookbook.txt Updated documentation of CD-TEXT pack types 0x86, 0x8d, 0x8e 2011.12.09.092152 [4483] cdrskin/cdrskin.c Tolerating trailing zero of Sony CDTEXT files 10 Dec 2011 [4484] doc/cookbook.txt Updated documentation of CD-TEXT pack types 0x88 and 0x89 10 Dec 2011 [4485] doc/cookbook.txt Some polishing in cookbook 12 Dec 2011 [4486] doc/cookbook.txt + doc/cdtext.txt Outsourced cdtext.txt from cookbook.txt 12 Dec 2011 [4487] cdrskin/cdrskin.1 Pointing from man cdrskin to doc/cdtext.txt for CD-TEXT details 2011.12.12.092602 [4488] libburn/libburn.h libburn/libdax_msgs.h libburn/init.c libburn/options.h libburn/options.c libburn/structure.h libburn/structure.c libburn/write.h libburn/write.c libburn/libburn.ver New API calls for composing CD-TEXT 2011.12.12.164452 [4490] libburn/libburn.h libburn/write.c doc/cdtext.txt New macros for CD-TEXT genre and language names 2011.12.12.181346 [4491] libburn/write.c Enabled repetition of track texts by TAB character 2011.12.13.164329 [4492] libburn/libburn.h More macros for CD-TEXT genre and language names 2011.12.14.124906 [4494] libburn/write.c Changed default CD-TEXT for tracks from track number text to empty text 2011.12.14.132551 [4495] cdrskin/cdrskin.c cdrskin/cdrskin.1 doc/cdtext.txt doc/cookbook.txt New option input_sheet_v07t= 14 Dec 2011 [4496] ChangeLog cdrskin/changelog.txt Updated change log ------------------------------------ cycle - cdrskin-1.1.9 - 2011.12.14.132711 * Bug fix: Solaris adapter mishandled write commands which failed on first try * Bug fix: Interrupting libburn while drive tray is loading led to endless loop * New API calls burn_disc_get_leadin_text(), burn_write_opts_set_leadin_text() * New API calls for composing CD-TEXT * Implemented cdrskin option textfile= * Implemented cdrskin option combination -vv -toc for cdtext.dat production * New cdrskin option input_sheet_v07t= 14 Dec 2011 [4497] cdrskin/cdrskin.1 cdrskin/cdrskin_eng.html Improved cdrskin man page and web page 15 Dec 2011 [4498] Makefile.am Included doc/cdtext.txt in libburn tarball 2011.12.15.104259 [4499] cdrskin/cdrskin.c cdrskin/cdrskin.1 Refusing to burn CD-TEXT if non-audio tracks are present 2011.12.15.154818 [4502] Makefile.am libburn/libburn.h libburn/libdax_msgs.h + libburn/cdtext.c libburn/libburn.ver doc/cdtext.txt New API call burn_session_input_sheet_v07t() 2011.12.15.155642 [4503] cdrskin/cdrskin.c cdrskin/compile_cdrskin.sh Moved reading of Sony Input Sheet v07 from cdrskin to libburn 2011.12.15.161349 [4504] libburn/libburn.h Documented new API call 2011.12.15.174914 [4505] libburn/cdtext.c libburn/write.c Moved burn_cdtext_from_session() from write.c to cdtext.c 2011.12.16.105329 [4506] libburn/util.c libburn/util.h libburn/cdtext.c Moved a function from cdtext.c to util.c 2011.12.16.111300 [4507] libburn/util.c libburn/util.h libburn/cdtext.c Moved a function from cdtext.c to util.c 2011.12.18.161107 [4508] cdrskin/cdrskin.c cdrskin/cdrskin.1 New options --cdtext_dummy and --cdtext_verbose 2011.12.22.112138 [4509] cdrskin/cdrskin.c Changed libburn print threshold of cdrskin -v to severity NOTE 2011.12.25.103852 [4510] libburn/libburn.h libburn/libdax_msgs.h libburn/structure.c libburn/file.c libburn/source.c libburn/cdtext.c libburn/libburn.ver New API calls burn_cdtext_from_packfile() and burn_session_by_cue_file() 2011.12.25.105032 [4511] cdrskin/cdrskin.c cdrskin/cdrskin.1 Partly implemented options cuefile= and -text 2011.12.25.110440 [4512] libburn/structure.c libburn/cdtext.c Reacted on compiler warnings about uninitialized variables 26 Dec 2011 [4514] doc/cdtext.txt Updated doc/cdtext.txt 2011.12.27.115645 [4515] libburn/libburn.h libburn/structure.h libburn/structure.c libburn/libburn.ver New API call burn_track_set_isrc_string() 2011.12.27.133733 [4516] libburn/write.c libburn/cdtext.c doc/cookbook.txt doc/cdtext.txt cdrskin/cdrskin.1 Writing CATALOG and ISRC into Q sub-channel of CD SAO sessions 2011.12.28.104044 [4517] libburn/libburn.h libburn/transport.h libburn/drive.c libburn/spc.h libburn/spc.c libburn/mmc.h libburn/mmc.c doc/cookbook.txt doc/cdtext.txt Transmitting CATALOG by mode page 5. ISRC too, if TAO. 2011.12.28.104536 [4518] cdrskin/cdrskin.c cdrskin/cdrskin.1 Implemented options mcn= and isrc= 2011.12.28.152153 [4519] libburn/transport.h libburn/write.c libburn/mmc.h libburn/mmc.c Improved reaction on failure of SEND CUE SHEET 2011.12.30.142742 [4521] libburn/spc.h libburn/spc.c libburn/mmc.c Reduced waiting time between retries of WRITE commands 2011.12.30.164755 [4522] cdrskin/cdrskin.c cdrskin/cdrskin.1 Coordinated option cuefile= with option input_sheet_v07t= 2011.12.30.174416 [4523] cdrskin/cdrskin.c cdrskin/cdrskin.1 Corrected precedence of media catalog and ISRC options 2011.12.31.120007 [4524] libburn/libburn.h libburn/write.c doc/cookbook.txt New track mode modifier BURN_SCMS 2012.01.01.124121 [4525] libburn/write.c Corrected CTL of lead-in CUE SHEET entry 2012.01.01.124330 [4526] libburn/mmc.c doc/cookbook.txt Writing SCMS into mode page 5 if TAO 2012.01.01.124424 [4627] libburn/drive.c Fixed a wrong assumption about track.mode 2012.01.01.124645 [4628] libburn/libburn.h libburn/structure.c doc/cdtext.txt Interpreting CDRWIN command FLAGS 2012.01.01.125539 [4529] cdrskin/cdrskin.c cdrskin/cdrskin.1 Implemented options -scms -copy -nocopy -preemp -nopreemp 2012.01.01.125539 [4530] cdrskin/cdrskin.c cdrskin/cdrskin.1 New cdrskin options --four_channel --two_channel 2012.01.01.173446 [4531] libburn/structure.c doc/cdtext.txt cdrskin/cdrskin.1 Implemented cue sheet file commands ARRANGER, COMPOSER, MESSAGE 2012.01.02.143655 [4532] libburn/libdax_msgs.h libburn/structure.c Reporting line number in case of cue sheet file problems 2012.01.02.164110 [4533] libburn/write.c Changed debug messages about CUE SHEET MSF from hex to decimal 2012.01.03.194322 [4534] libburn/libburn.h libburn/libdax_msgs.h libburn/structure.h libburn/structure.c libburn/write.c doc/cdtext.txt cdrskin/cdrskin.1 libburn/libburn.ver New API calls burn_track_set_index(), burn_track_clear_indice() 2012.01.04.131808 [4535] cdrskin/cdrskin.c cdrskin/cdrskin.1 Implemented option index= 2012.01.05.115516 [4536] libburn/drive.c libburn/write.c libburn/spc.h libburn/spc.c Bug fix: Progress report with blanking and formatting could be bogus 2012.01.05.120246 [4537] cdrskin/cdrskin.c Reacted on compiler warnings about rev 4535 2012.01.05.123114 [4538] ChangeLog cdrskin/changelog.txt cdrskin/cdrskin_eng.html Updated change log and web page 2012.01.05.140927 [4539] libburn/write.c Reacted on compiler warning about rev 4519 ------------------------------------ cycle - cdrskin-1.1.9 - 2012.01.05.141340 * New API call burn_session_input_sheet_v07t() * New API calls burn_cdtext_from_packfile() and burn_session_by_cue_file() * New API call burn_track_set_isrc_string() * New API calls burn_track_set_index(), burn_track_clear_indice() * New cdrskin options --cdtext_dummy and --cdtext_verbose * New cdrskin options --four_channel --two_channel * Implemented cdrskin options mcn= and isrc= * Implemented cdrskin options -scms -copy -nocopy -preemp -nopreemp * Implemented cdrskin option index= * Partly implemented cdrskin options cuefile= and -text * Bug fix: Progress report with blanking and formatting could be bogus 2012.01.06.125849 [4540] libburn/libburn.h libburn/structure.c cdrskin/cdrskin.1 doc/cdtext.txt Implemented data extraction from cue sheet FILE type WAVE 2012.01.07.190901 [4541] libburn/libburn.h libburn/libdax_msgs.h libburn/drive.c libburn/structure.c libburn/write.c libburn/spc.c libburn/mmc.c libburn/libburn.ver New API call burn_session_set_start_tno() 2012.01.08.132304 [4542] libburn/libburn.h libburn/structure.c libburn/cdtext.c doc/cdtext.txt Implemented track number starts > 1 with .cue and v07t.txt files 2012.01.08.140810 [4543] libburn/libburn.h libburn/libburn.ver libburn/structure.c New API call burn_session_get_start_tno() 2012.01.08.141104 [4544] cdrskin/cdrskin.c While writing: Reporting track numbers with correct start number offset 2012.01.08.154822 [4545] cdrskin/cdrskin.c Corrected display of track number offset with -toc and -minfo 2012.01.08.191443 [4546] cdrskin/cdrskin.c cdrskin/cdrskin.1 New cdrskin option cd_start_tno= 2012.01.10.122000 [4547] libburn/libburn.h libburn/libburn.ver libburn/structure.h libburn/structure.c libburn/write.c New API call burn_track_set_pregap_size() 2012.01.10.124916 [4548] libburn/write.c Removed a development test contraption introduced by previous revision 2012.01.11.111602 [4549] libburn/write.c Enabled pre-gap size for tracks other than the first one 2012.01.11.122013 [4550] libburn/write.c Reacted on compiler warning 2012.01.11.122158 [4551] libburn/structure.c doc/cdtext.txt cdrskin/cdrskin.1 Interpreting .cue file command PREGAP 2012.01.11.122442 [4552] libburn/structure.h libburn/structure.c libburn/mmc.h libburn/mmc.c Obtaining more accurate track sizes for CD with pre-gap 2012.01.11.132847 [4553] cdrskin/cdrskin.c Corrected track number of blank track reported by cdrskin -minfo 2012.01.11.132946 [4554] libburn/libburn.h Clarified meaning of parameter trackno with call burn_disc_track_lba_nwa() 2012.01.12.084429 [4555] libburn/libburn.h libburn/libburn.ver libburn/libdax_msgs.h libburn/structure.h libburn/structure.c libburn/write.c New API call burn_track_set_postgap_size() 2012.01.12.120316 [4556] libburn/libburn.h libburn/structure.c doc/cdtext.txt cdrskin/cdrskin.1 Interpreting .cue file command POSTGAP 2012.01.12.191143 [4557] cdrskin/cdrskin.c cdrskin/cdrskin.1 New cdrskin options sao_pregap=, sao_postgap= 2012.01.13.101844 [4558] cdrskin/cdrskin.c Avoided display of negative speed numbers at track change 2012.01.13.122205 [4559] libburn/write.c libburn/sector.h libburn/sector.c Flushing buffer to MMC before a new track begins 2012.01.13.141517 [4560] cdrskin/cdrskin.c Corrected type and sector size for .cue generated tracks 2012.01.13.142723 [4561] libburn/write.c Corrected write count for tracks with post-gap 2012.01.13.150949 [4562] libburn/write.c Removed development macro which sneaked in with previous revision 2012.01.13.151126 [4563] cdrskin/cdrskin.c Corrected total size summary of cdrskin before burn start 2012.01.13.170914 [4564] libburn/write.c libburn/sector.c Implemented index reporting for struct burn_progress 15 Jan 2012 [4568] doc/cookbook.txt Updated SAO cookbook about indice, pre-gap, post-gap 2012.01.16.112048 [4570] libburn/sector.c Corrected a comment 2012.01.16.112258 [4571] libburn/libburn.h libburn/write.c Preventing CD-TEXT with sessions that are not pure audio 2012.01.18.120429 [4573] libburn/structure.c Detecting address sequence errors with .cue command INDEX 2012.01.18.141954 [4574] libburn/spc.c Made conversion of ASC ASCQ to text independent of key and its text 2012.01.19.210418 [4575,4577] delayed_commit/B20119.200204 libburn/libburn.h libburn/structure.h libburn/structure.c libburn/write.c Counting post-gap as part of track with burn_track_get_sectors() 2012.01.20.091016 [4576,4578] delayed_commit/B20120.091044 libburn/libburn.h libburn/file.h libburn/file.c libburn/structure.c Introduced burn_offst_source_new() flag bit0 which prevents later size changes 2012.01.21.174103 [4579] delayed_commit/B20121.174108 libburn/read.c Allowing SCSI read operations > 32 kB 2012.01.22.124929 [4580] delayed_commit/B20122.124935 libburn/spc.c Revoked an aspect of rev 4465 which aborted operation before drive is ready 2012.01.22.125048 [4581] delayed_commit/B20122.125048 libburn/async.c Prevented SIGSEGV with testing drive for being prepared for writing 2012.01.22.125357 [4582] delayed_commit/B20122.125357 libburn/drive.c Improved reaction time on interrupt during writing of lead-in 2012.01.22.182854 [4583] delayed_commit/B20122.182858 libburn/libburn.h libburn/init.h libburn/init.c libburn/drive.c Disabled dangerous abort handler actions while BURN_DRIVE_GRABBING 2012.01.22.194131 [4584] delayed_commit/B20122.194131 cdrskin/cdrskin.c Bug fix: cdrskin produced a memory fault if interupted before writing began 2012.01.23.102720 [4585] libburn/libdax_msgs.h libburn/mmc.c libburn/options.c libburn/sg-freebsd-port.c libburn/crc.c libburn/write.c Corrected some minor differences between SVN and local development tree 23 Jan 2012 [4590] cdrskin/cdrskin_eng.html cdrskin/changelog.txt Updated change log 23 Jan 2012 [4591] ChangeLog Updated change log 23 Jan 2012 [4592] cdrskin/wiki_plain.txt Updated cdrskin wiki text 2012.01.23.164346 [4593] cdrskin/cdrskin.c Fixed an endless loop with cdrskin signal handling ------------------------------------ cycle - cdrskin-1.1.9 - 2012.01.23.164529 * Bug fix: cdrskin produced a memory fault if interupted before writing began * New API calls burn_session_set_start_tno(), burn_session_get_start_tno() * New API calls burn_track_set_pregap_size(), burn_track_set_postgap_size() * New cdrskin option cd_start_tno= * New cdrskin options sao_pregap=, sao_postgap= 2012.01.25.092650 [4595] cdrskin/cdrskin.c Removed overdone part of rev 4593 27 Jan 2012 [4598] svn copy -m Branching for libburn release 1.2.0 http://svn.libburnia-project.org/libburn/trunk http://svn.libburnia-project.org/libburn/branches/1.2.0 2012.01.27.103001 [4599] Makefile.am configure.ac README libburn/libburn.h cdrskin/cdrskin.c cdrskin/README cdrskin/compile_cdrskin.sh cdrskin/cdrskin_timestamp.h cdrskin/cdrskin_eng.html Made number transition to 1.2.0 27 Jan 2012 [4600] - cdrskin/add_ts_changes_to_libburn_1_1_8 - cdrskin/add_ts_changes_to_libburn_1_1_9 + cdrskin/add_ts_changes_to_libburn_1_2_0 + cdrskin/add_ts_changes_to_libburn_1_2_1 Updated cdrskin tarball generator 27 Jan 2012 [4601] ChangeLog cdrskin/changelog.txt Updated change log ----------------------------------- release - libburn-1.2.0 - 2012.01.27.103001 * Bug fix: cdrskin produced a memory fault if interupted before writing began * Bug fix: Solaris adapter mishandled write commands which failed on first try * Bug fix: Interrupting libburn while drive tray is loading led to endless loop * Bug fix: Progress report with blanking and formatting could be bogus * New API calls burn_disc_get_leadin_text(), burn_write_opts_set_leadin_text() * New API calls for composing CD-TEXT, see doc/cdtext.txt * New API call burn_session_by_cue_file() for reading CDRWIN .cue files * New API call burn_track_set_isrc_string() * New API calls burn_track_set_index(), burn_track_clear_indice() * New API calls burn_session_set_start_tno(), burn_session_get_start_tno() * New API calls burn_track_set_pregap_size(), burn_track_set_postgap_size() * Implemented cdrskin option textfile= * Implemented cdrskin option combination -vv -toc for cdtext.dat production * Implemented cdrskin options mcn= and isrc= * Implemented cdrskin options -scms -copy -nocopy -preemp -nopreemp * Implemented cdrskin option index= * Partly implemented cdrskin options cuefile= and -text * New cdrskin option input_sheet_v07t= for CD-TEXT definition * New cdrskin options --cdtext_dummy and --cdtext_verbose * New cdrskin options --four_channel --two_channel * New cdrskin option cd_start_tno= * New cdrskin options sao_pregap=, sao_postgap= 2012.01.27.150951 [4605] Makefile.am configure.ac README libburn/libburn.h cdrskin/cdrskin.c cdrskin/README cdrskin/compile_cdrskin.sh cdrskin/cdrskin_timestamp.h cdrskin/cdrskin_eng.html Made number transition to 1.2.1 27 Jan 2012 [4606] - cdrskin/add_ts_changes_to_libburn_1_1_8 - cdrskin/add_ts_changes_to_libburn_1_1_9 + cdrskin/add_ts_changes_to_libburn_1_2_0 + cdrskin/add_ts_changes_to_libburn_1_2_1 Updated cdrskin tarball generator 27 Jan 2012 [4607] ChangeLog cdrskin/changelog.txt Updated change log 27 Jan 2012 [4608] svn move -m libburn release 1.2.0 is ready http://svn.libburnia-project.org/libburn/branches/1.2.0 http://svn.libburnia-project.org/libburn/tags/1.2.0 27 Jan 2012 [tag:4612] [4613] libburn/write.c ChangeLog Corrected small flaws of libburn release tarball 27 Jan 2012 [4614] [4615] libburn/write.c One of the flaws was phony. Corrected back. ------------------------------------ cycle - cdrskin-1.2.1 - 2012.01.27.150951 2012.02.02.190720 [4624] libburn/write.c libburn/spc.c Reacted on warnings of Debian buildd 06 Feb 2012 [4625] doc/cdtext.txt Small corrections in CD-TEXT documentation 08 Feb 2012 [4626] doc/cdtext.txt Small corrections in CD-TEXT documentation 2012.02.11.171228 [4627] libburn/crc.c Mathematical description of crc_ccitt() versus crc_11021() 2012.02.13.102837 [4628] libburn/spc.c Added LG drive sense code 2 06 00 to error list (officially listed is 3 06 00) 2012.02.19.101022 [4631] libburn/crc.h libburn/crc.c Re-implemented the CRC functions under own copyright 2012.02.22.103056 [4632] libburn/util.c doc/mediainfo.txt Added to DVD manufacturer list: "UmeDisc Limited" 2012.03.21.193320 [4671] cdrskin/cdrskin.c Reacted on warning of cppcheck 2 Apr 2012 [4684] svn copy -m Branching for libburn release 1.2.2 http://svn.libburnia-project.org/libburn/trunk http://svn.libburnia-project.org/libburn/branches/1.2.2 2012.04.02.110001 [4685] Makefile.am configure.ac README libburn/libburn.h cdrskin/cdrskin.c cdrskin/README cdrskin/compile_cdrskin.sh cdrskin/cdrskin_timestamp.h cdrskin/cdrskin_eng.html Made number transition to 1.2.2 02 Apr 2012 [4686] - cdrskin/add_ts_changes_to_libburn_1_2_0 - cdrskin/add_ts_changes_to_libburn_1_2_1 + cdrskin/add_ts_changes_to_libburn_1_2_2 + cdrskin/add_ts_changes_to_libburn_1_2_3 Updated cdrskin tarball generator 02 Apr 2012 [4687] ChangeLog cdrskin/changelog.txt Updated change log ----------------------------------- release - libburn-1.2.2 - 2012.04.02.110001 * Small internal refinements 2012.04.02.172347 [4691] Makefile.am configure.ac README libburn/libburn.h cdrskin/cdrskin.c cdrskin/README cdrskin/compile_cdrskin.sh cdrskin/cdrskin_timestamp.h cdrskin/cdrskin_eng.html Made number transition to 1.2.3 02 Apr 2012 [4692] - cdrskin/add_ts_changes_to_libburn_1_2_0 - cdrskin/add_ts_changes_to_libburn_1_2_1 + cdrskin/add_ts_changes_to_libburn_1_2_2 + cdrskin/add_ts_changes_to_libburn_1_2_3 Updated cdrskin tarball generator 02 Apr 2012 [4693] ChangeLog cdrskin/changelog.txt Updated change log 02 Apr 2012 [4694] svn move -m libburn release 1.2.2 is ready http://svn.libburnia-project.org/libburn/branches/1.2.2 http://svn.libburnia-project.org/libburn/tags/1.2.2 ------------------------------------ cycle - cdrskin-1.2.3 - 2012.04.02.172347 2012.04.04.100754 [4698] cdrskin/cdrskin.c Bug fix: cdrskin SIGSEGV if track source was added when no drive was available 2012.04.04.183902 [4699] libburn/crc.c Reacted on warning of Debian buildd 2012.04.08.112703 [4701] libburn/libburn.h libburn/options.h libburn/options.c libburn/write.c libburn/libdax_msgs.h libburn/libburn.ver New API call burn_write_opts_set_obs_pad() 2012.04.08.112825 [4702] cdrskin/cdrskin.c cdrskin/cdrskin.1 New option --obs_pad 2012.04.10.181239 [4704] cdrskin/cdrskin.c Now recognizing long options with double dash 13 Apr 2012 [4706] cdrskin/cdrskin.1 Small correction in cdrskin man page 2012.04.13.202654 [4707] configure.ac libburn/libburn.h libburn/options.c cdrskin/cdrskin.1 Compile time option for obs_pad 18 Apr 2012 [4708] doc/cdtext.txt Augmented CD-TEXT documentation by a complete example of packs 18 Apr 2012 [4709] doc/cookbook.txt Small change in cookbook.txt about DVD-R DL 2012.05.08.080449 [4731] libburn/crc.c Corrections of CRC-32 algorithm for 32 bit systems. Mentioning of start value. 2012.05.30.202249 [4744] libburn/write.c libburn/mmc.c doc/cookbook.txt Bug fix: CD SAO sessions with data tracks started by an audio pause 2012.06.17.173420 [4762] libburn/sector.c Improved reported number of missing bytes in case of track source shortage 2012.07.08.103007 [4778] libburn/structure.c Bug fix: CD tracks were perceived 2 sectors too short. Nice with TAO, bad with SAO. 20 Jul 2012 [4794] svn copy -m "Branching for libburn release 1.2.4" http://svn.libburnia-project.org/libburn/trunk http://svn.libburnia-project.org/libburn/branches/1.2.4 2012.07.20.113001 [4795] Makefile.am configure.ac README libburn/libburn.h cdrskin/cdrskin.c cdrskin/cdrskin.1 cdrskin/README cdrskin/compile_cdrskin.sh cdrskin/cdrskin_timestamp.h cdrskin/cdrskin_eng.html Made number transition to 1.2.4 20 Jul 2012 [4796] - cdrskin/add_ts_changes_to_libburn_1_2_2 - cdrskin/add_ts_changes_to_libburn_1_2_3 + cdrskin/add_ts_changes_to_libburn_1_2_4 + cdrskin/add_ts_changes_to_libburn_1_2_5 Updated cdrskin tarball generator 20 Jul 2012 [] ChangeLog cdrskin/changelog.txt Updated change log ----------------------------------- release - libburn-1.2.4 - 2012.07.20.113001 * New API call burn_write_opts_set_obs_pad(), ./configure --enable-dvd-obs-pad * New cdrskin option --obs_pad * Bug fix: CD SAO sessions with data tracks started by an audio pause * Bug fix: CD tracks were perceived 2 sectors too short. Nice with TAO, bad with SAO. * Bug fix: cdrskin SIGSEGV if track source was added when no drive was available 2012.07.20.164346 [4801] Makefile.am configure.ac README libburn/libburn.h cdrskin/cdrskin.c cdrskin/cdrskin.1 cdrskin/README cdrskin/compile_cdrskin.sh cdrskin/cdrskin_timestamp.h cdrskin/cdrskin_eng.html Made number transition to 1.2.5 20 Jul 2012 [4802] - cdrskin/add_ts_changes_to_libburn_1_2_2 - cdrskin/add_ts_changes_to_libburn_1_2_3 + cdrskin/add_ts_changes_to_libburn_1_2_4 + cdrskin/add_ts_changes_to_libburn_1_2_5 Updated cdrskin tarball generator 20 Jul 2012 [4803] ChangeLog cdrskin/changelog.txt Updated change log 20 Jul 2012 [4806] svn move -m libburn release 1.2.4 is ready http://svn.libburnia-project.org/libburn/branches/1.2.4 http://svn.libburnia-project.org/libburn/tags/1.2.4 ------------------------------------ cycle - cdrskin-1.2.5 - 2012.07.20.164346 2012.07.26.122909 [4811] cdrskin/cdrskin.c cdrskin/cdrskin.1 New option --no_load 26 Jul 2012 [4813] ChangeLog cdrskin/cdrskin_eng.html cdrskin/changelog.txt Updated change log ------------------------------------ cycle - cdrskin-1.2.5 - 2012.07.26.195346 * New option --no_load 1 Aug 2012 [4814] doc/cdtext.txt Small grammatical correction in CD-TEXT documentaion 2012.08.28.161949 [4820] libburn/drive.c libburn/util.h libburn/util.c libburn/sg-freebsd.c Removed buggy burn_strdup() and burn_strndup(). Thanks to Rich Felker. 2012.09.13.085623 [4828] libburn/mmc.c Bug fix: Speed setting had no effect on BD media. Thanks to Dennis Vshivkov. 13 Sep 2012 [4829] ChangeLog cdrskin/cdrskin_eng.html cdrskin/changelog.txt Updated change log ------------------------------------ cycle - cdrskin-1.2.5 - 2012.09.13.090310 Bug fix: Speed setting had no effect on BD media. Thanks to Dennis Vshivkov. 2012.10.02.134821 [4841] configure.ac Configuration for use of libcdio on cygwin. Thanks Rocky Bernstein. 2012.10.24.095725 [4850] libburn/async.c Reporting (still cryptic) details about refusal to blank 2012.10.25.123837 [4852] libburn/libburn.h libburn/transport.h libburn/read.c libburn/spc.c libburn/mmc.c New flag bit4 of burn_read_data() for better handling of TAO end blocks 2012.10.25.173408 [4854] libburn/read.c Corrected error handling which was spoiled by rev 4852 2012.11.18.184006 [4858] libburn/libburn.h libburn/read.c libburn/spc.c libburn/mmc.h libburn/mmc.c Preserving an immature sketch of media quality scanning 2012.11.18.184114 [4859] cdrskin/cdrskin.c Preserving an immature sketch of media quality scanning 2012.11.24.181347 [4860] libburn/mmc.c Better reaction on non-plausible ATIP info from CD-ROM 2012.11.29.111344 [4865] libburn/libburn.h libburn/transport.h libburn/libdax_msgs.h libburn/options.h libburn/options.c libburn/toc.c libburn/read.c libburn/spc.c libburn/mmc.h libburn/sg-freebsd.c libburn/libburn.ver Beginning to create new API call burn_read_audio 2012.11.29.112506 [4866] libburn/mmc.c Forgot mcc.c with the previous commit 2012.11.29.112605 [4867] libburn/libdax_msgs.h libburn/mmc.c Let mmc_format_unit issue failure message on SCSI error 2012.11.30.193330 [4868] libburn/libburn.h libburn/read.c New API call burn_read_audio 2012.11.30.193415 [4869] test/telltoc.c Made telltoc ready for reading CD audio 2012.12.14.145101 [4878] libburn/libburn.h libburn/init.c libburn/libdax_msgs.h libburn/libdax_msgs.c libburn/libburn.ver New API call burn_list_sev_texts() 14 Dec 2012 [4879] doc/cookbook.txt Small change to burn cookbook about ISO multi-session emulation 08 Jan 2013 [4935] svn copy -m "Branching for libburn release 1.2.6" http://svn.libburnia-project.org/libburn/trunk http://svn.libburnia-project.org/libburn/branches/1.2.6 2013.01.08.090001 [4936] Makefile.am configure.ac README libburn/libburn.h cdrskin/cdrskin.c cdrskin/cdrskin.1 cdrskin/README cdrskin/compile_cdrskin.sh cdrskin/cdrskin_timestamp.h cdrskin/cdrskin_eng.html Made number transition to 1.2.6 08 Jan 2013 [4937] - cdrskin/add_ts_changes_to_libburn_1_2_4 - cdrskin/add_ts_changes_to_libburn_1_2_5 + cdrskin/add_ts_changes_to_libburn_1_2_6 + cdrskin/add_ts_changes_to_libburn_1_2_7 Updated cdrskin tarball generator 08 Jan 2013 [4938] ChangeLog cdrskin/changelog.txt Updated change log ----------------------------------- release - libburn-1.2.6 - 2013.01.08.090001 Bug fix: Speed setting had no effect on BD media. Thanks to Dennis Vshivkov. * New API call burn_read_audio() * New API call burn_list_sev_texts() * New cdrskin option --no_load 2013.01.08.144634 [] Makefile.am configure.ac README libburn/libburn.h cdrskin/cdrskin.c cdrskin/cdrskin.1 cdrskin/README cdrskin/compile_cdrskin.sh cdrskin/cdrskin_timestamp.h cdrskin/cdrskin_eng.html Made number transition to 1.2.7 08 Jan 2013 [4947] - cdrskin/add_ts_changes_to_libburn_1_2_4 - cdrskin/add_ts_changes_to_libburn_1_2_5 + cdrskin/add_ts_changes_to_libburn_1_2_6 + cdrskin/add_ts_changes_to_libburn_1_2_7 Updated cdrskin tarball generator 08 Jan 2013 [4948] ChangeLog cdrskin/changelog.txt Updated change log 08 Jan 2013 [4949] svn move -m libburn release 1.2.6 is ready http://svn.libburnia-project.org/libburn/branches/1.2.6 http://svn.libburnia-project.org/libburn/tags/1.2.6 ------------------------------------ cycle - cdrskin-1.2.7 - 2013.01.08.150303 2013.01.12.195030 [4955] libburn/libburn.h libburn/transport.h libburn/structure.h libburn/structure.c libburn/mmc.c libburn/libburn.ver New API call burn_disc_get_incomplete_sessions(), new burn_toc_entry.track_status_bits 2013.01.12.195311 [4956] cdrskin/cdrskin.c Made use of new API features to handle incomplete sessions 2013.01.15.104005 [4961] libburn/structure.c Bug fix: All CD tracks were reported with the sizes of the tracks in the first session. Regression introduced with version 1.2.0 (rev 4552). 16 Jan 2013 [4965] ChangeLog cdrskin/cdrskin_eng.html cdrskin/changelog.txt Updated change log 2013.01.16.181124 [4966] cdrskin/cdrskin.c Updated cdrskin copyright message ------------------------------------ cycle - cdrskin-1.2.7 - 2013.01.16.181124 * New API call burn_disc_get_incomplete_sessions() * New burn_toc_entry component .track_status_bits * -toc and -minfo now report about tracks in the incomplete session * Bug fix: All CD tracks were reported with the sizes of the tracks in the first session. Regression introduced with version 1.2.0 (rev 4552). 2013.02.26.080127 [4972] libburn/drive.c Corrected wrong use of sizeof 2013.03.04.211258 [4975] libburn/mmc.c Bug fix: On some drives the request for minimum speed yielded maximum speed 2013.03.04.232436 [4976] libburn/mmc.c Corrected previous bug fix which caused speed descriptors to appear twice 2013.03.05.124217 [4977] libburn/mmc.c Still correcting the bug fix of rev 4975 2013.03.05.124508 [4978] cdrskin/cdrskin.c New cdrskin option --list_speeds 05 Mar 2013 [4979] cdrskin/cdrskin.1 Mentioned --list_speeds in manual page 05 Mar 2013 [4980] ChangeLog cdrskin/cdrskin_eng.html cdrskin/changelog.txt Updated change log 2013.03.05.185356 [4981] libburn/mmc.c Always considering mode page 2A when looking for min and max speed 2013.03.05.185440 [4982] cdrskin/cdrskin.c Always considering mode page 2A when looking for min and max speed ------------------------------------ cycle - cdrskin-1.2.7 - 2013.03.05.185655 * Bug fix: On some drives the request for minimum speed yielded maximum speed * New cdrskin option --list_speeds 2013.03.12.114739 [4987] libburn/write.c Avoiding SYNCHRONIZE CACHE if DVD track preparation has failed 18 Mar 2013 [4994] svn copy -m "Branching for libburn release 1.2.8" http://svn.libburnia-project.org/libburn/trunk http://svn.libburnia-project.org/libburn/branches/1.2.8 2013.03.18.080001 [4997] Makefile.am configure.ac README libburn/libburn.h cdrskin/cdrskin.c cdrskin/cdrskin.1 cdrskin/README cdrskin/compile_cdrskin.sh cdrskin/cdrskin_timestamp.h cdrskin/cdrskin_eng.html Made number transition to 1.2.8 18 Mar 2013 [4998] - cdrskin/add_ts_changes_to_libburn_1_2_6 - cdrskin/add_ts_changes_to_libburn_1_2_7 + cdrskin/add_ts_changes_to_libburn_1_2_8 + cdrskin/add_ts_changes_to_libburn_1_2_9 Updated cdrskin tarball generator 18 Mar 2013 [4999] ChangeLog cdrskin/changelog.txt Updated change log ----------------------------------- release - libburn-1.2.8 - 2013.03.18.080001 * -toc and -minfo now report about tracks in the incomplete session * New API call burn_disc_get_incomplete_sessions() * New burn_toc_entry component .track_status_bits * Bug fix: All CD tracks were reported with the sizes of the tracks in the first session. Regression introduced with version 1.2.0 (rev 4552). * Bug fix: On some drives the request for minimum speed yielded maximum speed * New cdrskin option --list_speeds 2013.03.18.210519 [5007] Makefile.am configure.ac README libburn/libburn.h cdrskin/cdrskin.c cdrskin/cdrskin.1 cdrskin/README cdrskin/compile_cdrskin.sh cdrskin/cdrskin_timestamp.h cdrskin/cdrskin_eng.html Made number transition to 1.2.9 18 Mar 2013 [4996] - cdrskin/add_ts_changes_to_libburn_1_2_6 - cdrskin/add_ts_changes_to_libburn_1_2_7 + cdrskin/add_ts_changes_to_libburn_1_2_8 + cdrskin/add_ts_changes_to_libburn_1_2_9 Updated cdrskin tarball generator 18 Mar 2013 [5008] ChangeLog cdrskin/changelog.txt Updated change log 18 Mar 2013 [5009] svn move -m libburn release 1.2.8 is ready http://svn.libburnia-project.org/libburn/branches/1.2.8 http://svn.libburnia-project.org/libburn/tags/1.2.8 ------------------------------------ cycle - cdrskin-1.2.9 - 2013.03.18.211611 2013.04.01.121637 [5013] cdrskin/cdrskin.c Forgot to increment cdrskin version number 2013.04.01.121851 [5014] libburn/mmc.c libburn/libdax_msgs.h Bug fix: Formatting of BD-RE used certification regardless of drive capabilities 01 Apr 2013 [5015] ChangeLog cdrskin/cdrskin_eng.html cdrskin/changelog.txt Updated change log ------------------------------------ cycle - cdrskin-1.2.9 - 2013.04.01.125750 Bug fix: Formatting of BD-RE used certification regardless of drive capabilities 2013.05.10.064018 [5034] cdrskin/cdrskin.c Bug fix: DVD+R with damaged TOC were reported by -minfo with wrong end address 2013.05.10.072542 [5035] libburn/libdax_msgs.h Added new item to list of error codes 10 May 2013 [5036] ChangeLog cdrskin/cdrskin_eng.html cdrskin/changelog.txt Updated change log ------------------------------------ cycle - cdrskin-1.2.9 - 2013.05.10.073212 Bug fix: DVD+R with damaged TOC were reported by -minfo with wrong end address 17 May 2013 [5044] svn copy -m Branching for libburn release 1.3.0 2013.05.17.090001 [5045] Makefile.am configure.ac README libburn/libburn.h cdrskin/cdrskin.c cdrskin/cdrskin.1 cdrskin/README cdrskin/compile_cdrskin.sh cdrskin/cdrskin_timestamp.h cdrskin/cdrskin_eng.html Made number transition to 1.3.0 17 May 2013 [5046] - cdrskin/add_ts_changes_to_libburn_1_2_8 - cdrskin/add_ts_changes_to_libburn_1_2_9 + cdrskin/add_ts_changes_to_libburn_1_3_0 + cdrskin/add_ts_changes_to_libburn_1_3_1 Updated cdrskin tarball generator 17 May 2013 [5047] ChangeLog cdrskin/cdrskin_eng.html cdrskin/changelog.txt Updated change log ----------------------------------- release - libburn-1.3.0 - 2013.05.17.090001 * Bug fix: Full formatting of BD-RE used certification regardless of drive capabilities * Bug fix: DVD+R with damaged TOC were reported by -minfo with wrong end address 17 May 2013 [5051] - cdrskin/add_ts_changes_to_libburn_1_2_8 - cdrskin/add_ts_changes_to_libburn_1_2_9 + cdrskin/add_ts_changes_to_libburn_1_3_0 + cdrskin/add_ts_changes_to_libburn_1_3_1 Updated cdrskin tarball generator 2013.05.17.180032 [5052] Makefile.am configure.ac README libburn/libburn.h cdrskin/cdrskin.c cdrskin/cdrskin.1 cdrskin/README cdrskin/compile_cdrskin.sh cdrskin/cdrskin_timestamp.h cdrskin/cdrskin_eng.html Made number transition to 1.3.1 17 May 2013 [5053] ChangeLog cdrskin/changelog.txt Updated change log 17 May 2013 [5054] svn move -m libburn release 1.3.0 is ready ------------------------------------ cycle - cdrskin-1.3.1 - 2013.05.17.181442 2013.05.19.114643 [5059] libburn/libburn.h libburn/cdtext.c doc/cdtext.txt libburn/libburn.ver New API call burn_make_input_sheet_v07t() 2013.05.19.114854 [5060] cdrskin/cdrskin.c cdrskin/cdrskin.1 New option textfile_to_v07t= 2013.05.19.154838 [5061] cdrskin/cdrskin.c cdrskin/cdrskin.1 New options cdtext_to_textfile= and cdtext_to_v07t= 2013.05.20.104814 [5062] libburn/libburn.h libburn/cdtext.c libburn/libdax_msgs.h API call burn_session_input_sheet_v07t(): read multiple blocks from same file 2013.05.20.110128 [5063] cdrskin/cdrskin.c cdrskin/cdrskin.1 Allowed option input_sheet_v07t= to read multiple blocks from same file 2013.05.20.124448 [5064] libburn/cdtext.c Bug fixes with new API call burn_make_input_sheet_v07t() 2013.05.20.124520 [5065] cdrskin/cdrskin.c Closed memory leak introduced by rev 5063 20 May 2013 [5066] ChangeLog cdrskin/cdrskin_eng.html cdrskin/changelog.txt Updated change log ------------------------------------ cycle - cdrskin-1.3.1 - 2013.05.20.141737 * New API call burn_make_input_sheet_v07t() * New option textfile_to_v07t= * New options cdtext_to_textfile= and cdtext_to_v07t= * API call burn_session_input_sheet_v07t(): read multiple blocks from same file 2013.05.21.081819 [5067] cdrskin/cdrskin.c Defaulting -sao -multi to -tao -multi if -sao -multi is not possible 2013.05.23.154249 [5068] libburn/libburn.h libburn/file.c libburn/util.h libburn/util.c libburn/libdax_msgs.h libburn/libdax_msgs.c libburn/libburn.ver New API calls burn_drive_extract_audio(), burn_drive_extract_audio_track() 2013.05.23.154249 [5069] cdrskin/cdrskin.c cdrskin/cdrskin.1 New cdrskin options extract_audio_to= , extract_tracks= , extract_basename= , --extract_dap 23 May 2013 [5070] ChangeLog cdrskin/cdrskin_eng.html cdrskin/changelog.txt Updated change log ------------------------------------ cycle - cdrskin-1.3.1 - 2013.05.23.155617 * New API calls burn_drive_extract_audio(), burn_drive_extract_audio_track() * New cdrskin options extract_audio_to= , extract_tracks= , extract_basename= , --extract_dap 23 May 2013 [5071] doc/cdtext.txt Updated documentation about CD-TEXT 2013.05.26.185945 [5072] cdrskin/cdrskin.c Luring K3B into using -xa rather than -xa1 2013.05.30.133008 [5076] cdrskin/cdrskin.c Bug fix: cdrskin -msinfo on DVD and BD reported old session start == next writable address. Regression introduced by version 1.2.8 (rev 4956). [] ChangeLog cdrskin/cdrskin_eng.html cdrskin/changelog.txt Updated change log ------------------------------------ cycle - cdrskin-1.3.1 - 2013.05.30.133756 * Bug fix: cdrskin -msinfo on DVD and BD reported old session start == next writable address. Regression introduced by version 1.2.8 (rev 4956). 31 May 2013 [5079] svn copy -m Branching for libburn bugfix release 1.3.0.pl01 http://svn.libburnia-project.org/libburn/tags/1.3.0 http://svn.libburnia-project.org/libburn/branches/1.3.0.pl01 2013.05.31.080001 [5080] cdrskin/cdrskin.c Bug fix: cdrskin -msinfo on DVD and BD reported old session start = next writable address. Regression introduced by version 1.2.8 (rev 4956). 31 May 2013 [5081] README cdrskin/README ChangeLog cdrskin/cdrskin_eng.html cdrskin/changelog.txt Mentioned bug fix and pl01 31 May 2013 [5082] svn move -m libburn bugfix release 1.3.0.pl01 is ready http://svn.libburnia-project.org/libburn/branches/1.3.0.pl01 http://svn.libburnia-project.org/libburn/tags/1.3.0.pl01 ------------------------------ release - libburn-1.3.0.pl01 - 2013.05.31.080001 * Bug fix: cdrskin -msinfo on DVD and BD reported old session start = next writable address. Regression introduced by version 1.2.8 (rev 4956). 31 May 2013 [5083] README ChangeLog cdrskin/cdrskin_eng.html cdrskin/changelog.txt Mentioned bug fix and pl01 2013.06.09.152602 [5087] libburn/transport.h libburn/init.h libburn/init.c libburn/util.h libburn/util.c libburn/spc.h libburn/spc.c libburn/sg-linux.c libburn/sg-solaris.c libburn/sg-libcdio.c libburn/sg-freebsd.c Improved granularity of SCSI log time measurement and added absolute timestamp 2013.06.09.154237 [5088] libburn/util.c Prepared for optional use of clock_gettime() 2013.06.09.163052 [5089] libburn/util.c libburn/spc.c Some polishing of SCSI log time measurement 12 Jun 2013 [5090] ChangeLog cdrskin/cdrskin_eng.html cdrskin/changelog.txt Updated change log ------------------------------------ cycle - cdrskin-1.3.1 - 2013.06.12.104457 * Improved granularity of SCSI log time measurement, now with timestamp 24 Jun 2013 [5091] test/telltoc.c Removed inactive test code from telltoc.c 2013.06.28.104134 [5093] cdrskin/cdrskin.c Making sure in cdrskin that off_t is large enough before starting libburn 2013.06.28.104316 [5094] cdrskin/cdrskin.c Removed an obsolete note message from cdrskin --devices 2013.07.01.155958 [5097] libburn/libburn.h libburn/init.c libburn/cleanup.c New mode bit8 with burn_set_signal_handling() to particularly ignore SIGPIPE 2013.07.08.145600 [5110] libburn/cleanup.c Corrected typo in a comment 2013.07.08.151826 [5111] cdrskin/cdrskin.c cdrskin/cdrskin.1 New option --pacifier_with_newline 2013.07.21.170714 [5112] libburn/os-dummy.h libburn/os-freebsd.h libburn/os-libcdio.h libburn/os-linux.h libburn/os-solaris.h Bug fix: The signal handler aborted on SIGCONT, SIGTSTP, SIGTTIN, SIGTTOU 2013.07.29.091415 [5114] libburn/libburn.h Reacted on warnings of Debian build service about doxygen flaws 2013.08.04.100247 [5116] configure.ac libburn/write.c cdrskin/cdrskin.1 Changed default write chunk size for BD to 64 KiB 2013.08.04.124449 [5122] libburn/libburn.h Reacted on advise from Helmut Grohne to avoid confusion of doxygen 04 Aug 2013 [5124] doc/doxygen.conf.in Update of doxygen configuration for version 1.8.4 provided by George Danchev 07 Aug 2013 [5125] svn copy -m Branching for libburn release 1.3.2 2013.08.07.093001 [5126] Makefile.am configure.ac README libburn/libburn.h cdrskin/cdrskin.c cdrskin/cdrskin.1 cdrskin/README cdrskin/compile_cdrskin.sh cdrskin/cdrskin_timestamp.h cdrskin/cdrskin_eng.html Made number transition to 1.3.2 07 Aug 2013 [5127] - cdrskin/add_ts_changes_to_libburn_1_3_0 - cdrskin/add_ts_changes_to_libburn_1_3_1 + cdrskin/add_ts_changes_to_libburn_1_3_2 + cdrskin/add_ts_changes_to_libburn_1_3_3 Updated cdrskin tarball generator 07 Aug 2013 [5128] ChangeLog cdrskin/changelog.txt Documented changes and release timestamp ----------------------------------- release - cdrskin-1.3.2 - 2013.08.07.093001 * Bug fix: cdrskin -msinfo on DVD and BD reported old session start = next writable address. Regression introduced by version 1.2.8 (rev 4956). * Bug fix: The signal handler aborted on SIGCONT, SIGTSTP, SIGTTIN, SIGTTOU * New API call burn_make_input_sheet_v07t() * API call burn_session_input_sheet_v07t(): read multiple blocks from same file * New API calls burn_drive_extract_audio(), burn_drive_extract_audio_track() * New cdrskin option textfile_to_v07t= * New cdrskin options cdtext_to_textfile= and cdtext_to_v07t= * New cdrskin options extract_audio_to= , extract_tracks= , extract_basename= , --extract_dap * New cdrskin option --pacifier_with_newline * Improved granularity of SCSI log time measurement, now with timestamp * Optional "make doc" now demands doxygen 1.8.4 2013.08.07.134744 [5132] Makefile.am configure.ac README libburn/libburn.h cdrskin/cdrskin.c cdrskin/cdrskin.1 cdrskin/README cdrskin/compile_cdrskin.sh cdrskin/cdrskin_timestamp.h cdrskin/cdrskin_eng.html Made number transition to 1.3.3 07 Aug 2013 [5133] - cdrskin/add_ts_changes_to_libburn_1_3_0 - cdrskin/add_ts_changes_to_libburn_1_3_1 + cdrskin/add_ts_changes_to_libburn_1_3_2 + cdrskin/add_ts_changes_to_libburn_1_3_3 Updated cdrskin tarball generator 07 Aug 2013 [5134] ChangeLog cdrskin/changelog.txt Updated change log 07 Aug 2013 [5135] svn move -m libburn release 1.3.2 is ready http://svn.libburnia-project.org/libburn/branches/1.3.2 http://svn.libburnia-project.org/libburn/tags/1.3.2 ------------------------------------ cycle - cdrskin-1.3.3 - 2013.08.07.135823 2013.09.04.105934 [5145] libburn/mmc.c Catching and defaulting mad responses to READ BUFFER CAPACITY 2013.09.04.110910 [5146] [5147] cdrskin/cdrskin.c Closed a small memory leak with cdrskin -msinfo 2013.09.04.141706 [5148] cdrskin/cdrskin.c Reacted on warnings of PLD Linux 2013.09.05.084834 [5152] libburn/file.c libburn/mmc.c Reacted on warnings of PLD Linux build log 2013.09.16.172745 [5157] libburn/async.c Reacted on warning of Debian buildd with clang 2013.10.03.100011 [5158] cdrskin/cdrskin.c Made -version message more acceptable for K3B. Proposal of Omegaweapon. 2013.10.09.092306 [5161] libburn/mmc.c Separately determining the maximum speeds for writing and reading 2013.10.09.134543 [5163] libburn/mmc.c Forgot to disable a debugging message 2013.10.10.161931 [5164] libburn/drive.c libburn/spc.c libburn/libdax_msgs.h Bug fix: Drive error reports were ignored during blanking and formatting 2013.10.28.104957 [5168] libburn/libburn.h libburn/transport.h libburn/drive.c libburn/options.h libburn/options.c libburn/write.c libburn/mmc.c libburn/libburn.ver New API calls burn_drive_was_feat21_failure(), burn_write_opts_set_fail21h_sev() 2013.11.08.095023 [5172] libburn/write.c Closed potential memory leak introduced by rev 5168 2013.11.08.095213 [5173] [5174] libburn/mmc.c Enforcing reasonable maximum read speeds even if the drive is lying 2013.11.10.163403 [5175] libburn/libburn.h libburn/drive.c libburn/libburn.ver New API call burn_disc_pretend_full_uncond() 2013.11.11.160915 [5177] libburn/mmc.c Bug fix: Drive LG BH16NS40 stalled on inspection of unformatted DVD+RW 11 Nov 2013 [] ChangeLog cdrskin/cdrskin_eng.html cdrskin/changelog.txt Updated change log ------------------------------------ cycle - cdrskin-1.3.3 - 2013.11.11.172016 * Bug fix: Drive error reports were ignored during blanking and formatting * Bug fix: Drive LG BH16NS40 stalled on inspection of unformatted DVD+RW * New API call burn_disc_pretend_full_uncond() 2013.11.14.101636 [5180] libburn/libdax_msgs.h libburn/spc.h libburn/spc.c libburn/sg-linux.c Improved reaction on Linux SG_IO transport problems 2013.11.15.102314 [5182] libburn/mmc.c Enforcing reasonable minimum read speeds even if the drive is lying 2013.11.16.170431 [5184] libburn/options.c Prevented a memory leak that in most cases was closed by a race condition 2013.11.17.102351 [5185] libburn/write.c Resetting the drive failure status before starting random-access writing 2013.11.17.152544 [5187] libburn/sg-linux.c Corrected bugs introduced with rev 5180 2013.11.21.092012 [5189] libburn/drive.c Better reaction on drive errors during burn_drive_scan_and_grab() 12 Dec 2013 [5192] svn copy -m Branching for libburn release 1.3.4 http://svn.libburnia-project.org/libburn/trunk http://svn.libburnia-project.org/libburn/branches/1.3.4 2013.12.12.093001 [5193] Makefile.am configure.ac README libburn/libburn.h cdrskin/cdrskin.c cdrskin/cdrskin.1 cdrskin/README cdrskin/compile_cdrskin.sh cdrskin/cdrskin_timestamp.h cdrskin/cdrskin_eng.html Made number transition to 1.3.4 12 Dec 2013 [5194] - cdrskin/add_ts_changes_to_libburn_1_3_2 - cdrskin/add_ts_changes_to_libburn_1_3_3 + cdrskin/add_ts_changes_to_libburn_1_3_4 + cdrskin/add_ts_changes_to_libburn_1_3_5 Updated cdrskin tarball generator 12 Dec 2013 [5195] ChangeLog cdrskin/changelog.txt Documented changes and release timestamp ----------------------------------- release - cdrskin-1.3.4 - 2013.12.12.093001 * Bug fix: Drive error reports were ignored during blanking and formatting * Bug fix: Drive LG BH16NS40 stalled on inspection of unformatted DVD+RW * New API call burn_disc_pretend_full_uncond() 2013.12.12.140531 [5199] Makefile.am configure.ac README libburn/libburn.h cdrskin/cdrskin.c cdrskin/cdrskin.1 cdrskin/README cdrskin/compile_cdrskin.sh cdrskin/cdrskin_timestamp.h cdrskin/cdrskin_eng.html Made number transition to 1.3.5 12 Dec 2013 [5200] - cdrskin/add_ts_changes_to_libburn_1_3_2 - cdrskin/add_ts_changes_to_libburn_1_3_3 + cdrskin/add_ts_changes_to_libburn_1_3_4 + cdrskin/add_ts_changes_to_libburn_1_3_5 Updated cdrskin tarball generator 12 Dec 2013 [5201] ChangeLog cdrskin/changelog.txt Documented changes and release timestamp ------------------------------------ cycle - cdrskin-1.3.5 - 2013.12.12.140531 12 Dec 2013 [5202] svn move -m libburn release 1.3.4 is ready http://svn.libburnia-project.org/libburn/branches/1.3.4 http://svn.libburnia-project.org/libburn/tags/1.3.4 2014.01.07.115938 [5215] libburn/transport.h libburn/drive.h libburn/drive.c libburn/mmc.c Registering all drive-media feature descriptors in burn_drive 2014.01.09.132159 [5216] libburn/libburn.h libburn/spc.c libburn/mmc.h libburn/mmc.c Interpreting feature 0x107 when deciding from where to get speed info 2014.01.09.214841 [5218] libburn/sg-linux.c Adapted Linux SG_IO adapter to scsi/sg.h of git.kernel.org 2014.01.15.174741 [5225] libburn/sg-linux.c Updated copyright claim in sg-linux.c 2014.01.15.174907 [5226] libburn/drive.h libburn/drive.c libburn/write.c Improved handling of stdio pseudo-drives after aborted burn runs 2014.02.04.112944 [5233] libburn/transport.h libburn/spc.h libburn/spc.c Implemented a generic verification whether a SPC device is a MMC device 2014.02.05.124803 [5234] libburn/spc.c Trying to better handle MMC violating replies of MODE SENSE (Block Descriptors) 2014.02.05.185801 [5235] libburn/spc.c Fixed bugs introduced with previous commit 2014.02.05.191839 [5237] libburn/libburn.h libburn/transport.h libburn/drive.c libburn/options.c libburn/async.c libburn/spc.c libburn/mmc.c libburn/sg-freebsd.c Prepared for possible demise of mode page 2A 2014.02.07.180650 [5238] libburn/write.c Avoiding to have two file descriptors open to the same stdio drive 2014.02.10.213159 [5244] libburn/drive.c libburn/spc.c libburn/mmc.c Being more rugged towards missing MODE SENSE info 2014.02.10.213500 [5245] libburn/os.h libburn/sg.c + libburn/os-netbsd.h + libburn/sg-netbsd.c Inmplemented a system adapter for NetBSD 10 Feb 2014 [5246] Makefile.am Introduced NetBSD system adapter in tarball generator 11 Feb 2014 [5247] configure.ac acinclude.m4 Silenced warnings about -Wchar-subscripts, added /usr/local for NetBSD 12 Feb 2014 [5249] doc/comments cdrskin/README Mentioned support for NetBSD 2014.02.13.205358 [5252] libburn/sg-netbsd.c Corrected size determination of NetBSD block devices 2014.02.14.200129 [5253] libburn/drive.c Improved workaround for missing mode page 2A 2014.02.16.203859 [5254] libburn/spc.c Inquiring GET PERFORMANCE independently of existence of mode page 2A 2014.02.19.111017 [5255] libburn/os.h libburn/sg.c libburn/sg-netbsd.c Removed Linux compilability mock-up from sg-netbsd.c 2014.03.01.101537 [5257] libburn/libburn.h libburn/transport.h libburn/drive.c Improved emulation of mode page 2A 04 Mar 2014 [5260] svn copy -m Branching for libburn release 1.3.6 http://svn.libburnia-project.org/libburn/trunk http://svn.libburnia-project.org/libburn/branches/1.3.6 2014.03.04.110001 [5261] Makefile.am configure.ac README libburn/libburn.h cdrskin/cdrskin.c cdrskin/cdrskin.1 cdrskin/README cdrskin/compile_cdrskin.sh cdrskin/cdrskin_timestamp.h cdrskin/cdrskin_eng.html Made number transition to 1.3.6 04 Mar 2014 [5262] - cdrskin/add_ts_changes_to_libburn_1_3_4 - cdrskin/add_ts_changes_to_libburn_1_3_5 + cdrskin/add_ts_changes_to_libburn_1_3_6 + cdrskin/add_ts_changes_to_libburn_1_3_7 Updated cdrskin tarball generator 04 Mar 2014 [5263] ChangeLog cdrskin/changelog.txt Documented changes and release timestamp ----------------------------------- release - cdrskin-1.3.6 - 2014.03.04.110001 * New system adapter for NetBSD 2014.03.04.161835 [5269] Makefile.am configure.ac README libburn/libburn.h cdrskin/cdrskin.c cdrskin/cdrskin.1 cdrskin/README cdrskin/compile_cdrskin.sh cdrskin/cdrskin_timestamp.h cdrskin/cdrskin_eng.html Made number transition to 1.3.7 04 Mar 2014 [5270] - cdrskin/add_ts_changes_to_libburn_1_3_4 - cdrskin/add_ts_changes_to_libburn_1_3_5 + cdrskin/add_ts_changes_to_libburn_1_3_6 + cdrskin/add_ts_changes_to_libburn_1_3_7 Updated cdrskin tarball generator 04 Mar 2014 [5271] ChangeLog cdrskin/changelog.txt Documented changes and release timestamp ------------------------------------ cycle - cdrskin-1.3.7 - 2014.03.04.162814 04 Mar 2014 [5272] svn move -m libburn release 1.3.6 is ready http://svn.libburnia-project.org/libburn/branches/1.3.6 http://svn.libburnia-project.org/libburn/tags/1.3.6 2014.03.14.095413 [5281] libburn/write.c Bug fix: CD TAO with multiple tracks could cause a buffer overrun 14 Mar 2013 [5282] ChangeLog cdrskin/cdrskin_eng.html Updated change log ------------------------------------ cycle - cdrskin-1.3.7 - 2014.03.14.100747 * Bug fix: CD TAO with multiple tracks could cause a buffer overrun 2014.03.17.221810 [5284] libburn/sg.c Bug fix: Compilation warning for unsupported systems mutated into an error 18 Mar 2014 [5285] svn copy -m Branching for libburn bugfix release 1.3.6.pl01 http://svn.libburnia-project.org/libburn/tags/1.3.6 http://svn.libburnia-project.org/libburn/branches/1.3.6.pl01 2014.03.18.100001 [5286 tag 1.3.6.pl01] libburn/write.c Bug fix: CD TAO with multiple tracks could cause a buffer overrun 2014.03.18.100001 [5287 tag 1.3.6.pl01] libburn/sg.c Bug fix: Compilation warning for unsupported systems mutated into an error 18 Mar 2014 [5291] svn move -m libburn bugfix release 1.3.6.pl01 is ready http://svn.libburnia-project.org/libburn/branches/1.3.6.pl01 http://svn.libburnia-project.org/libburn/tags/1.3.6.pl01 ------------------------------ release - cdrskin-1.3.6.pl01 - 2014.03.18.100001 * Bug fix: Compilation warning for unsupported systems mutated into an error * Bug fix: CD TAO with multiple tracks could cause a buffer overrun 2014.04.06.111004 [5297] cdrskin/cdrskin.c Bug fix: Minimum drive buffer fill was measured before the buffer could get full 2014.04.09.152035 [5302] libburn/libburn.h libburn/options.c libburn/write.c Bug fix: A final fsync(2) was performed with stdio drives, even if not desired 2014.04.13.120906 [5309] libburn/write.c Restoring capability of burn_random_access_write() to fsync() (lost in rev 5302) 2014.04.14.103311 [5310] libburn/write.c Retrying write(2) if it returns a short non-negative write count 2014.04.19.114816 [5315] libburn/libburn.h libburn/read.c Improved read retrying with DVD and BD media 2014.04.29.061645 [5324] libburn/async.c Bug fix: Wrong stack usage caused SIGBUS on sparc when compiled by gcc -O2 2014.05.03.103448 [5328] libburn/mmc.c Bug fix: A failed MMC BLANK command did not cause error indication by libburn 2014.06.09.183251 [5335] libburn/libburn.h libburn/drive.c libburn/util.h libburn/util.c libburn/sg.h libburn/sg-dummy.c libburn/sg-freebsd.c libburn/sg-freebsd-port.c libburn/sg-libcdio.c libburn/sg-linux.c libburn/sg-netbsd.c libburn/sg-solaris.c Improved drive capacity estimation for sparse regular files 2014.06.10.130721 [5336] libburn/drive.c Fixed a SIGSEGV introduced by previous revision 2014.06.20.145224 [5346] libburn/sg-netbsd.c Reacted on compiler warning of gcc on NetBSD-current 27 Jun 2014 [5348] svn copy -m Branching for libburn release 1.3.8 http://svn.libburnia-project.org/libburn/trunk http://svn.libburnia-project.org/libburn/branches/1.3.8 2014.06.28.060001 [5349] Makefile.am configure.ac README libburn/libburn.h cdrskin/cdrskin.c cdrskin/cdrskin.1 cdrskin/README cdrskin/compile_cdrskin.sh cdrskin/cdrskin_timestamp.h cdrskin/cdrskin_eng.html Made number transition to 1.3.8 27 Jun 2014 [5350] - cdrskin/add_ts_changes_to_libburn_1_3_6 - cdrskin/add_ts_changes_to_libburn_1_3_7 + cdrskin/add_ts_changes_to_libburn_1_3_8 + cdrskin/add_ts_changes_to_libburn_1_3_9 Updated cdrskin tarball generator 27 Jun 2014 [5351] ChangeLog cdrskin/changelog.txt Documented changes and release timestamp ----------------------------------- release - cdrskin-1.3.8 - 2014.06.28.060001 * Bug fix: Wrong stack usage caused SIGBUS on sparc when compiled by gcc -O2 * Bug fix: Minimum drive buffer fill was measured by cdrskin before the buffer could get full * Bug fix: A failed MMC BLANK command did not cause error indication by libburn * Bug fix: A final fsync(2) was performed with stdio drives, even if not desired 2014.06.28.062807 [5356] Makefile.am configure.ac README libburn/libburn.h cdrskin/cdrskin.c cdrskin/cdrskin.1 cdrskin/README cdrskin/compile_cdrskin.sh cdrskin/cdrskin_timestamp.h cdrskin/cdrskin_eng.html Made number transition to 1.3.9 28 Jun 2014 [5357] - cdrskin/add_ts_changes_to_libburn_1_3_6 - cdrskin/add_ts_changes_to_libburn_1_3_7 + cdrskin/add_ts_changes_to_libburn_1_3_8 + cdrskin/add_ts_changes_to_libburn_1_3_9 Updated cdrskin tarball generator 28 Jun 2014 [5358] ChangeLog cdrskin/changelog.txt Documented changes and release timestamp ------------------------------------ cycle - cdrskin-1.3.9 - 2014.06.28.062807 28 Jun 2014 [5359] svn move -m libburn release 1.3.8 is ready http://svn.libburnia-project.org/libburn/branches/1.3.8 http://svn.libburnia-project.org/libburn/tags/1.3.8 06 Jul 2014 [5364] COPYRIGHT Updated copyright date 2014.07.14.180122 [5366] libburn/drive.c Fixed a wrong read access to memory. Reported by valgrind of lian jianfei, 2014.07.31.115829 [5367] libburn/spc.h libburn/spc.c New internal function for SCSI-logging arbitrary texts 2014.07.31.122752 [5368] libburn/sg-linux.c Debugging macro Libburn_debug_dxferP to check sg_io_hdr_t.dxferp 2014.07.31.123105 [5369] libburn/libdax_msgs.h libburn/mmc.c Keeping GET CONFIGURATION from requesting more than 4 KB of data 2014.08.14.085604 [5370] libburn/spc.c Improved error message for erase failures 2014.08.14.085850 [5371] libburn/mmc.c Small correction of rev5369 2014.08.31.110308 [5373] libburn/drive.c libburn/mmc.c Reduced number of GET CONFIGURATION transactions 2014.08.31.121421 [5374] libburn/drive.c Removed obsolete conditional code 2014.09.01.161217 [5375] libburn/libburn.h libburn/transport.h libburn/read.c libburn/spc.c libburn/mmc.c New flag bit5 with burn_read_data() and burn_read_audio() 2014.09.01.183908 [5376] libburn/spc.c Fixed a bug introduced with previous revision 2014.11.23.190942 [5395] cdrskin/cdrskin.c Bug fix: Double free with cdrskin -vvv. Introduced with rev 5065, version 1.3.1 2014.11.26.164119 [5397] libburn/drive.c libburn/file.c libburn/read.c libburn/write.c libburn/structure.c libburn/sector.c libburn/mmc.c libburn/sg-dummy.c libburn/sg-libcdio.c libburn/libdax_audioxtr.c libburn/ddlpa.c Equipped all non-system-dependent open(2) calls with O_BINARY 2014.12.06.175109 [5399] libburn/sg-solaris.c Added debugging messages for drive recognition on Solaris 2014.12.21.221245 [5400] acinclude.m4 libburn/sg-solaris.c Using libvolmgt on older Solaris 2014.12.29.105910 [5403] Makefile.am Fixed a typo in message of make install. Thanks to Jakub Wilk. 2015.03.08.073635 [5412] libburn/spc.c Human readable error message for 3 32 00 2015.05.17.083420 [5426] libburn/libburn.h doc/mediainfo.txt Corrected outdated references to function name burn_get_media_product_id() 17 May 2015 [5427] svn copy -m Branching for libburn release 1.4.0 http://svn.libburnia-project.org/libburn/trunk http://svn.libburnia-project.org/libburn/branches/1.4.0 2015.05.17.110001 [5428] Makefile.am configure.ac README libburn/libburn.h cdrskin/cdrskin.c cdrskin/cdrskin.1 cdrskin/README cdrskin/compile_cdrskin.sh cdrskin/cdrskin_timestamp.h cdrskin/cdrskin_eng.html Made number transition to 1.4.0 17 May 2015 [5429] - cdrskin/add_ts_changes_to_libburn_1_3_8 - cdrskin/add_ts_changes_to_libburn_1_3_9 + cdrskin/add_ts_changes_to_libburn_1_4_0 + cdrskin/add_ts_changes_to_libburn_1_4_1 Updated cdrskin tarball generator 17 May 2015 [5430] ChangeLog cdrskin/changelog.txt Documented changes and release timestamp 17 May 2015 [5435] acinclude.m4 Made sure that cdrskin on Solaris gets linked with libvolmgt ----------------------------------- release - cdrskin-1.4.0 - 2015.05.17.110001 * Bug fix: Double free with cdrskin -vvv. Introduced with rev 5065, version 1.3.1 * Bug fix: Wrong read access to memory. Reported by valgrind of lian jianfei. 2015.05.17.193727 [5437] acinclude.m4 Made sure that cdrskin on Solaris gets linked with libvolmgt 2015.05.17.200218 [5438] Makefile.am configure.ac README libburn/libburn.h cdrskin/cdrskin.c cdrskin/cdrskin.1 cdrskin/README cdrskin/compile_cdrskin.sh cdrskin/cdrskin_timestamp.h cdrskin/cdrskin_eng.html Made number transition to 1.4.1 17 May 2015 [5439] - cdrskin/add_ts_changes_to_libburn_1_3_8 - cdrskin/add_ts_changes_to_libburn_1_3_9 + cdrskin/add_ts_changes_to_libburn_1_4_0 + cdrskin/add_ts_changes_to_libburn_1_4_1 Updated cdrskin tarball generator 17 May 2015 [5440] ChangeLog cdrskin/changelog.txt Updated change log ------------------------------------ cycle - cdrskin-1.4.1 - 2015.05.17.202234 17 May 2015 [5441] svn move -m libburn release 1.4.0 is ready http://svn.libburnia-project.org/libburn/branches/1.4.0 http://svn.libburnia-project.org/libburn/tags/1.4.0 18 May 2015 [5442] doc/doxygen.conf.in Trying to become suitable for Debian reproducible builds 2015.05.25.204252 [5448] libburn/util.c doc/mediainfo.txt Registered BD-R producer Millenniata. Thanks to Lucjan Bryndza. 2015.05.26.054224 [5449] libburn/mmc.c libburn/util.c Bug fix: burn_disc_get_media_id() returned BD identifiers 2 chars too long 25 Jun 2015 [5452] cdrskin/README Mentioned option -use_libcdio of cdrskin/compile_cdrskin.sh 2015.06.25.192439 [5453] libburn/sg-linux.c Removed unused macro definitions 2015.08.01.135727 [5463] libburn/libburn.h libburn/sg-freebsd-port.c libburn/sg-libcdio.c libburn/sg-solaris.c libburn/sg-netbsd.c libburn/sg-linux.c libburn/sg-dummy.c cdrskin/cdrskin.c cdrskin/cdrfifo.h libburn/ecma130ab.c configure.ac README cdrskin/cdrskin.1 cdrskin/cdrskin_eng.html cdrskin/compile_cdrskin.sh cdrskin/make_timestamp.sh doc/cdtext.txt doc/comments doc/cookbook.txt doc/ddlp.txt test/libburner.c cdrskin/add_ts_changes_to_libburn_1_4_0 cdrskin/add_ts_changes_to_libburn_1_4_1 Changed wrong use of "resp." in docs 2015.08.02.141552 [5464] cdrskin/convert_man_to_html.sh + cdrskin/unite_html_b_line.c Reacting on changes in the output of my local man -H 2015.08.30.185208 [5471] libburn/libburn.h Small change in API documentation about burn_drive_set_buffer_waiting() 2015.08.30.185714 [5472] cdrskin/cdrskin.c cdrskin/cdrskin.1 New paramaters for option modesty_on_drive= timeout_sec, min_usec, max_usec 30 Aug 2015 [5473] libburn/mmc.c libburn/libdax_msgs.h cdrskin/cdrskin.1 Fixed typos reported by J.S.Junior 30Aug 2015 [5474] cdrskin/cdrskin.1 Avoiding to trigger lintian check "allows to allows one to" 2015.09.01.065852 [5475] libburn/libburn.h libburn/options.h libburn/mmc.c libburn/ecma130ab.c libburn/sg-linux.c libburn/sg-solaris.c libburn/sg-netbsd.c libburn/sg-libcdio.c libburn/sg-freebsd-port.c test/libburner.c test/telltoc.c README cdrskin/cdrskin.1 cdrskin/cdrskin_eng.html cdrskin/wiki_plain.txt doc/cookbook.txt More hunt for "allow to" 2015.09.17.160121 [5480] acinclude.m4 Recognizing again Debian GNU/kFreeBSD, regression by rev 5437 2015.09.23.110012 [5486] libburn/drive.c Bug fix: burn_disc_get_multi_caps() returned 2048 bytes too many in .start_range_high 23 Sep 2015 [5487] test/libburner.c test/telltoc.c Mutally mentioned the other demo program in their introdution comments 2015.10.18.125353 [5493] libburn/libburn.h libburn/transport.h libburn/drive.c libburn/spc.h libburn/spc.c libburn/mmc.c New API calls burn_drive_get_serial_no() and burn_drive_get_media_sno() 2015.10.18.133327 [5495] cdrskin/cdrskin.c New -toc output lines "Drive id" and "Media id" 2015.10.19.174459 [5496] cdrskin/cdrskin.c Bug fix: Media summary session count of blank and closed media was short by 1 23 Oct 2015 [5498] libburn/sg-linux.c Prevented potential use of file pointer after fopen() failed 2015.10.23.103324 [5499] libburn/spc.c Made sure that only existent CDB bytes get accessed by SCSI command logging. Coverity CID 21806. 2015.10.23.121415 [5500] libburn/sg-linux.c Completed rev 5498, which is a reaction on Coverity CID 21805. 2015.10.23.122644 [5501] libburn/spc.c Bug fix: Endless loop if transport error occurs while waiting for drive ready. 2015.10.23.123606 [5502] test/fake_au.c Checking program arguments of test/fake_au. Coverity CID 21832. 2015.10.23.124544 [5503] cdrskin/cdrskin.c Prevented use of an uninitialized variable. Coverity CID 21842. 2015.10.23.130707 [5504] libburn/sg-linux.c Removed surplus code statement which used uninitialized variable. Coverity CID 21843. 23 Oct 2015 [5505] [5506] test/poll.c Completed initialization of struct sigaction in test/poll.c. Coverity CID 21845. 2015.10.23.135526 [5507] cdrskin/cdrskin.c Moved unused variable into its ifdef case. Coverity CID 21799. 2015.10.23.140731 [5508] cdrskin/cdrskin.c Enabled display of pacifier state "formatting" in cdrskin. Coverity CID 21793. 2015.10.23.160546 [5509] libburn/drive.c Avoided a potential memory leak with debug messages. Coverity CID 21808. 2015.10.23.162527 [5510] libburn/options.c Closed a potential memory leak with CD-TEXT production. Coverity CID 21809. 2015.10.23.164931 [5511] libburn/write.c Closed a potential memory leak with writing to stdio pseudo drives. Coverity CID 21810. 2015.10.24.075251 [5512] cdrskin/cdrskin.c Closed memory leak with errors while attaching fifo. Coverity CID 21811. 24 Oct 2015 [5513] test/telltoc.c Closed memory leak in telltoc. Coverity CID 21812. 24 Oct 2015 [5514] test/telltoc.c Updated telltoc to BD and other old novelties. 24 Oct [5515] test/telltoc.c Closing output file pointer of telltoc --read_and_print. Coverity CID 21813. 24 Oct 2015 [5516] test/libburner.c Closed various memory leaks in libburner. Coverity CID 21814, CID 21815. 2015.10.26.092929 [5518] cdrskin/cdrskin.c Closed file pointer leak in case of error with audio source. Coverity CID 21816. 2015.10.26.102430 [5519] cdrskin/cdrskin.c Closed memory leak in case of burn failure. Coverity CID 21817. 2015.10.26.105324 [5520] libburn/cdtext.c libburn/libdax_msgs.h Avoiding to allocate empty buffer for texp packs. Indirectly Coverity CID 21818. 2015.10.26.105754 [5521] cdrskin/cdrskin.c Clarified the scope of an allocated variable. Coverity CID 21818. 2015.10.26.145305 [5522] cdrskin/cdrskin.c Distinguishing between self-opened and inherited file descriptors as track input. Coverity CID 21819. 2015.10.26.145941 [5523] libburn/structure.c Closed a memory leak with error opening audio input of CUE sheet. Coverity CID 21820. 2015.10.26.150529 [5524] libburn/structure.c Closed a file pointer leak with CUE file interpretation. Coverity CID 21821. 2015.10.26.151914 [5525] libburn/sg-linux.c Added missing break statement to SG_IO error reporting. Coverity CID 21803. 2015.10.26.153745 [5526] libburn/sector.c Corrected reaction on unsupported track modes. Coverity CID 21804. 2015.10.26.154728 [5527] libburn/mmc.c Preventing very improbable signed 32 bit overflow with MMC speed range. Coverity CID 21823. 2015.10.26.183813 [5528] libburn/drive.c Fixed memory waste by oversized feature descriptor objects. Coverity CID 21824. 2015.10.26.184231 [5529] libburn/libdax_audioxtr.c Removed overly optimistic test ocde for SUN audio. Coverity CID 21846. 2015.10.28.153929 [5530] libburn/write.c Removed a surplus test. Coverity CID 21796. 2015.10.28.162205 [5531] libburn/drive.c Closed memory leak with minor cdrskin jobs. Found by valgrind. 28 Oct 2015 [5532] test/fake_au.c Testing all arguments of fake_au for oversize. Coverity CID 21830. 2015.10.28.162537 [5533] [5534] cdrskin/cdrskin.c Prevented a quite unlikely buffer overflow by argument. Coverity CID 21827. 28 Oct 2015 [5535] test/telltoc.c Prevented a quite unlikely buffer overflow by argument. Coverity CID 21831. 2015.10.29.082150 [5536] cdrskin/cdrskin.c Cared for an improbable error case. Coverity CID 21784. 29 Oct 2015 [5537] Makefile.am test/structest.c Removed useless and faulty test/structest.c. Coverity CID 21785. 29 Oct 2015 [5538] libburn/libburn.ver Forgot to put burn_drive_get_serial_no and burn_drive_get_media_sno into API 29 Oct 2015 [5539] test/telltoc.c Handling failure to write to disk file. Coverity CID 21786. 2015.10.29.105609 [5540] libburn/mmc.c Removed a surplus development variable. Coverity CID 21795. 2015.10.31.122151 [5541] cdrskin/cdrskin.c Reacting on (improbable) failure of burn_disc_pretend_full(). Coverity CID 21847. 2015.11.01.102608 [5542] libburn/mmc.c Unified the tests against rogue GET CONFIGURATION replies. Coverity CID 21794. 2015.11.01.125502 [5543] libburn/mmc.c Corrected a mistake made in rev 5542. Coverity CID 28636. 2015.11.01.184659 [5544] libburn/structure.c Closed a memory leak with error around C-TEXT. Another try on Coverity CID 21818. 2015.11.01.194734 [5545] libburn/structure.c Took into respect that burn_session_by_cue_file() parameter text_packs may be NULL. 2015.11.01.195218 [5546] libburn/mmc.c Completed revision 5527. Coverity CID 21823. 02 Nov 2015 [5547] Corrected misperception of telltoc --read_and_print 1:. 2015.11.02.151241 [5548] libburn/mmc.c Completed revision 5527. Coverity CID 21823. 2015.11.25.093414 [5613] libburn/sg-freebsd.c Fixed a theoretical memory leak in actually unused code. Reported by cppcheck. 28 Nov 2015 [5614] svn copy -m Branching for libburn release 1.4.2 http://svn.libburnia-project.org/libburn/trunk http://svn.libburnia-project.org/libburn/branches/1.4.2 2015.11.28.120001 [5615] Makefile.am configure.ac README libburn/libburn.h cdrskin/cdrskin.c cdrskin/cdrskin.1 cdrskin/README cdrskin/compile_cdrskin.sh cdrskin/cdrskin_timestamp.h cdrskin/cdrskin_eng.html Made number transition to 1.4.2 28 Nov 2015 [5616] - cdrskin/add_ts_changes_to_libburn_1_4_0 - cdrskin/add_ts_changes_to_libburn_1_4_1 + cdrskin/add_ts_changes_to_libburn_1_4_2 + cdrskin/add_ts_changes_to_libburn_1_4_3 Updated cdrskin tarball generator 28 Nov 2015 [] ChangeLog cdrskin/changelog.txt Updated change log ----------------------------------- release - cdrskin-1.4.2 - 2015.11.28.120001 * Bug fix: burn_disc_get_media_id() returned BD identifiers 2 chars too long * Bug fix: burn_disc_get_multi_caps() returned 2048 bytes too many in caps.start_range_high * Bug fix: Media summary session count of blank and closed media was short by 1 * Bug fix: Endless loop if transport error occurs while waiting for drive ready * New API calls burn_drive_get_serial_no() and burn_drive_get_media_sno() * Result of a Coverity audit: 40+ code changes, but no easy-to-trigger bugs 2016.01.27.174553 [5653] cdrskin/cdrskin.c Bug fix: "failed to attach fifo" when burning from stdin. Regression of 1.4.2, rev 5522. ------------------------------ release - cdrskin-1.4.2.pl01 - 2016.01.29.100001 * Bug fix: "failed to attach fifo" when burning from stdin. Regression of 1.4.2, rev 5522. [] ChangeLog cdrskin/cdrskin_eng.html cdrskin/changelog.txt Updated change log ------------------------------------ cycle - cdrskin-1.4.3 - [] ChangeLog cdrskin/cdrskin_eng.html cdrskin/changelog.txt Updated change log ------------------------------------ cycle - cdrskin-1.4.3 - ********************************************************************** Important: When adding a public API function then add its name to file libburn/libburn.ver ********************************************************************** =============================================================================== TODO =============================================================================== CD-TEXT: - with SAO - libburn: - optionally genererate TOC pack type 0x88 with A[123] and track POINTS - .inf files - enforcing constraints: - examine how drives react on wodim's cue sheet of INDEX 00 == INDEX 01 qemu: - Re-assess benefit of BLKFLSBUF as of dvd+rw-tools/transport.hxx - Centralize SCSI log /tmp file opening Get sg-freebsd-port.c functional. Expose BD type from bytes 8+4 to 10+4 out of READ DISC STRUCTURE form 0. Expose Disc Size/Class/Version from byte 11+4. Better motivation of burn_set_signal_handling() in libburn.h. Explore MMC command GET EVENT STATUS NOTIFICATION -------------------------------- Solaris ----------------------------------- Locking of device files. Unmounting. Could need ioctl to obtain SCSI bus,target,lun from fd rather than name ( Subject: Re: [osol-help] DHCP configuration with fixed addresses pntadm -A 10.0.0.24 -f MANUAL -i 010008544255E7 -m 10.0.0.0 -y 10.0.0.0 ) --------------------------------- bugs ------------------------------------- - handle HD DVD profiles 0x50 "HD DVD-ROM", 0x51 "HD DVD-R", 0x52 "HD DVD-RAM" as readable. - Do something about drive->buffer asynchronous race conditions and dangerous use of temporary dynamic memory. (The various asynchronous operations use the same buffer pointer in struct burn_drive and let it point to their private memory. Of course, any problem is due to faulty application ... but then it is really hard to detect.) - Why are DVD+R tracks labeled "invisible" by dvd+rw-mediainfo ? Why does the DVD drive only show the first session ? READ TRACK INFORMATION[#5]: Track State: invisible Track Start Address: 954960*2KB Free Blocks: 0*2KB Track Size: 22784*2KB ROM Compatibility LBA: 265696 ------------------------------ end of bugs --------------------------------- Support for BD-R SRM+POW ? Enable profile 0x42 BD-R random recording Provide DVD+R DL layer break setter Check all SORRY and FATAL errors whether they should become FAILUREs What about cdrskin rc files ? Forward with fallback runs ? [] Emulate -dummy on overwriteables ? [] Emulate -dummy on DVD+R ? What about minimum track sizes ? (POWER OFF/ON , BUS RESET ?) After cooking: review of -do_diet ? growisofs.c : _LINUX_CAPABILITY_VERSION CAP_SYS_RAWIO SYS_capset ? Rectify mmc_read_atip speed interpretation. 12x media are reported as 10x. I never heard of 6x media. ----------------------------------------- long term intentions: [] -reset: ioctl(fd,CDROMRESET) ioctl(fd,SG_SCSI_RESET,SG_SCSI_RESET_DEVICE) http://developer.osdl.org/dev/robustmutexes/src/fusyn.hg/Documentation/ioctl/cdrom.txt [] Convert burn_print() into libdax_msgs_submit() [] Clear outdated persistent read buffer after small CD image was read (ticket 57) =============================================================================== This is the dirty end of the todo list. The recent changelog entries are above the headline "TODO". =============================================================================== ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������libburn-1.4.2/version.h.in��������������������������������������������������������������������������0000644�0001757�0001751�00000000220�12652644222�012346� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������#define BURN_MAJOR_VERSION @BURN_MAJOR_VERSION@ #define BURN_MINOR_VERSION @BURN_MINOR_VERSION@ #define BURN_MICRO_VERSION @BURN_MICRO_VERSION@ ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������libburn-1.4.2/AUTHORS�������������������������������������������������������������������������������0000644�0001757�0001751�00000000035�12652644223�011160� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������Mario Danic Thomas Schmitt ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������libburn-1.4.2/acinclude.m4��������������������������������������������������������������������������0000644�0001757�0001751�00000005753�12652644224�012316� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������AC_DEFUN([LIBBURNIA_SET_FLAGS], [ case $target_os in freebsd* | netbsd*) LDFLAGS="$LDFLAGS -L/usr/local/lib" CPPFLAGS="$CPPFLAGS -I/usr/local/include" ;; esac ]) AC_DEFUN([TARGET_SHIZZLE], [ ARCH="" LIBBURNIA_PKGCONFDIR="$libdir"/pkgconfig AC_MSG_CHECKING([target operating system]) LIBBURNIA_LDCONFIG_CMD="echo 'No ldconfig run performed. If needed, configure manually for:'" case $target in *-*-linux*) ARCH=linux LIBBURN_ARCH_LIBS= LIBBURNIA_LDCONFIG_CMD=ldconfig ;; *-*-freebsd*) ARCH=freebsd LIBBURN_ARCH_LIBS=-lcam LIBBURNIA_PKGCONFDIR=$(echo "$libdir" | sed 's/\/lib$/\/libdata/')/pkgconfig ;; *-kfreebsd*-gnu*) ARCH=freebsd LIBBURN_ARCH_LIBS=-lcam ;; *-solaris*) ARCH=solaris LIBBURN_ARCH_LIBS=-lvolmgt ;; *) ARCH= LIBBURN_ARCH_LIBS= # AC_ERROR([You are attempting to compile for an unsupported platform]) ;; esac AC_MSG_RESULT([$ARCH]) ]) dnl LIBBURN_ASSERT_VERS_LIBS is by Thomas Schmitt, libburnia project dnl It tests whether -Wl,--version-script=... works with the compiler AC_DEFUN([LIBBURN_ASSERT_VERS_LIBS], [ libburnia_save_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS -Wl,--version-script=libburn/libburn.ver" AC_TRY_LINK([#include <stdio.h>], [printf("Hello\n");], [vers_libs_test="yes"], [vers_libs_test="no"]) if test x$vers_libs_test = xno then LDFLAGS="$libburnia_save_LDFLAGS" fi ]) dnl LIBBURNIA_SET_PKGCONFIG determines the install directory for the *.pc file. dnl Important: Must be performed _after_ TARGET_SHIZZLE dnl AC_DEFUN([LIBBURNIA_SET_PKGCONFIG], [ ### for testing --enable-libdir-pkgconfig on Linux ### LIBBURNIA_PKGCONFDIR="$libdir"data/pkgconfig if test "x$LIBBURNIA_PKGCONFDIR" = "x$libdir"/pkgconfig then dummy=dummy else AC_ARG_ENABLE(libdir-pkgconfig, [ --enable-libdir-pkgconfig Install to $libdir/pkgconfig on any OS, default=no], , enable_libdir_pkgconfig="no") AC_MSG_CHECKING([for --enable-libdir-pkgconfig]) if test "x$enable_libdir_pkgconfig" = xyes then LIBBURNIA_PKGCONFDIR="$libdir"/pkgconfig fi AC_MSG_RESULT([$enable_libdir_pkgconfig]) fi libburnia_pkgconfig_override="no" AC_ARG_ENABLE(pkgconfig-path, [ --enable-pkgconfig-path=DIR Absolute path of directory for libisofs-*.pc], libburnia_pkgconfig_override="yes" , enable_pkgconfig_path="none") AC_MSG_CHECKING([for overridden pkgconfig directory path]) if test "x$enable_pkgconfig_path" = xno then libburnia_pkgconfig_override="no" fi if test "x$enable_pkgconfig_path" = x -o "x$enable_pkgconfig_path" = xyes then libburnia_pkgconfig_override="invalid argument" fi if test "x$libburnia_pkgconfig_override" = xyes then LIBBURNIA_PKGCONFDIR="$enable_pkgconfig_path" AC_MSG_RESULT([$LIBBURNIA_PKGCONFDIR]) else AC_MSG_RESULT([$libburnia_pkgconfig_override]) fi AC_SUBST(LIBBURNIA_PKGCONFDIR) dnl For debugging only ### AC_MSG_RESULT([LIBBURNIA_PKGCONFDIR = $LIBBURNIA_PKGCONFDIR]) ]) ���������������������libburn-1.4.2/compile�������������������������������������������������������������������������������0000755�0001757�0001751�00000016245�12652650102�011471� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������#! /bin/sh # Wrapper for compilers which do not understand '-c -o'. scriptversion=2012-10-14.11; # UTC # Copyright (C) 1999-2013 Free Software Foundation, Inc. # Written by Tom Tromey <tromey@cygnus.com>. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # This file is maintained in Automake, please report # bugs to <bug-automake@gnu.org> or send patches to # <automake-patches@gnu.org>. nl=' ' # We need space, tab and new line, in precisely that order. Quoting is # there to prevent tools from complaining about whitespace usage. IFS=" "" $nl" file_conv= # func_file_conv build_file lazy # Convert a $build file to $host form and store it in $file # Currently only supports Windows hosts. If the determined conversion # type is listed in (the comma separated) LAZY, no conversion will # take place. func_file_conv () { file=$1 case $file in / | /[!/]*) # absolute file, and not a UNC file if test -z "$file_conv"; then # lazily determine how to convert abs files case `uname -s` in MINGW*) file_conv=mingw ;; CYGWIN*) file_conv=cygwin ;; *) file_conv=wine ;; esac fi case $file_conv/,$2, in *,$file_conv,*) ;; mingw/*) file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'` ;; cygwin/*) file=`cygpath -m "$file" || echo "$file"` ;; wine/*) file=`winepath -w "$file" || echo "$file"` ;; esac ;; esac } # func_cl_dashL linkdir # Make cl look for libraries in LINKDIR func_cl_dashL () { func_file_conv "$1" if test -z "$lib_path"; then lib_path=$file else lib_path="$lib_path;$file" fi linker_opts="$linker_opts -LIBPATH:$file" } # func_cl_dashl library # Do a library search-path lookup for cl func_cl_dashl () { lib=$1 found=no save_IFS=$IFS IFS=';' for dir in $lib_path $LIB do IFS=$save_IFS if $shared && test -f "$dir/$lib.dll.lib"; then found=yes lib=$dir/$lib.dll.lib break fi if test -f "$dir/$lib.lib"; then found=yes lib=$dir/$lib.lib break fi if test -f "$dir/lib$lib.a"; then found=yes lib=$dir/lib$lib.a break fi done IFS=$save_IFS if test "$found" != yes; then lib=$lib.lib fi } # func_cl_wrapper cl arg... # Adjust compile command to suit cl func_cl_wrapper () { # Assume a capable shell lib_path= shared=: linker_opts= for arg do if test -n "$eat"; then eat= else case $1 in -o) # configure might choose to run compile as 'compile cc -o foo foo.c'. eat=1 case $2 in *.o | *.[oO][bB][jJ]) func_file_conv "$2" set x "$@" -Fo"$file" shift ;; *) func_file_conv "$2" set x "$@" -Fe"$file" shift ;; esac ;; -I) eat=1 func_file_conv "$2" mingw set x "$@" -I"$file" shift ;; -I*) func_file_conv "${1#-I}" mingw set x "$@" -I"$file" shift ;; -l) eat=1 func_cl_dashl "$2" set x "$@" "$lib" shift ;; -l*) func_cl_dashl "${1#-l}" set x "$@" "$lib" shift ;; -L) eat=1 func_cl_dashL "$2" ;; -L*) func_cl_dashL "${1#-L}" ;; -static) shared=false ;; -Wl,*) arg=${1#-Wl,} save_ifs="$IFS"; IFS=',' for flag in $arg; do IFS="$save_ifs" linker_opts="$linker_opts $flag" done IFS="$save_ifs" ;; -Xlinker) eat=1 linker_opts="$linker_opts $2" ;; -*) set x "$@" "$1" shift ;; *.cc | *.CC | *.cxx | *.CXX | *.[cC]++) func_file_conv "$1" set x "$@" -Tp"$file" shift ;; *.c | *.cpp | *.CPP | *.lib | *.LIB | *.Lib | *.OBJ | *.obj | *.[oO]) func_file_conv "$1" mingw set x "$@" "$file" shift ;; *) set x "$@" "$1" shift ;; esac fi shift done if test -n "$linker_opts"; then linker_opts="-link$linker_opts" fi exec "$@" $linker_opts exit 1 } eat= case $1 in '') echo "$0: No command. Try '$0 --help' for more information." 1>&2 exit 1; ;; -h | --h*) cat <<\EOF Usage: compile [--help] [--version] PROGRAM [ARGS] Wrapper for compilers which do not understand '-c -o'. Remove '-o dest.o' from ARGS, run PROGRAM with the remaining arguments, and rename the output as expected. If you are trying to build a whole package this is not the right script to run: please start by reading the file 'INSTALL'. Report bugs to <bug-automake@gnu.org>. EOF exit $? ;; -v | --v*) echo "compile $scriptversion" exit $? ;; cl | *[/\\]cl | cl.exe | *[/\\]cl.exe ) func_cl_wrapper "$@" # Doesn't return... ;; esac ofile= cfile= for arg do if test -n "$eat"; then eat= else case $1 in -o) # configure might choose to run compile as 'compile cc -o foo foo.c'. # So we strip '-o arg' only if arg is an object. eat=1 case $2 in *.o | *.obj) ofile=$2 ;; *) set x "$@" -o "$2" shift ;; esac ;; *.c) cfile=$1 set x "$@" "$1" shift ;; *) set x "$@" "$1" shift ;; esac fi shift done if test -z "$ofile" || test -z "$cfile"; then # If no '-o' option was seen then we might have been invoked from a # pattern rule where we don't need one. That is ok -- this is a # normal compilation that the losing compiler can handle. If no # '.c' file was seen then we are probably linking. That is also # ok. exec "$@" fi # Name of file we expect compiler to create. cofile=`echo "$cfile" | sed 's|^.*[\\/]||; s|^[a-zA-Z]:||; s/\.c$/.o/'` # Create the lock directory. # Note: use '[/\\:.-]' here to ensure that we don't use the same name # that we are using for the .o file. Also, base the name on the expected # object file name, since that is what matters with a parallel build. lockdir=`echo "$cofile" | sed -e 's|[/\\:.-]|_|g'`.d while true; do if mkdir "$lockdir" >/dev/null 2>&1; then break fi sleep 1 done # FIXME: race condition here if user kills between mkdir and trap. trap "rmdir '$lockdir'; exit 1" 1 2 15 # Run the compile. "$@" ret=$? if test -f "$cofile"; then test "$cofile" = "$ofile" || mv "$cofile" "$ofile" elif test -f "${cofile}bj"; then test "${cofile}bj" = "$ofile" || mv "${cofile}bj" "$ofile" fi rmdir "$lockdir" exit $ret # Local Variables: # mode: shell-script # sh-indentation: 2 # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC" # time-stamp-end: "; # UTC" # End: �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������libburn-1.4.2/doc/����������������������������������������������������������������������������������0000755�0001757�0001751�00000000000�12652650103�010731� 5����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������libburn-1.4.2/doc/cdtext.txt������������������������������������������������������������������������0000644�0001757�0001751�00000071113�12652644224�012717� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ Description of CD-TEXT Guided by Leon Merten Lohse via libcdio-devel@gnu.org by reading mmc3r10g.pdf from http://www.t10.org/ftp/t10/drafts/mmc3/ by docs and results of cdtext.zip from http://www.sonydadc.com/file/ by reading http://digitalx.org/cue-sheet/syntax by reading source of libcdio from http://www.gnu.org/s/libcdio which quotes source of cdrecord from ftp://ftp.berlios.de/pub/cdrecord/alpha by reading cdrecord.1 from ftp://ftp.berlios.de/pub/cdrecord/alpha Language codes were learned from http://tech.ebu.ch/docs/tech/tech3264.pdf Genre codes were learned from libcdio and confirmed by http://helpdesk.audiofile-engineering.com/index.php?pg=kb.page&id=123 For libburnia-project.org by Thomas Schmitt <scdbackup@gmx.net> Content: - CD-TEXT from the view of the user - Content specifications of particular pack types - Format of a CD-TEXT packs array - Overview of libburn API calls for CD-TEXT - Sony Text File Format (Input Sheet Version 0.7T) - CDRWIN cue sheet files ------------------------------------------------------------------------------- CD-TEXT from the view of the user: CD-TEXT records attributes of disc and tracks on audio CD. The attributes are grouped into blocks which represent particular languages. Up to 8 blocks are possible. There are 13 defined attribute categories, which are called Pack Types and are identified by a single-byte code: 0x80 = Title 0x81 = Names of Performers 0x82 = Names of Songwriters 0x83 = Names of Composers 0x84 = Names of Arrangers 0x85 = Messages 0x86 = text-and-binary: Disc Identification 0x87 = text-and-binary: Genre Identification 0x88 = binary: Table of Content information 0x89 = binary: Second Table of Content information (0x8a to 0x8c are reserved.) 0x8d = Closed Information 0x8e = UPC/EAN code of the album and ISRC code of each track 0x8f = binary: Size Information of the Block Some of these categories apply to the whole disc only: 0x86, 0x87, 0x88, 0x89, 0x8d Some have to be additionally attributed to each track, if they are present for the whole disc: 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x8e One describes the overall content of a block and in part of all other blocks: 0x8f The total size of a block's attribute set is restricted by the fact that it has to be stored in at most 253 records with 12 bytes of payload. These records are called Text Packs. A shortcut for repeated identical track texts is provided, so that a text that is identical to the one of the previous track occupies only 2 or 4 bytes. ------------------------------------------------------------------------------- Content specification of particular pack types: Pack types 0x80 to 0x85 and 0x8e contain 0-terminated cleartext. If double byte characters are used, then two 0-bytes terminate the cleartext. The meaning of 0x80 to 0x85 should be clear by above list. They are encoded according to the Character Code of their block. Either as ISO-8859-1 single byte characters, or as 7-bit ASCII single byte characters, or as MS-JIS double byte characters. More info to 0x8e is given below. Pack type 0x86 (Disc Identification) is documented by Sony as "Catalog Number: (use ASCII Code) Catalog Number of the album". So it is not really binary but might be non-printable, and should contain only bytes with bit7 = 0. Pack type 0x87 contains 2 binary bytes, followed by 0-terminated cleartext. The two binary bytes form a big-endian index to the following list. 0x0000 = "Not Used" (Sony prescribes to use this if no genre applies) 0x0001 = "Not Defined" 0x0002 = "Adult Contemporary" 0x0003 = "Alternative Rock" 0x0004 = "Childrens Music" 0x0005 = "Classical" 0x0006 = "Contemporary Christian" 0x0007 = "Country" 0x0008 = "Dance" 0x0009 = "Easy Listening" 0x000a = "Erotic" 0x000b = "Folk" 0x000c = "Gospel" 0x000d = "Hip Hop" 0x000e = "Jazz" 0x000f = "Latin" 0x0010 = "Musical" 0x0011 = "New Age" 0x0012 = "Opera" 0x0013 = "Operetta" 0x0014 = "Pop Music" 0x0015 = "Rap" 0x0016 = "Reggae" 0x0017 = "Rock Music" 0x0018 = "Rhythm & Blues" 0x0019 = "Sound Effects" 0x001a = "Spoken Word" 0x001b = "World Music" Sony documents the cleartext part as "Genre information that would supplement the Genre Code, such as 'USA Rock music in the 60s'". Always ASCII encoded. Pack type 0x88 records information from the CD's Table of Content, as of READ PMA/TOC/ATIP Format 0010b (mmc3r10g.pdf, table 237 TOC Track Descriptor Format, Q Sub-channel). See below, Format of a CD-TEXT packs array, for more details about the content of pack type 0x88. Pack type 0x89 is yet quite unclear. It might be a representation of Playback Skip Interval, Mode-5 Q sub-channel, POINT 01 to 40 (mmc3r10g.pdf 4.2.3.6.3). If so, then this seems not to apply to write type SAO, because the CUE SHEET format offers no way to express Mode-5 Q. See below, Format of a CD-TEXT packs array, for an example of this pack type. Pack type 0x8d is documented by Sony as "Closed Information: (use 8859-1 Code) Any information can be recorded on disc as memorandum. Information in this field will not be read by CD TEXT players available to the public." Always ISO-8859-1 encoded. Pack type 0x8e is documented by Sony as "UPC/EAN Code (POS Code) of the album. This field typically consists of 13 characters." Always ASCII encoded. It applies to tracks as "ISRC code [which] typically consists of 12 characters" and is always ISO-8859-1 encoded. MMC calls these information entities Media Catalog Number and ISRC. The catalog number consists of 13 decimal digits. ISRC consists of 12 characters: 2 country code [0-9A-Z], 3 owner code [0-9A-Z], 2 year digits (00 to 99), 5 serial number digits (00000 to 99999). Pack type 0x8f summarizes the whole list of text packs of a block. See below, Format of a CD-TEXT packs array, for details. ------------------------------------------------------------------------------- Format of a CD-TEXT packs array: The attributes are represented on CD as Text Packs in the sub-channel of the Lead-in of the disc. See doc/cookbook.txt for a description how to write the readily formatted CD-TEXT pack array to CD, and how to read CD-TEXT packs from CD. The format is explained in part in MMC-3 (mmc3r10g.pdf, Annex J) and in part by the documentation in Sony's cdtext.zip : Each pack consists of a 4-byte header, 12 bytes of payload, and 2 bytes of CRC. The first byte of each pack tells the pack type. See above for a list of types. The second byte tells the track number to which the first text piece in a pack is associated. Number 0 means the whole album. Higher numbers are valid for types 0x80 to 0x85, and 0x8e. With these types, there should be one text for the disc and one for each track. With types 0x88 and 0x89, the second byte bears a track number, too. With type 0x8f, the second byte counts the record parts from 0 to 2. The third byte is a sequential counter. The fourth byte is the Block Number and Character Position Indicator. It consists of three bit fields: bit7 = Double Bytes Character Code (0= single byte characters) bit4-6 = Block Number (groups text packs in language blocks) bit0-3 = Character position. Either the number of characters which the current text inherited from the previous pack, or 15 if the current text started before the previous pack. The 12 payload bytes contain pieces of 0-terminated texts or binary data. A text may span over several packs. Unused characters in a pack are used for the next text of the same pack type. If no text of the same type follows, then the remaining text bytes are set to 0. The CRC algorithm uses divisor 0x11021. The resulting 16-bit residue of the polynomial division gets inverted and written as big-endian number to bytes 16 and 17 of the pack. The text packs are grouped in up to 8 blocks of at most 256 packs. Each block is in charge for one language. Sequence numbers of each block are counted separately. All packs of block 0 come before the packs of block 1. The limitation of block number and sequence numbers imply that there are at most 2048 text packs possible. (READ TOC/PMA/ATIP could retrieve 3640 packs, as it is limited to 64 kB - 2.) If a text of a track (pack types 0x80 to 0x85 and 0x8e) repeats identically for the next track, then it may be represented by a TAB character (ASCII 9) for single byte texts, and two TAB characters for double byte texts. (This should be used because 256 * 12 bytes is few space for 99 tracks.) The two binary bytes of pack type 0x87 are written to the first 0x87 pack of a block. They may or may not be repeated at the start of the follow-up packs of type 0x87. The first pack of type 0x88 in a block records in its payload bytes: 0 : PMIN of POINT A1 = First Track Number 1 : PMIN of POINT A2 = Last Track Number 2 : unknown, 0 in Sony example 3 : PMIN of POINT A2 = Start position of Lead-Out 4 : PSEC of POINT A2 = Start position of Lead-Out 5 : PFRAME of POINT A2 = Start position of Lead-Out 6 to 11 : unknown, 0 in Sony example The following packs record PMIN, PSEC, PFRAME of the POINTs between the lowest track number (min 01h) and the highest track number (max 63h). The payload of the last pack is padded by 0s. The Sony .TOC example: A0 01 A1 14 A2 63:02:18 01 00:02:00 02 04:11:25 03 08:02:50 04 11:47:62 ... 13 53:24:25 14 57:03:25 yields 88 00 23 00 01 0e 00 3f 02 12 00 00 00 00 00 00 12 00 88 01 24 00 00 02 00 04 0b 19 08 02 32 0b 2f 3e 67 2d ... 88 0d 27 00 35 18 19 39 03 19 00 00 00 00 00 00 ea af Pack type 0x89 is yet quite unclear. Especially what the information shall mean to the user of the CD. The time points in the Sony example are in the time range of the tracks numbers that are given before the time points: 01 02:41:48 01 02:52:58 06 23:14:25 06 23:29:60 07 28:30:39 07 28:42:30 13 55:13:26 13 55:31:50 yields 89 01 28 00 01 04 00 00 00 00 02 29 30 02 34 3a f3 0c 89 06 29 00 02 04 00 00 00 00 17 0e 19 17 1d 3c 73 92 89 07 2a 00 03 04 00 00 00 00 1c 1e 27 1c 2a 1e 72 20 89 0d 2b 00 04 04 00 00 00 00 37 0d 1a 37 1f 32 0b 62 The track numbers are stored in the track number byte of the packs. The two time points are stored in byte 6 to 11 of the payload. Byte 0 of the payload seems to be a sequential counter. Byte 1 always 4 ? Byte 2 to 5 always 0 ? Pack type 0x8f summarizes the whole list of text packs of a block. So there is one group of three 0x8f packs per block. Nevertheless each 0x8f group tells the highest sequence number and the language code of all blocks. The payload bytes of three 0x8f packs form a 36 byte record. The track number bytes of the three packs have the values 0, 1, 2. Byte : 0 : Character code for pack types 0x80 to 0x85: 0x00 = ISO-8859-1 0x01 = 7 bit ASCII 0x80 = MS-JIS (japanese Kanji, double byte characters) 1 : Number of first track 2 : Number of last track 3 : libcdio source states: "cd-text information copyright byte" Probably 3 means "copyrighted", 0 means "not copyrighted". 4 - 19 : Pack count of the various types 0x80 to 0x8f. Byte number N tells the count of packs of type 0x80 + (N - 4). I.e. the first byte in this field of 16 counts packs of type 0x80. 20 - 27 : Highest sequence byte number of blocks 0 to 7. 28 - 36 : Language code for blocks 0 to 7 (tech3264.pdf appendix 3) Not all of these Codes have ever been seen with CD-TEXT, though. 0x00 = Unknown 0x01 = Albanian 0x02 = Breton 0x03 = Catalan 0x04 = Croatian 0x05 = Welsh 0x06 = Czech 0x07 = Danish 0x08 = German 0x09 = English 0x0a = Spanish 0x0b = Esperanto 0x0c = Estonian 0x0d = Basque 0x0e = Faroese 0x0f = French 0x10 = Frisian 0x11 = Irish 0x12 = Gaelic 0x13 = Galician 0x14 = Icelandic 0x15 = Italian 0x16 = Lappish 0x17 = Latin 0x18 = Latvian 0x19 = Luxembourgian 0x1a = Lithuanian 0x1b = Hungarian 0x1c = Maltese 0x1d = Dutch 0x1e = Norwegian 0x1f = Occitan 0x20 = Polish 0x21 = Portuguese 0x22 = Romanian 0x23 = Romansh 0x24 = Serbian 0x25 = Slovak 0x26 = Slovenian 0x27 = Finnish 0x28 = Swedish 0x29 = Turkish 0x2a = Flemish 0x2b = Wallon 0x45 = Zulu 0x46 = Vietnamese 0x47 = Uzbek 0x48 = Urdu 0x49 = Ukrainian 0x4a = Thai 0x4b = Telugu 0x4c = Tatar 0x4d = Tamil 0x4e = Tadzhik 0x4f = Swahili 0x50 = Sranan Tongo 0x51 = Somali 0x52 = Sinhalese 0x53 = Shona 0x54 = Serbo-croat 0x55 = Ruthenian 0x56 = Russian 0x57 = Quechua 0x58 = Pushtu 0x59 = Punjabi 0x5a = Persian 0x5b = Papamiento 0x5c = Oriya 0x5d = Nepali 0x5e = Ndebele 0x5f = Marathi 0x60 = Moldavian 0x61 = Malaysian 0x62 = Malagasay 0x63 = Macedonian 0x64 = Laotian 0x65 = Korean 0x66 = Khmer 0x67 = Kazakh 0x68 = Kannada 0x69 = Japanese 0x6a = Indonesian 0x6b = Hindi 0x6c = Hebrew 0x6d = Hausa 0x6e = Gurani 0x6f = Gujurati 0x70 = Greek 0x71 = Georgian 0x72 = Fulani 0x73 = Dari 0x74 = Churash 0x75 = Chinese 0x76 = Burmese 0x77 = Bulgarian 0x78 = Bengali 0x79 = Bielorussian 0x7a = Bambora 0x7b = Azerbaijani 0x7c = Assamese 0x7d = Armenian 0x7e = Arabic 0x7f = Amharic E.g. these three packs 42 : 8f 00 2a 00 01 01 03 00 06 05 04 05 07 06 01 02 48 65 43 : 8f 01 2b 00 00 00 00 00 00 00 06 03 2c 00 00 00 c0 20 44 : 8f 02 2c 00 00 00 00 00 09 00 00 00 00 00 00 00 11 45 decode to Byte :Value Meaning 0 : 01 = ASCII 7-bit 1 : 01 = first track is 1 2 : 03 = last track is 3 3 : 00 = copyright (0 = public domain, 3 = copyrighted ?) 4 : 06 = 6 packs of type 0x80 5 : 05 = 5 packs of type 0x81 6 : 04 = 4 packs of type 0x82 7 : 05 = 5 packs of type 0x83 8 : 07 = 7 packs of type 0x84 9 : 06 = 6 packs of type 0x85 10 : 01 = 1 pack of type 0x86 11 : 02 = 2 packs of type 0x87 12 : 00 = 0 packs of type 0x88 13 : 00 = 0 packs of type 0x89 14 : 00 00 00 00 = 0 packs of types 0x8a to 0x8d 18 : 06 = 6 packs of type 0x8e 19 : 03 = 3 packs of type 0x8f 20 : 2c = last sequence for block 0 This matches the sequence number of the last text pack (0x2c = 44) 21 : 00 00 00 00 00 00 00 = last sequence numbers for block 1..7 (none) 28 : 09 = language code for block 0: English 29 : 00 00 00 00 00 00 00 = language codes for block 1..7 (none) ------------------------------------------------------------------------------- Overview of libburn API calls for CD-TEXT (see libburn/libburn.h for details): libburn can retrieve the array of text packs from a CD: int burn_disc_get_leadin_text(struct burn_drive *d, unsigned char **text_packs, int *num_packs, int flag); It can write a text pack set with a CD SAO session. This set may be attached as array of readily formatted text packs by: int burn_write_opts_set_leadin_text(struct burn_write_opts *opts, unsigned char *text_packs, int num_packs, int flag); The array of text packs may be read from a file by int burn_cdtext_from_packfile(char *path, unsigned char **text_packs, int *num_packs, int flag); Alternatively the pack set may be defined by attaching CD-TEXT attributes to burn_session and burn_track: int burn_session_set_cdtext_par(struct burn_session *s, int char_codes[8], int copyrights[8], int languages[8], int flag); int burn_session_set_cdtext(struct burn_session *s, int block, int pack_type, char *pack_type_name, unsigned char *payload, int length, int flag); int burn_track_set_cdtext(struct burn_track *t, int block, int pack_type, char *pack_type_name, unsigned char *payload, int length, int flag); Macros list the texts for genre and language codes: BURN_CDTEXT_LANGUAGES_0X00 BURN_CDTEXT_FILLER BURN_CDTEXT_LANGUAGES_0X45 BURN_CDTEXT_GENRE_LIST BURN_CDTEXT_NUM_GENRES There is a reader for Sony Input Sheet Version 0.7T: int burn_session_input_sheet_v07t(struct burn_session *session, char *path, int block, int flag); and a writer which converts an array of text packs to such a Sony Input Sheet: int burn_make_input_sheet_v07t(unsigned char *text_packs, int num_packs, int start_tno, int track_count, char **result, int *char_code, int flag); CD-TEXT can be read from a CDRWIN cue sheet file which defines the tracks of a session int burn_session_by_cue_file(struct burn_session *session, char *path, int fifo_size, struct burn_source **fifo, unsigned char **text_packs, int *num_packs, int flag); The session and track attributes can then be converted into an array of text packs by: int burn_cdtext_from_session(struct burn_session *s, unsigned char **text_packs, int *num_packs, int flag); or they can be written as array of text packs to CD when burning begins and no array of pre-formatted packs was attached to the write options by burn_write_opts_set_leadin_text(). There are calls for inspecting the attached attributes: int burn_session_get_cdtext_par(struct burn_session *s, int char_codes[8], int copyrights[8], int block_languages[8], int flag); int burn_session_get_cdtext(struct burn_session *s, int block, int pack_type, char *pack_type_name, unsigned char **payload, int *length, int flag); int burn_track_get_cdtext(struct burn_track *t, int block, int pack_type, char *pack_type_name, unsigned char **payload, int *length, int flag); and for removing attached attributes: int burn_session_dispose_cdtext(struct burn_session *s, int block); int burn_track_dispose_cdtext(struct burn_track *t, int block); UPC/EAN and ISRC not only affect CD-TEXT but also information that is written along with the tracks in Q sub-channel. These can be influenced by burn_session_input_sheet_v07t(), burn_session_by_cue_file() and by void burn_write_opts_set_mediacatalog(struct burn_write_opts *opts, unsigned char mediacatalog[13]); void burn_write_opts_set_has_mediacatalog(struct burn_write_opts *opts, int has_mediacatalog); void burn_track_set_isrc(struct burn_track *t, char *country, char *owner, unsigned char year, unsigned int serial); int burn_track_set_isrc_string(struct burn_track *t, char isrc[13], int flag); ------------------------------------------------------------------------------- Sony Text File Format (Input Sheet Version 0.7T): This text file format provides comprehensive means to define the text attributes of session and tracks for a single block. More than one such file has to be read to form an attribute set with multiple blocks. The information is given by text lines of the following form: purpose specifier [whitespace] = [whitespace] content text [whitespace] is zero or more ASCII 32 (space) or ASCII 9 (tab) characters. The purpose specifier tells the meaning of the content text. Empty content text does not cause a CD-TEXT attribute to be attached. The following purpose specifiers apply to the session as a whole: Specifier = Meaning ------------------------------------------------------------------------- Text Code = Character code for pack type 0x8f "ASCII", "8859" Language Code = One of the language names for pack type 0x8f Album Title = Content of pack type 0x80 Artist Name = Content of pack type 0x81 Songwriter = Content of pack type 0x82 Composer = Content of pack type 0x83 Arranger = Content of pack type 0x84 Album Message = Content of pack type 0x85 Catalog Number = Content of pack type 0x86 Genre Code = One of the genre names for pack type 0x87 Genre Information = Cleartext part of pack type 0x87 Closed Information = Content of pack type 0x8d UPC / EAN = Content of pack type 0x8e Text Data Copy Protection = Copyright value for pack type 0x8f "ON" = 0x03, "OFF" = 0x00 First Track Number = The lowest track number used in the file Last Track Number = The highest track number used in the file The following purpose specifiers apply to particular tracks: Track NN Title = Content of pack type 0x80 Track NN Artist = Content of pack type 0x81 Track NN Songwriter = Content of pack type 0x82 Track NN Composer = Content of pack type 0x83 Track NN Arranger = Content of pack type 0x84 Track NN Message = Content of pack type 0x85 ISRC NN = Content of pack type 0x8e The following purpose specifiers have no effect on CD-TEXT: Remarks = Comments with no influence on CD-TEXT Disc Information NN = Supplementary information for use by record companies. ISO-8859-1 encoded. NN ranges from 01 to 04. Input Sheet Version = "0.7T" libburn peculiarties: libburn may read files of the described format by burn_session_input_sheet_v07t() after the burn_session has been establiched and all burn_track objects have been added. It can convert an array of CD-TEXT packs into this format by burn_make_input_sheet_v07t() The following purpose specifiers accept byte values of the form 0xXY. Text Code , Language Code , Genre Code , Text Data Copy Protection E.g. to indicate MS-JIS character code (of which the exact name is unknown): Text Code = 0x80 Genre Code is settable by 0xXY or 0xXYZT or 0xXY 0xZT. Genre Code = 0x001b Purpose specifiers which have the meaning "Content of pack type 0xXY" may be replaced by the pack type codes. E.g.: 0x80 = Session content of pack type 0x80 Track 02 0x80 = Track content of pack type 0x80 for track 2. Applicable are pack types 0x80 to 0x86, 0x8d, 0x8e. Text Code may be specified only once. It gets speficied to "ISO-8850-1" automatically as soon as content is defined which depends on the text encoding of the block. I.e with pack types 0x80 to 0x85. If a track attribute is set, but the corresponding session attribute is not defined or defined with empty text, then the session attribute gets attached as empty test. (Normally empty content is ignored.) Example cdrskin run with three tracks: $ cdrskin dev=/dev/sr0 -v input_sheet_v07t=NIGHTCATS.TXT \ -audio -swab track_source_1 track_source_2 track_source_3 ---------------------------------------------------------- Content of file NIGHTCATS.TXT : ---------------------------------------------------------- Input Sheet Version = 0.7T Text Code = 8859 Language Code = English Album Title = Joyful Nights Artist Name = United Cat Orchestra Songwriter = Various Songwriters Composer = Various Composers Arranger = Tom Cat Album Message = For all our fans Catalog Number = 1234567890 Genre Code = Classical Genre Information = Feline classic music Closed Information = This is not to be shown by CD players UPC / EAN = 1234567890123 Text Data Copy Protection = OFF First Track Number = 1 Last Track Number = 3 Track 01 Title = Song of Joy Track 01 Artist = Felix and The Purrs Track 01 Songwriter = Friedrich Schiller Track 01 Composer = Ludwig van Beethoven Track 01 Arranger = Tom Cat Track 01 Message = Fritz and Louie once were punks ISRC 01 = XYBLG1101234 Track 02 Title = Humpty Dumpty Track 02 Artist = Catwalk Beauties Track 02 Songwriter = Mother Goose Track 02 Composer = unknown Track 02 Arranger = Tom Cat Track 02 Message = Pluck the goose ISRC 02 = XYBLG1100005 Track 03 Title = Mee Owwww Track 03 Artist = Mia Kitten Track 03 Songwriter = Mia Kitten Track 03 Composer = Mia Kitten Track 03 Arranger = Mia Kitten Track 03 Message = ISRC 03 = XYBLG1100006 ---------------------------------------------------------- ------------------------------------------------------------------------------- CDRWIN cue sheet files: A CDRWIN cue sheet file defines the track data source (FILE), various text attributes (CATALOG, TITLE, PERFORMER, SONGWRITER, ISRC), track block types (TRACK), track start addresses (INDEX). The rules for CDRWIN cue sheet files are described at http://digitalx.org/cue-sheet/syntax/ There are three more text attributes mentioned in man cdrecord for defining the corresponding CD-TEXT attributes: ARRANGER, COMPOSER, MESSAGE. -------------------------------------------------------- Example of a CDRWIN cue sheet file named NIGHTCATS.CUE : -------------------------------------------------------- CATALOG 1234567890123 FILE "audiodata.bin" BINARY TITLE "Joyful Nights" TRACK 01 AUDIO FLAGS DCP TITLE "Song of Joy" PERFORMER "Felix and The Purrs" SONGWRITER "Friedrich Schiller" ISRC XYBLG1101234 INDEX 01 00:00:00 TRACK 02 AUDIO FLAGS DCP TITLE "Humpty Dumpty" PERFORMER "Catwalk Beauties" SONGWRITER "Mother Goose" ISRC XYBLG1100005 INDEX 01 08:20:12 TRACK 03 AUDIO FLAGS DCP TITLE "Mee Owwww" PERFORMER "Mia Kitten" SONGWRITER "Mia Kitten" ISRC XYBLG1100006 INDEX 01 13:20:33 By $ cdrskin -v dev=/dev/sr0 -text cuefile=NIGHTCATS.CUE this yields as text packs: 0 : 80 00 00 00 J o y f u l N i g h t f0 f7 1 : 80 00 01 0c s 00 S o n g o f J o 43 1c 2 : 80 01 02 0a y 00 H u m p t y D u m 43 f9 3 : 80 02 03 0a p t y 00 M e e O w w w 24 72 4 : 80 03 04 08 w 00 00 00 00 00 00 00 00 00 00 00 6e af 5 : 81 00 05 00 00 F e l i x a n d T 4d 51 6 : 81 01 06 0b h e P u r r s 00 C a t a7 40 7 : 81 02 07 03 w a l k B e a u t i e 59 80 8 : 81 02 08 0f s 00 M i a K i t t e n 30 c9 9 : 81 03 09 0a 00 00 00 00 00 00 00 00 00 00 00 00 ad 19 10 : 82 00 0a 00 00 F r i e d r i c h S 70 8f 11 : 82 01 0b 0b c h i l l e r 00 M o t h 33 43 12 : 82 02 0c 04 e r G o o s e 00 M i a d6 f5 13 : 82 03 0d 03 K i t t e n 00 00 00 00 00 f5 83 14 : 8e 00 0e 00 1 2 3 4 5 6 7 8 9 0 1 2 92 3e 15 : 8e 00 0f 0c 3 00 X Y B L G 1 1 0 1 2 c0 2b 16 : 8e 01 10 0a 3 4 00 X Y B L G 1 1 0 0 bb b3 17 : 8e 02 11 09 0 0 5 00 X Y B L G 1 1 0 f3 bf 18 : 8e 03 12 08 0 0 0 6 00 00 00 00 00 00 00 00 5b 5c 19 : 8f 00 13 00 00 01 03 00 05 05 04 00 00 00 00 00 9b fe 20 : 8f 01 14 00 00 00 00 00 00 00 05 03 15 00 00 00 11 0b 21 : 8f 02 15 00 00 00 00 00 09 00 00 00 00 00 00 00 da 77 -------------------------------------- Some restrictions apply in the libburn call burn_session_by_cue_file(): Only FILE types BINARY, MOTOROLA, WAVE are allowed. Only TRACK datatypes AUDIO, MODE1/2048 are allowed. They may not be mixed in the same session. On the other hand, ARRANGER, COMPOSER, MESSAGE are supported unconditionally. ------------------------------------------------------------------------------- This text is copyright 2011 - 2012 Thomas Schmitt <scdbackup@gmx.net>. Permission is granted to copy, modify, and distribute it, as long as the references to the original information sources are maintained. There is NO WARRANTY, to the extent permitted by law. ------------------------------------------------------------------------------- �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������libburn-1.4.2/doc/comments��������������������������������������������������������������������������0000644�0001757�0001751�00000011276�12652644224�012437� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/** @author Mario Danic, Thomas Schmitt @mainpage Libburn Documentation Index @section intro Introduction Libburnia is an open-source project for reading, mastering and writing optical discs. This page is about its capability to handle optical media. For now this means CD-R, CD-RW, DVD-RAM, DVD+RW, DVD+R, DVD+R/DL, DVD-RW, DVD-R, DVD-R/DL, BD-R, BD-RE. Our scope is currently Linux 2.4 and 2.6, FreeBSD, OpenSolaris, or NetBSD. For ports to other systems we would need : login on a development machine or an OS that is installable on an AMD 64-bit PC, advise from a system person about the equivalent of Linux sg or FreeBSD CAM, volunteers for testing of realistic use cases. libburn is the library by which preformatted data get onto optical media. Its code is independent of cdrecord. Its DVD capabilities are learned from studying the code of dvd+rw-tools and MMC-5 specs. No code but only the pure SCSI knowledge has been taken from dvd+rw-tools, though. cdrskin is a limited cdrecord compatibility wrapper for libburn. cdrecord is a powerful GPL'ed burn program included in Joerg Schilling's cdrtools. cdrskin strives to be a second source for the services traditionally provided by cdrecord. Additionally it provides libburn's DVD/BD capabilities, where only -sao is compatible with cdrecord. cdrskin does not contain any bytes copied from cdrecord's sources. Many bytes have been copied from the message output of cdrecord runs, though. See cdrskin/README for more. The burn API example of libburn is named test/libburner.c . The API for media information inquiry is demonstrated in test/telltoc.c . Explore these examples if you look for inspiration. SONAME: libburn.so.4 (since 0.3.4, March 2007), @section using Using libburn Our build system is based on autotools. User experience tells us that you will need at least autotools version 1.7. To build libburn and its companion applications go into its toplevel directory and execute - ./bootstrap (needed if you downloaded from SVN) - ./configure - make To make the libraries accessible for running and developing applications - make install @section libburner Libburner libburner is a minimal demo application for the library libburn (see: libburn/libburn.h) as provided on http://libburnia-project.org . It can list the available devices, can burn to recordable CD, DVD, or BD, can blank a CD-RW or DVD-RW, and can format unformatted DVD-RW, BD-R, or BD-RE. It's main purpose, nevertheless, is to show you how to use libburn and also to serve the libburnia team as reference application. libburner does indeed define the standard way how above gestures can be implemented and stay upward compatible for a good while. @subsection libburner-help Libburner --help <pre> Usage: test/libburner [--drive address|driveno|"-"] [--audio] [--blank_fast|--blank_full|--format] [--try_to_simulate] [--multi] [one or more imagefiles|"-"] Examples A bus scan (needs rw-permissions to see a drive): test/libburner --drive - Burn a file to drive chosen by number, leave appendable: test/libburner --drive 0 --multi my_image_file Burn a file to drive chosen by persistent address, close: test/libburner --drive /dev/hdc my_image_file Blank a used CD-RW (is combinable with burning in one run): test/libburner --drive /dev/hdc --blank_fast Blank a used DVD-RW (is combinable with burning in one run): test/libburner --drive /dev/hdc --blank_full Format a DVD-RW, BD-RE or BD-R: test/libburner --drive /dev/hdc --format Burn two audio tracks (to CD only): lame --decode -t /path/to/track1.mp3 track1.cd test/dewav /path/to/track2.wav -o track2.cd test/libburner --drive /dev/hdc --audio track1.cd track2.cd Burn a compressed afio archive on-the-fly: ( cd my_directory ; find . -print | afio -oZ - ) | \ test/libburner --drive /dev/hdc - To be read from *not mounted* media via: afio -tvZ /dev/hdc </pre> libburner has two companions, telltoc and dewav, which help to perform some peripheral tasks of burning. telltoc prints a table of content (sessions, tracks and leadouts), it tells about type and state of media, and also is able to provide the necessary multi-session information for program mkisofs option -C. Especially helpful are its predictions with "Write multi" and "Write modes" where availability of "TAO" indicates that tracks of unpredicted length can be written. See: test/telltoc --help. dewav extracts raw byte-swapped audio data from files of format .wav (MS WAVE) or .au (SUN Audio). See example in libburner --help. @subsection libburner-source Sourceode of libburner Click on blue names of functions, structures, variables, etc in oder to get to the according specs of libburn API or libburner sourcecode. @include libburner.c */ ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������libburn-1.4.2/doc/doxygen.conf.in�������������������������������������������������������������������0000644�0001757�0001751�00000235650�12652644224�013624� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Doxyfile 1.8.4 # This file describes the settings to be used by the documentation system # doxygen (www.doxygen.org) for a project. # # All text after a double hash (##) is considered a comment and is placed # in front of the TAG it is preceding . # All text after a hash (#) is considered a comment and will be ignored. # The format is: # TAG = value [value, ...] # For lists items can also be appended using: # TAG += value [value, ...] # Values that contain spaces should be placed between quotes (" "). #--------------------------------------------------------------------------- # Project related configuration options #--------------------------------------------------------------------------- # This tag specifies the encoding used for all characters in the config file # that follow. The default is UTF-8 which is also the encoding used for all # text before the first occurrence of this tag. Doxygen uses libiconv (or the # iconv built into libc) for the transcoding. See # http://www.gnu.org/software/libiconv for the list of possible encodings. DOXYFILE_ENCODING = UTF-8 # The PROJECT_NAME tag is a single word (or sequence of words) that should # identify the project. Note that if you do not use Doxywizard you need # to put quotes around the project name if it contains spaces. PROJECT_NAME = @PACKAGE_NAME@ # The PROJECT_NUMBER tag can be used to enter a project or revision number. # This could be handy for archiving the generated documentation or # if some version control system is used. PROJECT_NUMBER = @PACKAGE_VERSION@ # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer # a quick idea about the purpose of the project. Keep the description short. PROJECT_BRIEF = # With the PROJECT_LOGO tag one can specify an logo or icon that is # included in the documentation. The maximum height of the logo should not # exceed 55 pixels and the maximum width should not exceed 200 pixels. # Doxygen will copy the logo to the output directory. PROJECT_LOGO = # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) # base path where the generated documentation will be put. # If a relative path is entered, it will be relative to the location # where doxygen was started. If left blank the current directory will be used. OUTPUT_DIRECTORY = @abs_top_builddir@ # If the CREATE_SUBDIRS tag is set to YES, then doxygen will create # 4096 sub-directories (in 2 levels) under the output directory of each output # format and will distribute the generated files over these directories. # Enabling this option can be useful when feeding doxygen a huge amount of # source files, where putting all generated files in the same directory would # otherwise cause performance problems for the file system. CREATE_SUBDIRS = NO # The OUTPUT_LANGUAGE tag is used to specify the language in which all # documentation generated by doxygen is written. Doxygen will use this # information to generate all constant output in the proper language. # The default language is English, other supported languages are: # Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, # Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German, # Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English # messages), Korean, Korean-en, Latvian, Lithuanian, Norwegian, Macedonian, # Persian, Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrillic, # Slovak, Slovene, Spanish, Swedish, Ukrainian, and Vietnamese. OUTPUT_LANGUAGE = English # If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will # include brief member descriptions after the members that are listed in # the file and class documentation (similar to JavaDoc). # Set to NO to disable this. BRIEF_MEMBER_DESC = YES # If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend # the brief description of a member or function before the detailed description. # Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the # brief descriptions will be completely suppressed. REPEAT_BRIEF = YES # This tag implements a quasi-intelligent brief description abbreviator # that is used to form the text in various listings. Each string # in this list, if found as the leading text of the brief description, will be # stripped from the text and the result after processing the whole list, is # used as the annotated text. Otherwise, the brief description is used as-is. # If left blank, the following values are used ("$name" is automatically # replaced with the name of the entity): "The $name class" "The $name widget" # "The $name file" "is" "provides" "specifies" "contains" # "represents" "a" "an" "the" ABBREVIATE_BRIEF = # If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then # Doxygen will generate a detailed section even if there is only a brief # description. ALWAYS_DETAILED_SEC = NO # If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all # inherited members of a class in the documentation of that class as if those # members were ordinary class members. Constructors, destructors and assignment # operators of the base classes will not be shown. INLINE_INHERITED_MEMB = NO # If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full # path before files name in the file list and in the header files. If set # to NO the shortest path that makes the file name unique will be used. FULL_PATH_NAMES = NO # If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag # can be used to strip a user-defined part of the path. Stripping is # only done if one of the specified strings matches the left-hand part of # the path. The tag can be used to show relative paths in the file list. # If left blank the directory from which doxygen is run is used as the # path to strip. Note that you specify absolute paths here, but also # relative paths, which will be relative from the directory where doxygen is # started. STRIP_FROM_PATH = # The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of # the path mentioned in the documentation of a class, which tells # the reader which header file to include in order to use a class. # If left blank only the name of the header file containing the class # definition is used. Otherwise one should specify the include paths that # are normally passed to the compiler using the -I flag. STRIP_FROM_INC_PATH = # If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter # (but less readable) file names. This can be useful if your file system # doesn't support long names like on DOS, Mac, or CD-ROM. SHORT_NAMES = NO # If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen # will interpret the first line (until the first dot) of a JavaDoc-style # comment as the brief description. If set to NO, the JavaDoc # comments will behave just like regular Qt-style comments # (thus requiring an explicit @brief command for a brief description.) JAVADOC_AUTOBRIEF = YES # If the QT_AUTOBRIEF tag is set to YES then Doxygen will # interpret the first line (until the first dot) of a Qt-style # comment as the brief description. If set to NO, the comments # will behave just like regular Qt-style comments (thus requiring # an explicit \brief command for a brief description.) QT_AUTOBRIEF = NO # The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen # treat a multi-line C++ special comment block (i.e. a block of //! or /// # comments) as a brief description. This used to be the default behaviour. # The new default is to treat a multi-line C++ comment block as a detailed # description. Set this tag to YES if you prefer the old behaviour instead. MULTILINE_CPP_IS_BRIEF = YES # If the INHERIT_DOCS tag is set to YES (the default) then an undocumented # member inherits the documentation from any documented member that it # re-implements. INHERIT_DOCS = YES # If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce # a new page for each member. If set to NO, the documentation of a member will # be part of the file/class/namespace that contains it. SEPARATE_MEMBER_PAGES = NO # The TAB_SIZE tag can be used to set the number of spaces in a tab. # Doxygen uses this value to replace tabs by spaces in code fragments. TAB_SIZE = 4 # This tag can be used to specify a number of aliases that acts # as commands in the documentation. An alias has the form "name=value". # For example adding "sideeffect=\par Side Effects:\n" will allow you to # put the command \sideeffect (or @sideeffect) in the documentation, which # will result in a user-defined paragraph with heading "Side Effects:". # You can put \n's in the value part of an alias to insert newlines. ALIASES = # This tag can be used to specify a number of word-keyword mappings (TCL only). # A mapping has the form "name=value". For example adding # "class=itcl::class" will allow you to use the command class in the # itcl::class meaning. TCL_SUBST = # Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C # sources only. Doxygen will then generate output that is more tailored for C. # For instance, some of the names that are used will be different. The list # of all members will be omitted, etc. OPTIMIZE_OUTPUT_FOR_C = YES # Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java # sources only. Doxygen will then generate output that is more tailored for # Java. For instance, namespaces will be presented as packages, qualified # scopes will look different, etc. OPTIMIZE_OUTPUT_JAVA = NO # Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran # sources only. Doxygen will then generate output that is more tailored for # Fortran. OPTIMIZE_FOR_FORTRAN = NO # Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL # sources. Doxygen will then generate output that is tailored for # VHDL. OPTIMIZE_OUTPUT_VHDL = NO # Doxygen selects the parser to use depending on the extension of the files it # parses. With this tag you can assign which parser to use for a given # extension. Doxygen has a built-in mapping, but you can override or extend it # using this tag. The format is ext=language, where ext is a file extension, # and language is one of the parsers supported by doxygen: IDL, Java, # Javascript, CSharp, C, C++, D, PHP, Objective-C, Python, Fortran, VHDL, C, # C++. For instance to make doxygen treat .inc files as Fortran files (default # is PHP), and .f files as C (default is Fortran), use: inc=Fortran f=C. Note # that for custom extensions you also need to set FILE_PATTERNS otherwise the # files are not read by doxygen. EXTENSION_MAPPING = # If MARKDOWN_SUPPORT is enabled (the default) then doxygen pre-processes all # comments according to the Markdown format, which allows for more readable # documentation. See http://daringfireball.net/projects/markdown/ for details. # The output of markdown processing is further processed by doxygen, so you # can mix doxygen, HTML, and XML commands with Markdown formatting. # Disable only in case of backward compatibilities issues. MARKDOWN_SUPPORT = YES # When enabled doxygen tries to link words that correspond to documented # classes, or namespaces to their corresponding documentation. Such a link can # be prevented in individual cases by by putting a % sign in front of the word # or globally by setting AUTOLINK_SUPPORT to NO. AUTOLINK_SUPPORT = YES # If you use STL classes (i.e. std::string, std::vector, etc.) but do not want # to include (a tag file for) the STL sources as input, then you should # set this tag to YES in order to let doxygen match functions declarations and # definitions whose arguments contain STL classes (e.g. func(std::string); v.s. # func(std::string) {}). This also makes the inheritance and collaboration # diagrams that involve STL classes more complete and accurate. BUILTIN_STL_SUPPORT = NO # If you use Microsoft's C++/CLI language, you should set this option to YES to # enable parsing support. CPP_CLI_SUPPORT = NO # Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. # Doxygen will parse them like normal C++ but will assume all classes use public # instead of private inheritance when no explicit protection keyword is present. SIP_SUPPORT = NO # For Microsoft's IDL there are propget and propput attributes to indicate # getter and setter methods for a property. Setting this option to YES (the # default) will make doxygen replace the get and set methods by a property in # the documentation. This will only work if the methods are indeed getting or # setting a simple type. If this is not the case, or you want to show the # methods anyway, you should set this option to NO. IDL_PROPERTY_SUPPORT = YES # If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC # tag is set to YES, then doxygen will reuse the documentation of the first # member in the group (if any) for the other members of the group. By default # all members of a group must be documented explicitly. DISTRIBUTE_GROUP_DOC = NO # Set the SUBGROUPING tag to YES (the default) to allow class member groups of # the same type (for instance a group of public functions) to be put as a # subgroup of that type (e.g. under the Public Functions section). Set it to # NO to prevent subgrouping. Alternatively, this can be done per class using # the \nosubgrouping command. SUBGROUPING = YES # When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and # unions are shown inside the group in which they are included (e.g. using # @ingroup) instead of on a separate page (for HTML and Man pages) or # section (for LaTeX and RTF). INLINE_GROUPED_CLASSES = NO # When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and # unions with only public data fields or simple typedef fields will be shown # inline in the documentation of the scope in which they are defined (i.e. file, # namespace, or group documentation), provided this scope is documented. If set # to NO (the default), structs, classes, and unions are shown on a separate # page (for HTML and Man pages) or section (for LaTeX and RTF). INLINE_SIMPLE_STRUCTS = NO # When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum # is documented as struct, union, or enum with the name of the typedef. So # typedef struct TypeS {} TypeT, will appear in the documentation as a struct # with name TypeT. When disabled the typedef will appear as a member of a file, # namespace, or class. And the struct will be named TypeS. This can typically # be useful for C code in case the coding convention dictates that all compound # types are typedef'ed and only the typedef is referenced, never the tag name. TYPEDEF_HIDES_STRUCT = NO # The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This # cache is used to resolve symbols given their name and scope. Since this can # be an expensive process and often the same symbol appear multiple times in # the code, doxygen keeps a cache of pre-resolved symbols. If the cache is too # small doxygen will become slower. If the cache is too large, memory is wasted. # The cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid # range is 0..9, the default is 0, corresponding to a cache size of 2^16 = 65536 # symbols. LOOKUP_CACHE_SIZE = 0 #--------------------------------------------------------------------------- # Build related configuration options #--------------------------------------------------------------------------- # If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in # documentation are documented, even if no documentation was available. # Private class members and static file members will be hidden unless # the EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES EXTRACT_ALL = YES # If the EXTRACT_PRIVATE tag is set to YES all private members of a class # will be included in the documentation. EXTRACT_PRIVATE = YES # If the EXTRACT_PACKAGE tag is set to YES all members with package or internal # scope will be included in the documentation. EXTRACT_PACKAGE = NO # If the EXTRACT_STATIC tag is set to YES all static members of a file # will be included in the documentation. EXTRACT_STATIC = YES # If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) # defined locally in source files will be included in the documentation. # If set to NO only classes defined in header files are included. EXTRACT_LOCAL_CLASSES = YES # This flag is only useful for Objective-C code. When set to YES local # methods, which are defined in the implementation section but not in # the interface are included in the documentation. # If set to NO (the default) only methods in the interface are included. EXTRACT_LOCAL_METHODS = NO # If this flag is set to YES, the members of anonymous namespaces will be # extracted and appear in the documentation as a namespace called # 'anonymous_namespace{file}', where file will be replaced with the base # name of the file that contains the anonymous namespace. By default # anonymous namespaces are hidden. EXTRACT_ANON_NSPACES = NO # If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all # undocumented members of documented classes, files or namespaces. # If set to NO (the default) these members will be included in the # various overviews, but no documentation section is generated. # This option has no effect if EXTRACT_ALL is enabled. HIDE_UNDOC_MEMBERS = NO # If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all # undocumented classes that are normally visible in the class hierarchy. # If set to NO (the default) these classes will be included in the various # overviews. This option has no effect if EXTRACT_ALL is enabled. HIDE_UNDOC_CLASSES = NO # If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all # friend (class|struct|union) declarations. # If set to NO (the default) these declarations will be included in the # documentation. HIDE_FRIEND_COMPOUNDS = NO # If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any # documentation blocks found inside the body of a function. # If set to NO (the default) these blocks will be appended to the # function's detailed documentation block. HIDE_IN_BODY_DOCS = NO # The INTERNAL_DOCS tag determines if documentation # that is typed after a \internal command is included. If the tag is set # to NO (the default) then the documentation will be excluded. # Set it to YES to include the internal documentation. INTERNAL_DOCS = NO # If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate # file names in lower-case letters. If set to YES upper-case letters are also # allowed. This is useful if you have classes or files whose names only differ # in case and if your file system supports case sensitive file names. Windows # and Mac users are advised to set this option to NO. CASE_SENSE_NAMES = NO # If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen # will show members with their full class and namespace scopes in the # documentation. If set to YES the scope will be hidden. HIDE_SCOPE_NAMES = NO # If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen # will put a list of the files that are included by a file in the documentation # of that file. SHOW_INCLUDE_FILES = YES # If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen # will list include files with double quotes in the documentation # rather than with sharp brackets. FORCE_LOCAL_INCLUDES = NO # If the INLINE_INFO tag is set to YES (the default) then a tag [inline] # is inserted in the documentation for inline members. INLINE_INFO = YES # If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen # will sort the (detailed) documentation of file and class members # alphabetically by member name. If set to NO the members will appear in # declaration order. SORT_MEMBER_DOCS = YES # If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the # brief documentation of file, namespace and class members alphabetically # by member name. If set to NO (the default) the members will appear in # declaration order. SORT_BRIEF_DOCS = NO # If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen # will sort the (brief and detailed) documentation of class members so that # constructors and destructors are listed first. If set to NO (the default) # the constructors will appear in the respective orders defined by # SORT_MEMBER_DOCS and SORT_BRIEF_DOCS. # This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO # and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO. SORT_MEMBERS_CTORS_1ST = NO # If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the # hierarchy of group names into alphabetical order. If set to NO (the default) # the group names will appear in their defined order. SORT_GROUP_NAMES = NO # If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be # sorted by fully-qualified names, including namespaces. If set to # NO (the default), the class list will be sorted only by class name, # not including the namespace part. # Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. # Note: This option applies only to the class list, not to the # alphabetical list. SORT_BY_SCOPE_NAME = NO # If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to # do proper type resolution of all parameters of a function it will reject a # match between the prototype and the implementation of a member function even # if there is only one candidate or it is obvious which candidate to choose # by doing a simple string match. By disabling STRICT_PROTO_MATCHING doxygen # will still accept a match between prototype and implementation in such cases. STRICT_PROTO_MATCHING = NO # The GENERATE_TODOLIST tag can be used to enable (YES) or # disable (NO) the todo list. This list is created by putting \todo # commands in the documentation. GENERATE_TODOLIST = YES # The GENERATE_TESTLIST tag can be used to enable (YES) or # disable (NO) the test list. This list is created by putting \test # commands in the documentation. GENERATE_TESTLIST = YES # The GENERATE_BUGLIST tag can be used to enable (YES) or # disable (NO) the bug list. This list is created by putting \bug # commands in the documentation. GENERATE_BUGLIST = YES # The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or # disable (NO) the deprecated list. This list is created by putting # \deprecated commands in the documentation. GENERATE_DEPRECATEDLIST= YES # The ENABLED_SECTIONS tag can be used to enable conditional # documentation sections, marked by \if section-label ... \endif # and \cond section-label ... \endcond blocks. ENABLED_SECTIONS = # The MAX_INITIALIZER_LINES tag determines the maximum number of lines # the initial value of a variable or macro consists of for it to appear in # the documentation. If the initializer consists of more lines than specified # here it will be hidden. Use a value of 0 to hide initializers completely. # The appearance of the initializer of individual variables and macros in the # documentation can be controlled using \showinitializer or \hideinitializer # command in the documentation regardless of this setting. MAX_INITIALIZER_LINES = 30 # Set the SHOW_USED_FILES tag to NO to disable the list of files generated # at the bottom of the documentation of classes and structs. If set to YES the # list will mention the files that were used to generate the documentation. SHOW_USED_FILES = YES # Set the SHOW_FILES tag to NO to disable the generation of the Files page. # This will remove the Files entry from the Quick Index and from the # Folder Tree View (if specified). The default is YES. SHOW_FILES = YES # Set the SHOW_NAMESPACES tag to NO to disable the generation of the # Namespaces page. # This will remove the Namespaces entry from the Quick Index # and from the Folder Tree View (if specified). The default is YES. SHOW_NAMESPACES = YES # The FILE_VERSION_FILTER tag can be used to specify a program or script that # doxygen should invoke to get the current version for each file (typically from # the version control system). Doxygen will invoke the program by executing (via # popen()) the command <command> <input-file>, where <command> is the value of # the FILE_VERSION_FILTER tag, and <input-file> is the name of an input file # provided by doxygen. Whatever the program writes to standard output # is used as the file version. See the manual for examples. FILE_VERSION_FILTER = # The LAYOUT_FILE tag can be used to specify a layout file which will be parsed # by doxygen. The layout file controls the global structure of the generated # output files in an output format independent way. To create the layout file # that represents doxygen's defaults, run doxygen with the -l option. # You can optionally specify a file name after the option, if omitted # DoxygenLayout.xml will be used as the name of the layout file. LAYOUT_FILE = # The CITE_BIB_FILES tag can be used to specify one or more bib files # containing the references data. This must be a list of .bib files. The # .bib extension is automatically appended if omitted. Using this command # requires the bibtex tool to be installed. See also # http://en.wikipedia.org/wiki/BibTeX for more info. For LaTeX the style # of the bibliography can be controlled using LATEX_BIB_STYLE. To use this # feature you need bibtex and perl available in the search path. Do not use # file names with spaces, bibtex cannot handle them. CITE_BIB_FILES = #--------------------------------------------------------------------------- # configuration options related to warning and progress messages #--------------------------------------------------------------------------- # The QUIET tag can be used to turn on/off the messages that are generated # by doxygen. Possible values are YES and NO. If left blank NO is used. QUIET = YES # The WARNINGS tag can be used to turn on/off the warning messages that are # generated by doxygen. Possible values are YES and NO. If left blank # NO is used. WARNINGS = YES # If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings # for undocumented members. If EXTRACT_ALL is set to YES then this flag will # automatically be disabled. WARN_IF_UNDOCUMENTED = YES # If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for # potential errors in the documentation, such as not documenting some # parameters in a documented function, or documenting parameters that # don't exist or using markup commands wrongly. WARN_IF_DOC_ERROR = YES # The WARN_NO_PARAMDOC option can be enabled to get warnings for # functions that are documented, but have no documentation for their parameters # or return value. If set to NO (the default) doxygen will only warn about # wrong or incomplete parameter documentation, but not about the absence of # documentation. WARN_NO_PARAMDOC = NO # The WARN_FORMAT tag determines the format of the warning messages that # doxygen can produce. The string should contain the $file, $line, and $text # tags, which will be replaced by the file and line number from which the # warning originated and the warning text. Optionally the format may contain # $version, which will be replaced by the version of the file (if it could # be obtained via FILE_VERSION_FILTER) WARN_FORMAT = "$file:$line: $text " # The WARN_LOGFILE tag can be used to specify a file to which warning # and error messages should be written. If left blank the output is written # to stderr. WARN_LOGFILE = #--------------------------------------------------------------------------- # configuration options related to the input files #--------------------------------------------------------------------------- # The INPUT tag can be used to specify the files and/or directories that contain # documented source files. You may enter file names like "myfile.cpp" or # directories like "/usr/src/myproject". Separate the files or directories # with spaces. INPUT = libburn \ doc \ test # This tag can be used to specify the character encoding of the source files # that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is # also the default input encoding. Doxygen uses libiconv (or the iconv built # into libc) for the transcoding. See http://www.gnu.org/software/libiconv for # the list of possible encodings. INPUT_ENCODING = UTF-8 # If the value of the INPUT tag contains directories, you can use the # FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp # and *.h) to filter out the source-files in the directories. If left # blank the following patterns are tested: # *.c *.cc *.cxx *.cpp *.c++ *.d *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh # *.hxx *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.dox *.py # *.f90 *.f *.for *.vhd *.vhdl FILE_PATTERNS = libburn.h \ comments \ libburner.c # The RECURSIVE tag can be used to turn specify whether or not subdirectories # should be searched for input files as well. Possible values are YES and NO. # If left blank NO is used. RECURSIVE = NO # The EXCLUDE tag can be used to specify files and/or directories that should be # excluded from the INPUT source files. This way you can easily exclude a # subdirectory from a directory tree whose root is specified with the INPUT tag. # Note that relative paths are relative to the directory from which doxygen is # run. EXCLUDE = # The EXCLUDE_SYMLINKS tag can be used to select whether or not files or # directories that are symbolic links (a Unix file system feature) are excluded # from the input. EXCLUDE_SYMLINKS = NO # If the value of the INPUT tag contains directories, you can use the # EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude # certain files from those directories. Note that the wildcards are matched # against the file with absolute path, so to exclude all test directories # for example use the pattern */test/* EXCLUDE_PATTERNS = # The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names # (namespaces, classes, functions, etc.) that should be excluded from the # output. The symbol name can be a fully qualified name, a word, or if the # wildcard * is used, a substring. Examples: ANamespace, AClass, # AClass::ANamespace, ANamespace::*Test EXCLUDE_SYMBOLS = # The EXAMPLE_PATH tag can be used to specify one or more files or # directories that contain example code fragments that are included (see # the \include command). EXAMPLE_PATH = test # If the value of the EXAMPLE_PATH tag contains directories, you can use the # EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp # and *.h) to filter out the source-files in the directories. If left # blank all files are included. EXAMPLE_PATTERNS = # If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be # searched for input files to be used with the \include or \dontinclude # commands irrespective of the value of the RECURSIVE tag. # Possible values are YES and NO. If left blank NO is used. EXAMPLE_RECURSIVE = NO # The IMAGE_PATH tag can be used to specify one or more files or # directories that contain image that are included in the documentation (see # the \image command). IMAGE_PATH = # The INPUT_FILTER tag can be used to specify a program that doxygen should # invoke to filter for each input file. Doxygen will invoke the filter program # by executing (via popen()) the command <filter> <input-file>, where <filter> # is the value of the INPUT_FILTER tag, and <input-file> is the name of an # input file. Doxygen will then use the output that the filter program writes # to standard output. # If FILTER_PATTERNS is specified, this tag will be ignored. # Note that the filter must not add or remove lines; it is applied before the # code is scanned, but not when the output code is generated. If lines are added # or removed, the anchors will not be placed correctly. INPUT_FILTER = # The FILTER_PATTERNS tag can be used to specify filters on a per file pattern # basis. # Doxygen will compare the file name with each pattern and apply the # filter if there is a match. # The filters are a list of the form: # pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further # info on how filters are used. If FILTER_PATTERNS is empty or if # non of the patterns match the file name, INPUT_FILTER is applied. FILTER_PATTERNS = # If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using # INPUT_FILTER) will be used to filter the input files when producing source # files to browse (i.e. when SOURCE_BROWSER is set to YES). FILTER_SOURCE_FILES = NO # The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file # pattern. A pattern will override the setting for FILTER_PATTERN (if any) # and it is also possible to disable source filtering for a specific pattern # using *.ext= (so without naming a filter). This option only has effect when # FILTER_SOURCE_FILES is enabled. FILTER_SOURCE_PATTERNS = # If the USE_MD_FILE_AS_MAINPAGE tag refers to the name of a markdown file that # is part of the input, its contents will be placed on the main page # (index.html). This can be useful if you have a project on for instance GitHub # and want reuse the introduction page also for the doxygen output. USE_MDFILE_AS_MAINPAGE = #--------------------------------------------------------------------------- # configuration options related to source browsing #--------------------------------------------------------------------------- # If the SOURCE_BROWSER tag is set to YES then a list of source files will # be generated. Documented entities will be cross-referenced with these sources. # Note: To get rid of all source code in the generated output, make sure also # VERBATIM_HEADERS is set to NO. SOURCE_BROWSER = YES # Setting the INLINE_SOURCES tag to YES will include the body # of functions and classes directly in the documentation. INLINE_SOURCES = YES # Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct # doxygen to hide any special comment blocks from generated source code # fragments. Normal C, C++ and Fortran comments will always remain visible. STRIP_CODE_COMMENTS = NO # If the REFERENCED_BY_RELATION tag is set to YES # then for each documented function all documented # functions referencing it will be listed. REFERENCED_BY_RELATION = YES # If the REFERENCES_RELATION tag is set to YES # then for each documented function all documented entities # called/used by that function will be listed. REFERENCES_RELATION = YES # If the REFERENCES_LINK_SOURCE tag is set to YES (the default) # and SOURCE_BROWSER tag is set to YES, then the hyperlinks from # functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will # link to the source code. # Otherwise they will link to the documentation. REFERENCES_LINK_SOURCE = YES # If the USE_HTAGS tag is set to YES then the references to source code # will point to the HTML generated by the htags(1) tool instead of doxygen # built-in source browser. The htags tool is part of GNU's global source # tagging system (see http://www.gnu.org/software/global/global.html). You # will need version 4.8.6 or higher. USE_HTAGS = NO # If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen # will generate a verbatim copy of the header file for each class for # which an include is specified. Set to NO to disable this. VERBATIM_HEADERS = YES #--------------------------------------------------------------------------- # configuration options related to the alphabetical class index #--------------------------------------------------------------------------- # If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index # of all compounds will be generated. Enable this if the project # contains a lot of classes, structs, unions or interfaces. ALPHABETICAL_INDEX = NO # If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then # the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns # in which this list will be split (can be a number in the range [1..20]) COLS_IN_ALPHA_INDEX = 5 # In case all classes in a project start with a common prefix, all # classes will be put under the same header in the alphabetical index. # The IGNORE_PREFIX tag can be used to specify one or more prefixes that # should be ignored while generating the index headers. IGNORE_PREFIX = OB \ OTK \ _ #--------------------------------------------------------------------------- # configuration options related to the HTML output #--------------------------------------------------------------------------- # If the GENERATE_HTML tag is set to YES (the default) Doxygen will # generate HTML output. GENERATE_HTML = YES # The HTML_OUTPUT tag is used to specify where the HTML docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `html' will be used as the default path. HTML_OUTPUT = doc/html # The HTML_FILE_EXTENSION tag can be used to specify the file extension for # each generated HTML page (for example: .htm,.php,.asp). If it is left blank # doxygen will generate files with .html extension. HTML_FILE_EXTENSION = .html # The HTML_HEADER tag can be used to specify a personal HTML header for # each generated HTML page. If it is left blank doxygen will generate a # standard header. Note that when using a custom header you are responsible # for the proper inclusion of any scripts and style sheets that doxygen # needs, which is dependent on the configuration options used. # It is advised to generate a default header using "doxygen -w html # header.html footer.html stylesheet.css YourConfigFile" and then modify # that header. Note that the header is subject to change so you typically # have to redo this when upgrading to a newer version of doxygen or when # changing the value of configuration settings such as GENERATE_TREEVIEW! HTML_HEADER = # The HTML_FOOTER tag can be used to specify a personal HTML footer for # each generated HTML page. If it is left blank doxygen will generate a # standard footer. HTML_FOOTER = # The HTML_STYLESHEET tag can be used to specify a user-defined cascading # style sheet that is used by each HTML page. It can be used to # fine-tune the look of the HTML output. If left blank doxygen will # generate a default style sheet. Note that it is recommended to use # HTML_EXTRA_STYLESHEET instead of this one, as it is more robust and this # tag will in the future become obsolete. HTML_STYLESHEET = # The HTML_EXTRA_STYLESHEET tag can be used to specify an additional # user-defined cascading style sheet that is included after the standard # style sheets created by doxygen. Using this option one can overrule # certain style aspects. This is preferred over using HTML_STYLESHEET # since it does not replace the standard style sheet and is therefor more # robust against future updates. Doxygen will copy the style sheet file to # the output directory. HTML_EXTRA_STYLESHEET = # The HTML_EXTRA_FILES tag can be used to specify one or more extra images or # other source files which should be copied to the HTML output directory. Note # that these files will be copied to the base HTML output directory. Use the # $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these # files. In the HTML_STYLESHEET file, use the file name only. Also note that # the files will be copied as-is; there are no commands or markers available. HTML_EXTRA_FILES = # The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. # Doxygen will adjust the colors in the style sheet and background images # according to this color. Hue is specified as an angle on a colorwheel, # see http://en.wikipedia.org/wiki/Hue for more information. # For instance the value 0 represents red, 60 is yellow, 120 is green, # 180 is cyan, 240 is blue, 300 purple, and 360 is red again. # The allowed range is 0 to 359. HTML_COLORSTYLE_HUE = 220 # The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of # the colors in the HTML output. For a value of 0 the output will use # grayscales only. A value of 255 will produce the most vivid colors. HTML_COLORSTYLE_SAT = 100 # The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to # the luminance component of the colors in the HTML output. Values below # 100 gradually make the output lighter, whereas values above 100 make # the output darker. The value divided by 100 is the actual gamma applied, # so 80 represents a gamma of 0.8, The value 220 represents a gamma of 2.2, # and 100 does not change the gamma. HTML_COLORSTYLE_GAMMA = 80 # If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML # page will contain the date and time when the page was generated. Setting # this to NO can help when comparing the output of multiple runs. HTML_TIMESTAMP = NO # If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML # documentation will contain sections that can be hidden and shown after the # page has loaded. HTML_DYNAMIC_SECTIONS = NO # With HTML_INDEX_NUM_ENTRIES one can control the preferred number of # entries shown in the various tree structured indices initially; the user # can expand and collapse entries dynamically later on. Doxygen will expand # the tree to such a level that at most the specified number of entries are # visible (unless a fully collapsed tree already exceeds this amount). # So setting the number of entries 1 will produce a full collapsed tree by # default. 0 is a special value representing an infinite number of entries # and will result in a full expanded tree by default. HTML_INDEX_NUM_ENTRIES = 100 # If the GENERATE_DOCSET tag is set to YES, additional index files # will be generated that can be used as input for Apple's Xcode 3 # integrated development environment, introduced with OSX 10.5 (Leopard). # To create a documentation set, doxygen will generate a Makefile in the # HTML output directory. Running make will produce the docset in that # directory and running "make install" will install the docset in # ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find # it at startup. # See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html # for more information. GENERATE_DOCSET = NO # When GENERATE_DOCSET tag is set to YES, this tag determines the name of the # feed. A documentation feed provides an umbrella under which multiple # documentation sets from a single provider (such as a company or product suite) # can be grouped. DOCSET_FEEDNAME = "Doxygen generated docs" # When GENERATE_DOCSET tag is set to YES, this tag specifies a string that # should uniquely identify the documentation set bundle. This should be a # reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen # will append .docset to the name. DOCSET_BUNDLE_ID = org.doxygen.Project # When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely # identify the documentation publisher. This should be a reverse domain-name # style string, e.g. com.mycompany.MyDocSet.documentation. DOCSET_PUBLISHER_ID = org.doxygen.Publisher # The GENERATE_PUBLISHER_NAME tag identifies the documentation publisher. DOCSET_PUBLISHER_NAME = Publisher # If the GENERATE_HTMLHELP tag is set to YES, additional index files # will be generated that can be used as input for tools like the # Microsoft HTML help workshop to generate a compiled HTML help file (.chm) # of the generated HTML documentation. GENERATE_HTMLHELP = NO # If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can # be used to specify the file name of the resulting .chm file. You # can add a path in front of the file if the result should not be # written to the html output directory. CHM_FILE = # If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can # be used to specify the location (absolute path including file name) of # the HTML help compiler (hhc.exe). If non-empty doxygen will try to run # the HTML help compiler on the generated index.hhp. HHC_LOCATION = # If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag # controls if a separate .chi index file is generated (YES) or that # it should be included in the master .chm file (NO). GENERATE_CHI = NO # If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING # is used to encode HtmlHelp index (hhk), content (hhc) and project file # content. CHM_INDEX_ENCODING = # If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag # controls whether a binary table of contents is generated (YES) or a # normal table of contents (NO) in the .chm file. BINARY_TOC = NO # The TOC_EXPAND flag can be set to YES to add extra items for group members # to the contents of the HTML help documentation and to the tree view. TOC_EXPAND = NO # If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and # QHP_VIRTUAL_FOLDER are set, an additional index file will be generated # that can be used as input for Qt's qhelpgenerator to generate a # Qt Compressed Help (.qch) of the generated HTML documentation. GENERATE_QHP = NO # If the QHG_LOCATION tag is specified, the QCH_FILE tag can # be used to specify the file name of the resulting .qch file. # The path specified is relative to the HTML output folder. QCH_FILE = # The QHP_NAMESPACE tag specifies the namespace to use when generating # Qt Help Project output. For more information please see # http://doc.trolltech.com/qthelpproject.html#namespace QHP_NAMESPACE = org.doxygen.Project # The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating # Qt Help Project output. For more information please see # http://doc.trolltech.com/qthelpproject.html#virtual-folders QHP_VIRTUAL_FOLDER = doc # If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to # add. For more information please see # http://doc.trolltech.com/qthelpproject.html#custom-filters QHP_CUST_FILTER_NAME = # The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the # custom filter to add. For more information please see # <a href="http://doc.trolltech.com/qthelpproject.html#custom-filters"> # Qt Help Project / Custom Filters</a>. QHP_CUST_FILTER_ATTRS = # The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this # project's # filter section matches. # <a href="http://doc.trolltech.com/qthelpproject.html#filter-attributes"> # Qt Help Project / Filter Attributes</a>. QHP_SECT_FILTER_ATTRS = # If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can # be used to specify the location of Qt's qhelpgenerator. # If non-empty doxygen will try to run qhelpgenerator on the generated # .qhp file. QHG_LOCATION = # If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files # will be generated, which together with the HTML files, form an Eclipse help # plugin. To install this plugin and make it available under the help contents # menu in Eclipse, the contents of the directory containing the HTML and XML # files needs to be copied into the plugins directory of eclipse. The name of # the directory within the plugins directory should be the same as # the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before # the help appears. GENERATE_ECLIPSEHELP = NO # A unique identifier for the eclipse help plugin. When installing the plugin # the directory name containing the HTML and XML files should also have # this name. ECLIPSE_DOC_ID = org.doxygen.Project # The DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) # at top of each HTML page. The value NO (the default) enables the index and # the value YES disables it. Since the tabs have the same information as the # navigation tree you can set this option to NO if you already set # GENERATE_TREEVIEW to YES. DISABLE_INDEX = NO # The GENERATE_TREEVIEW tag is used to specify whether a tree-like index # structure should be generated to display hierarchical information. # If the tag value is set to YES, a side panel will be generated # containing a tree-like index structure (just like the one that # is generated for HTML Help). For this to work a browser that supports # JavaScript, DHTML, CSS and frames is required (i.e. any modern browser). # Windows users are probably better off using the HTML help feature. # Since the tree basically has the same information as the tab index you # could consider to set DISABLE_INDEX to NO when enabling this option. GENERATE_TREEVIEW = NO # The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values # (range [0,1..20]) that doxygen will group on one line in the generated HTML # documentation. Note that a value of 0 will completely suppress the enum # values from appearing in the overview section. ENUM_VALUES_PER_LINE = 4 # If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be # used to set the initial width (in pixels) of the frame in which the tree # is shown. TREEVIEW_WIDTH = 200 # When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open # links to external symbols imported via tag files in a separate window. EXT_LINKS_IN_WINDOW = NO # Use this tag to change the font size of Latex formulas included # as images in the HTML documentation. The default is 10. Note that # when you change the font size after a successful doxygen run you need # to manually remove any form_*.png images from the HTML output directory # to force them to be regenerated. FORMULA_FONTSIZE = 10 # Use the FORMULA_TRANPARENT tag to determine whether or not the images # generated for formulas are transparent PNGs. Transparent PNGs are # not supported properly for IE 6.0, but are supported on all modern browsers. # Note that when changing this option you need to delete any form_*.png files # in the HTML output before the changes have effect. FORMULA_TRANSPARENT = YES # Enable the USE_MATHJAX option to render LaTeX formulas using MathJax # (see http://www.mathjax.org) which uses client side Javascript for the # rendering instead of using prerendered bitmaps. Use this if you do not # have LaTeX installed or if you want to formulas look prettier in the HTML # output. When enabled you may also need to install MathJax separately and # configure the path to it using the MATHJAX_RELPATH option. USE_MATHJAX = NO # When MathJax is enabled you can set the default output format to be used for # the MathJax output. Supported types are HTML-CSS, NativeMML (i.e. MathML) and # SVG. The default value is HTML-CSS, which is slower, but has the best # compatibility. MATHJAX_FORMAT = HTML-CSS # When MathJax is enabled you need to specify the location relative to the # HTML output directory using the MATHJAX_RELPATH option. The destination # directory should contain the MathJax.js script. For instance, if the mathjax # directory is located at the same level as the HTML output directory, then # MATHJAX_RELPATH should be ../mathjax. The default value points to # the MathJax Content Delivery Network so you can quickly see the result without # installing MathJax. # However, it is strongly recommended to install a local # copy of MathJax from http://www.mathjax.org before deployment. MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest # The MATHJAX_EXTENSIONS tag can be used to specify one or MathJax extension # names that should be enabled during MathJax rendering. MATHJAX_EXTENSIONS = # The MATHJAX_CODEFILE tag can be used to specify a file with javascript # pieces of code that will be used on startup of the MathJax code. MATHJAX_CODEFILE = # When the SEARCHENGINE tag is enabled doxygen will generate a search box # for the HTML output. The underlying search engine uses javascript # and DHTML and should work on any modern browser. Note that when using # HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets # (GENERATE_DOCSET) there is already a search function so this one should # typically be disabled. For large projects the javascript based search engine # can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution. SEARCHENGINE = NO # When the SERVER_BASED_SEARCH tag is enabled the search engine will be # implemented using a web server instead of a web client using Javascript. # There are two flavours of web server based search depending on the # EXTERNAL_SEARCH setting. When disabled, doxygen will generate a PHP script for # searching and an index file used by the script. When EXTERNAL_SEARCH is # enabled the indexing and searching needs to be provided by external tools. # See the manual for details. SERVER_BASED_SEARCH = NO # When EXTERNAL_SEARCH is enabled doxygen will no longer generate the PHP # script for searching. Instead the search results are written to an XML file # which needs to be processed by an external indexer. Doxygen will invoke an # external search engine pointed to by the SEARCHENGINE_URL option to obtain # the search results. Doxygen ships with an example indexer (doxyindexer) and # search engine (doxysearch.cgi) which are based on the open source search # engine library Xapian. See the manual for configuration details. EXTERNAL_SEARCH = NO # The SEARCHENGINE_URL should point to a search engine hosted by a web server # which will returned the search results when EXTERNAL_SEARCH is enabled. # Doxygen ships with an example search engine (doxysearch) which is based on # the open source search engine library Xapian. See the manual for configuration # details. SEARCHENGINE_URL = # When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the unindexed # search data is written to a file for indexing by an external tool. With the # SEARCHDATA_FILE tag the name of this file can be specified. SEARCHDATA_FILE = searchdata.xml # When SERVER_BASED_SEARCH AND EXTERNAL_SEARCH are both enabled the # EXTERNAL_SEARCH_ID tag can be used as an identifier for the project. This is # useful in combination with EXTRA_SEARCH_MAPPINGS to search through multiple # projects and redirect the results back to the right project. EXTERNAL_SEARCH_ID = # The EXTRA_SEARCH_MAPPINGS tag can be used to enable searching through doxygen # projects other than the one defined by this configuration file, but that are # all added to the same external search index. Each project needs to have a # unique id set via EXTERNAL_SEARCH_ID. The search mapping then maps the id # of to a relative location where the documentation can be found. # The format is: EXTRA_SEARCH_MAPPINGS = id1=loc1 id2=loc2 ... EXTRA_SEARCH_MAPPINGS = #--------------------------------------------------------------------------- # configuration options related to the LaTeX output #--------------------------------------------------------------------------- # If the GENERATE_LATEX tag is set to YES (the default) Doxygen will # generate Latex output. GENERATE_LATEX = NO # The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `latex' will be used as the default path. LATEX_OUTPUT = latex # The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be # invoked. If left blank `latex' will be used as the default command name. # Note that when enabling USE_PDFLATEX this option is only used for # generating bitmaps for formulas in the HTML output, but not in the # Makefile that is written to the output directory. LATEX_CMD_NAME = latex # The MAKEINDEX_CMD_NAME tag can be used to specify the command name to # generate index for LaTeX. If left blank `makeindex' will be used as the # default command name. MAKEINDEX_CMD_NAME = makeindex # If the COMPACT_LATEX tag is set to YES Doxygen generates more compact # LaTeX documents. This may be useful for small projects and may help to # save some trees in general. COMPACT_LATEX = NO # The PAPER_TYPE tag can be used to set the paper type that is used # by the printer. Possible values are: a4, letter, legal and # executive. If left blank a4 will be used. PAPER_TYPE = letter # The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX # packages that should be included in the LaTeX output. EXTRA_PACKAGES = # The LATEX_HEADER tag can be used to specify a personal LaTeX header for # the generated latex document. The header should contain everything until # the first chapter. If it is left blank doxygen will generate a # standard header. Notice: only use this tag if you know what you are doing! LATEX_HEADER = # The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for # the generated latex document. The footer should contain everything after # the last chapter. If it is left blank doxygen will generate a # standard footer. Notice: only use this tag if you know what you are doing! LATEX_FOOTER = # The LATEX_EXTRA_FILES tag can be used to specify one or more extra images # or other source files which should be copied to the LaTeX output directory. # Note that the files will be copied as-is; there are no commands or markers # available. LATEX_EXTRA_FILES = # If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated # is prepared for conversion to pdf (using ps2pdf). The pdf file will # contain links (just like the HTML output) instead of page references # This makes the output suitable for online browsing using a pdf viewer. PDF_HYPERLINKS = YES # If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of # plain latex in the generated Makefile. Set this option to YES to get a # higher quality PDF documentation. USE_PDFLATEX = NO # If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. # command to the generated LaTeX files. This will instruct LaTeX to keep # running if errors occur, instead of asking the user for help. # This option is also used when generating formulas in HTML. LATEX_BATCHMODE = NO # If LATEX_HIDE_INDICES is set to YES then doxygen will not # include the index chapters (such as File Index, Compound Index, etc.) # in the output. LATEX_HIDE_INDICES = NO # If LATEX_SOURCE_CODE is set to YES then doxygen will include # source code with syntax highlighting in the LaTeX output. # Note that which sources are shown also depends on other settings # such as SOURCE_BROWSER. LATEX_SOURCE_CODE = NO # The LATEX_BIB_STYLE tag can be used to specify the style to use for the # bibliography, e.g. plainnat, or ieeetr. The default style is "plain". See # http://en.wikipedia.org/wiki/BibTeX for more info. LATEX_BIB_STYLE = plain #--------------------------------------------------------------------------- # configuration options related to the RTF output #--------------------------------------------------------------------------- # If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output # The RTF output is optimized for Word 97 and may not look very pretty with # other RTF readers or editors. GENERATE_RTF = NO # The RTF_OUTPUT tag is used to specify where the RTF docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `rtf' will be used as the default path. RTF_OUTPUT = rtf # If the COMPACT_RTF tag is set to YES Doxygen generates more compact # RTF documents. This may be useful for small projects and may help to # save some trees in general. COMPACT_RTF = NO # If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated # will contain hyperlink fields. The RTF file will # contain links (just like the HTML output) instead of page references. # This makes the output suitable for online browsing using WORD or other # programs which support those fields. # Note: wordpad (write) and others do not support links. RTF_HYPERLINKS = NO # Load style sheet definitions from file. Syntax is similar to doxygen's # config file, i.e. a series of assignments. You only have to provide # replacements, missing definitions are set to their default value. RTF_STYLESHEET_FILE = # Set optional variables used in the generation of an rtf document. # Syntax is similar to doxygen's config file. RTF_EXTENSIONS_FILE = #--------------------------------------------------------------------------- # configuration options related to the man page output #--------------------------------------------------------------------------- # If the GENERATE_MAN tag is set to YES (the default) Doxygen will # generate man pages GENERATE_MAN = NO # The MAN_OUTPUT tag is used to specify where the man pages will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `man' will be used as the default path. MAN_OUTPUT = man # The MAN_EXTENSION tag determines the extension that is added to # the generated man pages (default is the subroutine's section .3) MAN_EXTENSION = .3 # If the MAN_LINKS tag is set to YES and Doxygen generates man output, # then it will generate one additional man file for each entity # documented in the real man page(s). These additional files # only source the real man page, but without them the man command # would be unable to find the correct page. The default is NO. MAN_LINKS = NO #--------------------------------------------------------------------------- # configuration options related to the XML output #--------------------------------------------------------------------------- # If the GENERATE_XML tag is set to YES Doxygen will # generate an XML file that captures the structure of # the code including all documentation. GENERATE_XML = NO # The XML_OUTPUT tag is used to specify where the XML pages will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `xml' will be used as the default path. XML_OUTPUT = xml # The XML_SCHEMA tag can be used to specify an XML schema, # which can be used by a validating XML parser to check the # syntax of the XML files. XML_SCHEMA = # The XML_DTD tag can be used to specify an XML DTD, # which can be used by a validating XML parser to check the # syntax of the XML files. XML_DTD = # If the XML_PROGRAMLISTING tag is set to YES Doxygen will # dump the program listings (including syntax highlighting # and cross-referencing information) to the XML output. Note that # enabling this will significantly increase the size of the XML output. XML_PROGRAMLISTING = YES #--------------------------------------------------------------------------- # configuration options related to the DOCBOOK output #--------------------------------------------------------------------------- # If the GENERATE_DOCBOOK tag is set to YES Doxygen will generate DOCBOOK files # that can be used to generate PDF. GENERATE_DOCBOOK = NO # The DOCBOOK_OUTPUT tag is used to specify where the DOCBOOK pages will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be put in # front of it. If left blank docbook will be used as the default path. DOCBOOK_OUTPUT = docbook #--------------------------------------------------------------------------- # configuration options for the AutoGen Definitions output #--------------------------------------------------------------------------- # If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will # generate an AutoGen Definitions (see autogen.sf.net) file # that captures the structure of the code including all # documentation. Note that this feature is still experimental # and incomplete at the moment. GENERATE_AUTOGEN_DEF = NO #--------------------------------------------------------------------------- # configuration options related to the Perl module output #--------------------------------------------------------------------------- # If the GENERATE_PERLMOD tag is set to YES Doxygen will # generate a Perl module file that captures the structure of # the code including all documentation. Note that this # feature is still experimental and incomplete at the # moment. GENERATE_PERLMOD = NO # If the PERLMOD_LATEX tag is set to YES Doxygen will generate # the necessary Makefile rules, Perl scripts and LaTeX code to be able # to generate PDF and DVI output from the Perl module output. PERLMOD_LATEX = NO # If the PERLMOD_PRETTY tag is set to YES the Perl module output will be # nicely formatted so it can be parsed by a human reader. # This is useful # if you want to understand what is going on. # On the other hand, if this # tag is set to NO the size of the Perl module output will be much smaller # and Perl will parse it just the same. PERLMOD_PRETTY = YES # The names of the make variables in the generated doxyrules.make file # are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. # This is useful so different doxyrules.make files included by the same # Makefile don't overwrite each other's variables. PERLMOD_MAKEVAR_PREFIX = #--------------------------------------------------------------------------- # Configuration options related to the preprocessor #--------------------------------------------------------------------------- # If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will # evaluate all C-preprocessor directives found in the sources and include # files. ENABLE_PREPROCESSING = YES # If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro # names in the source code. If set to NO (the default) only conditional # compilation will be performed. Macro expansion can be done in a controlled # way by setting EXPAND_ONLY_PREDEF to YES. MACRO_EXPANSION = NO # If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES # then the macro expansion is limited to the macros specified with the # PREDEFINED and EXPAND_AS_DEFINED tags. EXPAND_ONLY_PREDEF = NO # If the SEARCH_INCLUDES tag is set to YES (the default) the includes files # pointed to by INCLUDE_PATH will be searched when a #include is found. SEARCH_INCLUDES = YES # The INCLUDE_PATH tag can be used to specify one or more directories that # contain include files that are not input files but should be processed by # the preprocessor. INCLUDE_PATH = # You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard # patterns (like *.h and *.hpp) to filter out the header-files in the # directories. If left blank, the patterns specified with FILE_PATTERNS will # be used. INCLUDE_FILE_PATTERNS = # The PREDEFINED tag can be used to specify one or more macro names that # are defined before the preprocessor is started (similar to the -D option of # gcc). The argument of the tag is a list of macros of the form: name # or name=definition (no spaces). If the definition and the = are # omitted =1 is assumed. To prevent a macro definition from being # undefined via #undef or recursively expanded use the := operator # instead of the = operator. PREDEFINED = DOXYGEN # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then # this tag can be used to specify a list of macro names that should be expanded. # The macro definition that is found in the sources will be used. # Use the PREDEFINED tag if you want to use a different macro definition that # overrules the definition found in the source code. EXPAND_AS_DEFINED = # If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then # doxygen's preprocessor will remove all references to function-like macros # that are alone on a line, have an all uppercase name, and do not end with a # semicolon, because these will confuse the parser if not removed. SKIP_FUNCTION_MACROS = YES #--------------------------------------------------------------------------- # Configuration::additions related to external references #--------------------------------------------------------------------------- # The TAGFILES option can be used to specify one or more tagfiles. For each # tag file the location of the external documentation should be added. The # format of a tag file without this location is as follows: # # TAGFILES = file1 file2 ... # Adding location for the tag files is done as follows: # # TAGFILES = file1=loc1 "file2 = loc2" ... # where "loc1" and "loc2" can be relative or absolute paths # or URLs. Note that each tag file must have a unique name (where the name does # NOT include the path). If a tag file is not located in the directory in which # doxygen is run, you must also specify the path to the tagfile here. TAGFILES = # When a file name is specified after GENERATE_TAGFILE, doxygen will create # a tag file that is based on the input files it reads. GENERATE_TAGFILE = # If the ALLEXTERNALS tag is set to YES all external classes will be listed # in the class index. If set to NO only the inherited external classes # will be listed. ALLEXTERNALS = NO # If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed # in the modules index. If set to NO, only the current project's groups will # be listed. EXTERNAL_GROUPS = YES # If the EXTERNAL_PAGES tag is set to YES all external pages will be listed # in the related pages index. If set to NO, only the current project's # pages will be listed. EXTERNAL_PAGES = YES # The PERL_PATH should be the absolute path and name of the perl script # interpreter (i.e. the result of `which perl'). PERL_PATH = /usr/bin/perl #--------------------------------------------------------------------------- # Configuration options related to the dot tool #--------------------------------------------------------------------------- # If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will # generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base # or super classes. Setting the tag to NO turns the diagrams off. Note that # this option also works with HAVE_DOT disabled, but it is recommended to # install and use dot, since it yields more powerful graphs. CLASS_DIAGRAMS = YES # You can define message sequence charts within doxygen comments using the \msc # command. Doxygen will then run the mscgen tool (see # http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the # documentation. The MSCGEN_PATH tag allows you to specify the directory where # the mscgen tool resides. If left empty the tool is assumed to be found in the # default search path. MSCGEN_PATH = # If set to YES, the inheritance and collaboration graphs will hide # inheritance and usage relations if the target is undocumented # or is not a class. HIDE_UNDOC_RELATIONS = YES # If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is # available from the path. This tool is part of Graphviz, a graph visualization # toolkit from AT&T and Lucent Bell Labs. The other options in this section # have no effect if this option is set to NO (the default) HAVE_DOT = NO # The DOT_NUM_THREADS specifies the number of dot invocations doxygen is # allowed to run in parallel. When set to 0 (the default) doxygen will # base this on the number of processors available in the system. You can set it # explicitly to a value larger than 0 to get control over the balance # between CPU load and processing speed. DOT_NUM_THREADS = 0 # By default doxygen will use the Helvetica font for all dot files that # doxygen generates. When you want a differently looking font you can specify # the font name using DOT_FONTNAME. You need to make sure dot is able to find # the font, which can be done by putting it in a standard location or by setting # the DOTFONTPATH environment variable or by setting DOT_FONTPATH to the # directory containing the font. DOT_FONTNAME = Helvetica # The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. # The default size is 10pt. DOT_FONTSIZE = 10 # By default doxygen will tell dot to use the Helvetica font. # If you specify a different font using DOT_FONTNAME you can use DOT_FONTPATH to # set the path where dot can find it. DOT_FONTPATH = # If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen # will generate a graph for each documented class showing the direct and # indirect inheritance relations. Setting this tag to YES will force the # CLASS_DIAGRAMS tag to NO. CLASS_GRAPH = YES # If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen # will generate a graph for each documented class showing the direct and # indirect implementation dependencies (inheritance, containment, and # class references variables) of the class with other documented classes. COLLABORATION_GRAPH = YES # If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen # will generate a graph for groups, showing the direct groups dependencies GROUP_GRAPHS = YES # If the UML_LOOK tag is set to YES doxygen will generate inheritance and # collaboration diagrams in a style similar to the OMG's Unified Modeling # Language. UML_LOOK = NO # If the UML_LOOK tag is enabled, the fields and methods are shown inside # the class node. If there are many fields or methods and many nodes the # graph may become too big to be useful. The UML_LIMIT_NUM_FIELDS # threshold limits the number of items for each type to make the size more # manageable. Set this to 0 for no limit. Note that the threshold may be # exceeded by 50% before the limit is enforced. UML_LIMIT_NUM_FIELDS = 10 # If set to YES, the inheritance and collaboration graphs will show the # relations between templates and their instances. TEMPLATE_RELATIONS = YES # If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT # tags are set to YES then doxygen will generate a graph for each documented # file showing the direct and indirect include dependencies of the file with # other documented files. INCLUDE_GRAPH = YES # If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and # HAVE_DOT tags are set to YES then doxygen will generate a graph for each # documented header file showing the documented files that directly or # indirectly include this file. INCLUDED_BY_GRAPH = YES # If the CALL_GRAPH and HAVE_DOT options are set to YES then # doxygen will generate a call dependency graph for every global function # or class method. Note that enabling this option will significantly increase # the time of a run. So in most cases it will be better to enable call graphs # for selected functions only using the \callgraph command. CALL_GRAPH = NO # If the CALLER_GRAPH and HAVE_DOT tags are set to YES then # doxygen will generate a caller dependency graph for every global function # or class method. Note that enabling this option will significantly increase # the time of a run. So in most cases it will be better to enable caller # graphs for selected functions only using the \callergraph command. CALLER_GRAPH = NO # If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen # will generate a graphical hierarchy of all classes instead of a textual one. GRAPHICAL_HIERARCHY = NO # If the DIRECTORY_GRAPH and HAVE_DOT tags are set to YES # then doxygen will show the dependencies a directory has on other directories # in a graphical way. The dependency relations are determined by the #include # relations between the files in the directories. DIRECTORY_GRAPH = YES # The DOT_IMAGE_FORMAT tag can be used to set the image format of the images # generated by dot. Possible values are svg, png, jpg, or gif. # If left blank png will be used. If you choose svg you need to set # HTML_FILE_EXTENSION to xhtml in order to make the SVG files # visible in IE 9+ (other browsers do not have this requirement). DOT_IMAGE_FORMAT = png # If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to # enable generation of interactive SVG images that allow zooming and panning. # Note that this requires a modern browser other than Internet Explorer. # Tested and working are Firefox, Chrome, Safari, and Opera. For IE 9+ you # need to set HTML_FILE_EXTENSION to xhtml in order to make the SVG files # visible. Older versions of IE do not have SVG support. INTERACTIVE_SVG = NO # The tag DOT_PATH can be used to specify the path where the dot tool can be # found. If left blank, it is assumed the dot tool can be found in the path. DOT_PATH = # The DOTFILE_DIRS tag can be used to specify one or more directories that # contain dot files that are included in the documentation (see the # \dotfile command). DOTFILE_DIRS = # The MSCFILE_DIRS tag can be used to specify one or more directories that # contain msc files that are included in the documentation (see the # \mscfile command). MSCFILE_DIRS = # The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of # nodes that will be shown in the graph. If the number of nodes in a graph # becomes larger than this value, doxygen will truncate the graph, which is # visualized by representing a node as a red box. Note that doxygen if the # number of direct children of the root node in a graph is already larger than # DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note # that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. DOT_GRAPH_MAX_NODES = 50 # The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the # graphs generated by dot. A depth value of 3 means that only nodes reachable # from the root by following a path via at most 3 edges will be shown. Nodes # that lay further from the root node will be omitted. Note that setting this # option to 1 or 2 may greatly reduce the computation time needed for large # code bases. Also note that the size of a graph can be further restricted by # DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. MAX_DOT_GRAPH_DEPTH = 0 # Set the DOT_TRANSPARENT tag to YES to generate images with a transparent # background. This is disabled by default, because dot on Windows does not # seem to support this out of the box. Warning: Depending on the platform used, # enabling this option may lead to badly anti-aliased labels on the edges of # a graph (i.e. they become hard to read). DOT_TRANSPARENT = NO # Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output # files in one run (i.e. multiple -o and -T options on the command line). This # makes dot run faster, but since only newer versions of dot (>1.8.10) # support this, this feature is disabled by default. DOT_MULTI_TARGETS = NO # If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will # generate a legend page explaining the meaning of the various boxes and # arrows in the dot generated graphs. GENERATE_LEGEND = YES # If the DOT_CLEANUP tag is set to YES (the default) Doxygen will # remove the intermediate dot files that are used to generate # the various graphs. DOT_CLEANUP = YES ����������������������������������������������������������������������������������������libburn-1.4.2/doc/mediainfo.txt���������������������������������������������������������������������0000644�0001757�0001751�00000143055�12652644224�013364� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ ------------------------------------------------------------------------------- Note: This is about how libburn operates optical drives. Not about how to operate libburn. The libburn API is described in libburn/libburn.h ------------------------------------------------------------------------------- Overview of class specific or individual media information especially manufacturer and exact product type Inspired by Andy Polyakov's http://fy.chalmers.se/~appro/linux/DVD+RW/tools , and by Joerg Schilling's http://cdrecord.berlios.de/private/cdrecord.html, backed by reading mmc5r03c.pdf from http://www.t10.org/ftp/t10/drafts/mmc5/, ECMA-279 (DVD-R), ECMA-337 (DVD+RW), ECMA-349 (DVD+R), and by searching the web for media manufacturer IDs (see list of URLs below). For libburnia-project.org by Thomas Schmitt <scdbackup@gmx.net> September 2009 ------------------------------------------------------------------------------- CD: The manufacturers vary the lead-in address in ATIP ATIP start of lead in: -12490 (97:15/35) Media sizes and nominal speeds often get expressed in the ATIP lead-out address. ATIP start of lead out: 359849 (79:59/74) (example media labeled "LITEON CD-RW 4x-12x", by "Nan-Ya Plastics Corporation") This is available only with profile 0x09 (CD-R) and 0x0A (CD-RW). CD-ROM media (0x08) cannot be inquired by command 43h READ TOC/PMA/ATIP. 6.26 READ TOC/PMA/ATIP Format 4 with MSF bit produces these data as described in 6.26.3.6 Response Format 0100b: ATIP. The minute, second, and frame number of lead-in can be read from byte 4 to 6 of the ATIP descriptor. The lead-out bytes are at position 8 to 10. The ATIP descriptor is preceeded by a four byte header. I could not find out yet whether (lead-in,lead-out) is mandatorily unique for each particular media product. The parameters can be obtained via libburn by : burn_disc_read_atip(d), burn_drive_get_start_end_lba(d, start_lba, end_lba, 0), burn_lba_to_msf(start_lba, &m_li, &s_li, &f_li) and burn_lba_to_msf(end_lba, &m_lo, &s_lo, &f_lo) There seems to be no public and free list of manufacturers and codes. Nevertheless many people report codes and manufacturer names in the web. Especially helpful are media compatibility lists by drive manufacturers. The items from the CD media list below are the foundation of libburn API call burn_guess_cd_manufacturer() which rounds the lead-in address down to multiples of 10 frames and then looks them up in its list. ------------------------------------------------------------------------------- DVD + BD: dvd+rw-mediainfo uses MMC-5 6.23, ADh READ DISC STRUCTURE which returns media type specific information if the drive supports the particular Format Code. With DVD+ and BD there is a 8 character Manufacturer ID, a 3 character Media Id and a single character Media Revision. With DVD-R, ECMA-279 promises a Manufacturer ID of up to 18 characters. With DVD-RW, ECMA-338 gives up the meaning of the last six-pack. Both, DVD-RW RITEKW01 and DVD-R RITEKF1 bear unprintable characters there. With DVD-ROM and DVD-RAM there seem to be no such ids. 6.23.3.2.1 Format Code 00h: Physical Format Information Disk Category in bits 4 to 7 of byte 0 gives the "Book Type". MMC-5 Table 401 gives this list 0x0 DVD-ROM 0x1 DVD-RAM 0x2 DVD-R 0x3 DVD-RW 0x4 HD DVD-ROM 0x5 HD DVD-RAM 0x6 HD DVD-R 0x9 DVD+RW 0xA DVD+R 0xD DVD+RW DL 0xE DVD+R DL Bits 0 to 3 is Part Version "[revision %d]" 6.23.3.1.7 Format Code FFh: Disc Structure List Returns a list of 4-byte list entries: Byte0 gives an available format code. Byte1,bit6 confirms that it is readable. Bytes 2 and 3 predict the reply length. DVD+RW and DVD+R: dvd+rw-mediainfo prefers this if available: Format code 11h : "ADIP Information" dvd+rw-mediainfo: printf (" Media ID: %.8s/%.3s\n",dvd._11+23,dvd._11+31), = ECMA-337 (DVD+RW) and ECMA-349 (DVD+R) 14.4.2 Physical format information in ADIP, Table 3 byte 19: Disk Manufacturer ID byte 27: Media Type ID (byte 28: Product revision number) MMC-5 6.23.3.2.17 , Table 426 shows 4 byte header: MSB,LSB of Disc Structure Data Length 2 bytes reserved Two of my burners do not perform this operation on DVD+ media and reply [5 24 00] "Invalid field in cdb": 'HL-DT-ST' 'BD-RE GGW-H20L' 'HL-DT-ST' 'BDDVDRW GGC-H20L' The other one does it with the same media: 'TSSTcorp' 'CDDVDW SH-S203B' This refusal seems not uncommon. dvd+rw-mediainfo later does: Format code 00h : "Physical Format Information" dvd+rw-mediainfo: if (dvd_plus && !plus_mediaid_printed) printf (" Media ID: %.8s/%.3s\n",header+23,header+31); = ECMA-337 (DVD+RW) and ECMA-349 (DVD+R) 14.4.2 Physical format information in ADIP, Table 3 byte 19: Disk Manufacturer ID byte 27: Media Type ID (byte 28: Product revision number) MMC-5 6.23.3.2.1 , Table 400, Table 407 says for DVD+RW bytes 19 - 255 are a copy of bytes 19 -255 from ADIP dvd+rw-mediainfo applies this to DVD+R too DVD-R , DVD-RW, (DVD-R DL) : Format code 0Eh "Pre-recorded Information in Lead-in" dvd+rw-mediainfo: if (!dvd_plus && dvd_0E && dvd._e[4+16]==3 && dvd._e[4+24]==4) printf (" Media ID: %6.6s%-6.6s\n",dvd._e+4+17,dvd._e+4+25); = ECMA-279 (DVD-R) 27.3.7 Field ID3 to Field ID5 28.3.2.1 RMD Field 0, Table 20 - Copy of Pre-pit Information It appears that the reply format of MMC ADh format 0Eh is the data record shown in Table 20 of ECMA-279 with offset 22: Manufacturer ID at bytes 17 to 22, 25 to 30, 33 to 38. Bytes 16, 24, 32 have content 3, 4, 5. ECMA-338 (DVD-RW) says the same in: 29.3.3.1.1 Format1 RMD Field0 Table 24 - Copy of Pre-pit Information Manufacturer ID at bytes 17 to 22, 25 to 30, but not at 33 6.23.3.2.14 Format Code 0Eh: Pre-recorded Information in Lead-in Table 423 shows 4 byte header: MSB,LSB of Disc Structure Data Length 2 bytes reserved >>> still to evaluate: Format code 0Fh : "Unique Disc Identifier" = 6.23.3.2.15 Format Code 0Fh: Unique Disc Identifier DVD-RAM : dvd+rw-mediainfo lists no info about manufacturer or type. No format code of ADh READ DISC STRUCTURE promises such info for DVD-RAM. BD-R and BD-RE: dvd+rw-mediainfo: if (di[4+0]=='D' && di[4+1]=='I') printf (" Media ID: %6.6s/%-3.3s\n",di+4+100,di+4+106); = MMC-5 6.23.3.3.1 Format Code 00h: Disc Information (DI) Table 288 says that Media Type Code (byte 1 of CDB) for BD media is 1. Table 446 says that Disc Information is preceeded by 4 bytes of header. Table 448 says that bytes 0 to 1 are Disc Information Identifier "DI". that bytes 8 to 10 are Disc Type Identifier BDO for BD-ROM, BDW for BD-RE, BDR for BD-R that bytes 100 to 105 are Disc Manufactuer ID that bytes 106 to 108 are Media Type ID that byte 111 is Product Revision Number Via libburn these manufacturer and media ids can be retrieved by API call burn_disc_get_media_id() as a single printable word product_id and as two printable words media_code1, media_code2. The latter can be translated into a manufacturer company name by API call burn_guess_manufacturer(). (Both calls work for CD, too. burn_disc_get_media_id() eventually calls burn_disc_read_atip().) =============================================================================== Collection of Media IDs Sources: [Gig] http://www.gigabyte.com.tw/FileList/WebPage/old_system_oddwebpage/media_support_list_r5232a.pdf [Aopen] http://download.aopen.com.tw/Download.aspx?RecNo=11411&Model=2597&Section=1&DL=yes [Msi] http://ru.msi.com/products/multimedia/optical/spec/recommend_disc.pdf [Btc] http://www.btc.com.tw/english/3-2-1MediaSupport_combo5216_cdr.htm [Mits] http://www.mitsubishielectric.com.au/assets/vis/DD16C48_Media_Compatibility.pdf [Hij] http://hijacker.rpc1.org/toshiba/SD-R5372V/MediaList_SD-R5372V_TU15.pdf [Teac] http://www.google.com/url?sa=t&source=web&ct=res&cd=4&url=http%3A%2F%2Fdspd.teac.de%2Ffileadmin%2Fredaktion%2Fdownloads%2Ffirmware%2Fmedialist%2Fmedialist_dvw50e_130.pdf&ei=0smfSt-TBNaosgbnm6wZ&rct=j&q=cd+%22manufacturer+id%22+97&usg=AFQjCNH4hSHb7yphONuO_NnaaWLV4g5v9A [Blu] http://www.blu-raydisc.info/licensee_info.php [Edig] http://www.editgrid.com/user/idrs/DVR112_MediaList_109_20070118_2final.xml Found by : www.google.com : NAN-YA cmc Princo Ricoh lead-in Try also : www.google.com : cd "manufacturer id" 97 ------------------------------------------------------------------------------ CD Media IDs The findings from the web have been cross checked with the lists of cdrecord. But no codes or manufacturer ids have been taken from diskid.c out of cdrtools-2.01.01a39/cdrecord/. X = not in cdrecord D = different in cdrecord The exact lettering of manufacturer names may differ from cdrecord. For any exact comparison use rather the minute,second,frame tuples of the ATIP lead-in address directly. The vast majority of these tuples begin with 97. (libburn API call burn_disc_get_media_id() encodes both tuples in its reply parameters as e.g. "97m15s35f/79m59s74f" , "97m15s35f", "79m59s74f") Chosen Name Lead-in Lead-out Name [source] ======================================================== "SKC" X 96 40 05 79 59 74 - SKC(90) 24X [Msi] "Ritek Corp" X 96 43 33 79 59 74 702.83MB TRAXDATA 24X [Msi] 96 43 33 79 59 74 90 32x "Prodisc Technology Inc." [Gig] 96 43 37 79 59 73 99 48x "Ritek Corp" [Gig] 96 43 37 79 59 73 Ritek [Aopen] 96 43 37 79 59 74 702.83MB PHIL(Ritek) Multi Speed [Msi] 96 43 37 79 59 74 90 48x "Ritek Corp" [Gig] 96 43 37 79 59 74 Ritek [Aopen] 96 43 37 79 59 74 Ritek [Btc] "TDK / Ritek" X 97 10 00 79 59 74 702.83MB RiDATA(Ritek) N/A 12X [Msi] 97 10 00 79 59 74 702.83MB TRAXDATA(Ritek) 10X [Msi] 97 10 00 79 59 74 702.83MB TRAXDATA(Ritek) N/A 10X [Msi] 97 10 00 79 59 74 80 12X "TDK Corporation" [Gig] 97 10 00 79 59 74 TDK(RITEK) [Aopen] 97 10 01 79 59 74 702.83MB Ritek.Co. 16X [Msi] 97 10 01 79 59 74 Ritek [Aopen] 97 10 03 79 59 74 80 32X "RITEK" [Gig] "TDK Corporation" 97 15 00 79 59 74 702.83MB 52X TDK Multi Speed [Msi] 97 15 00 79 59 74 TDK [Btc] 97 15 01 79 59 74 80 24X "TDK Corporation" [Gig] 97 15 05 79 59 74 80 52X "TDK Corporation" [Gig] 97 15 05 79 59 74 TDK 52X [Msi] 97 15 05 79 59 74 TDK [Aopen] 97 15 05 79 59 74 TDK [Btc] 97 15 05 91 01 48 800MB TDK 40X 800MB [Msi] 97 15 05 91 01 48 800MB TDK 40X [Msi] 97 15 05 91 01 48 90 24X "TDK Corporation" [Gig] 97 15 05 91 01 48 TDK [Aopen] "Ritek Corp" 97 15 12 79 59 73 702.83MB Ritek Co. 52X [Msi] 97 15 12 79 59 73 80 52x "Ritek Corp" [Gig] 97 15 12 79 59 73 Ritek,80 [Aopen] 97 15 12 79 59 73 Ritek [Btc] 97 15 12 79 59 73 Ritek CD-R 52X 702.83MB [Mits] 97 15 12 79 59 74 80 24x "Ritek Corp" [Gig] 97 15 12 79 59 74 Ritek [Btc] 97 15 17 24 15 01 Ritek [Btc] 97 15 17 74 45 01 Ritek [Btc] 97 15 17 79 59 70 702.83MB 7-plus (Ritek) Multi Speed [Msi] 97 15 17 79 59 70 702.83MB Aopen (Ritek) Multi Speed [Msi] 97 15 17 79 59 70 702.83MB PONY (Ritek) Multi Speed [Msi] 97 15 17 79 59 70 702.83MB PONY(Ritek) Multi Speed [Msi] 97 15 17 79 59 70 702.83MB Power Source(Ritek) 32X [Msi] 97 15 17 79 59 70 702.83MB Ritek 40X [Msi] 97 15 17 79 59 70 702.83MB Ritek Co. 52X [Msi] 97 15 17 79 59 70 702.83MB TDK (Ritek ) 40X [Msi] 97 15 17 79 59 70 702.83MB TDK(Ritek ) 40X [Msi] 97 15 17 79 59 70 702.83MB TDK(Ritek ) 48X [Msi] 97 15 17 79 59 70 702.83MB TDK(Ritek) 48X [Msi] 97 15 17 79 59 70 702.83MB TRAXDATA (Ritek ) 40X [Msi] 97 15 17 79 59 70 80 52x "Ritek Corp" [Gig] 97 15 17 79 59 70 Aopen CD-R Multi Speed 702.83MB [Mits] 97 15 17 79 59 70 HiCO CD-R Multi Speed 702.83MB [Mits] 97 15 17 79 59 70 PHILIPS CD-R 48X 702.83MB [Mits] 97 15 17 79 59 70 PONY CD-R Multi Speed 702.83MB [Mits] 97 15 17 79 59 70 Primdisc CD-R 52X 702.83MB [Mits] 97 15 17 79 59 70 RiDATA CD-R 40X 702.83MB [Mits] 97 15 17 79 59 70 Ritek [Aopen] 97 15 17 79 59 70 Ritek [Btc] 97 15 17 79 59 70 Ritek CD-R 40X 702.83MB [Mits] 97 15 17 79 59 70 Ritek CD-R 52X 702.83MB [Mits] 97 15 17 79 59 70 TDK CD-R 40X 702.82MB [Mits] 97 15 17 79 59 70 TDK CD-R 40X 702.83MB [Mits] 97 15 17 79 59 70 TRAXDATA CD-R 40X 702.83MB [Mits] 97 15 17 79 59 70 Victor.JVC CD-R 48X 702.82MB [Mits] 97 15 17 79 59 71 702.82MB PONY(Ritek) Multi Speed [Msi] 97 15 17 79 59 71 702.83MB TRAXDATA(Ritek) 24X [Msi] 97 15 17 79 59 71 80 24x "Ritek Corp" [Gig] 97 15 17 79 59 71 Ritek [Btc] 97 15 17 79 59 72 Ritek [Btc] 97 15 17 79 59 73 702.83MB OPTI STORAGE (Ritek) 40X [Msi] 97 15 17 79 59 73 702.83MB Ritek 48X [Msi] 97 15 17 79 59 73 702.83MB Ritek.Co (Trax) 40X [Msi] 97 15 17 79 59 73 702.83MB Samsung Digit(Ritek) 40X [Msi] 97 15 17 79 59 73 80 52x "Ritek Corp" [Gig] 97 15 17 79 59 73 Ritek [Aopen] 97 15 17 79 59 74 Ritek [Btc] 97 15 18 79 59 74 80 32x "Ritek Corp" [Gig] "Mitsubishi Chemical Corporation" 97 15 21 79 59 74 MCC ("Mitsubishi Chemical Corporation") [Btc] "Nan-Ya Plastics Corporation" 97 15 35 79 59 73 702.83MB NANYA 4-12X [Msi] 97 15 35 79 59 73 80 12X "Nan-Ya" [Gig] 97 15 35 79 59 73 NanYa [Aopen] 97 15 35 79 59 74 702.83MB Hatron(NANYA) 4-10X [Msi] 97 15 35 79 59 74 702.83MB MMore(NANYA) 4-10X [Msi] 97 15 35 79 59 74 (NanYa) [Aopen] 97 15 36 79 59 74 80 40x "Nan-Ya plastics Corporation" [Gig] 97 15 36 79 59 74 NanYa [Aopen] 97 15 36 79 59 74 NANYA [Btc] 97 15 37 79 59 73 NANYA [Btc] 97 15 37 79 59 74 702.83MB NANYA 1-52X [Msi] 97 15 37 79 59 74 702.83MB NANYA 48X [Msi] 97 15 37 79 59 74 80 52x "Nan-Ya plastics Corporation" [Gig] 97 15 37 79 59 74 Acer CD-R 48X 702.83MB [Mits] 97 15 37 79 59 74 LITEON CD-R 48X 702.83MB [Mits] 97 15 37 79 59 74 LITEON CD-R 52X 702.83MB [Mits] 97 15 37 79 59 74 NANYA [Btc] 97 15 37 79 59 74 NANYA CD-R 1-52X 702.83MB [Mits] 97 15 39 79 59 74 80 52x "Nan-Ya plastics Corporation" [Gig] 97 15 39 79 59 74 NanYa [Aopen] 97 15 39 79 59 74 NANYA [Btc] "Delphi" X 97 15 57 79 59 73 Delphi [Aopen] 97 15 57 79 59 74 Delphi [Btc] "Shenzhen SG&SAST" 97 16 29 79 59 73 702.83MB SAST(SHENZHEN) Multi peed [Msi] 97 16 29 79 59 73 80 52x "Shenzhen SG&SAST [Gig] 97 16 29 79 59 73 SAST [Btc] 97 16 29 79 59 73 SAST(ultra [Aopen] 97 16 29 79 59 74 80 52x "Shenzhen SG&SAST" [Gig] "Moser Baer India Limited" 97 17 00 4x "Moser Baer India Limited" [Gig] 97 17 01 79 59 74 MBI [Aopen] 97 17 06 79 59 74 702.83MB EMTEC (Moser Bear India) 48X [Msi] 97 17 06 79 59 74 702.83MB Intenso (Moser Bear India) 1-48X [Msi] 97 17 06 79 59 74 702.83MB Moser Bear India 52X [Msi] 97 17 06 79 59 74 702.83MB YAKUMO(Moser Bear India) 52X [Msi] 97 17 06 79 59 74 80 52x "Moser Baer India Limited" [Gig] 97 17 06 79 59 74 MBI [Aopen] 97 17 06 79 59 74 Moser Bear India CD-R 52X 702.83MB [Mits] 97 17 06 79 59 74 PLATINUM CD-R 52X 702.83MB [Mits] 97 17 06 79 59 74 Silver Circle CD-R 52X 702.83MB [Mits] "SKY media Manufacturing SA" X 97 17 16 79 59 74 80 48x "SKY media Manufacturing SA" [Gig] 97 17 16 79 59 74 SKY [Aopen] "Wing" D "WEALTH FAIR INVESTMENT LIMITED" 97 18 17 79 59 74 Wing [Aopen] "DDT" X 97 18 28 79 59 74 DDT [Aopen] "Taroko International Co.Ltd" 97 18 67 79 59 73 80 48x "Taroko International Co.Ltd" [Gig] 97 18 67 79 59 74 Taroko [Aopen] 97 18 67 79 59 74 TAROKO [Btc] "Daxon Technology Inc. / Acer" D "Acer Media Technology, Inc." 97 22 60 4x "Daxon Technology Inc." [Gig] 97 22 60 74 41 50 74 12X "Daxon Technology Inc." [Gig] 97 22 60 74 41 50 Acer CD-RW 4X 656.20MB [Mits] 97 22 60 74 41 50 Acer US-RW 24X 656.20MB [Mits] 97 22 60 74 41 50 Daxon [Aopen] 97 22 60 79 59 74 702.83MB Maxmax(Acer) 8-10X [Msi] 97 22 60 79 59 74 80 24x "Daxon Technology Inc." [Gig] 97 22 60 79 59 74 Acer CD-RW 4X 702.83MB [Mits] 97 22 60 79 59 74 Daxon [Aopen] 97 22 60 79 59 74 Diamond Data HS-RW 4-16X 702.83MB [Mits] 97 22 60 79 59 74 Maxmax HS-RW 8-10X 702.83MB [Mits] 97 22 62 79 59 74 702.83MB Acer 4-16X [Msi] 97 22 62 79 59 74 702.83MB Acer N/A 4-16X [Msi] 97 22 62 79 59 74 Acer [Aopen] 97 22 66 79 59 74 80 52x "Daxon Technology Inc." [Gig] 97 22 66 79 59 74 Acer [Aopen] 97 22 67 79 59 74 702.83MB Acer 52X [Msi] 97 22 67 79 59 74 702.83MB BenQ(Acer) 40X [Msi] 97 22 67 79 59 74 702.83MB BenQ (Acer) 48X [Msi] 97 22 67 79 59 74 702.83MB Daxon(Acer) 48X [Msi] 97 22 67 79 59 74 702.83MB gold(Acer) 32X [Msi] 97 22 67 79 59 74 702.83MB SONY(Acer) 48X [Msi] 97 22 67 79 59 74 80 52x "Daxon Technology Inc." [Gig] 97 22 67 79 59 74 Acer [Btc] 97 22 67 79 59 74 Acer CD-R 52X 702.83MB [Mits] 97 22 67 79 59 74 Acer,DAXON [Aopen] "Taiyo Yuden Company Limited" 97 24 01 74 43 00 74 16x "Taiyo Yuden Company Limited" [Gig] 97 24 01 74 43 01 656.40MB Maxell(Taiyo Yuden) 32X [Msi] 97 24 01 74 43 01 656.40MB Taiyo Yuden 32X [Msi] 97 24 01 74 43 01 74 48x "Taiyo Yuden Company Limited" [Gig] 97 24 01 74 43 01 Taiyo Yuden [Btc] 97 24 01 74 43 01 TY,tuned [Aopen] 97 24 01 74 43 02 656.40MB Taiyo Yuden 40-48X [Msi] 97 24 01 74 43 02 74 52x "Taiyo Yuden Company Limited" [Gig] 97 24 01 74 43 02 FUJIFILM CD-R 48X 656.40MB [Mits] 97 24 01 74 43 02 Taiyo Yuden [Btc] 97 24 01 74 43 02 TY [Aopen] 97 24 01 79 59 72 702.83MB Taiyo Yuden 40-48X [Msi] 97 24 01 79 59 72 702.83MB Taiyo Yuden 48X [Msi] 97 24 01 79 59 72 702.83MB Taiyo Yuden Multi Speed [Msi] 97 24 01 79 59 72 80 52x "Taiyo Yuden Company Limited" [Gig] 97 24 01 79 59 72 Maxell CD-R 48X 702.83MB [Mits] 97 24 01 79 59 72 SONY CD-R 48X 702.83MB [Mits] 97 24 01 79 59 72 Taiyo Yuden [Btc] 97 24 01 79 59 72 Taiyo Yuden CD-R 52X 702.83MB [Mits] 97 24 01 79 59 72 Taiyo Yuden CD-R Multi Speed 702.83MB [Mits] 97 24 01 79 59 72 TY [Aopen] 97 24 01 79 59 73 702.83MB SONY(Taiyo Yuden) 32X [Msi] 97 24 01 79 59 73 702.83MB Taiyo Yuden 32X [Msi] 97 24 01 79 59 73 80 48x "Taiyo Yuden Company Limited" [Gig] 97 24 01 79 59 73 Taiyo Yuden [Btc] 97 24 01 79 59 73 TY,tuned [Aopen] 97 24 01 79 59 74 702.83MB FUJIFILM(Tayio Yuden) 48X [Msi] 97 24 01 79 59 74 80 16x "Taiyo Yuden Company Limited" [Gig] "Sony Corporation" 97 24 11 74 43 00 74 24x "Sony Corporation" [Gig] 97 24 11 79 59 11 80 24x "Sony Corporation" [Gig] 97 24 11 79 59 74 Sony [Aopen] 97 24 11 79 59 74 SONY [Btc] 97 24 12 74 43 00 74 48x "Sony Corporation" [Gig] 97 24 12 74 43 00 LeadData,Sony [Aopen] 97 24 12 79 59 74 80 32x "Sony Corporation" [Gig] 97 24 12 79 59 74 SONY [Btc] 97 24 15 74 30 00 Imation [Aopen] 97 24 15 74 43 00 654.49MB imation(Sony) 4X-10X [Msi] 97 24 15 79 59 74 702.83MB (SONY) 2-24X [Msi] 97 24 15 79 59 74 702.83MB SONY(Lead data) 48X [Msi] 97 24 15 79 59 74 80 48x "Sony Corporation" [Gig] 97 24 15 79 59 74 Sony [Aopen] 97 24 16 79 59 74 702.83MB SONY(Lead data) 52X [Msi] 97 24 16 79 59 74 80 52x "Sony Corporation" [Gig] 97 24 16 79 59 74 Sony [Aopen] 97 24 16 79 59 74 SONY [Btc] "Computer Support Italcard s.r.l" 97 24 26 79 59 74 80 52x "Computer Support Italcard s.r.l" [Gig] 97 24 26 79 59 74 Csita [Aopen] "Unitech Japan Inc." 97 24 39 79 59 74 80 52x "Unitech Japan Inc." [Gig] 97 24 39 79 59 74 RA [Aopen] "MPO, France" 97 25 00 79 59 74 TDK CD-R80(25) [Teac] 97 25 06 74 45 00 74 52x "MPO" [Gig] 97 25 06 74 45 00 MPO,France [Aopen] 97 25 06 79 59 74 80 52x "MPO" [Gig] 97 25 07 79 59 00 MPO,France [Aopen] "Hitachi Maxell Ltd." 97 25 22 79 59 74 80 16x "Hitachi Maxell Ltd." [Gig] 97 25 29 74 30 00 654.49MB Hitachi Maxell Multi Speed [Msi] 97 25 29 74 30 00 74 52x "Hitachi Maxell Ltd." [Gig] 97 25 29 74 30 00 MAXELL [Aopen] 97 25 29 74 30 00 Maxell [Btc] 97 25 29 79 59 74 702.83MB Hitachi Maxell(Acer OEM) 32X [Msi] 97 25 29 79 59 74 702.83MB Hitachi Maxell Multi Speed [Msi] 97 25 29 79 59 74 80 52x "Hitachi Maxell Ltd." [Gig] 97 25 29 79 59 74 Eigen CD-R Multi Speed 702.83MB [Mits] 97 25 29 79 59 74 Maxell [Btc] 97 25 29 79 59 74 MAXWELL [Aopen] "Infodisc Technology Co,Ltd." 97 25 30 24 01 05 Infodisk 8cm HS-RW 12X 210.80MB [Mits] 97 25 30 - - - 4x "Infodisc Technology Co,Ltd." [Gig] 97 25 30 74 44 07 INFODISC [Aopen] 97 25 30 79 59 72 INFODISC [Aopen] 97 25 30 79 59 73 MEMOREX [Aopen] 97 25 30 79 59 74 80 10X "Infodisc Technology Co,Ltd." [Gig] 97 25 30 79 59 74 Infodisk CD-RW 4X 702.83MB [Mits] 97 25 30 79 59 74 MEMOREX(INFODISC) [Aopen] 97 25 31 79 59 73 80 24x "Infodisc Technology Co,Ltd." [Gig] 97 25 35 79 59 74 702.83MB Infodisc 52X [Msi] 97 25 35 79 59 74 702.83MB SPEEDA(Infodisc) 40X [Msi] 97 25 35 79 59 74 80 48x "Infodisc Technology Co,Ltd." [Gig] 97 25 35 79 59 74 Lead data [Btc] "Xcitec" D "Xcitec Inc." 97 25 66 79 59 73 XGITEK [Aopen] "Fornet International Pte Ltd" 97 26 00 4x "Fornet International Pte Ltd" [Gig] 97 26 00 79 59 74 80 12X "Fornet International Pte Ltd" [Gig] 97 26 00 79 59 74 COMPUSA,Fornet [Aopen] 97 26 01 74 56 00 74 24x "Fornet International Pte Ltd" [Gig] 97 26 01 79 59 74 80 12X "Fornet International Pte Ltd" [Gig] 97 26 06 79 59 74 80 24x "Fornet International Pte Ltd" [Gig] 97 26 07 79 59 64 90 24x "Fornet International Pte Ltd" [Gig] 97 26 07 79 59 64 Formet [Btc] 97 26 07 79 59 71 702.82MB Cdhouse (Fornet International) 52X [Msi] 97 26 07 79 59 71 80 52x "Fornet International Pte Ltd" [Gig] 97 26 07 79 59 71 Formet [Btc] 97 26 07 79 59 71 Fornet [Aopen] 97 26 07 79 59 74 Fornet [Aopen] "Postech Corporation" 97 26 11 22 23 60 Postech [Btc] 97 26 11 79 59 73 702.83MB Postech 52X [Msi] 97 26 11 79 59 73 80 52x "Postech Corporation" [Gig] 97 26 11 79 59 73 Postech [Aopen] 97 26 11 79 59 73 POSTECH [Aopen] 97 26 11 79 59 73 Postech [Btc] 97 26 11 79 59 73 Postech CD-R 52X 702.83MB [Mits] 97 26 11 79 59 74 702.83MB Postech corp Multi Speed [Msi] 97 26 11 79 59 74 702.83MB Postech N/A 12X [Msi] 97 26 11 79 59 74 80 12X "Postech Corporation" [Gig] 97 26 11 79 59 74 80 40x "Postech Corporation" [Gig] 97 26 11 79 59 74 Mr.Platinum [Aopen] 97 26 11 79 59 74 POSTECH [Aopen] 97 26 11 79 59 74 Postech [Btc] 97 26 15 79 59 74 80 32x "Postech Corporation" [Gig] "SKC Co Ltd." 97 26 21 74 59 73 74 12X "SKC Co Ltd." [Gig] 97 26 21 74 59 73 SKC74-Korea [Aopen] 97 26 21 79 59 74 80 12X "SKC Co Ltd." [Gig] 97 26 21 79 59 74 SKC80-Korea [Aopen] 97 26 26 79 59 73 702.83MB SKC 48X [Msi] 97 26 26 79 59 73 80 52x "SKC Co Ltd." [Gig] 97 26 26 79 59 73 Infinite CD-R 48X 702.83MB [Mits] 97 26 26 79 59 73 SKC [Btc] 97 26 26 79 59 73 SKC(Korea) [Aopen] "Fuji Photo Film Co,Ltd." 97 26 45 79 59 73 702.83MB FUJI 52X [Msi] 97 26 45 79 59 73 80 52x "Fuji Photo Film Co,Ltd." [Gig] 97 26 45 79 59 73 Fujifilm [Aopen] 97 26 45 79 59 74 80 32x "Fuji Photo Film Co,Ltd." [Gig] "Lead Data Inc." 97 26 50 4x "Lead Data Inc." [Gig] 97 26 50 74 59 74 SONY CD-RW 1-4X 702.83MB [Mits] 97 26 51 79 59 74 702.83MB Lead Data 12X [Msi] 97 26 51 79 59 74 80 12X "Lead Data Inc." [Gig] 97 26 51 79 59 74 Leaddata [Aopen] 97 26 52 79 59 74 80 32x "Lead Data Inc." [Gig] 97 26 53 79 59 74 702.83MB Lead Data 48X [Msi] 97 26 53 79 59 74 Gigastorage [Btc] 97 26 54 79 59 74 702.83MB Lead Data 48X [Msi] 97 26 54 79 59 74 80 48x "Lead Data Inc." [Gig] 97 26 54 79 59 74 LeadData [Aopen] 97 26 54 79 59 74 Lead data [Btc] 97 26 54 79 59 74 Lead Data CD-R 48X 702.83MB [Mits] 97 26 56 79 59 74 80 52x "Lead Data Inc." [Gig] 97 26 56 79 59 74 LeadData [Aopen] 97 26 56 79 59 74 Lead data [Btc] 97 26 57 79 59 74 80 52x "Lead Data Inc." [Gig] 97 26 57 79 59 74 MIRAGE [Aopen] "CMC Magnetics Corporation" 97 26 60 74 41 50 74 32x "Daxon Technology Inc." [Gig] 97 26 61 79 59 74 80 32x "CMC Magnetics Corporation" [Gig] 97 26 65 21 59 74 Verbatim 8mm CD-RW 2-4X 193.06MB [Mits] 97 26 65 24 30 00 215.04MB Memorex(CMC)8cm 4X [Msi] 97 26 65 24 30 00 Bi-Winner 8cm HS-RW 4-8X 215.04MB [Mits] 97 26 65 24 30 00 Memorex 8cm CD-RW 4X 215.04MB [Mits] 97 26 65 4x "CMC Magnetics Corporation" [Gig] 97 26 65 74 12 00 PLEXTOR [Aopen] 97 26 65 74 59 64 658.89MB CMC 16X [Msi] 97 26 65 74 59 64 CMC [Aopen] 97 26 65 75 00 00 658.89MB YAMAHA(CMC) 4-10X [Msi] 97 26 65 75 00 00 658.89MB YAMAHA(CMC) N/A 4-10X [Msi] 97 26 65 75 00 00 74 12X "CMC Magnetics Corporation" [Gig] 97 26 65 75 00 00 CMC [Aopen] 97 26 65 75 00 00 CMC CD-RW 4X 658.89MB [Mits] 97 26 65 79 59 64 CMC [Aopen] 97 26 65 79 59 74 702.83MB Melody(CMC) 10X [Msi] 97 26 65 79 59 74 702.83MB Office DEPOT(CMC) 1-4X [Msi] 97 26 65 79 59 74 702.83MB Philips(CMC) 4-12X [Msi] 97 26 65 79 59 74 702.83MB Philips(CMC) N/A 4-12X [Msi] 97 26 65 79 59 74 CMC [Aopen] 97 26 65 79 59 74 CMC CD-RW 4X 702.83MB [Mits] 97 26 65 79 59 74 Office DEPOT CD-RW 1-4X 702.83MB [Mits] 97 26 66 23 00 00 CMC [Btc] 97 26 66 23 59 74 CMC [Btc] 97 26 66 75 00 00 74 40x "CMC Magnetics Corporation" [Gig] 97 26 66 75 00 00 CMC [Aopen] 97 26 66 75 10 00 CMC [Aopen] 97 26 66 75 10 00 CMC [Btc] 97 26 66 75 10 00 CMC CD-R 52X 660.35MB [Mits] 97 26 66 79 59 71 702.83MB CMC 52X [Msi] 97 26 66 79 59 71 702.83MB eMARK(CMC) 48X [Msi] 97 26 66 79 59 71 702.83MB imation(CMC) 48X [Msi] 97 26 66 79 59 71 702.83MB imation(CMC) 48X [Msi] 97 26 66 79 59 71 80 52x "CMC Magnetics Corporation" [Gig] 97 26 66 79 59 71 CMC [Btc] 97 26 66 79 59 71 CMC CD-R 52X 702.83MB [Mits] 97 26 66 79 59 71 CMC,MEMOREX [Aopen] 97 26 66 79 59 73 702.83MB CMC 52X [Msi] 97 26 66 79 59 73 702.83MB HyperMedia(CMC) 52X [Msi] 97 26 66 79 59 73 702.83MB imation(CMC) 48X [Msi] 97 26 66 79 59 73 702.83MB imation(CMC) 48X [Msi] 97 26 66 79 59 73 702.83MB Melody (CMC) 40X [Msi] 97 26 66 79 59 73 702.83MB Melody(CMC) 40X [Msi] 97 26 66 79 59 73 702.83MB Samsung(CMC) 48X [Msi] 97 26 66 79 59 73 80 52x "CMC Magnetics Corporation" [Gig] 97 26 66 79 59 73 CMC [Aopen] 97 26 66 79 59 73 CMC [Btc] 97 26 66 79 59 73 CMC CD-R 52X 702.83MB [Mits] 97 26 66 79 59 73 Imation CD-R 48X 702.83MB [Mits] 97 26 66 79 59 73 Shintaro CD-R 40X 702.83MB [Mits] 97 26 66 79 59 73 Techworks CD-R 48X 702.83MB [Mits] 97 26 66 79 59 74 702.83MB Bi-Winner(CMC)99min 40X [Msi] 97 26 66 79 59 74 702.83MB Bi-Winner(CMC)99min 40X [Msi] 97 26 66 79 59 74 702.83MB Memorex(CMC) 48X [Msi] 97 26 66 79 59 74 702.83MB PHILIPS(CMC) 40X [Msi] 97 26 66 79 59 74 702.83MB PHILIPS(CMC) Multi Speed [Msi] 97 26 66 79 59 74 80 16x "CMC Magnetics Corporation" [Gig] 97 26 66 79 59 74 CMC [Aopen] 97 26 66 79 59 74 CMC [Btc] 97 26 67 75 00 00 658.89MB CMC 24X [Msi] 97 26 67 75 00 00 74 24x "CMC Magnetics Corporation" [Gig] 97 26 67 75 00 00 CMC US-RW 24X 658.89MB [Mits] 97 26 67 79 59 64 80 32X "CMC Magnetics Corporation" [Gig] "Ricoh Company Limited" D "DIGITAL STORAGE TECHNOLOGY CO.,LTD" 97 27 00 4x "Ricoh Company Limited" [Gig] 97 27 00 74 12 00 651.86MB RICOH N/A 4-10X [Msi] 97 27 00 74 12 00 651.86MB Sony(Digital Storage) 4X-10X [Msi] 97 27 00 74 12 00 651.86MB Sony(Digital Storage) 4X-10X [Msi] 97 27 00 74 12 00 74 10X "Ricoh Company Limited" [Gig] 97 27 00 74 12 00 74 24x "Ricoh Company Limited" [Gig] 97 27 00 74 12 00 RICOH [Aopen] 97 27 00 74 12 00 Ricoh HS-RW 4X-10X 651.86MB [Mits] 97 27 00 74 12 00 Sony HS-RW 4X-10X 651.86MB [Mits] 97 27 00 75 00 00 74 32x "Digital Storage Techology" [Gig] 97 27 00 79 59 74 702.83MB Laser 48X [Msi] 97 27 00 79 59 74 80 40x "Digital Storage Techology" [Gig] 97 27 00 79 59 74 Csita [Aopen] 97 27 00 79 59 74 RICOH [Aopen] 97 27 06 79 59 72 Digital Storage CD-R 52X 53.318MB [Mits] 97 27 06 79 59 72 DST [Aopen] 97 27 06 79 59 73 702.83MB Digital Storage 32X [Msi] 97 27 06 79 59 73 702.83MB Digital Storage 52X [Msi] 97 27 06 79 59 73 DST [Btc] 97 27 06 79 59 74 80 40x "Digital Storage Techology" [Gig] 97 27 06 79 59 74 DST [Aopen] "Plasmon Data systems Ltd" 97 27 10 21 30 00 188.67MB Plasmon 4-10X [Msi] 97 27 10 21 30 00 Ritek 8cm HS-RW 4-10X 188.67MB [Mits] 97 27 10 4x "Ritek Corp" [Gig] 97 27 10 74 41 00 656.10MB TDK(Plasmon) 4X-10X [Msi] 97 27 10 74 41 00 74 12X "Ritek Corp" [Gig] 97 27 10 74 41 00 EMTEC CD-RW 1-4X 656.10MB [Mits] 97 27 10 74 41 00 Ritek [Aopen] 97 27 10 74 41 00 TDK HS-RW 4-10X 651.86MB [Mits] 97 27 11 74 41 00 Ritek [Aopen] 97 27 11 74 41 01 656.10MB Plasmon 16X [Msi] 97 27 12 74 41 00 656.10MB RiDATA(Plasmon) 24X [Msi] 97 27 12 74 41 00 656.10MB Riteck co. 24X [Msi] 97 27 12 74 41 00 74 24x "Ritek Corp" [Gig] 97 27 12 74 41 00 Plasmon US-RW 24X 656.10MB [Mits] 97 27 18 79 59 74 702.83MB ALPHAPET(Plasmon)() 1-40X [Msi] 97 27 18 79 59 74 702.83MB MANIA(Plasmon)() 48X [Msi] 97 27 18 79 59 74 80 52x "Plasmon Data systems Ltd" [Gig] 97 27 18 79 59 74 Plasmon [Aopen] 97 27 18 79 59 74 Plasmon [Btc] 97 27 19 79 59 74 4M [Aopen] 97 27 19 79 59 74 80 48x "Plasmon Data systems Ltd" [Gig] "Princo Corporation" 97 27 21 79 59 74 Princo Co CD-RW 4X 702.83MB [Mits] 97 27 28 4x "Princo Corporation" [Gig] 97 27 28 74 50 01 74 40x "Princo Corporation" [Gig] 97 27 28 74 50 01 Princo [Aopen] 97 27 28 79 59 74 702.83MB Princo 2-48X [Msi] 97 27 28 79 59 74 702.83MB Princo 52X [Msi] 97 27 28 79 59 74 80 52x "Princo Corporation" [Gig] 97 27 28 79 59 74 Princo [Aopen] 97 27 28 79 59 74 Princo [Btc] 97 27 29 79 59 74 80 12X "Princo Corporation" [Gig] 97 27 29 79 59 74 Princo [Aopen] 97 27 29 79 59 74 Princo Co HS-RW 4-12X 702.83MB [Mits] "Pioneer" 97 27 30 PIONEER [Hij] "Eastman Kodak Company" 97 27 45 74 05 01 74 32x "Eastman Kodak Company" [Gig] "Mitsui Chemicals Inc." 97 27 55 74 05 10 74 16x "Mitsui Chemicals Inc." [Gig] 97 27 56 74 05 11 74 16x "Mitsui Chemicals Inc." [Gig] 97 27 56 79 59 74 80 24x "Mitsui Chemicals Inc." [Gig] 97 27 57 79 59 74 80 40x "Mitsui Chemicals Inc." [Gig] 97 27 57 79 59 74 MITSUI [Aopen] 97 27 58 74 05 13 MAM-A [Aopen] 97 27 58 79 59 74 80 52x "Mitsui Chemicals Inc." [Gig] 97 27 58 79 59 74 Mitsui [Aopen] 97 27 58 79 59 74 TDK [Btc] "Ricoh Company Limited" 97 27 66 74 12 00 RICOH [Btc] 97 27 66 74 12 02 74 48x "Ricoh Company Limited" [Gig] 97 27 66 74 12 02 Ricoh [Aopen] 97 27 66 74 12 03 74 52x "Ricoh Company Limited" [Gig] 97 27 66 74 12 03 Ritek [Btc] 97 27 66 74 12 03 Ritek,RS [Aopen] 97 27 66 79 59 71 702.82MB RICOH 40X [Msi] 97 27 66 79 59 71 80 48x "Ricoh Company Limited" [Gig] 97 27 66 79 59 71 RICOH [Btc] 97 27 66 79 59 71 RICOH CD-R 40X 702.82MB [Mits] 97 27 66 79 59 71 Ritek,RS [Aopen] 97 27 66 79 59 72 80 48x "Ricoh Company Limited" [Gig] 97 27 66 79 59 72 Ricoh [Aopen] 97 27 66 79 59 74 RICOH [Btc] "Gigastorage Corporation" 97 28 12 79 59 72 702.83MB Gigastorage 52X [Msi] 97 28 12 79 59 72 80 52x "Gigastorage Corporation" [Gig] 97 28 12 79 59 72 GigaSto [Aopen] 97 28 12 79 59 74 702.83MB Gigastorage 40X [Msi] 97 28 12 79 59 74 80 48x "Gigastorage Corporation" [Gig] 97 28 12 79 59 74 GigaSto, MaxMax [Aopen] 97 28 12 79 59 74 Gigastorage [Btc] 97 28 15 4x "Gigastorage Corporation" [Gig] 97 28 15 4x "Nan-Ya" [Gig] 97 28 15 74 12 00 74 10X "Gigastorage Corporation" [Gig] 97 28 15 74 12 00 CURSOR [Aopen] 97 28 15 79 59 72 702.83MB Gigastorage 52X [Msi] 97 28 15 79 59 72 702.83MB MaxMax (Gigastorage) 40X [Msi] 97 28 15 79 59 72 GigaSto [Aopen] 97 28 15 79 59 72 Gigastorage [Btc] 97 28 15 79 59 74 702.83MB Gigastorage 40X [Msi] 97 28 15 79 59 74 80 48x "Gigastorage Corporation" [Gig] 97 28 15 79 59 74 80 52x "Gigastorage Corporation" [Gig] 97 28 15 79 59 74 GigaSto [Aopen] 97 28 15 79 59 74 Gigastorage [Btc] 97 28 15 79 59 74 Gigastorage HS-RW 4X-8X 702.83MB [Mits] "Multi Media Masters&Machinary SA" 97 28 22 79 59 67 80 24x "Multi Media Masters&Machinary SA" [Gig] 97 28 22 79 59 67 King [Aopen] 97 28 22 79 59 67 Multi Media CD-R 48X 702.82MB [Mits] 97 28 26 79 59 74 702.83MB Mmirex(Multi Media) 24X [Msi] 97 28 26 79 59 74 80 52x "Multi Media Masters&Machinary SA" [Gig] 97 28 26 79 59 74 KingPro [Aopen] "Ritek Corp" 97 31 01 74 45 00 74 24x "Ritek Corp" [Gig] 97 31 01 74 45 00 Ritek [Btc] 97 31 01 74 45 01 656.68MB Ritek Co. 40X [Msi] 97 31 01 74 45 01 656.68MB Ritek Co. 52X [Msi] 97 31 01 74 45 01 74 52x "Ritek Corp" [Gig] 97 31 01 74 45 01 Ritek,74 [Aopen] 97 31 01 74 45 01 Ritek [Btc] 97 31 07 21 15 01 Ritek [Btc] 97 31 07 74 45 00 Ritek [Btc] 97 31 07 74 45 01 656.69MB Ritek Co. 48X [Msi] 97 31 07 74 45 01 656.69MB TDK(Ritek) 40X [Msi] 97 31 07 74 45 01 74 52x "Ritek Corp" [Gig] 97 31 07 74 45 01 Ritek [Aopen] 97 31 07 74 45 01 Ritek [Btc] 97 31 07 74 45 02 Ritek [Btc] "Grand Advance Technology Sdn. Bhd." 97 31 35 79 59 74 GAT [Aopen] "TDK Corporation" 97 32 00 74 59 00 74 16x "TDK Corporation" [Gig] 97 32 01 74 59 74 74 24X "TDK Corporation" [Gig] 97 32 05 74 59 00 74 52X "TDK Corporation" [Gig] 97 32 05 74 59 00 TDK [Aopen] "Prodisc Technology Inc." 97 32 10 79 59 74 702.83MB Prodisc 12X [Msi] 97 32 10 79 59 74 702.83MB Smartbuy(Prodisc) 8-12X [Msi] 97 32 10 79 59 74 702.83MB Smartbuy(Prodisc) N/A 8-12X [Msi] 97 32 10 79 59 74 80 12X "Prodisc Technology Inc." [Gig] 97 32 10 79 59 74 PRODISC [Aopen] 97 32 10 79 59 74 Smartbuy HS-RW 8-12X 702.83MB [Mits] 97 32 11 22 00 00 Prodisc CD-RW 1-4X 193.07MB [Mits] 97 32 11 4x "Prodisc Technology Inc." [Gig] 97 32 11 79 59 74 Prodisc CD-RW 1X-4X 702.83MB [Mits] 97 32 12 79 59 74 80 10X "Prodisc Technology Inc." [Gig] 97 32 12 79 59 74 PRODISC [Aopen] 97 32 13 79 59 74 (PRODISC) [Aopen] 97 32 19 22 00 00 Prodisc [Btc] 97 32 19 74 30 01 74 52x "Prodisc Technology Inc." [Gig] 97 32 19 74 30 01 Prodisc [Aopen] 97 32 19 74 30 01 Prodisc [Btc] 97 32 19 79 59 71 702.83MB Mitsubishi (Prodisc) 52X [Msi] 97 32 19 79 59 71 702.83MB Prodise 52X [Msi] 97 32 19 79 59 71 80 52x "Prodisc Technology Inc." [Gig] 97 32 19 79 59 71 Prodisc [Aopen] 97 32 19 79 59 71 Prodisc [Btc] 97 32 19 79 59 72 654.49MB Prodise 48X [Msi] 97 32 19 79 59 72 654.49MB Prodise 48X [Msi] 97 32 19 79 59 72 702.83MB Digmaster(Prodisc) 40X [Msi] 97 32 19 79 59 72 702.83MB Digmaster(Prodisc) 48X [Msi] 97 32 19 79 59 72 702.83MB LG(Prodisc) 1-48X [Msi] 97 32 19 79 59 72 702.83MB Mitsubishi (Prodisc) Multi Speed [Msi] 97 32 19 79 59 72 702.83MB Prodise 48X [Msi] 97 32 19 79 59 72 80 52x "Prodisc Technology Inc." [Gig] 97 32 19 79 59 72 Mitsubishi CD-R Multi Speed 702.83MB [Mits] 97 32 19 79 59 72 Prodisc [Aopen] 97 32 19 79 59 72 Prodisc [Btc] 97 32 19 79 59 73 654.49MB Prodisc 40X [Msi] 97 32 19 79 59 73 702.83MB Media Market(Prodisc) 1-40X [Msi] 97 32 19 79 59 73 80 48x "Prodisc Technology Inc." [Gig] 97 32 19 79 59 73 Prodisc [Aopen] 97 32 19 79 59 73 Prodisc [Btc] 97 32 19 79 59 74 80 48x "Prodisc Technology Inc." [Gig] 97 32 19 79 59 74 Prodisc [Aopen] 97 32 19 79 59 74 Prodisc [Btc] "Mitsubishi Chemical Corporation" 97 34 21 74 43 00 74 24x "Mitsubishi Chemical Corporation" [Gig] 97 34 21 74 43 00 MCC [Btc] 97 34 21 79 59 74 702.83MB Mitsubishi Multi Speed [Msi] 97 34 21 79 59 74 MCC [Btc] 97 34 21 79 59 74 MCC(Metal [Aopen] 97 34 22 4x "Mitsubishi Chemical Corporation" [Gig] 97 34 22 74 43 00 656.40MB Mitsubishi N/A 1-4X [Msi] 97 34 22 74 43 00 74 32x "Mitsubishi Chemical Corporation" [Gig] 97 34 22 74 43 00 MCC [Btc] 97 34 22 74 43 00 Mitsubishi CD-RW 1-4X 656.40MB [Mits] 97 34 22 79 59 74 702.83MB Mitsubishi 32X [Msi] 97 34 22 79 59 74 80 32x "Mitsubishi Chemical Corporation" [Gig] 97 34 22 79 59 74 MCC [Btc] 97 34 22 79 59 74 Mitsubishi CD-RW 1-4X 702.83MB [Mits] 97 34 23 74 43 00 656.40MB Mitsubishi 4-10X [Msi] 97 34 23 74 43 00 74 10X "Mitsubishi Chemical Corporation" [Gig] 97 34 23 74 43 00 MCC [Aopen] 97 34 23 74 43 00 Mitsubishi HS-RW 4-10X 656.40MB [Mits] 97 34 23 74 43 00 Mitsubishi HS-RW 4-12X 656.40MB [Mits] 97 34 23 74 43 00 Verbatim HS-RW 4-12X 656.40MB [Mits] 97 34 23 74 43 01 656.40MB Mitsubishi 52X [Msi] 97 34 23 74 43 01 MCC [Aopen] 97 34 23 74 43 01 MCC [Btc] 97 34 23 74 43 01 Mitsubishi CD-R 52X 656.40MB [Mits] 97 34 23 79 59 73 702.83MB Mitsubishi 52X [Msi] 97 34 23 79 59 73 702.83MB Mitsubishi 52X [Msi] 97 34 23 79 59 73 702.83MB Mitsubishi [Msi] 97 34 23 79 59 73 702.83MB Verbatim(Mitsubishi) 48X [Msi] 97 34 23 79 59 73 702.83MB Verbatim(Mitsubishi) 48X [Msi] 97 34 23 79 59 73 702.83MB YAMAHA(Mitsubishi) 48X [Msi] 97 34 23 79 59 73 MCC [Aopen] 97 34 23 79 59 73 MCC [Btc] 97 34 23 79 59 73 Mitsubishi CD-R 52X 702.83MB [Mits] 97 34 23 79 59 73 Mitsubishi CD-R 52X 702.83MB [Mits] 97 34 23 79 59 74 702.83MB Mitsubishi 40X [Msi] 97 34 23 79 59 74 702.83MB Verbatim(Mitsubishi) 40X [Msi] 97 34 23 79 59 74 702.83MB Verbatim(Mitsubishi) N/A 4-10X [Msi] 97 34 23 79 59 74 80 48x "Mitsubishi Chemical Corporation" [Gig] 97 34 23 79 59 74 MCC [Aopen] 97 34 23 79 59 74 MCC [Aopen] 97 34 23 79 59 74 MCC [Btc] 97 34 23 79 59 74 Mitsubishi HS-RW 12X 702.83MB [Mits] 97 34 23 79 59 74 Verbatim HS-RW 4-10X 702.83MB [Mits] 97 34 23 79 59 76 80 52x "Mitsubishi Chemical Corporation" [Gig] 97 34 24 74 43 00 656.40MB Mitsubishi 24X [Msi] 97 34 24 74 43 00 74 24x "Mitsubishi Chemical Corporation" [Gig] 97 34 24 74 43 00 Mitsubishi US-RW 24X 656.40MB [Mits] 97 34 24 79 59 74 702.83MB Mitsubishi 24X [Msi] 97 34 24 79 59 74 Mitsubishi US-RW 24X 702.83MB [Mits] 97 34 24 79 59 74 Verbatim US-RW 24X 702.83MB [Mits] 97 34 25 74 43 00 656.40MB Mitsubishi(standard) 32X [Msi] 97 34 25 74 43 00 74 32x "Mitsubishi Chemical Corporation" [Gig] "Mitsui Chemicals Inc." 97 48 55 63 04 00 MCI(Mitsui) MTCDR63G [Teac] 97 48 55 63 04 00 MCI(MITSUI) MTCDR63G [Edig] "TDK Corporation" 97 49 00 63 52 00 TDK CD-R63S [Teac] 97 49 00 63 52 00 TDK CD-R63S [Edig] ------------------------------------------------------------------------------- DVD and BD Media IDs "UML" AML 003 UME 8X [Hij] "BeAll Developers, Inc." BeAll000 P40 BeAll 4X [Hij] BeAll G40001 BeAll 4X [Hij] "CMC Magnetics Corporation" CMC MAG M01 CMC 16X [Hij] CMC MAG F01 CMC 4X [Hij] CMC MAG R01 CMC 2.5X [Hij] CMC MAG W01 CMC 2.5x [Hij] CMC MAG. AE1 CMC 8X [Hij] CMC MAG. AF1 CMC 4X [Hij] CMC MAG. AM1 CMC 12X [Hij] CMCW02 CMC 2x [Hij] CMC00RG200 CMC 2X [Hij] CMCMAG CMC 12X [Hij] CMCMAG BA2 CMC Magnetics Corporation 1-2X HTL 25GB (12cm) [Blu] CMCMAG BA3 CMC Magnetics Corporation 1-4X HTL 25GB (12cm) [Blu] CMCMAG BA5 CMC Magnetics Corporation 1-6X HTL 25GB (12cm) [Blu] CMCMAG CN2 CMC Magnetics Corporation 1-2X HTL 25GB(12cm) [Blu] "Daxon Technology Inc. / Acer" DAXON 016 DAXON 8X [Hij] DAXON AZ3 DAXON 16X [Hij] DAXON CY3 DAXON 12X [Hij] DAXON D42/52 (user reported DVD+RW) Daxon R2X Daxon Technology Inc. 1-2X HTL 25GB(12cm) [Blu] Daxon R4X Daxon Technology Inc. 1-4X HTL 25GB(12cm) [Blu] "Fujifilm Holdings Corporation" FUJI Fujifilm Corporation [Blu] FUJIFILM02 FUJIFILM 4X [Hij] FUJIFILM03 FUJIFILM 8X [Hij] FUJIFILM04 FUJIFILM 12X [Hij] "New Star Digital Co., Ltd." INFODISC R20 NSD 8X [Hij] INFODISC-R20 NSD 8X [Hij] "InfoMedia Inc." INFOME E20 INFOMEDIA INC. 1-2X [Blu] INFOME R30 INFOMEDIA 16X [Hij] INFOME R20 INFOMEDIA INC. 1-2X [Blu] INFOME R30 INFOMEDIA INC. 1-4X [Blu] "Info Source Multi Media Ltd." ISMMBD R01 Info Source Multi Media Ltd. 1-4X HTL 12cm [Blu] ISMMBD R02 Info Source Multi Media Ltd. 1-6X HTL 12cm [Blu] ISMMBD RE1 Info Source Multi Media Ltd. 1-2X HTL 12cm [Blu] "JVC Limited" JVC0VictorD7 JVC 4X [Hij] JVC1Victord7 JVC 6X [Hij] JVC/VictorT7 JVC 1x [Hij] JVC_VictorW7 JVC 2x [Hij] JVCRE1 Victor Company of Japan, Limited [Blu] "AMC" KIC01RG160 AMC 12X [Hij] "Lead Data Inc." LD M04 LEADDATA 8X [Hij] LD S04 LEADDATA 8X [Hij] LEADDATA01 LEADDATA 4X [Hij] "LG Electronics" LGE04 LG 2X [Hij] LGEBRA S04 LG Electronics Inc. 1-4X HTL 12cm (25GB) [Blu] LGEBRA S06 LG Electronics Inc. 1-6X HTL 12cm (25GB) [Blu] LGEBRE S01 LG Electronics, Inc. 1-2X HTL 12cm(25GB) [Blu] LGEP16 001 LGE 8X [Hij] "Mitsui Advanced Media, Inc. Europe" MAM M02 MAM-E 8X [Hij] "Hitachi Maxell Ltd." MAXELL 001 HITACHI MAXELL 4X [Hij] MAXELL 002 HITACHI MAXELL 8X [Hij] MAXELL 003 HITACHI MAXELL 16X [Hij] MAXELL ES1 Hitachi Maxell, Ltd. 1-2X HTL 12cm and 8cm [Blu] MAXELL RS1 Hitachi Maxell, Ltd. 1-2X HTL 12cm and 8cm [Blu] "Moser Baer India Limited" MBI E02 Moser Baer India Ltd 1-2X HTL 25GB [Blu] MBI F01 Moser Baer India Ltd 1-2X LTH 25GB [Blu] MBI F02 Moser Baer India Ltd 1-4X LTH 25GB [Blu] MBI R02 Moser Baer India Ltd 1-2X HTL 25GB [Blu] MBI R04 Moser Baer India Ltd 1-4X HTL 25GB [Blu] MBI R06 Moser Baer India Ltd 1-6X HTL 25GB [Blu] MBI 01RG20 Moser Bear India 4X [Hij] MBI 01RG40 MBI 16X [Hij] MBI 03RG30 MBI 8X [Hij] MBI 03RG40 MBI 12X [Hij] MBIPG101 Moser Bear India 4X [Hij] MBIPG101 R04 MBI 8X [Hij] MBIPG101 R05 MBI 16X [Hij] "Mitsubishi Chemical Corporation" MCC 002 MKM 4X [Hij] MCC 003 MKM 8X [Hij] MCC 00RG200 MKM 2X [Hij] MCC 01RG20 MKM 4X [Hij] MCC 01RW11n9 MKM 2x [Hij] MCC 01RW4X MKM 4X [Hij] MCC 02RG20 MKM 8X [Hij] MCC 03RG20 MKM 16X [Hij] MCC A01 MKM 2.5x [Hij] "Mitsui Chemicals Inc." MCI G01 Mitsui 2X [Hij] "Panasonic Corporation" MEI RA1 Panasonic Corporation 1-6X HTL 12cm [Blu] MEI RB1 Panasonic Corporation 1-6X HTL 12cm [Blu] MEI T01 Panasonic Corporation 1-2X HTL 12cm [Blu] MEI T02 Panasonic Corporation 1-4X HTL 12cm [Blu] MEI 00V001 MATSUSHITA EI 2X [Hij] MEI 00V002 MATSUSHITA EI 4X [Hij] "Millenniata Inc." MILLENMR MR1 Verbatim M-DISC 4x 25 GB (user reported) "Mitsubishi Kagaku Media Co." MKM 001 MKM 6X [Hij] MKM 003 MKM 8X [Hij] MKM A02 MKM 4x [Hij] MKM 01RD30 MKM 6X [Hij] MKM01RW6X01 MKM 6X [Hij] "Mitsubishi Kagaku Media Co." MMC 001 MKM 2.5X [Hij] "Hitachi Maxell Ltd." MXL RG01 MAXELL 2X [Hij] MXL RG02 MAXELL 4X [Hij] MXL RG03 MAXELL 8X [Hij] MXL RG04 MAXELL 16X [Hij] "Nan-Ya Plastics Corporation" NANYA ALX NANYA 8X [Hij] "NESA International Inc." NSDR40 NSD 8X [Hij] "Optodisc Technology Corporation" OPTODISC F16 OPTODISC 12X [Hij] OPTODISC OP1 OPTODISC 2.5x [Hij] OPTODISC OP1 OPTODISC 2.5X [Hij] OPTODISC OR8 OPTODISC 8X [Hij] OPTODISCR004 OPTODISC 4X [Hij] OPTODISCR008 OPTODISC 8X [Hij] OPTODISC R01 OPTODISC 16X [Hij] OPTODISC R02 OPTODISC 4X [Hij] OPTODISCR016 OPTODISC 8X [Hij] "Optodisc Technology Corporation" OTCBDR 001 Optodisc Technology Corporation 1-4X HTL 25GB (12cm) [Blu] OTCBDR 002 Optodisc Technology Corporation 1-6X HTL 25GB (12cm) [Blu] OTCBRE 001 Optodisc Technology Corporation 1-2X HTL 25GB (12cm) [Blu] "Moser Baer India Limited" PHILIP R02 Moser Baer India Ltd 1-2X HTL 25GB [Blu] PHILIP R04 Moser Baer India Ltd 1-4X HTL 25GB [Blu] PHILIP W02 Moser Baer India Ltd 1-2X HTL 25GB [Blu] "Philips" PHILIPS C16 PHILIPS 12X [Hij] PHILIPS CD2 CMC (PHILIPS) 2.5X [Hij] "Princo Corporation" PRINCO PRONCO 4X [Hij] "Prodisc Technology Inc." ProdiscF02 PRODISC 12X [Hij] PRODISC R01 PRODISC 2.5X [Hij] Prodisc R02 PRODISC 4X [Hij] Prodisc R03 PRODISC 8X [Hij] Prodisc R04 PRODISC 16X [Hij] Prodisc R05 PRODISC 16X [Hij] ProdiscS03 PRODISC 4X [Hij] ProdiscS04 PRODISC 8X [Hij] ProdiscS05 PRODISC 16X [Hij] PRODISC W01 PRODISC 2.5x [Hij] "Pioneer" PVC001001 PIONEER VIDEO 2X [Hij] PVCR001002 PIONEER VIDEO 4X [Hij] PVCW00D002K9 PVC 2x [Hij] "Ricoh Company Limited" RICOHJPN D00 RICOH 2.5X [Hij] RICOHJPN D01 RICOH 2.5X [Hij] RICOHJPN R00 RICOHJPN 2.5X [Hij] RICOHJPN R01 RICOH 4X [Hij] RICOHJPN R02 RICOH 12X [Hij] RICOHJPN R03 RICOH 16X [Hij] RICOHJPN W01 RICOH 2.5x [Hij] RICOHJPN W11 RICOH 4x [Hij] RICOHJPN W21 RICOH 8X [Hij] "Ritek Corp" RITEK 001 Ritek 2.5x [Hij] RITEK BR1 RITEK CORPORATION 1-2X HTL 25GB [Blu] RITEK BR2 RITEK CORPORATION 1-4X HTL 25GB [Blu] RITEK BR3 RITEK CORPORATION 1-6X HTL 25GB [Blu] RITEK D01 RITEK 2.5X [Hij] RITEK DR2 RITEK CORPORATION 1-4X HTL 50GB [Blu] RITEK DW1 RITEK CORPORATION 1-2X HTL 50GB [Blu] RITEK F16 RITEK 8X [Hij] RITEKF1 RITEK 12X [Hij] RITEK G03 RITEK 2X [Hij] RITEK G04 RITEK 4X [Hij] RITEKG05 RITEK 4X [Hij] RITEKG06 RITEK 8X [Hij] RITEK M02 RITEK 4X [Hij] RITEKM16 RITEK 12X [Hij] RITEK R01 RITEK 2.5X [Hij] RITEK R02 RITEK 4X [Hij] RITEK R03 RITEK 8X [Hij] RITEK R04 RITEK 12X [Hij] RITEK R05 RITEK 16X [Hij] RITEKW01 RiTEK 2x [Hij] RITEKW06 RITEK 6X [Hij] "Sony Corporation" SONY SONY 2X [Hij] SONY D11 SONY 8X [Hij] SONY D21 SONY 16X [Hij] SONY ED4 Sony Corporation 1-2X HTL 50GB [Blu] SONY ES1 Sony Corporation 1-2X 25GB [Blu] SONY NO1 Sony Corporation 1-2X HTL 25GB [Blu] SONY NS1 Sony Corporation 1-2X HTL 25GB [Blu] SONY NS2 Sony Corporation 1-4X HTL 25GB [Blu] SONY NN1 Sony Corporation 1-2X HTL 25GB [Blu] SONY NN2 Sony Corporation 1-4X HTL 25GB [Blu] SONY NN3 Sony Corporation 1-6X HTL 25GB [Blu] SONY04D1 SONY 4X [Hij] SONY08D1 SONY 12X [Hij] SONY16D1 SONY 16X [Hij] "TDK Corporation" TDK 001 TDK 4X [Hij] TDK 002 TDK 8X [Hij] TDK 003 TDK 16X [Hij] TDKBLD RBA TDK Corporation 1-2X HTL 12cm [Blu] TDKBLD RBB TDK Corporation 1-4X HTL 12cm [Blu] TDKBLD RBD TDK Corporation 1-6x HTL 12cm (25GB) [Blu] TDKBLD RDA TDK Corporation 1-2X HTL 8cm [Blu] TDKBLD RFA TDK Corporation 1-2X HTL 12cm [Blu] TDKBLD RFB TDK Corporation 1-4X HTL 12cm [Blu] TDKBLD RFD TDK Corporation 1-6x HTL 12cm (50GB) [Blu] TDKBLD WBA TDK Corporation 1-2X HTL 12cm [Blu] TDKBLD WDA TDK Corporation 1-2X HTL 8cm [Blu] TDKBLD Wfa TDK Corporation 1-2X HTL 12cm [Blu] TDK502sakuM3 TDK 2x [Hij] TDK601saku TDK 4X [Hij] TDKG02000000 TDK 2X [Hij] "TDK Corporation" TTG01 TDK 4X [Hij] TTG02 TDK 8X [Hij] TTH01 TDK 8X [Hij] TTH02 TDK 12X [Hij] "Taiyo Yuden Company Limited" TYG01 TAIYO YUDEN 4X [Hij] TYG02 TAIYO YUDEN 12X [Hij] TYG03 TAIYO YUDEN 16X [Hij] TYG11 TAIYO YUDEN DVD-R DL 8x TYG-BD Y01 TAIYO YUDEN Co., Ltd. 1-2X LTH [Blu] TYG-BD Y03 TAIYO YUDEN Co., Ltd. 1-4X LTH [Blu] "UmeDisc Limited" UMEDISC DL1 Elite DVD+R DL [User report feb 2012] "Unifino Inc." UTJR001001 UNIFINO 4X [Hij] "Mitsubishi Kagaku Media Co." VERBAT IM0 Mitsubishi Kagaku Media, Co., Ltd. 1-2X 25GB (12cm) and 7.8GB (8cm) [Blu] VERBAT IM1 Mitsubishi kagaku Media, Co., ltd. 1-2X HTL 50GB(12cm) [Blu] VERBAT IMa Mitsubishi Kagaku Media, Co., Ltd. 1-2X HTL 25GB (12cm) and 7.8GB (8cm) [Blu] VERBAT IMb Mitsubishi Kagaku Media, Co., Ltd. 1-2X HTL 50GB (12cm) and 15.6GB (8cm) [Blu] VERBAT IMc Mitsubishi Kagaku Media, Co., Ltd. 1-4X HTL 25GB (12cm) and 7.8GB (8cm) [Blu] VERBAT IMd Mitsubishi Kagaku Media, Co., Ltd. 1-4X HTL 50GB (12cm) [Blu] VERBAT IMe Mitsubishi Kagaku Media, Co., Ltd. 1-6X HTL 25GB (12cm) [Blu] VERBAT IMf Mitsubishi Kagaku Media, Co., Ltd. 1-6X HTL 50GB (12cm) [Blu] VERBAT IMu Mitsubishi Kagaku Media, Co., Ltd. 1-6X LTH 25GB (12cm) [Blu] VERBAT IMv Mitsubishi Kagaku Media, Co., Ltd. 1-4X LTH 25GB (12cm) [Blu] VERBAT IMw Mitsubishi Kagaku Media, Co., Ltd. 1-2X LTH 25GB (12cm) [Blu] "Taiyo Yuden Company Limited" YUDEN000 T01 TAIYO YUDEN 4X [Hij] YUDEN000 T02 TAIYO YUDEN 12x [Hij] YUDEN000 T03 TAIYO YUDEN 16X [Hij] �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������libburn-1.4.2/doc/cookbook.txt����������������������������������������������������������������������0000644�0001757�0001751�00000215177�12652644224�013244� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ ------------------------------------------------------------------------------- Note: This is about how libburn operates optical drives. Not about how to operate libburn. The libburn API is described in libburn/libburn.h ------------------------------------------------------------------------------- libburnia-project.org Optical Media Rotisserie Recipes as of December 2011 Content: - TAO Multi-Session CD Cookbook (CD-R, CD-RW) - SAO CD Cookbook (CD-R, CD-RW, pure audio or pure data only) - Overwriteable DVD Cookbook (DVD-RAM, DVD+RW, DVD-RW, BD-RE) - Sequential DVD-R[W] Cookbook - DVD+R[/DL] Cookbook - BD-R Cookbook ------------------------------------------------------------------------------- TAO Multi-Session CD Cookbook ------------------------------------------------------------------------------- Guided by reading mmc-r10a.pdf , O.8 "Write a Track" from http://www.t10.org/ftp/t10/drafts/mmc/ backed by reading mmc5r03c.pdf from http://www.t10.org/ftp/t10/drafts/mmc5/ by reading spc3r23.pdf from http://www.t10.org/ftp/t10/drafts/spc3/ by reading libburn/* from http://icculus.org/burn and by experiments with drives NEC ND-4570A, LG GSA-4082B, LITE-ON LTR48125S which used in part code from http://icculus.org/burn. For libburnia-project.org by Thomas Schmitt <scdbackup@gmx.net> ------------------------------------------------------------------------------- Media type can be recognized by Current Profile from 46h GET CONFIGURATION. (mmc5r03c.pdf 6.6.2.1) CD-R 0009h CD-RW 000ah The following topics are covered in this text: - About blank, appendable and finalized CD media - Writing a session to CD in TAO mode - Obtaining CD multi-session info for extending ISO-9660 filesystems - Obtaining a Table Of Content from CD ------------------------------------------------------------------------------- About blank, appendable and finalized CD media : CD media have to be blank or appendable in order to be writeable in TAO mode. The according status may be inquired by 51h READ DISC INFORMATION requesting Data Type 000b Standard Disc Information, where reply value Disc Status indicates: 00b blank 01b appendable 10b finalized 11b others (unsuitable for this recipe) (mmc5r03c.pdf 6.22.3.1.4) CD-RW which are finalized or appendable may be blanked by command A1h BLANK with blanking types 000b "Blank the disc" or 001b "Minimally blank the disc". The Start Address/Track Number will be ignored so it may well be 0. Because the operation is long running it is advised to set the Immed bit and to watch the progress by commands 00h TEST UNIT READY and 03h REQUEST SENSE with DESC bit set to 0 for fixed format reply. It is done when 00h succeeds and 03h reports 0 in PROGRESS INDICATION (byte 1+2 in Table 22 = byte 16+17 SENSE KEY SPECIFIC in table 26). (mmc5r03c.pdf 6.2 BLANK) (spc3r23.pdf 4.5.2.4.4 table 22, 4.5.3 table 26, 6.27 REQUEST SENSE, 6.33 TEST UNIT READY) ------------------------------------------------------------------------------- Writing a session to CD in TAO mode : The writing method for blank or appendable media is the same. A new session will get created automatically by the first track when it is written. If the media is blank then the new session will be the first and only one in the table of content. If the media is appendable then a new session will be appended to the existing sessions. In any case the new track will be the first one in the new session. Speed may be set by BBh SET CD SPEED parameter Drive Write Speed. Note that kbytes/sec means 1000 bytes/sec and not 1024/sec. Rotational control should be set to 00b. 1x CD speed is 176.4 kbytes/sec. Speed is usually set to the next lower possible value by the drive. So it is helpful to add a few kbytes/sec just in case the drive has rounding problems. (mmc5r03c.pdf 6.37) Before writing can occur, a Write Parameters mode page 05h has to be composed and transmitted via 55h MODE SELECT. Mode page 05h describes several burn parameters: BUFE Buffer Underrun protection 0=off, 1=on Test Write -dummy mode for writing 0=off, 1=on Write Type Packet/TAO/SAO/RAW 01h = TAO Multi-session Whether to keep appendable 00b = finalize 11b = keep appendable Copy Whether to deny copying 1 = deny by SCMS , 0 = allow Track Mode Describes frame type 4 for data , 0 for audio Data Block Type Layout of payload blocks 8 for 2048 byte data blocks 0 for 2352 byte audio blocks Audio Pause Length 150 = 2 seconds Media Catalog Number A property of the disc 0x80 if valid 13 decimal digits as ASCII ISRC A property of the track 0x80 if valid 12 letters and digits, ASCII Any other parameters may be set to 0. Mode page data as of MMC-5 table 644 are preceded by a Mode Parameter Header as of SPC-3 table 240. This 8-byte header may be filled with zeros. (mmc5r03c.pdf 7.5.4 The Mode Page, 4.2.3.4 Table 17 CONTROL = Track Mode) (spc3r23.pdf 6.8 MODE SELECT, 7.4.3 Mode parameter header formats) Writing has to begin at the address returned by 52h READ TRACK INFORMATION with Address/Number Type set to 01b and Logical Block Address/Track/Session Number set to FFh. The Next Writeable Address as of table 500 is the number to start writing with. (mmc5r03c.pdf 6.27 ) Writing is performed by one or more 2Ah WRITE transactions with the Logical Block Address counted up from the initial number in sync with the number of blocks written. I.e the Transfer Length of the previous 2Ah WRITE has to be added to the Logical Block Address for the next 2Ah WRITE. Only full blocks can be written. (mmc5r03c.pdf, 6.44) When writing is done, it is mandatory to force the drive's buffer to media by 35h SYNCHRONIZE CACHE. (mmc5r03c.pdf, 6.41) A track must at least contain 300 payload blocks: 4 seconds of audio or 600 KiB of data. (mmc5r03c.pdf 6.3.3.1.2) Up to december 2009 the track was closed by 5Bh CLOSE TRACK SESSION Close Function 001b. Older MMC specifies a valid Logical Track Number FFh to depict the open track. MMC-5 is quite silent about this. FFh worked for my drives. (mmc5r03c.pdf 6.3.3.1.2) This is omitted since libburn-0.7.4, relying entirely on 35h SYNCHRONIZE CACHE. First appeared a drive where CLOSE TRACK fails in simulation mode, later another one produced error replies even with real burning. After that, a new track may be written beginning with sending the mode page 05h again. It is not tested whether 05h can be omitted if Track Mode and Data Block Type are the same as with the previous track. The new track will be added to the session which was opened by the first track. After the last track of a session, 5Bh CLOSE TRACK SESSION Close Function 010b with Logical Track Number 0 closes the session. It depends on the Multi-Session value in mode page 05h whether the disc is finalized or stays appendable. (mmc5r03c.pdf 6.3.3.1.3) ------------------------------------------------------------------------------- Obtaining CD multi-session info for extending ISO-9660 filesystems : Program mkisofs expects two numbers with its option -C which describe the situation on an appendable CD which already contains a ISO-9660 filesystem in the first track of the last session. The first number is the Logical Block Address of that track containing the existing ISO-9660 filesystem image. This number is needed for mkisofs option -M to connect to the existing image. The new image will refer to files in the previously existing image. mkisofs option -M needs read access to the CD or a blockwise copy of it on hard disk. The number is gained by 43h READ TOC/PMA/ATIP. (mmc5r03c.pdf 6.26) Untested is Format 0001b which in table 478 promises quick access via Start Address Of First Track In Last Session. (mmc5r03c.pdf 6.26.2.5 table 478, 6.26.3.3.1) libburn gets the number from its Table Of Content model which is obtained by 43h READ TOC/PMA/ATIP, Format 0010b. See below. The second number is an exact prediction of the Logical Block Address of the new track which will contain the newly generated ISO-9660 image. Even without mkisofs option -M this second number is still needed to make the inner block address pointers of the image match the Logical Block Addresses on CD. For that one may inquire 52h READ TRACK INFORMATION with Address/Number Type set to 01b and Logical Block Address/Track/Session Number set to FFh. The Next Writeable Address as of table 500 is the number to use. (mmc5r03c.pdf 6.27 ) ------------------------------------------------------------------------------- Obtaining a Table Of Content from CD : The structure of a CD is comprised of sessions. Each session contains one or more tracks and is followed by a lead-out. A track has an address and a length. Table of content information is gained by 43h READ TOC/PMA/ATIP, Format 0010b. (mmc5r03c.pdf 6.26.2.5 table 478) The number of sessions is given by Last Complete Session Number. The number of TOC Track descriptors is: (TOC Data Length - 2)/11 . Each TOC Track Descriptor contains a Session Number. If POINT is >= 1 and <= 99 (63h) then the descriptor is about the track of which POINT tells the number. The start address of this track can be read from PMIN, PSEC, PFRAME where it is encoded in MSF format: If M is smaller than 90: LBA = (M * 60 + S) * 75 + F - 150 Else : LBA = (M * 60 + S) * 75 + F - 450150 The length of the track is given by MIN,SEC,FRAME in the same format. If POINT = A0h then the descriptor tells in PMIN the first track number of its session. POINT = A1h tells in PMIN the last track number of its session. POINT = A2h describes in PMIN, PSEC, PFRAME the lead-out of a session, i.e the first address after the session's end. (Next writeable address typically is lead-out + 11400 after the first session, lead-out + 6900 after further sessions.) POINT = B0h tells in MIN,SEC,FRAME this next writeable address or FFh,FFh,FFh for finalized disc. (mmc5r03c.pdf 6.26.3.4 table 489, 4.2.3.7 Mode-1 Q, Mode-5 Q) In libburn the address of the first track in the last session is obtained from the last session's POINT = A0h and from the track descriptor with the POINT value matching the PMIN value of the A0h descriptor. Untested is whether POINT = B0h and 52h READ TRACK INFORMATION are always in sync. libburn uses the info provided by 52h READ TRACK INFORMATION. ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- SAO CD Cookbook ------------------------------------------------------------------------------- Guided by reading libburn/* from http://icculus.org/burn backed by reading mmc5r03c.pdf from http://www.t10.org/ftp/t10/drafts/mmc5/ backed by reading scms.html from http://www.barrel-of-monkeys.com/graphics/prod/dvdplayers/ and by experiments with drives NEC ND-4570A, LG GSA-4082B, LITE-ON LTR48125S, Optiarc BD RW BD-5300S, LG BDDVDRW GGC-H20L For libburnia-project.org by Thomas Schmitt <scdbackup@gmx.net> ------------------------------------------------------------------------------- Recognition of media type and state (blank, appendable, finalized) is as described in the TAO Multi-Session CD Cookbook. See there. The MMC specs do not give much hint about the combination of SAO and multi-session. My drives refused not only on a few experiments which i did in libburn but also failed with cdrecord -sao on an appendable CD. So for now only blank CD seem to be suitable for SAO writing. Different from TAO mode, the whole session layout is announced to the drive by sending a Cue Sheet. This implies that the sizes of the tracks have to be known in advance, which is a heavy drawback when dealing with track data sources like stdin, named pipes or sockets. Nevertheless, SAO seems to be best writing mode for audio purposes, as our audio expert Lorenzo Taylor found out. A SAO session in libburn may either consist entirely of audio tracks or entirely of data tracks. For mixed sessions, only TAO is usable yet. - Composing a SAO CD Cue Sheet (either audio or data, but not mixed) - Writing the prepared SAO CD session - What is known about mixed mode sessions ------------------------------------------------------------------------------- Composing a Cue Sheet (either audio or data, but not mixed) : The Cue Sheet will get submitted to the drive by 5Dh SEND CUE SHEET. Each entry of the sheet is of 8 bytes size. Its fields are named CTL|ADR, TNO, INDEX, DATA FORM, SCMS, MIN, SEC, FRAME . (mmc5r03c.pdf 6.33) CTL is comprised of four bits: bit4 = Pre-emphasis (audio only) bit5 = Digital copy permission: 0 = prohibited (one-time copy is permitted if SCMS is 00h) 1 = permitted (unlimited) bit6 = Data track indicator (bit4 and bit7 shall be 0) bit7 = 4-channel audio Usually CTL is 40h for data and 00h for audio. (mmc5r03c.pdf 6.33.3.4) ADR is 01h for entries which define time points. It is 02h for media catalog entries and it is 03h for track ISRC entries. The bits of CTL and ADR are combined in the CTL|ADR byte. TNO is the track number. The TNO of the first track may be chosen in the range of 1 to 99. The TNO of following tracks must be the TNO of their predecessor plus 1. The last track must not have a TNO larger than 99. INDEX is a subaddress within tracks. INDEX 1 is mandatory and marks the start of the payload area of a track. The range between INDEX 0 and 1 is called pre-gap. It should contain zeros if it exists. Further cue sheet entries with consecutive INDEX numbers mark ranges within the track. The range of the last index may contain a post-gap with zeros. (mmc5r03c.pdf 4.2.3.5.2) A pre-gap of 2 seconds is mandatory only for the first track. Pre-gap and post-gap may be needed with further tracks if they have neighbors with different DATA FORM values. (Such mixing is not yet supported by libburn.) DATA FORM is 00h for audio payload, 01h for audio pause (Lead-in and Lead-out), 10h for data, 14h for data pause (Lead-in and Lead-out). This shall be ored with 40h for CD-TEXT in Lead-in. (mmc5r03c.pdf 6.33.3.11 CD-DA Data Form, 6.33.3.12 CD-ROM mode 1 Form) SCMS value 80h in conjunction with bit5 of CTL is an indicator for exhausted one-time-copy permission. If this permission is still intact, then SCMS is 00h. MIN, SEC, FRAME give the MSF address where the described data entity starts. LBA = frames - 150, 75 frames = 1 sec , 60 sec = 1 min. This address must increase from entry to entry (or at least stay equal). The first two entries in a Cue Sheet may describe the Media Catalog Number, a string of 13 characters, also known with CD-TEXT as "UPC/EAN". (02h, catalog characters 1 to 7) (02h, catalog characters 8 to 13, 00h) These two entries shall be omitted if no catalog number is given. The next entry (eventually being the first one) describes the Lead-in. Its content is (CTL|ADR ,00h,00h, DATA FORM ,00h,00h,00h,00h) With the CTL|ADR for the first track: 41h for data, 01h for audio. DATA FORM is pause (audio=01h, data=14h). Ored with 40h if CD-TEXT shall be stored in Lean-in. The LBA for the first write is negative: -150. This corresponds to MSF address 00h:00h:00h. All addresses are to be given in MSF format. Each track may be preceded by two entries describing an ISRC string of 12 characters. (CTL | 03h, TNO, characters 1 to 6) (CTL | 03h, TNO, characters 7 to 12) These entries shall be omitted if no ISRC is given for the track. CTL shall be the same as with the track. The first information track on disc is preceded by a pause encoding or pre-gap of at least 2 seconds: (CTL|ADR,01h,00h, DATA FORM ,00h,00h,00h,00h) with DATA FORM = 00h for audio and 10h for data. By those 2 seconds the MSF address increases to 00h:02h:00h = LBA 0. Optional further sectors may occupy addresses larger than 0. This entry has to come after ISRC, if ISRC is given for the track. INDEX has to be 0. Each track is represented by one or more entries, with increasing index number. At least the entry for INDEX 1 has to exist: (CTL|ADR, TNO ,01h,DATA FORM,00h, MIN , SEC , FRAME) TNO gives the track number. MIN, SEC, FRAME give the MSF address which becomes the start address of the track. The MSF address is then increased by the size of the track (to be used with next track or with lead-out). There may be more entries with INDEX 2 to 99. Their MSF address tells the sector where their range starts. This range ends at the MSF of the next entry in the cue sheet. INDEX information is stored in the sub-channel of the sectors but not in the Table-of-Content of the disc. A track must at least contain 300 payload blocks: 4 seconds of audio or 600 KiB of data. (mmc5r03c.pdf 6.33.3.6) At the end of the session there is a lead-out entry (CTL|ADR,AAh,01h,DATA FORM,00h,MIN,SEC,FRAME) marking the end of the last track. (With libburn CTL is as of the last track.) DATA FORM is 01h for audio, 14h for data. ------------------------------------------------------------------------------- Writing the prepared session : Speed may be set by BBh SET CD SPEED parameter Drive Write Speed. Note that kbytes/sec means 1000 bytes/sec and not 1024/sec. Rotational control should be set to 00b. 1x CD speed is 176.4 kbytes/sec. Speed is usually set to the next lower possible value by the drive. So it is helpful to add a few kbytes/sec just in case the drive has rounding problems. (mmc5r03c.pdf 6.37) If CD-TEXT shall be written into Lead-in, then it is necessary to obtain the Start Time of Lead-in by 43h READ TOC/PMA/ATIP Format 0100b. It is an MFS address which varies from media manufacturer to media manufacturer. Minute will be >= 90. Therefore this conversion applies: LBA = (M * 60 + S) * 75 + F - 450150 A Write Parameters mode page 05h has to be composed and transmitted via 55h MODE SELECT. This page describes the following parameters: BUFE Buffer Underrun protection 0=off, 1=on Test Write -dummy mode for writing 0=off, 1=on Write Type Packet/TAO/SAO/RAW 02h = SAO Multi-session Whether to keep appendable 00b = finalize 11b = keep appendable Track Mode Describes frame type 0 (is ignored) Data Block Type Layout of payload blocks 0 (is ignored) Audio Pause Length 150 = 2 seconds (ignored ?) Media Catalog Number 0x80 if valid See also Cue Sheet ADR 02h 13 decimal digits as ASCII (With SAO, ISRC is transmitted only by the Cue Sheet.) Any other parameters may be set to 0. Mode page data as of MMC-5 table 644 are preceded by a Mode Parameter Header as of SPC-3 table 240. This 8-byte header may be filled with zeros. (mmc5r03c.pdf 7.5.4 The Mode Page, 4.2.3.4 Table 17 CONTROL = Track Mode) (spc3r23.pdf 6.8 MODE SELECT, 7.4.3 Mode parameter header formats) The Cue Sheet is submitted to the drive by 5Dh SEND CUE SHEET. Cue Sheet Size is 8 times the number of entries. (mmc5r03c.pdf 6.33) Writing is performed by multiple 2Ah WRITE transactions with the Logical Block Address counted up from the initial number in sync with the number of blocks written. I.e the Transfer Length of the previous 2Ah WRITE has to be added to the Logical Block Address for the next 2Ah WRITE. Only full blocks can be written. (mmc5r03c.pdf, 6.44) Block addresses may be negative for areas before the normally readable data. Data representation of addresses is 4-byte, big-endian, two's-complement. E.g: -150 = FFh FFh FFh 6Ah. This is the natural form found with about any 32-bit processor, so only the endianness has to be taken into respect when converting a 32-bit integer into a LBA for command 2Ah WRITE. If CD-TEXT shall be written into Lead-in, then writing begins at the start address of Lead-in, which was obtained above. The 18 bytes of each text pack have to be split up to 24 bytes with only the lowest six bits used in each byte. E.g. text pack 8F 00 2A 00 01 01 03 00 06 05 04 05 07 06 01 02 48 65 becomes 23 30 00 2A 00 00 04 01 00 30 00 06 01 10 10 05 01 30 18 01 00 24 21 25 4 of these 24 byte packs form a block of DATA FORM 41h. I.e. only 96 bytes payload per block. The whole range from Lead-in start to LBA -150 has to be filled with blocks of this form. Therefore it is necessary to write the list of given packs in repeated cycles. A typical Lead-in start address is -11635 = FFh FFh D2h 8Dh. A description of the CD-TEXT pack format is given in file doc/cdtext.txt . Writing without CD-TEXT begins at LBA -150 = FFh FFh FFh 6Ah. In both cases, the mandatory pause preceding the first track has to be written as 150 blocks of the matching sector size: 2048 for data, 2352 for audio. By this, the LBA increases from -150 to 0. Next the tracks' payload is sent. For each track exactly the number of blocks has to be transmitted as is announced in the Cue Sheet by the difference of the track's own start address and the start address of the next entry in the Cue Sheet. After each write the LBA for the next write has to be increased by the number of blocks transmitted. Just like with TAO writing. There is no separator between the tracks of a pure mode SAO session. (If the session was mixed mode, there would be extended Pre-gaps and Post-gaps between data mode tracks and audio mode tracks.) (libburn sends its own buffer to the drive at the end of each track but does not sync the drive's chache. It is unclear whether this separation of tracks on the level of 2Ah WRITE is necessary with a pure mode session. It does not harm in any case and would probably be unavoidable if audio and data tracks were mixed.) When writing of all tracks is done, it is mandatory to force the drive's buffer to media by 35h SYNCHRONIZE CACHE. (mmc5r03c.pdf, 6.41) No further finalization is necessary. (I.e. no 5Bh CLOSE TRACK SESSION.) ------------------------------------------------------------------------------- Obtaining CD-TEXT from Lead-in : Audio CDs may contain CD-TEXT information in their Lead-in. It is gained by 43h READ TOC/PMA/ATIP, Format 0101b. The reply consists of 4 bytes header, of which the first two bytes give the number of following bytes as big-endian 16 bit number. The other two bytes are 0. Following are text packs of 18 bytes each. (mmc5r03c.pdf 6.26.3.7.1 table 495) A description of CD-TEXT packs and of the applicable libburn API calls is given in file doc/cdtext.txt . ---------------------------------------------------------------------------- What is known about mixed mode sessions : For now, SAO sessions with a mix of data and audio are not supported in libburn. Here are the reasons why. Obviously the code of http://icculus.org/burn is incomplete in this aspect. In mmc5r03c.pdf comparison of table 555 and 6.33.3.18 seems self-contradicting. (The second Pre-gap in table 555 does not match any of the criteria of 6.33.3.18. Also, there is no Post-gap shown in table 555 although 6.33.3.19 would prescribe some.) If a data track follows an audio track then the data track gets a preceding extended Pre-gap: (CTL|ADR, TNO ,01h,DATA FORM,00h, MIN , SEC , FRAME) with TNO already the number of the data track. The MSF address is to be increased by 3 seconds. The first second of the extended Pre-gap needs to be written in the audio track's mode and the other 2 seconds are to be written in the data track's mode. (libburn compares DATA FORM rather than burn_track.mode . Wrong ?) (libburn currently does only 2 seconds and the second part of Pre-gap. There is an issue with burn_track.pregap1 about this. Seems libburn mistakes the pause preceding track 1 for a part 2 of an extended Pre-gap.) If a data track is followed by an audio track then it gets a Post-gap of at least two seconds. No example of Post-gap is given for Cue Sheet. Maybe it is to be added to the track, or maybe it gets an own Cue Sheet entry ... who knows ? (libburn contains write code for pregap1, pregap2 and postgap. But only pregap2 ever gets activated. Once hackingly for the first 2 second pause, once incompletely for a change of DATA FORM.) Seems nobody ever tested this. Libburnia simply knows no use case where the correctness of Pre-gap and Post-gap would become evident. ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- Overwriteable DVD Cookbook ------------------------------------------------------------------------------- Inspired by Andy Polyakov's http://fy.chalmers.se/~appro/linux/DVD+RW/tools , backed by reading mmc5r03c.pdf from http://www.t10.org/ftp/t10/drafts/mmc5/ by own experiments with drives NEC ND-4570A, LG GSA-4082B, PHILIPS SPD3300L, LG GGW H20L, and by BD-RE experiments done by Giulio Orsero on LG BE06LU10. For libburnia-project.org by Thomas Schmitt <scdbackup@gmx.net> ------------------------------------------------------------------------------- Media type can be recognized by Current Profile from 46h GET CONFIGURATION. (mmc5r03c.pdf 6.6.2.1) DVD-RAM 0012h DVD-RW Restricted Overwrite 0013h DVD-RW Sequential Recording 0014h (i.e. unformatted) DVD+RW 001Ah BD-RE 0043h A short compilation of the write model: - Overwriting in general The recipes described here are depending on formatting state: - DVD-RAM, fully formatted DVD+RW, DVD-RW, BD-RE - Unformatted DVD+RW - Partly formatted DVD+RW - Unformatted DVD-RW - Partly formatted DVD-RW - Intermediate state DVD-RW - DVD-RAM and BD-RE formatting - DVD-RAM and BD-RE speed tuning Slightly off topic are - ISO 9660 multi-session emulation on overwriteable media - ISO 9660 based TOC emulation on overwriteable media ------------------------------------------------------------------------------- Overwriting in general : Depending on media type, some kind of formatting has to have happened before data can be written. Formatting may happen separately from writing or simultaneously. See the particular recipes below. No Write Parameters mode page 05h is to be sent. Speed can be influenced by B6h SET STREAMING , speed capabilities can be inquired by ACh GET PERFORMANCE. It is advised to set only speeds and sizes which are returned by ACh. (mmc5r03c.pdf 6.39 SET STREAMING, 6.8 GET PERFORMANCE) Optimal performance is promised without any speed setting. But my experiments showed that SET STREAMING values persist after media change. In the formatted area of the media, coarse random access is possible. For DVD-RAM, DVD+RW, BD-RE write addresses and data size need to be aligned to 2 KiB. For DVD-RW alignment has to be 32 KiB. Within these limitations the write address is at the discretion of the sending program. Just use 2Ah WRITE to send data. (mmc5r03c.pdf, 6.44) When writing is done, it is mandatory to force the drive's buffer to media by 35h SYNCHRONIZE CACHE. (mmc5r03c.pdf, 6.41) The size of the formatted area can be inquired by 23h READ FORMAT CAPACITIES. The Number Of Blocks value in the Current/Maximum Capacity Descriptor gives this size in 2 KiB blocks. But this is true only if Descriptor Type is 10b ("Formatted Media"). (mmc5r03c.pdf, 6.24.3.2.1, 6.24.3.2.3) Not yet formatted areas may be completely forbidden or they may be allowed for sequential writing (DVD-RW Intermediate state) or they may be allowed for random access only after the necessary waiting time for formatting to reach the desired address (DVD+RW with background formatting active). Already written areas can be overwritten without special precaution. Blanking a DVD-RW actually destroys its formatting. Most of the concepts usually expressed in Write Parameters mode page 05h do not apply to the recipes here: Test-Write, Buffer Underrun protection, Multi-session, Write Type, Block Type, Track Mode, ... There are hints for multi-session formats with DVD-RW but both of my drives do not offer "Add Session" Format Types 12h or 14h. (mmc5r03c.pdf 6.5.4.2.7 , 6.5.4.2.9) Caution: Drive and media compatibility seems still to be quite an adventure. If you experience problems, especially problems with readability, then try different drives and media brands. Failure does not necessarily mean that the software did anything wrong. ------------------------------------------------------------------------------- DVD-RAM, fully formatted DVD+RW, DVD-RW, BD-RE : Full format is the natural state of DVD-RAM. BD-RE are sold unformatted and need to be fully formatted first. See paragraph about DVD-RAM and BD-RE formatting below. DVD+RW reaches this state if Background Formatting is allowed to finish without being stopped by 5Bh CLOSE TRACK SESSION. (mmc5r03c.pdf, 6.5 FORMAT UNIT, 6.5.4.2.14 Format Type = 26h) The formatting state of a DVD+RW may be inquired by 51h READ DISC INFORMATION requesting Data Type 000b "Standard Disc Information". In the reply, BG Format 3 indicates fully formatted media. (mmc5r03c.pdf 6.22.3.1.13) DVD-RW reaches this state either by Format Type 00h (or 10h) with maximum size given as Number Of Blocks, or by writing sequentially until the disc is completely full into an intermediate session opened by format 15h or 13h. (mmc5r03c.pdf, 6.5 FORMAT UNIT, 6.5.4.2.1, 6.5.4.2.10, 6.5.4.2.8) A fully formatted DVD-RW can be recognized by 23h READ FORMAT CAPACITIES. The Descriptor Type of the Current/Maximum Capacity Descriptor is 10b ("Formatted Media") and 0 blocks are offered with Format Types 13h or 11h. (mmc5r03c.pdf, 6.24.3.2.1, 6.24.3.3) See also discussion of unformatted or partially formatted DVD-RW below. In fully formatted state there is no need for any formatting before writing nor for any finalizing other than forcing the drive's buffer to media by 35h SYNCHRONIZE CACHE (which is mandatory for writing, anyway). (mmc5r03c.pdf, 6.41) (It seems to do no harm to send to DVD+RW or DVD-RW a 5Bh CLOSE TRACK SESSION with Close Function 010b despite there is no session open in this scenario.) ------------------------------------------------------------------------------- Unformatted DVD+RW : This is the state of previously unused DVD+RW media. The formatting state of a DVD+RW may be inquired by 51h READ DISC INFORMATION requiring Data Type 000b "Standard Disc Information". In the reply, BG Format 0 indicates unformatted media (or unsuitable media). (mmc5r03c.pdf 6.22.3.1.13) Formatting has to be started by command 04h FORMAT UNIT, Format Type 26h. Different from other format types, 26h is allowed to send a fantasy size of 0xffffffff blocks and does not require the caller to know the exact maximum size offered with that format. (mmc5r03c.pdf, 6.5 FORMAT UNIT, 6.5.4.2.14 Format Type = 26h) As its name suggests, one has not to wait for background formatting to end but may very soon start writing as on formatted media. Random access to yet unformatted areas can last long, though. If backup formatting has been started at the beginning of the session, then it may get stopped after the final cache sync by 5Bh CLOSE TRACK SESSION with Close Function 010b. (mmc5r03c.pdf 6.3.3.6) Formatting of DVD+RW is called "de-icing" because unformatted areas offer no hold for random access addressing and are thus slippery like ice. One can also see a color change from shiny unformatted to more dull formatted media. ------------------------------------------------------------------------------- Partly formatted DVD+RW : This state is achieved by stopping background formatting before the media was completely formmatted. The formatting state of a DVD+RW is obtained by 51h READ DISC INFORMATION requiring Data Type 000b "Standard Disc Information". In the reply, BG Format 1 indicates partly formatted media. (mmc5r03c.pdf 6.22.3.1.13) If the data of the session surely fit into the formatted area, then it would be unnecessary to restart background formatting. But in order to make the DVD+RW surely accept its maximum number of bytes, formatting may be restarted by command 04h FORMAT UNIT, Format Type 26h, with the Restart bit set and Number of Blocks set to 0xffffffff. (mmc5r03c.pdf, 6.5 FORMAT UNIT, 6.5.4.2.14 Format Type = 26h) From then on, the same rules apply as for previously unformatted DVD+RW. ------------------------------------------------------------------------------- Unformatted DVD-RW (media profile is 0014h) : This state is present with previously unused media. It is also present with media blanked by programs cdrecord, wodim or dvd+rw-format and with media which were sequentially written from blank state. Profile transition from formatted 0013h to unformatted 0014h is done by A1h BLANK. (mmc5r03c.pdf, 6.2) Experiments on my drives indicate that only Blanking Type 000b "Blank the disc" achieves neat media. Media blanked via type 001b offer no feature 0021h and stall cdrecord or libburn already when those media get examined. growisofs can burn them - but only via DAO (feature 002Fh which prescribes Write Type 2). (mmc5r03c.pdf 5.3.11, 5.3.25) For becoming overwriteable such media need to be treated by command 04h FORMAT UNIT. (mmc5r03c.pdf, 6.5) The Format Type has to be chosen from the list replied by 23h READ FORMAT CAPACITIES. Suitable are Format Types 00h, 10h, 15h. (mmc5r03c.pdf 6.24) Format Types 00h and 10h provide a writeable area of a size given by Number of Blocks. Type 00h seems to be the most traditional and complete one. It needs no closing of a session at the end of writing. The Number Of Blocks may be at most the value reported by 23h READ FORMAT CAPACITIES in the entry for the desired format type. Full format is achieved by sending exactly the reported value. (mmc5r03c.pdf, 6.5.4.2.1 Format Type = 00h, 6.5.4.2.5 Format Type = 10h) Format Type 15h provides a writeable area of given size too, but this area can be expanded by sequential writing and afterwards marked as overwriteable by closing the session. It is even allowed to format with size 0 and to leave the size claim entirely to a sequential write process beginning at LBA 0. (mmc5r03c.pdf, 6.5.4.2.10 Format Type = 15h) When writing is done and cache is synced, one should send 5Bh CLOSE TRACK SESSION with Close Function 010b in order to bring the session out of Intermediate state. (mmc5r03c.pdf 6.3.3.2.3) If not written up to the last 32 KiB block, the DVD-RW is only partly formatted after that. ------------------------------------------------------------------------------- Partly formatted DVD-RW (media profile is 0013h) : This state is achieved by formatting a DVD-RW with a number of blocks which is less than offered for the Format Type by the drive's reply to 23h READ FORMAT CAPACITIES. If the media was most recently formatted by Format Types 015h or 013h then it must have got written some bytes and afterwards treated by 5Bh CLOSE TRACK SESSION, 010b in order to be partly formatted. (mmc5r03c.pdf 6.3.3.2.3 CLOSE TRACK SESSION 010b, 6.24 READ FORMAT CAPACITIES) Elsewise the media is in Intermediate state. See below. A partly formatted DVD-RW can be recognized by 23h READ FORMAT CAPACITIES. The Descriptor Type of the Current/Maximum Capacity Descriptor is 10b ("Formatted Media") and the Number Of Blocks with formats 00h, 10h or 15h is larger than the currently formatted size, or more than 0 blocks are offered with Format Types 13h or 11h. (mmc5r03c.pdf, 6.24.3.2.1, 6.24.3.3) If the data of the session surely fit into the formatted area, then it would be unnecessary to do any further formatting. But in order to make the DVD-RW surely accept its maximum number of bytes, partial formatting may be expanded by command 04h FORMAT UNIT, Format Type 13h, which is supposed to be offered by the drive in this state. This brings the session again into Intermediate state and thus enables expansion by sequential writing. As with Format Type 15h it is ok to set Number Of Blocks to 0, so that no fixed size formatting work is done and writing can begin soon after. (mmc5r03c.pdf, 6.5.4.2.8 Format Type = 13h) When writing is done and cache is synced, one should send 5Bh CLOSE TRACK SESSION with Close Function 010b in order to bring the session out of Intermediate state. (mmc5r03c.pdf 6.3.3.2.3) If not written up to the last 32 KiB block, the DVD-RW is only partly formatted after that. Format Type 13h has been tested only with expanding sessions formatted by 15h. Nevertheless it is offered with sessions from 00h and 10h, too. According to the specs, Format Type 11h would expand a session by a fixed size. This has not been tested yet because it is less appealing than 13h. (mmc5r03c.pdf, 6.5.4.2.6 Format Type = 11h) ------------------------------------------------------------------------------- Intermediate state DVD-RW (media profile is 0013h) : This state is achieved by formatting a DVD-RW with Format Type 15h or 13h without subsequentially writing data and sending 5Bh CLOSE TRACK SESSION with Close Function 010b. Such media behave very unpleasing with my DVD-ROM drive under Linux 2.4 ide-cd. One should therefore better avoid to release media in this state. This state can be recognized by 23h READ FORMAT CAPACITIES. The Descriptor Type of the Current/Maximum Capacity Descriptor is 11b ("Unknown Capacity") and no formats 13h or 11h are offered. (mmc5r03c.pdf, 6.24.3.2.1, 6.24.3.3) One may treat such media as if Format Type 15h or 13h had been freshly applied. I.e. sequential writing from LBA 0. After cache sync bring the session out of Intermediate state by 5Bh CLOSE TRACK SESSION with Close Function 010b. (mmc5r03c.pdf 6.3.3.2.3) ------------------------------------------------------------------------------- DVD-RAM and BD-RE formatting : Although DVD-RAM usually are sold formatted, there may still arise the wish to adjust formatting. BD-RE are sold unformatted and need to be formatted prior to usage. Two format types are relevant for DVD-RAM : 00h and 01h. 00h offers the default size format and usually a maximum payload size format. Even with that maximum size payload there is hardware defect management. (mmc5r03c.pdf 6.5.4.2.1.2) 01h can convert payload capacity into spare blocks for defect managment. There is no way to increase payload capacity by format 01h. (mmc5r03c.pdf 6.5.4.2.2.1) With BD-RE there are three format types : 00h, 30h and 31h. 00h offers the default size format. This may be the only fast formatting mode that is offered by the drive. Feature 0023h tells whether format 31h and certain 30h subtypes are available. (mmc5r03c.pdf 5.3.13) 30h offers several sizes with defect management. Usually there are three sizes given: #1: default size, #2: maximum spare area, #3: minimal spare. One may demand any spare size between maximum and minimum. There may be quick certification and full certification. See feature 0023h. 31h offers a single size and disables defect management. This has the side effect to speed up writing to nominal speed. (mmc5r03c.pdf 6.5.4.2.15, 6.24.3.3, Table 472) Only format sizes from the list of format descriptors are permissible for DVD-RAM. The format list can be obtained by 23h READ FORMAT CAPACITIES. It also includes a description of the current formatting state. (mmc5r03c.pdf 6.24, 6.24.3.2, 6.24.3.3) Formatting is done by command 04h FORMAT UNIT. Its data payload consists of a Format List Header and a Format Descriptor. It is advisable to set the Immed bit and the FOV bit in header byte number 1. The descriptor should be a copy of a descriptor from 23h READ FORMAT CAPACITIES. (mmc5r03c.pdf 6.5, 6.5.3.2, 6.5.3.3) With nearly all formats Sub-type should be set to 0. But with BD-RE formats 30h and 31h the Sub-type selects the certification mode. Usable with 30h seem 10b Full Certification and 11b Quick Certification. Usable with 31h seem also 00b Quick Reformat and 01b No Certification. (mmc5r03c.pdf 6.5.4.2.15.1) Other format types have their certification intensity controlled by a pair of bits: CmpList and DCRT. CmpList resides in CDB byte 1 as bit 3. DCRT resides in the payload byte 1 as bit 5. Both together should request a quick size change without lengthy certification but maintaining the list of known defects. (mmc5r03c.pdf 6.5, table 249, 6.5.3.2) With DVD-RAM on my PHILIPS SPD3300L drive they prevent any format size change though. The TSSTcorp SH-S203B works properly. With BD-RE format 00h, the default is specified to be Quick Reformat, and with 00h in general certification can only be disabled not enabled. (mmc5r03c.pdf 6.5.4.2.1.7) ------------------------------------------------------------------------------- DVD-RAM and BD-RE tuning : A special aspect of DVD-RAM and BD-RE is their low speed with write operations, which usually is only half than the nominal speed of media and drive. This is blamed to the automatic checkreading which happens for managing eventual defects. Defect management of BD-RE can be disabled by format type 31h. See above. There is no drive known yet which would apply command 2Ah WRITE10 to DVD-RAM with full speed. The only known way to get full speed from DVD-RAM or BD-RE with enabled defect management is the use of AAh WRITE12 with Streaming Bit set to 1. (mmc5r03c.pdf 6.45) With some DVD-RAM drives this fails if a write buffer is not full 32 kB. With the tested BD-RE one must write full 64 kB buffers, or else writing might not get into effect at all. Although it seems not optimal, this is specified not only to disable the cumbersome checkread but also to ignore known defects and to write data to these defective addresses. (mmc5r03c.pdf 4.8.5) So the speed-up is only advisable as long as the media are free of incorrectable errors. Caveat: MMC-5 does not guarantee AAh WRITE12 to work on DVD-RAM or BD-RE at all. None of the features of profiles 0012h and 0043h promises the existence of AAh WRITE12. (mmc5r03c.pdf 5.4.13, 6.45) Nevertheless it worked on all tested drives if proper alignment and block size was observed. ------------------------------------------------------------------------------- ISO 9660 multi-session emulation on overwriteable media : Overwriteable media provide a single overwriteable track which may grow up to the full media capacity. There is no builtin table-of-content which records the history of write sessions. mount -t iso9660 will use sbsector=0 as default. The term "superblock" shall depict the first 64 KiB after the sbsector address. ISO 9660 multi-session depends on typical TOC information in two ways: It needs the superblock address MSC1 of the most recently recorded session and it needs the Next Writeable Address NWA for which to prepare the adress offset. The following is learned from growisofs and from ECMA-119: http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-119.pdf ISO 9660 filesystems provide information about the number of sectors which is also the lowest unused block address and thus a suitable NWA. This block address is stored in the Primary Volume Descriptor which is supposed to be stored in block 16 (eventually relative to MSC1). The bytes 0 to 5 of a PVD block are 0x01 'C' 'D' '0' '0' '1' The sector count can then be read from byte 80 to 83 sectors= pvd[80] | (pvd[81] << 8) | (pvd[82] << 16) | (pvd[83] << 24); (Ecma-119.pdf 8.4) To support CD, DVD and BD media alike, it is advisable to round the NWA to the next multiple of 32 (= 64 KiB). So one can use 0 as MSC1 and prepare a new ISO session for the computed NWA. After writing the session it is necessary to copy the PVD from session start plus 16 to LBA 16 and to adjust it to its new location. The minimal change would be to update the number of image sectors. It is stored in both notations LSB and MSB: for(i= 0; i < 4; i++) pvd[87 - i]= pvd[80 + i]= (sectors >> (8 * i)) & 0xff; cdrskin --grow_overwriteable_iso not only patches the sector fields of the PVD block but also the blocks up to LBA 31 which begin with 0xff 'C' 'D' '0' '0' '1' libisoburn submits 64 KiB data buffer to libisofs before image generation and afterwards writes these 64 KiB as new superblock to LBA 0. ------------------------------------------------------------------------------- ISO 9660 based TOC emulation on overwriteable media : Above method of multi-session emulation yields a single session image after each add-on session. No reliable session history can be read because the sector size of the existing session gets overwritten by the new one. A TOC with session history is nevertheless desirable with incremental backups in order to access older backup states by mounting older superblocks at the start addresses of older sessions. All usual ISO 9660 formatter programs write a complete superblock to the start of each session. With a uniform NWA rounding rule it is possible to compute the address of superblock N+1 as the NWA after session N. The only problem is N=1 because it gets overwritten by later sessions. libisoburn preserves the information of session 1 by writing the first session to LBA 32 rather than LBA 0. Afterwards it writes the overall superblock to LBA 0 (up to 31). So with all further add-on sessions the superblock at LBA 0 will enclose the overall image, while the superblocks of the sessions form a chain beginning at LBA 32. Each session superblock points to the next one by its sector count rounded up to 32. The chain end is marked by the overall image size. This chain gives the start addresses of sessions. The sector count minus start address gives the size of a particular session. ECMA-119 explains how to retrieve more info from the PVD (e.g. the volume id). See also the multi-session example in libisofs/doc/checksums.txt. ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- Sequential DVD-R[W] Cookbook ------------------------------------------------------------------------------- Inspired by Andy Polyakov's http://fy.chalmers.se/~appro/linux/DVD+RW/tools , backed by reading mmc5r03c.pdf from http://www.t10.org/ftp/t10/drafts/mmc5/ and by experiments with drives NEC ND-4570A and LG GSA-4082B. For libburnia-project.org by Thomas Schmitt <scdbackup@gmx.net> ------------------------------------------------------------------------------- Media type can be recognized by Current Profile from 46h GET CONFIGURATION. (mmc5r03c.pdf 6.6.2.1) DVD-R 0011h DVD-RW Restricted Overwrite 0013h DVD-RW Sequential Recording 0014h DVD-R/DL Sequential Recording 0015h (can only do single-session) There are two approaches for writing to sequential DVD-R[W]: DAO and Incremental. Not all media and drives offer Incremental which can do multi-session as with CD media and does not demand a predicted track size. DAO seems to be the older method. It can only write one single session and track, and it demands an exactly predicted track size. - About overwriteable, blank, appendable and finalized DVD-R[W] media - Incremental writing - DAO writing - Obtaining DVD-R[W] multi-session info for extending ISO-9660 filesystems - Obtaining a Table Of Content from DVD-R[W] - Hearsay about DVD-R/DL (Dual Layer) ------------------------------------------------------------------------------- About overwriteable, blank, appendable and finalized DVD-R[W] media : DVD-RW can be either in formatted state Restricted Overwrite or in unformatted state Sequential Recording. Sequential media can be either blank, appendable or finalized. Only blank and appendable media are sequentially writeable. For overwriteable DVD-RW see the Overwriteable DVD Cookbook. Overwriteable DVD-RW can be detected by their profile number 0013h in contrast to profile number 0014h for sequential DVD-RW. The status of sequential media can be inquired like with CD by 51h READ DISC INFORMATION requesting Data Type 000b Standard Disc Information, where reply value Disc Status indicates: 00b blank 01b appendable 10b finalized 11b others (unsuitable for this recipe) (mmc5r03c.pdf 6.22.3.1.4) Finalized, appendable or overwriteable DVD-RW can be brought into blank sequential state by command A1h BLANK with blanking type 000b "Blank the disc". See TAO Multi-Session CD Cookbook for details about blanking. After minimal blanking (type 001b) DVD-RW my two drives do not offer the Incremental Streaming feature 0021h the media any more. Full blanking (000b) brings back this feature. (mmc5r03c.pdf 6.2) ------------------------------------------------------------------------------- Incremental writing : Incremental writing can produce multi-session DVDs. It is indicated by feature 0021h being marked current in the reply of 46h GET CONFIGURATION. growisofs inquires 0021h by setting Starting Feature Number to 0x21 and Allocation Length to 16 in order to get only this one. The feature descriptor begins at byte 8 of the reply. Its availability is indicated by the Current Bit. libburn obtains the full feature list for this and other info. (mmc5r03c.pdf 5.2.2. Feature Descriptor format, 5.3.11 Feature 0021h, 6.2 46h GET CONFIGURATION, ) In mode page 05h this method is selected by Write Type 00h. Speed can be influenced by B6h SET STREAMING , speed capabilities can be inquired by ACh GET PERFORMANCE. It is advised to set only speeds and sizes which are returned by ACh. (mmc5r03c.pdf 6.39 SET STREAMING, 6.8 GET PERFORMANCE) growisofs fetches a mode page 05h template by MODE SENSE and inserts its own parameters. It sets Multi-session to 11b, unless dvd_compat is nonzero. libburn composes its mode page 05h from zero and enables the application to control Multi-Session. BUFE Buffer Underrun protection 0=off, 1=on LS_V Link size valid 1=true Test Write -dummy mode for writing 0=off, 1=on Write Type Packet/TAO/SAO/RAW 00h = Incremental (Packet) Multi-session Whether to keep appendable 00b = finalize 11b = keep appendable Track Mode Describes frame type 5 [*1] Data Block Type Layout of payload blocks 8 [*2] Link Size ??? 16 [*3] FP Fixed Packet Size Bit 1 Packet Size 16 [*4] (mmc5r03c.pdf 7.5.4 The Mode Page, 4.2.3.4 Table 17 CONTROL = Track Mode) (spc3r23.pdf 6.8 MODE SELECT, 7.4.3 Mode parameter header formats) [*1:] growisofs takes the Track Mode from 52h READ TRACK INFORMATION, Address/Number Type 1, Track 1, Track Information Block byte 5 & 0xf. (mmc5r03.pdf 6.27) The specs predict that this will be Track Mode 4 (6.27.3.8) and also state that default is 5 (7.5.4.12). 4 means: uninterrupted, do not copy. 5 means increment, do not copy. [*2:] 8 means: 2048 byte data blocks. growisofs sets this value if Data Mode from above 52h READ TRACK INFORMATION is 1 or Fh, which is predicted by the specs to be always true. (mmc5r03.pdf 6.27.3.10) [*3:] growisofs (transport.hxx) sets Link Size to 16 for profiles 0011h and 0014h. libburn now records the first link size from feature 0021h in its burn_drive structure. If another link size item is 16, then 16 is used. [*4:] growisofs takes Packet Size from 52h. Specs predict it will be 16 (= 32 kiB). (mmc5r03.pdf 7.5.4.16) The writing process is much like in "Writing a session to CD in TAO mode" : Next Writeable Address is fetched from the reply of 52h READ TRACK INFORMATION. libburn writes full 32 kiB buffers via 2Ah WRITE. (mmc5r03c.pdf, 6.27 READ TRACK INFORMATION, 6.44 WRITE) When writing is done, it is mandatory to force the drive's buffer to media by 35h SYNCHRONIZE CACHE. (mmc5r03c.pdf, 6.41) The track has to be closed by 5Bh CLOSE TRACK SESSION Close Function 001b. growisofs uses the logical track number for that and not FFh like libburn does with TAO CD. So libburn obtains the Last Track Number in Last Session from the reply of 51h READ DISC INFORMATION requesting Data Type 000b "Standard Disc Information". (mmc5r03c.pdf 6.3.3.2.2 CLOSE TRACK, 6.22.3.1.) Multiple tracks are permissible in a single session. After all of them have been written, 5Bh CLOSE TRACK SESSION Close Function 010b with Logical Track Number 0 closes the session. It depends on the Multi-Session value in mode page 05h whether the disc is finalized or stays appendable. (mmc5r03c.pdf 6.3.3.2.3) ------------------------------------------------------------------------------- DAO writing : DAO is the mode described by feature 002Fh. This feature also gives information about capabilities for Burnfree (BUF), Test Write and DVD-RW. (mmc5r03c.pdf 5.3.25) Experiments with growisofs showed that the track size needs to be predicted and may not be exceeded during the write process. (growisofs ran into SCSI errors with piped non-ISO-9660 images and with piped ISO-9660 which have trailing data.) Speed can be influenced by B6h SET STREAMING , speed capabilities can be inquired by ACh GET PERFORMANCE. It is advised to set only speeds and sizes which are returned by ACh. (mmc5r03c.pdf 6.39 SET STREAMING, 6.8 GET PERFORMANCE) The mode page 05h to be sent : BUFE Buffer Underrun protection 0=off, 1=on LS_V Link size valid 0=false [*3] Test Write -dummy mode for writing 0=off, 1=on Write Type Packet/TAO/SAO/RAW 02h = DAO (same code as SAO) Multi-session Whether to keep appendable 00b = finalize Track Mode Describes frame type 5 [*1] Data Block Type Layout of payload blocks 8 [*2] Link Size ??? 0 [*3] FP Fixed Packet Size Bit 0 [*3] Packet Size 0 [*3] (mmc5r03c.pdf 7.5.4 The Mode Page, 4.2.3.4 Table 17 CONTROL = Track Mode) (spc3r23.pdf 6.8 MODE SELECT, 7.4.3 Mode parameter header formats) [*1:] growisofs takes the Track Mode from 52h READ TRACK INFORMATION, Address/Number Type 1, Track 1, Track Information Block byte 5 & 0xf. (mmc5r03.pdf 6.27) [*2:] 8 means: 2048 byte data blocks. growisofs sets this value if Data Mode from above 52h READ TRACK INFORMATION is 1 or Fh, which is predicted by the specs to be always true. (If not: growisofs aborts.) (mmc5r03.pdf 6.27.3.10) [*3:] Link Size, Packet Size and their companions only apply to Write Type 00h. The session layout must be described by 53h RESERVE TRACK, RMZ=ARSV=0. Reservation size should better already be aligned to 32 KiB. It has not been tested yet, what happens if not enough data get written. (mmc5r03c.pdf 6.31) Next Writeable Address is fetched from the reply of 52h READ TRACK INFORMATION. The reply is supposed to be 0. libburn writes full 32 kiB buffers via 2Ah WRITE. (mmc5r03c.pdf, 6.27 READ TRACK INFORMATION, 6.44 WRITE) If the track source delivers less than the announced size then libburn pads up by zeros. When writing is done, it is mandatory to force the drive's buffer to media by 35h SYNCHRONIZE CACHE. (mmc5r03c.pdf, 6.41) No further finalization is necessary. (I.e. no 5Bh CLOSE TRACK SESSION.) ------------------------------------------------------------------------------- Obtaining DVD-R[W] multi-session info for extending ISO-9660 filesystems : (valid for DVD+R too) Like with CD it is necessary to obtain the two numbers for mkisofs option -C in order to prepare a ISO-9660 filesystem image which by its inner pointers matches the block addresses of the future location on media. These are the start address of the first track in the last complete session and the predicted start address of the track which will host the new image. See TAO Multi-Session CD Cookbook for some more info about mkisofs aspects. The first number may be gained by 43h READ TOC/PMA/ATIP Format 0001b which in table 478 promises quick access via Start Address Of First Track In Last Session. (mmc5r03c.pdf 6.26.2.5 table 478, 6.26.3.3.1) Regrettably the MMC-5 specs still define a useless reply for non-CD media which obviously stems from MMC-3 times when no multi-session was possible with non-CD. (mmc5r03c.pdf 6.26.3.3.3) Both my drives do give a useful reply with the correct number for appendable DVD-RW. But not being backed by the specs this method appears unappealing . Another approach would be a formatted Table of Content, obtained by 43h READ TOC/PMA/ATIP Format 0000b. The specs do not totally outrule that this returns useful data with non-CD but they define a crippled TOC for multi-session. (mmc5r03c.pdf 6.26.3.2.4) My LG drive returns a more detailed TOC, my NEC drive stays with the rather suboptimal specs. So one would get different TOCs on different drives. Nevertheless, the MMC-5 compliant TOC would return the desired number in the Track Start address of the track with the highest number before AAh. Most stable seems the approach to obtain the desired number from the reply of 52h READ TRACK INFORMATION, Address/Number Type 01b. The field Logical Block Address/Track/Session has to bear the track number of the first track in the last complete session. To determine this number one has to determine the number of the last session and the number of the last track from 51h READ DISC INFORMATION and to iterate over the tracknumber by 52h READ TRACK INFORMATION until the first track with the desired session number appears and reveils its start address. (mmc5r03c.pdf 6.22 51h DISC, 6.27 52h TRACK) This method is very near to fabricating an own TOC. So libburn does this when inspecting the media. If the first number for -C is needed, libburn inquires its TOC model for the address of the first track in the last complete session. See below for a detailed description of TOC fabrication. The second -C number is the exact prediction of future track start address. It is gained like with CD by 52h READ TRACK INFORMATION Type 01b. Different from CD one may not use track number FFh but has to use the Last Track in Last Session from 51h READ DISC INFORMATION. (mmc5r03c.pdf 6.22 51h DISC, 6.27 52h TRACK) ------------------------------------------------------------------------------- Obtaining a Table Of Content from DVD-R[W]: (valid for DVD+R too) The raw TOC entries from 43h READ TOC/PMA/ATIP Format 0010b as described with CD media are not available with non-CD. There is a Format 0000b "Formatted TOC" but this is with non-CD a fictional information much at the discretion of the drive. Two drives with the same disc may well return different Formatted TOC. They are supposed to be consistent only about the last complete session and even there the MMC-5 specification 6.26.3.2.5 seems to prescribe a structure which does not match the true structure of incremental writing to sequential DVD-R[W]. (mmc5r03c.pdf 6.26.3.2) So i prefer not to use this method of getting a TOC. The alternative is to produce an own TOC from information gained by 51h READ DISC INFORMATION and by 52h READ TRACK INFORMATION which reveil a CD-like structure of sessions and 1:n related tracks. 51h READ DISC INFORMATION Data Type 000b, fields Number of Sessions (Least Significant Byte) and Number of Sessions (Most Significant Byte) give the number of sessions. The last complete session number of an appendable disc is one less because there is an incomplete session at its end. libburn only records complete sessions in its TOC model. libburn uses Last Track in Last Session as a hint for the range of track numbers. (mmc5r03c.pdf 6.22) Next step is to iterate from 1 up to the last track number and to obtain the according track info by 52h READ TRACK INFORMATION. Each track tells its Session Number (LSB at byte 2, MSB at 33), its Logical Track Start Address, its Logical Track Size, and much more which is not needed for a fake CD TOC. One may analyze the track info more finely but for this special purpose it is enough to discard the tracks which do not belong to complete sessions. (mmc5r03c.pdf 6.27) At the end of each session libburn inserts fake leadout entries into its TOC model. Their start address is computed from the start and size of the last track of the session. ------------------------------------------------------------------------------- Hearsay about DVD-R/DL (Dual Layer) : Meanwhile confirmed by one user: DVD-R/DL can assume profile 0015h DVD-R Dual Layer Sequential which is supposed to behave like DVD-R or 0016h DVD-R Dual Layer Jump which has no counterpart with DVD-R. A half-sentence in mmc5r03c.pdf 6.3.3.3.3 indicates that closing a session by 5Bh CLOSE TRACK SESSION Close Function 010b overrides the multi-session bits in mode page 05h. growisofs applies this function in case of not DAO, though. A comment in growisofs_mmc.cpp states: "// DVD-R DL Seq has no notion of multi-session". I am not reading this from the specs - but not explicitely the contrary either. For now libburn will close the session but there is a macro prepared in libburn/write.c Libburn_dvd_r_dl_multi_no_close_sessioN which will suppress close session if multi-session is demanded. ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- DVD+R[/DL] Cookbook ------------------------------------------------------------------------------- Inspired by reading mmc5r03c.pdf from http://www.t10.org/ftp/t10/drafts/mmc5/ backed by Andy Polyakov's http://fy.chalmers.se/~appro/linux/DVD+RW/tools , For libburnia-project.org by Thomas Schmitt <scdbackup@gmx.net> ------------------------------------------------------------------------------- Media type can be recognized by Current Profile from 46h GET CONFIGURATION. (mmc5r03c.pdf 6.6.2.1) DVD+R 001bh DVD+R/DL 002bh - About empty, appendable and finalized DVD+R - Writing a Pseudo Session to DVD+R - DVD+R/DL (Dual Layer The following two chapters of the Sequential DVD-R[W] Cookbook are valid for DVD+R media too: - Obtaining DVD-R[W] multi-session info for extending ISO-9660 filesystems - Obtaining a Table Of Content from DVD-R[W] ------------------------------------------------------------------------------- About blank, appendable and finalized DVD+R : In the beginning a DVD+R holds an empty session and the Incomplete Fragment. From these one may spawn reserved fragments or one may write directly to the incomplete fragment. As soon as this is done the empty session becomes the open session which finally needs to get closed. By closing fragments and session a new empty session with empty Incomplete Fragment gets spawned. So the disc stays appendable. A DVD+R may hold 153 closed sessions with a single track each. The open session may hold up to 15 open fragments. But on closure of the session those fragments together form a single logical track. So one will usually only use a single fragment for sequential writing. (mmc5r03c.pdf 4.3.6.2) The disc may get finalized by another close command so that no more data can be written. (mmc5r03c.pdf 6.3.3.4.4) ------------------------------------------------------------------------------- Writing a Pseudo Session to DVD+R : Session writing has to be pseudo because only one logical track per session can be distinguished. So actually there have to be written multiple sessions to mark multiple tracks. The pseudo session cannot get marked on disc and thus the tracks of a pseudo session cannot be grouped accordingly in a TOC. Speed can be influenced by B6h SET STREAMING , speed capabilities can be inquired by ACh GET PERFORMANCE. It is advised to set only speeds and sizes which are returned by ACh. (mmc5r03c.pdf 6.39 SET STREAMING, 6.8 GET PERFORMANCE) No mode page 05h is to be sent. growisofs sends a page but the specs clearly state that one shall not do. (mmc5r03c.pdf 7.5.3) It is optional whether a track size is reserved in advance or not. Eventually this is done by 53h RESERVE TRACK, RMZ=ARSV=0. Reservation size should better already be aligned to 32 KiB. (mmc5r03c.pdf 6.31) The specs promise to pad up the track if not enough data get written. (mmc5r03c.pdf 6.3.3.4.2) Next Writeable Address is fetched from the reply of 52h READ TRACK INFORMATION with track number FFh. (mmc5r03c.pdf 6.27) Since the fixely set write type is 16-block packet, full 32 kiB buffers have to be transmitted via 2Ah WRITE. (mmc5r03c.pdf 4.3.6.2.2) When writing is done, it is mandatory to force the drive's buffer to media by 35h SYNCHRONIZE CACHE. (mmc5r03c.pdf 6.41) The written fragment (i.e. track-to-be) has to be closed by 5Bh CLOSE TRACK SESSION Close Function 001b. (mmc5r03c.pdf 6.3.3.4.2) libburn obtains the necessary logical track number from Last Track Number in Last Session from the reply of 51h READ DISC INFORMATION requesting Data Type 000b. (mmc5r03c.pdf 6.22) After each track 5Bh CLOSE TRACK SESSION Close Function 010b with Logical Track Number 0 closes the DVD+R session but keeps the media appendable. (mmc5r03c.pdf 6.3.3.4.3) If the media shall not stay appendable then the last DVD+R session is to be closed by Close Function 101b rather than 010b. This finalizes the media "with minimal radius". (mmc5r03c.pdf 6.3.3.4.4) Note: growisofs has code for that gesture but explicitly avoids to use it, if the media was appendable before writing began. Instead it recommends to fill up the media with zeros. This gesture nevertheless caused error replies from the drives in my own experiments. The reason given by Andy Polyakov is that some DVD-ROM drives get mislead by the lead-out information of (formerly) appendable media unless the media is fully written. (http://fy.chalmers.se/~appro/linux/DVD+RW/ , "Compatibility: caveat lector") Own experiments showed no such problems with PC attached PATA DVD-ROM drives. For best DVD-ROM compatibility one should avoid appendable media at all by closing them already after the first session. ------------------------------------------------------------------------------- DVD+R/DL (Dual Layer) : libburn treats DL media just like their single layer equivalents. This seems to work fine for DVD+R/DL, according to a report by nightmorph in http://libburnia-project.org/ticket/13 . ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- BD-R Cookbook ------------------------------------------------------------------------------- Inspired by reading mmc5r03c.pdf from http://www.t10.org/ftp/t10/drafts/mmc5/ backed by experiments iwith drive LG GGW H20L. For libburnia-project.org by Thomas Schmitt <scdbackup@gmx.net> ------------------------------------------------------------------------------- Media type can be recognized by Current Profile from 46h GET CONFIGURATION. (mmc5r03c.pdf 6.6.2.1) BD-R 0042h There are two basic recording modes defined: Sequential Recording Mode SRM and Random Recording Mode RRM. The latter is optional and for now not topic of this text. (mmc5r03c.pdf 4.5.3.5) - SRM Formatting - Writing a session in SRM-POW (- Pseudo-OverWrite SRM+POW) ------------------------------------------------------------------------------- SRM Formatting: Despite being write-once media BD-R can optionally carry some formatting. SRM has a disc structure model with tracks and sessions. Several tracks may be open at the same time, each having its own NWA. (mmc5r03c.pdf 4.5.3.5.2.2) This structure is formatted onto blank media automatically as soon as the first serious write attempt occurs. (mmc5r03c.pdf 4.5.3.5) Before such a write attempt, blank media may be explicitely formatted with spares, which provide defect management. (mmc5r03c.pdf 4.5.3.5.3) Tracks get created from other tracks via RESERVE TRACK splitting. (mmc5r03c.pdf 4.5.3.5.2.5) On top of defect management there may be Pseudo-OverWrite SRM+POW, a costly way to write several times to the same LBA. See below. Fully sequential states are called SRM-POW. (mmc5r03c.pdf 4.5.3.5.4) Explicite formatting is done by 04h FORMAT UNIT. Its data payload consists of a Format List Header and a Format Descriptor. It is advisable to set the Immed bit and the FOV bit in header byte number 1. The descriptor should be a copy of a descriptor from 23h READ FORMAT CAPACITIES but the size may be adjusted within a certain range. (mmc5r03c.pdf 6.5, 6.5.3.2, 6.5.3.3) Format type 00h creates SRM layouts with a default number of spares (or eventually RRM) chosen by the format sub-type: 00b = SRM with support for POW 01b = SRM without POW (but with some spares for defect management) 10b = (RRM) (mmc5r03c.pdf 6.5.4.2.1.6) Format type 32h uses the same sub-types but can allocate non-default amounts of spares. Similar to BD-RE format 31h, three format descriptors are offered: #1: default size, #2: maximum spare area, #3: minimal spare. The size may be chosen within that range. The sense behind the Type Dependent Parameters is obscure to me. Best will be to set ISA_V and TDMA_V to 0. (mmc5r03c.pdf 6.5.4.2.1.17) ------------------------------------------------------------------------------- Writing a session in SRM: The procedure and constraints for writing BD-R SRM-POW are very similar to DVD+R. libburn flatly re-uses its DVD+R code except the Close Function for finalizing a disc. In short: If all written sessions are closed, then there is exactly one NWA. In the beginning there is an empty session and track. A new track can be written either with pre-announced size (by RESERVE TRACK) or open-end by simply starting to write to the NWA. When done the track gets closed by close function 001b. Then either session or disc gets closed depending on the Close Function used: - Close Function 010b closes the session and keeps the media appendable (same as with DVD+R) - Close Function 110b finalizes the media and makes it read-only. (differs from libburn DVD+R procedure which uses 101b) ------------------------------------------------------------------------------- Pseudo-OverWrite POW: (no used yet by libburn) This enhancement of SRM emulates overwriting of existing data blocks. (mmc5r03c.pdf 4.5.3.5.4) POW establishes a virtual vLBA space on top of the real address space rLBA. All read and write commands deal with vLBA. It seems that track NWAs are assumed to be identical in vLBA space and in rLBA space. It is not clear whether one may write to vLBA blocks which are neither written yet nor at one of the track NWAs. Probably not, or else one could make NWAs run into vLBAs which are associated with older rLBAs. Replacing invalidated blocks consumes addresses in rLBA space at the NWA of some track. I.e. no spares are consumed by POW. Nevertheless it is costly by a special map called Orphanage. It covers rLBA which have been consumed by differing vLBAs. It never shrinks and can grow with each write to remapped addresses. To avoid heavy Orphanage growth it is advised to write mostly to vLBA which still coincide with their rLBA. E.g. those addresses which have neither been written as rLBA nor as vLBA yet. So one should begin the vLBA of new sessions at the NWA of a sufficiently sized track. (mmc5r03c.pdf 4.5.3.5.4.2 , 4.5.3.6.9) ------------------------------------------------------------------------------- This text is copyright 2011 - 2012 Thomas Schmitt <scdbackup@gmx.net>. Permission is granted to copy, modify, and distribute it, as long as the references to the original information sources are maintained. There is NO WARRANTY, to the extent permitted by law. ------------------------------------------------------------------------------- �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������libburn-1.4.2/install-sh����������������������������������������������������������������������������0000755�0001757�0001751�00000033255�12652650102�012117� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/bin/sh # install - install a program, script, or datafile scriptversion=2011-11-20.07; # UTC # This originates from X11R5 (mit/util/scripts/install.sh), which was # later released in X11R6 (xc/config/util/install.sh) with the # following copyright and license. # # Copyright (C) 1994 X Consortium # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to # deal in the Software without restriction, including without limitation the # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or # sell copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN # AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- # TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # # Except as contained in this notice, the name of the X Consortium shall not # be used in advertising or otherwise to promote the sale, use or other deal- # ings in this Software without prior written authorization from the X Consor- # tium. # # # FSF changes to this file are in the public domain. # # Calling this script install-sh is preferred over install.sh, to prevent # 'make' implicit rules from creating a file called install from it # when there is no Makefile. # # This script is compatible with the BSD install script, but was written # from scratch. nl=' ' IFS=" "" $nl" # set DOITPROG to echo to test this script # Don't use :- since 4.3BSD and earlier shells don't like it. doit=${DOITPROG-} if test -z "$doit"; then doit_exec=exec else doit_exec=$doit fi # Put in absolute file names if you don't have them in your path; # or use environment vars. chgrpprog=${CHGRPPROG-chgrp} chmodprog=${CHMODPROG-chmod} chownprog=${CHOWNPROG-chown} cmpprog=${CMPPROG-cmp} cpprog=${CPPROG-cp} mkdirprog=${MKDIRPROG-mkdir} mvprog=${MVPROG-mv} rmprog=${RMPROG-rm} stripprog=${STRIPPROG-strip} posix_glob='?' initialize_posix_glob=' test "$posix_glob" != "?" || { if (set -f) 2>/dev/null; then posix_glob= else posix_glob=: fi } ' posix_mkdir= # Desired mode of installed file. mode=0755 chgrpcmd= chmodcmd=$chmodprog chowncmd= mvcmd=$mvprog rmcmd="$rmprog -f" stripcmd= src= dst= dir_arg= dst_arg= copy_on_change=false no_target_directory= usage="\ Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE or: $0 [OPTION]... SRCFILES... DIRECTORY or: $0 [OPTION]... -t DIRECTORY SRCFILES... or: $0 [OPTION]... -d DIRECTORIES... In the 1st form, copy SRCFILE to DSTFILE. In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. In the 4th, create DIRECTORIES. Options: --help display this help and exit. --version display version info and exit. -c (ignored) -C install only if different (preserve the last data modification time) -d create directories instead of installing files. -g GROUP $chgrpprog installed files to GROUP. -m MODE $chmodprog installed files to MODE. -o USER $chownprog installed files to USER. -s $stripprog installed files. -t DIRECTORY install into DIRECTORY. -T report an error if DSTFILE is a directory. Environment variables override the default commands: CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG " while test $# -ne 0; do case $1 in -c) ;; -C) copy_on_change=true;; -d) dir_arg=true;; -g) chgrpcmd="$chgrpprog $2" shift;; --help) echo "$usage"; exit $?;; -m) mode=$2 case $mode in *' '* | *' '* | *' '* | *'*'* | *'?'* | *'['*) echo "$0: invalid mode: $mode" >&2 exit 1;; esac shift;; -o) chowncmd="$chownprog $2" shift;; -s) stripcmd=$stripprog;; -t) dst_arg=$2 # Protect names problematic for 'test' and other utilities. case $dst_arg in -* | [=\(\)!]) dst_arg=./$dst_arg;; esac shift;; -T) no_target_directory=true;; --version) echo "$0 $scriptversion"; exit $?;; --) shift break;; -*) echo "$0: invalid option: $1" >&2 exit 1;; *) break;; esac shift done if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then # When -d is used, all remaining arguments are directories to create. # When -t is used, the destination is already specified. # Otherwise, the last argument is the destination. Remove it from $@. for arg do if test -n "$dst_arg"; then # $@ is not empty: it contains at least $arg. set fnord "$@" "$dst_arg" shift # fnord fi shift # arg dst_arg=$arg # Protect names problematic for 'test' and other utilities. case $dst_arg in -* | [=\(\)!]) dst_arg=./$dst_arg;; esac done fi if test $# -eq 0; then if test -z "$dir_arg"; then echo "$0: no input file specified." >&2 exit 1 fi # It's OK to call 'install-sh -d' without argument. # This can happen when creating conditional directories. exit 0 fi if test -z "$dir_arg"; then do_exit='(exit $ret); exit $ret' trap "ret=129; $do_exit" 1 trap "ret=130; $do_exit" 2 trap "ret=141; $do_exit" 13 trap "ret=143; $do_exit" 15 # Set umask so as not to create temps with too-generous modes. # However, 'strip' requires both read and write access to temps. case $mode in # Optimize common cases. *644) cp_umask=133;; *755) cp_umask=22;; *[0-7]) if test -z "$stripcmd"; then u_plus_rw= else u_plus_rw='% 200' fi cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; *) if test -z "$stripcmd"; then u_plus_rw= else u_plus_rw=,u+rw fi cp_umask=$mode$u_plus_rw;; esac fi for src do # Protect names problematic for 'test' and other utilities. case $src in -* | [=\(\)!]) src=./$src;; esac if test -n "$dir_arg"; then dst=$src dstdir=$dst test -d "$dstdir" dstdir_status=$? else # Waiting for this to be detected by the "$cpprog $src $dsttmp" command # might cause directories to be created, which would be especially bad # if $src (and thus $dsttmp) contains '*'. if test ! -f "$src" && test ! -d "$src"; then echo "$0: $src does not exist." >&2 exit 1 fi if test -z "$dst_arg"; then echo "$0: no destination specified." >&2 exit 1 fi dst=$dst_arg # If destination is a directory, append the input filename; won't work # if double slashes aren't ignored. if test -d "$dst"; then if test -n "$no_target_directory"; then echo "$0: $dst_arg: Is a directory" >&2 exit 1 fi dstdir=$dst dst=$dstdir/`basename "$src"` dstdir_status=0 else # Prefer dirname, but fall back on a substitute if dirname fails. dstdir=` (dirname "$dst") 2>/dev/null || expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$dst" : 'X\(//\)[^/]' \| \ X"$dst" : 'X\(//\)$' \| \ X"$dst" : 'X\(/\)' \| . 2>/dev/null || echo X"$dst" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q' ` test -d "$dstdir" dstdir_status=$? fi fi obsolete_mkdir_used=false if test $dstdir_status != 0; then case $posix_mkdir in '') # Create intermediate dirs using mode 755 as modified by the umask. # This is like FreeBSD 'install' as of 1997-10-28. umask=`umask` case $stripcmd.$umask in # Optimize common cases. *[2367][2367]) mkdir_umask=$umask;; .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; *[0-7]) mkdir_umask=`expr $umask + 22 \ - $umask % 100 % 40 + $umask % 20 \ - $umask % 10 % 4 + $umask % 2 `;; *) mkdir_umask=$umask,go-w;; esac # With -d, create the new directory with the user-specified mode. # Otherwise, rely on $mkdir_umask. if test -n "$dir_arg"; then mkdir_mode=-m$mode else mkdir_mode= fi posix_mkdir=false case $umask in *[123567][0-7][0-7]) # POSIX mkdir -p sets u+wx bits regardless of umask, which # is incompatible with FreeBSD 'install' when (umask & 300) != 0. ;; *) tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0 if (umask $mkdir_umask && exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1 then if test -z "$dir_arg" || { # Check for POSIX incompatibilities with -m. # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or # other-writable bit of parent directory when it shouldn't. # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. ls_ld_tmpdir=`ls -ld "$tmpdir"` case $ls_ld_tmpdir in d????-?r-*) different_mode=700;; d????-?--*) different_mode=755;; *) false;; esac && $mkdirprog -m$different_mode -p -- "$tmpdir" && { ls_ld_tmpdir_1=`ls -ld "$tmpdir"` test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" } } then posix_mkdir=: fi rmdir "$tmpdir/d" "$tmpdir" else # Remove any dirs left behind by ancient mkdir implementations. rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null fi trap '' 0;; esac;; esac if $posix_mkdir && ( umask $mkdir_umask && $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" ) then : else # The umask is ridiculous, or mkdir does not conform to POSIX, # or it failed possibly due to a race condition. Create the # directory the slow way, step by step, checking for races as we go. case $dstdir in /*) prefix='/';; [-=\(\)!]*) prefix='./';; *) prefix='';; esac eval "$initialize_posix_glob" oIFS=$IFS IFS=/ $posix_glob set -f set fnord $dstdir shift $posix_glob set +f IFS=$oIFS prefixes= for d do test X"$d" = X && continue prefix=$prefix$d if test -d "$prefix"; then prefixes= else if $posix_mkdir; then (umask=$mkdir_umask && $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break # Don't fail if two instances are running concurrently. test -d "$prefix" || exit 1 else case $prefix in *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; *) qprefix=$prefix;; esac prefixes="$prefixes '$qprefix'" fi fi prefix=$prefix/ done if test -n "$prefixes"; then # Don't fail if two instances are running concurrently. (umask $mkdir_umask && eval "\$doit_exec \$mkdirprog $prefixes") || test -d "$dstdir" || exit 1 obsolete_mkdir_used=true fi fi fi if test -n "$dir_arg"; then { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 else # Make a couple of temp file names in the proper directory. dsttmp=$dstdir/_inst.$$_ rmtmp=$dstdir/_rm.$$_ # Trap to clean up those temp files at exit. trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 # Copy the file name to the temp name. (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && # and set any options; do chmod last to preserve setuid bits. # # If any of these fail, we abort the whole thing. If we want to # ignore errors from any of these, just make sure not to ignore # errors from the above "$doit $cpprog $src $dsttmp" command. # { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && # If -C, don't bother to copy if it wouldn't change the file. if $copy_on_change && old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && eval "$initialize_posix_glob" && $posix_glob set -f && set X $old && old=:$2:$4:$5:$6 && set X $new && new=:$2:$4:$5:$6 && $posix_glob set +f && test "$old" = "$new" && $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 then rm -f "$dsttmp" else # Rename the file to the real destination. $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || # The rename failed, perhaps because mv can't rename something else # to itself, or perhaps because mv is so ancient that it does not # support -f. { # Now remove or move aside any old file at destination location. # We try this two ways since rm can't unlink itself on some # systems and the destination file might be busy for other # reasons. In this case, the final cleanup might fail but the new # file should still install successfully. { test ! -f "$dst" || $doit $rmcmd -f "$dst" 2>/dev/null || { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } } || { echo "$0: cannot unlink or rename $dst" >&2 (exit 1); exit 1 } } && # Now rename the file to the real destination. $doit $mvcmd "$dsttmp" "$dst" } fi || exit 1 trap '' 0 fi done # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC" # time-stamp-end: "; # UTC" # End: ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������libburn-1.4.2/depcomp�������������������������������������������������������������������������������0000755�0001757�0001751�00000056016�12652650102�011470� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������#! /bin/sh # depcomp - compile a program generating dependencies as side-effects scriptversion=2013-05-30.07; # UTC # Copyright (C) 1999-2013 Free Software Foundation, Inc. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # Originally written by Alexandre Oliva <oliva@dcc.unicamp.br>. case $1 in '') echo "$0: No command. Try '$0 --help' for more information." 1>&2 exit 1; ;; -h | --h*) cat <<\EOF Usage: depcomp [--help] [--version] PROGRAM [ARGS] Run PROGRAMS ARGS to compile a file, generating dependencies as side-effects. Environment variables: depmode Dependency tracking mode. source Source file read by 'PROGRAMS ARGS'. object Object file output by 'PROGRAMS ARGS'. DEPDIR directory where to store dependencies. depfile Dependency file to output. tmpdepfile Temporary file to use when outputting dependencies. libtool Whether libtool is used (yes/no). Report bugs to <bug-automake@gnu.org>. EOF exit $? ;; -v | --v*) echo "depcomp $scriptversion" exit $? ;; esac # Get the directory component of the given path, and save it in the # global variables '$dir'. Note that this directory component will # be either empty or ending with a '/' character. This is deliberate. set_dir_from () { case $1 in */*) dir=`echo "$1" | sed -e 's|/[^/]*$|/|'`;; *) dir=;; esac } # Get the suffix-stripped basename of the given path, and save it the # global variable '$base'. set_base_from () { base=`echo "$1" | sed -e 's|^.*/||' -e 's/\.[^.]*$//'` } # If no dependency file was actually created by the compiler invocation, # we still have to create a dummy depfile, to avoid errors with the # Makefile "include basename.Plo" scheme. make_dummy_depfile () { echo "#dummy" > "$depfile" } # Factor out some common post-processing of the generated depfile. # Requires the auxiliary global variable '$tmpdepfile' to be set. aix_post_process_depfile () { # If the compiler actually managed to produce a dependency file, # post-process it. if test -f "$tmpdepfile"; then # Each line is of the form 'foo.o: dependency.h'. # Do two passes, one to just change these to # $object: dependency.h # and one to simply output # dependency.h: # which is needed to avoid the deleted-header problem. { sed -e "s,^.*\.[$lower]*:,$object:," < "$tmpdepfile" sed -e "s,^.*\.[$lower]*:[$tab ]*,," -e 's,$,:,' < "$tmpdepfile" } > "$depfile" rm -f "$tmpdepfile" else make_dummy_depfile fi } # A tabulation character. tab=' ' # A newline character. nl=' ' # Character ranges might be problematic outside the C locale. # These definitions help. upper=ABCDEFGHIJKLMNOPQRSTUVWXYZ lower=abcdefghijklmnopqrstuvwxyz digits=0123456789 alpha=${upper}${lower} if test -z "$depmode" || test -z "$source" || test -z "$object"; then echo "depcomp: Variables source, object and depmode must be set" 1>&2 exit 1 fi # Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po. depfile=${depfile-`echo "$object" | sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`} tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`} rm -f "$tmpdepfile" # Avoid interferences from the environment. gccflag= dashmflag= # Some modes work just like other modes, but use different flags. We # parameterize here, but still list the modes in the big case below, # to make depend.m4 easier to write. Note that we *cannot* use a case # here, because this file can only contain one case statement. if test "$depmode" = hp; then # HP compiler uses -M and no extra arg. gccflag=-M depmode=gcc fi if test "$depmode" = dashXmstdout; then # This is just like dashmstdout with a different argument. dashmflag=-xM depmode=dashmstdout fi cygpath_u="cygpath -u -f -" if test "$depmode" = msvcmsys; then # This is just like msvisualcpp but w/o cygpath translation. # Just convert the backslash-escaped backslashes to single forward # slashes to satisfy depend.m4 cygpath_u='sed s,\\\\,/,g' depmode=msvisualcpp fi if test "$depmode" = msvc7msys; then # This is just like msvc7 but w/o cygpath translation. # Just convert the backslash-escaped backslashes to single forward # slashes to satisfy depend.m4 cygpath_u='sed s,\\\\,/,g' depmode=msvc7 fi if test "$depmode" = xlc; then # IBM C/C++ Compilers xlc/xlC can output gcc-like dependency information. gccflag=-qmakedep=gcc,-MF depmode=gcc fi case "$depmode" in gcc3) ## gcc 3 implements dependency tracking that does exactly what ## we want. Yay! Note: for some reason libtool 1.4 doesn't like ## it if -MD -MP comes after the -MF stuff. Hmm. ## Unfortunately, FreeBSD c89 acceptance of flags depends upon ## the command line argument order; so add the flags where they ## appear in depend2.am. Note that the slowdown incurred here ## affects only configure: in makefiles, %FASTDEP% shortcuts this. for arg do case $arg in -c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;; *) set fnord "$@" "$arg" ;; esac shift # fnord shift # $arg done "$@" stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi mv "$tmpdepfile" "$depfile" ;; gcc) ## Note that this doesn't just cater to obsosete pre-3.x GCC compilers. ## but also to in-use compilers like IMB xlc/xlC and the HP C compiler. ## (see the conditional assignment to $gccflag above). ## There are various ways to get dependency output from gcc. Here's ## why we pick this rather obscure method: ## - Don't want to use -MD because we'd like the dependencies to end ## up in a subdir. Having to rename by hand is ugly. ## (We might end up doing this anyway to support other compilers.) ## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like ## -MM, not -M (despite what the docs say). Also, it might not be ## supported by the other compilers which use the 'gcc' depmode. ## - Using -M directly means running the compiler twice (even worse ## than renaming). if test -z "$gccflag"; then gccflag=-MD, fi "$@" -Wp,"$gccflag$tmpdepfile" stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" echo "$object : \\" > "$depfile" # The second -e expression handles DOS-style file names with drive # letters. sed -e 's/^[^:]*: / /' \ -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile" ## This next piece of magic avoids the "deleted header file" problem. ## The problem is that when a header file which appears in a .P file ## is deleted, the dependency causes make to die (because there is ## typically no way to rebuild the header). We avoid this by adding ## dummy dependencies for each header file. Too bad gcc doesn't do ## this for us directly. ## Some versions of gcc put a space before the ':'. On the theory ## that the space means something, we add a space to the output as ## well. hp depmode also adds that space, but also prefixes the VPATH ## to the object. Take care to not repeat it in the output. ## Some versions of the HPUX 10.20 sed can't process this invocation ## correctly. Breaking it into two sed invocations is a workaround. tr ' ' "$nl" < "$tmpdepfile" \ | sed -e 's/^\\$//' -e '/^$/d' -e "s|.*$object$||" -e '/:$/d' \ | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; hp) # This case exists only to let depend.m4 do its work. It works by # looking at the text of this script. This case will never be run, # since it is checked for above. exit 1 ;; sgi) if test "$libtool" = yes; then "$@" "-Wp,-MDupdate,$tmpdepfile" else "$@" -MDupdate "$tmpdepfile" fi stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files echo "$object : \\" > "$depfile" # Clip off the initial element (the dependent). Don't try to be # clever and replace this with sed code, as IRIX sed won't handle # lines with more than a fixed number of characters (4096 in # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines; # the IRIX cc adds comments like '#:fec' to the end of the # dependency line. tr ' ' "$nl" < "$tmpdepfile" \ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' \ | tr "$nl" ' ' >> "$depfile" echo >> "$depfile" # The second pass generates a dummy entry for each header file. tr ' ' "$nl" < "$tmpdepfile" \ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ >> "$depfile" else make_dummy_depfile fi rm -f "$tmpdepfile" ;; xlc) # This case exists only to let depend.m4 do its work. It works by # looking at the text of this script. This case will never be run, # since it is checked for above. exit 1 ;; aix) # The C for AIX Compiler uses -M and outputs the dependencies # in a .u file. In older versions, this file always lives in the # current directory. Also, the AIX compiler puts '$object:' at the # start of each line; $object doesn't have directory information. # Version 6 uses the directory in both cases. set_dir_from "$object" set_base_from "$object" if test "$libtool" = yes; then tmpdepfile1=$dir$base.u tmpdepfile2=$base.u tmpdepfile3=$dir.libs/$base.u "$@" -Wc,-M else tmpdepfile1=$dir$base.u tmpdepfile2=$dir$base.u tmpdepfile3=$dir$base.u "$@" -M fi stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" exit $stat fi for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" do test -f "$tmpdepfile" && break done aix_post_process_depfile ;; tcc) # tcc (Tiny C Compiler) understand '-MD -MF file' since version 0.9.26 # FIXME: That version still under development at the moment of writing. # Make that this statement remains true also for stable, released # versions. # It will wrap lines (doesn't matter whether long or short) with a # trailing '\', as in: # # foo.o : \ # foo.c \ # foo.h \ # # It will put a trailing '\' even on the last line, and will use leading # spaces rather than leading tabs (at least since its commit 0394caf7 # "Emit spaces for -MD"). "$@" -MD -MF "$tmpdepfile" stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" # Each non-empty line is of the form 'foo.o : \' or ' dep.h \'. # We have to change lines of the first kind to '$object: \'. sed -e "s|.*:|$object :|" < "$tmpdepfile" > "$depfile" # And for each line of the second kind, we have to emit a 'dep.h:' # dummy dependency, to avoid the deleted-header problem. sed -n -e 's|^ *\(.*\) *\\$|\1:|p' < "$tmpdepfile" >> "$depfile" rm -f "$tmpdepfile" ;; ## The order of this option in the case statement is important, since the ## shell code in configure will try each of these formats in the order ## listed in this file. A plain '-MD' option would be understood by many ## compilers, so we must ensure this comes after the gcc and icc options. pgcc) # Portland's C compiler understands '-MD'. # Will always output deps to 'file.d' where file is the root name of the # source file under compilation, even if file resides in a subdirectory. # The object file name does not affect the name of the '.d' file. # pgcc 10.2 will output # foo.o: sub/foo.c sub/foo.h # and will wrap long lines using '\' : # foo.o: sub/foo.c ... \ # sub/foo.h ... \ # ... set_dir_from "$object" # Use the source, not the object, to determine the base name, since # that's sadly what pgcc will do too. set_base_from "$source" tmpdepfile=$base.d # For projects that build the same source file twice into different object # files, the pgcc approach of using the *source* file root name can cause # problems in parallel builds. Use a locking strategy to avoid stomping on # the same $tmpdepfile. lockdir=$base.d-lock trap " echo '$0: caught signal, cleaning up...' >&2 rmdir '$lockdir' exit 1 " 1 2 13 15 numtries=100 i=$numtries while test $i -gt 0; do # mkdir is a portable test-and-set. if mkdir "$lockdir" 2>/dev/null; then # This process acquired the lock. "$@" -MD stat=$? # Release the lock. rmdir "$lockdir" break else # If the lock is being held by a different process, wait # until the winning process is done or we timeout. while test -d "$lockdir" && test $i -gt 0; do sleep 1 i=`expr $i - 1` done fi i=`expr $i - 1` done trap - 1 2 13 15 if test $i -le 0; then echo "$0: failed to acquire lock after $numtries attempts" >&2 echo "$0: check lockdir '$lockdir'" >&2 exit 1 fi if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" # Each line is of the form `foo.o: dependent.h', # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'. # Do two passes, one to just change these to # `$object: dependent.h' and one to simply `dependent.h:'. sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile" # Some versions of the HPUX 10.20 sed can't process this invocation # correctly. Breaking it into two sed invocations is a workaround. sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" \ | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; hp2) # The "hp" stanza above does not work with aCC (C++) and HP's ia64 # compilers, which have integrated preprocessors. The correct option # to use with these is +Maked; it writes dependencies to a file named # 'foo.d', which lands next to the object file, wherever that # happens to be. # Much of this is similar to the tru64 case; see comments there. set_dir_from "$object" set_base_from "$object" if test "$libtool" = yes; then tmpdepfile1=$dir$base.d tmpdepfile2=$dir.libs/$base.d "$@" -Wc,+Maked else tmpdepfile1=$dir$base.d tmpdepfile2=$dir$base.d "$@" +Maked fi stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile1" "$tmpdepfile2" exit $stat fi for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" do test -f "$tmpdepfile" && break done if test -f "$tmpdepfile"; then sed -e "s,^.*\.[$lower]*:,$object:," "$tmpdepfile" > "$depfile" # Add 'dependent.h:' lines. sed -ne '2,${ s/^ *// s/ \\*$// s/$/:/ p }' "$tmpdepfile" >> "$depfile" else make_dummy_depfile fi rm -f "$tmpdepfile" "$tmpdepfile2" ;; tru64) # The Tru64 compiler uses -MD to generate dependencies as a side # effect. 'cc -MD -o foo.o ...' puts the dependencies into 'foo.o.d'. # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put # dependencies in 'foo.d' instead, so we check for that too. # Subdirectories are respected. set_dir_from "$object" set_base_from "$object" if test "$libtool" = yes; then # Libtool generates 2 separate objects for the 2 libraries. These # two compilations output dependencies in $dir.libs/$base.o.d and # in $dir$base.o.d. We have to check for both files, because # one of the two compilations can be disabled. We should prefer # $dir$base.o.d over $dir.libs/$base.o.d because the latter is # automatically cleaned when .libs/ is deleted, while ignoring # the former would cause a distcleancheck panic. tmpdepfile1=$dir$base.o.d # libtool 1.5 tmpdepfile2=$dir.libs/$base.o.d # Likewise. tmpdepfile3=$dir.libs/$base.d # Compaq CCC V6.2-504 "$@" -Wc,-MD else tmpdepfile1=$dir$base.d tmpdepfile2=$dir$base.d tmpdepfile3=$dir$base.d "$@" -MD fi stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" exit $stat fi for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" do test -f "$tmpdepfile" && break done # Same post-processing that is required for AIX mode. aix_post_process_depfile ;; msvc7) if test "$libtool" = yes; then showIncludes=-Wc,-showIncludes else showIncludes=-showIncludes fi "$@" $showIncludes > "$tmpdepfile" stat=$? grep -v '^Note: including file: ' "$tmpdepfile" if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" echo "$object : \\" > "$depfile" # The first sed program below extracts the file names and escapes # backslashes for cygpath. The second sed program outputs the file # name when reading, but also accumulates all include files in the # hold buffer in order to output them again at the end. This only # works with sed implementations that can handle large buffers. sed < "$tmpdepfile" -n ' /^Note: including file: *\(.*\)/ { s//\1/ s/\\/\\\\/g p }' | $cygpath_u | sort -u | sed -n ' s/ /\\ /g s/\(.*\)/'"$tab"'\1 \\/p s/.\(.*\) \\/\1:/ H $ { s/.*/'"$tab"'/ G p }' >> "$depfile" echo >> "$depfile" # make sure the fragment doesn't end with a backslash rm -f "$tmpdepfile" ;; msvc7msys) # This case exists only to let depend.m4 do its work. It works by # looking at the text of this script. This case will never be run, # since it is checked for above. exit 1 ;; #nosideeffect) # This comment above is used by automake to tell side-effect # dependency tracking mechanisms from slower ones. dashmstdout) # Important note: in order to support this mode, a compiler *must* # always write the preprocessed file to stdout, regardless of -o. "$@" || exit $? # Remove the call to Libtool. if test "$libtool" = yes; then while test "X$1" != 'X--mode=compile'; do shift done shift fi # Remove '-o $object'. IFS=" " for arg do case $arg in -o) shift ;; $object) shift ;; *) set fnord "$@" "$arg" shift # fnord shift # $arg ;; esac done test -z "$dashmflag" && dashmflag=-M # Require at least two characters before searching for ':' # in the target name. This is to cope with DOS-style filenames: # a dependency such as 'c:/foo/bar' could be seen as target 'c' otherwise. "$@" $dashmflag | sed "s|^[$tab ]*[^:$tab ][^:][^:]*:[$tab ]*|$object: |" > "$tmpdepfile" rm -f "$depfile" cat < "$tmpdepfile" > "$depfile" # Some versions of the HPUX 10.20 sed can't process this sed invocation # correctly. Breaking it into two sed invocations is a workaround. tr ' ' "$nl" < "$tmpdepfile" \ | sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \ | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; dashXmstdout) # This case only exists to satisfy depend.m4. It is never actually # run, as this mode is specially recognized in the preamble. exit 1 ;; makedepend) "$@" || exit $? # Remove any Libtool call if test "$libtool" = yes; then while test "X$1" != 'X--mode=compile'; do shift done shift fi # X makedepend shift cleared=no eat=no for arg do case $cleared in no) set ""; shift cleared=yes ;; esac if test $eat = yes; then eat=no continue fi case "$arg" in -D*|-I*) set fnord "$@" "$arg"; shift ;; # Strip any option that makedepend may not understand. Remove # the object too, otherwise makedepend will parse it as a source file. -arch) eat=yes ;; -*|$object) ;; *) set fnord "$@" "$arg"; shift ;; esac done obj_suffix=`echo "$object" | sed 's/^.*\././'` touch "$tmpdepfile" ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@" rm -f "$depfile" # makedepend may prepend the VPATH from the source file name to the object. # No need to regex-escape $object, excess matching of '.' is harmless. sed "s|^.*\($object *:\)|\1|" "$tmpdepfile" > "$depfile" # Some versions of the HPUX 10.20 sed can't process the last invocation # correctly. Breaking it into two sed invocations is a workaround. sed '1,2d' "$tmpdepfile" \ | tr ' ' "$nl" \ | sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \ | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" "$tmpdepfile".bak ;; cpp) # Important note: in order to support this mode, a compiler *must* # always write the preprocessed file to stdout. "$@" || exit $? # Remove the call to Libtool. if test "$libtool" = yes; then while test "X$1" != 'X--mode=compile'; do shift done shift fi # Remove '-o $object'. IFS=" " for arg do case $arg in -o) shift ;; $object) shift ;; *) set fnord "$@" "$arg" shift # fnord shift # $arg ;; esac done "$@" -E \ | sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ | sed '$ s: \\$::' > "$tmpdepfile" rm -f "$depfile" echo "$object : \\" > "$depfile" cat < "$tmpdepfile" >> "$depfile" sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; msvisualcpp) # Important note: in order to support this mode, a compiler *must* # always write the preprocessed file to stdout. "$@" || exit $? # Remove the call to Libtool. if test "$libtool" = yes; then while test "X$1" != 'X--mode=compile'; do shift done shift fi IFS=" " for arg do case "$arg" in -o) shift ;; $object) shift ;; "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI") set fnord "$@" shift shift ;; *) set fnord "$@" "$arg" shift shift ;; esac done "$@" -E 2>/dev/null | sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile" rm -f "$depfile" echo "$object : \\" > "$depfile" sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::'"$tab"'\1 \\:p' >> "$depfile" echo "$tab" >> "$depfile" sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile" rm -f "$tmpdepfile" ;; msvcmsys) # This case exists only to let depend.m4 do its work. It works by # looking at the text of this script. This case will never be run, # since it is checked for above. exit 1 ;; none) exec "$@" ;; *) echo "Unknown depmode $depmode" 1>&2 exit 1 ;; esac exit 0 # Local Variables: # mode: shell-script # sh-indentation: 2 # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC" # time-stamp-end: "; # UTC" # End: ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������libburn-1.4.2/bootstrap�����������������������������������������������������������������������������0000755�0001757�0001751�00000000267�12652644224�012063� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/bin/sh -x aclocal -I . libtoolize --copy --force autoconf # ts A61101 : libburn is not prepared for config.h # autoheader automake --foreign --add-missing --copy --include-deps �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������libburn-1.4.2/ltmain.sh�����������������������������������������������������������������������������0000644�0001757�0001751�00001052356�12652650101�011736� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ # libtool (GNU libtool) 2.4.2 # Written by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996 # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006, # 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc. # This is free software; see the source for copying conditions. There is NO # warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # GNU Libtool is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # As a special exception to the GNU General Public License, # if you distribute this file as part of a program or library that # is built using GNU Libtool, you may include this file under the # same distribution terms that you use for the rest of that program. # # GNU Libtool is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with GNU Libtool; see the file COPYING. If not, a copy # can be downloaded from http://www.gnu.org/licenses/gpl.html, # or obtained by writing to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # Usage: $progname [OPTION]... [MODE-ARG]... # # Provide generalized library-building support services. # # --config show all configuration variables # --debug enable verbose shell tracing # -n, --dry-run display commands without modifying any files # --features display basic configuration information and exit # --mode=MODE use operation mode MODE # --preserve-dup-deps don't remove duplicate dependency libraries # --quiet, --silent don't print informational messages # --no-quiet, --no-silent # print informational messages (default) # --no-warn don't display warning messages # --tag=TAG use configuration variables from tag TAG # -v, --verbose print more informational messages than default # --no-verbose don't print the extra informational messages # --version print version information # -h, --help, --help-all print short, long, or detailed help message # # MODE must be one of the following: # # clean remove files from the build directory # compile compile a source file into a libtool object # execute automatically set library path, then run a program # finish complete the installation of libtool libraries # install install libraries or executables # link create a library or an executable # uninstall remove libraries from an installed directory # # MODE-ARGS vary depending on the MODE. When passed as first option, # `--mode=MODE' may be abbreviated as `MODE' or a unique abbreviation of that. # Try `$progname --help --mode=MODE' for a more detailed description of MODE. # # When reporting a bug, please describe a test case to reproduce it and # include the following information: # # host-triplet: $host # shell: $SHELL # compiler: $LTCC # compiler flags: $LTCFLAGS # linker: $LD (gnu? $with_gnu_ld) # $progname: (GNU libtool) 2.4.2 Debian-2.4.2-1.11 # automake: $automake_version # autoconf: $autoconf_version # # Report bugs to <bug-libtool@gnu.org>. # GNU libtool home page: <http://www.gnu.org/software/libtool/>. # General help using GNU software: <http://www.gnu.org/gethelp/>. PROGRAM=libtool PACKAGE=libtool VERSION="2.4.2 Debian-2.4.2-1.11" TIMESTAMP="" package_revision=1.3337 # Be Bourne compatible if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac fi BIN_SH=xpg4; export BIN_SH # for Tru64 DUALCASE=1; export DUALCASE # for MKS sh # A function that is used when there is no print builtin or printf. func_fallback_echo () { eval 'cat <<_LTECHO_EOF $1 _LTECHO_EOF' } # NLS nuisances: We save the old values to restore during execute mode. lt_user_locale= lt_safe_locale= for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES do eval "if test \"\${$lt_var+set}\" = set; then save_$lt_var=\$$lt_var $lt_var=C export $lt_var lt_user_locale=\"$lt_var=\\\$save_\$lt_var; \$lt_user_locale\" lt_safe_locale=\"$lt_var=C; \$lt_safe_locale\" fi" done LC_ALL=C LANGUAGE=C export LANGUAGE LC_ALL $lt_unset CDPATH # Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh # is ksh but when the shell is invoked as "sh" and the current value of # the _XPG environment variable is not equal to 1 (one), the special # positional parameter $0, within a function call, is the name of the # function. progpath="$0" : ${CP="cp -f"} test "${ECHO+set}" = set || ECHO=${as_echo-'printf %s\n'} : ${MAKE="make"} : ${MKDIR="mkdir"} : ${MV="mv -f"} : ${RM="rm -f"} : ${SHELL="${CONFIG_SHELL-/bin/sh}"} : ${Xsed="$SED -e 1s/^X//"} # Global variables: EXIT_SUCCESS=0 EXIT_FAILURE=1 EXIT_MISMATCH=63 # $? = 63 is used to indicate version mismatch to missing. EXIT_SKIP=77 # $? = 77 is used to indicate a skipped test to automake. exit_status=$EXIT_SUCCESS # Make sure IFS has a sensible default lt_nl=' ' IFS=" $lt_nl" dirname="s,/[^/]*$,," basename="s,^.*/,," # func_dirname file append nondir_replacement # Compute the dirname of FILE. If nonempty, add APPEND to the result, # otherwise set result to NONDIR_REPLACEMENT. func_dirname () { func_dirname_result=`$ECHO "${1}" | $SED "$dirname"` if test "X$func_dirname_result" = "X${1}"; then func_dirname_result="${3}" else func_dirname_result="$func_dirname_result${2}" fi } # func_dirname may be replaced by extended shell implementation # func_basename file func_basename () { func_basename_result=`$ECHO "${1}" | $SED "$basename"` } # func_basename may be replaced by extended shell implementation # func_dirname_and_basename file append nondir_replacement # perform func_basename and func_dirname in a single function # call: # dirname: Compute the dirname of FILE. If nonempty, # add APPEND to the result, otherwise set result # to NONDIR_REPLACEMENT. # value returned in "$func_dirname_result" # basename: Compute filename of FILE. # value retuned in "$func_basename_result" # Implementation must be kept synchronized with func_dirname # and func_basename. For efficiency, we do not delegate to # those functions but instead duplicate the functionality here. func_dirname_and_basename () { # Extract subdirectory from the argument. func_dirname_result=`$ECHO "${1}" | $SED -e "$dirname"` if test "X$func_dirname_result" = "X${1}"; then func_dirname_result="${3}" else func_dirname_result="$func_dirname_result${2}" fi func_basename_result=`$ECHO "${1}" | $SED -e "$basename"` } # func_dirname_and_basename may be replaced by extended shell implementation # func_stripname prefix suffix name # strip PREFIX and SUFFIX off of NAME. # PREFIX and SUFFIX must not contain globbing or regex special # characters, hashes, percent signs, but SUFFIX may contain a leading # dot (in which case that matches only a dot). # func_strip_suffix prefix name func_stripname () { case ${2} in .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;; *) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;; esac } # func_stripname may be replaced by extended shell implementation # These SED scripts presuppose an absolute path with a trailing slash. pathcar='s,^/\([^/]*\).*$,\1,' pathcdr='s,^/[^/]*,,' removedotparts=':dotsl s@/\./@/@g t dotsl s,/\.$,/,' collapseslashes='s@/\{1,\}@/@g' finalslash='s,/*$,/,' # func_normal_abspath PATH # Remove doubled-up and trailing slashes, "." path components, # and cancel out any ".." path components in PATH after making # it an absolute path. # value returned in "$func_normal_abspath_result" func_normal_abspath () { # Start from root dir and reassemble the path. func_normal_abspath_result= func_normal_abspath_tpath=$1 func_normal_abspath_altnamespace= case $func_normal_abspath_tpath in "") # Empty path, that just means $cwd. func_stripname '' '/' "`pwd`" func_normal_abspath_result=$func_stripname_result return ;; # The next three entries are used to spot a run of precisely # two leading slashes without using negated character classes; # we take advantage of case's first-match behaviour. ///*) # Unusual form of absolute path, do nothing. ;; //*) # Not necessarily an ordinary path; POSIX reserves leading '//' # and for example Cygwin uses it to access remote file shares # over CIFS/SMB, so we conserve a leading double slash if found. func_normal_abspath_altnamespace=/ ;; /*) # Absolute path, do nothing. ;; *) # Relative path, prepend $cwd. func_normal_abspath_tpath=`pwd`/$func_normal_abspath_tpath ;; esac # Cancel out all the simple stuff to save iterations. We also want # the path to end with a slash for ease of parsing, so make sure # there is one (and only one) here. func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \ -e "$removedotparts" -e "$collapseslashes" -e "$finalslash"` while :; do # Processed it all yet? if test "$func_normal_abspath_tpath" = / ; then # If we ascended to the root using ".." the result may be empty now. if test -z "$func_normal_abspath_result" ; then func_normal_abspath_result=/ fi break fi func_normal_abspath_tcomponent=`$ECHO "$func_normal_abspath_tpath" | $SED \ -e "$pathcar"` func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \ -e "$pathcdr"` # Figure out what to do with it case $func_normal_abspath_tcomponent in "") # Trailing empty path component, ignore it. ;; ..) # Parent dir; strip last assembled component from result. func_dirname "$func_normal_abspath_result" func_normal_abspath_result=$func_dirname_result ;; *) # Actual path component, append it. func_normal_abspath_result=$func_normal_abspath_result/$func_normal_abspath_tcomponent ;; esac done # Restore leading double-slash if one was found on entry. func_normal_abspath_result=$func_normal_abspath_altnamespace$func_normal_abspath_result } # func_relative_path SRCDIR DSTDIR # generates a relative path from SRCDIR to DSTDIR, with a trailing # slash if non-empty, suitable for immediately appending a filename # without needing to append a separator. # value returned in "$func_relative_path_result" func_relative_path () { func_relative_path_result= func_normal_abspath "$1" func_relative_path_tlibdir=$func_normal_abspath_result func_normal_abspath "$2" func_relative_path_tbindir=$func_normal_abspath_result # Ascend the tree starting from libdir while :; do # check if we have found a prefix of bindir case $func_relative_path_tbindir in $func_relative_path_tlibdir) # found an exact match func_relative_path_tcancelled= break ;; $func_relative_path_tlibdir*) # found a matching prefix func_stripname "$func_relative_path_tlibdir" '' "$func_relative_path_tbindir" func_relative_path_tcancelled=$func_stripname_result if test -z "$func_relative_path_result"; then func_relative_path_result=. fi break ;; *) func_dirname $func_relative_path_tlibdir func_relative_path_tlibdir=${func_dirname_result} if test "x$func_relative_path_tlibdir" = x ; then # Have to descend all the way to the root! func_relative_path_result=../$func_relative_path_result func_relative_path_tcancelled=$func_relative_path_tbindir break fi func_relative_path_result=../$func_relative_path_result ;; esac done # Now calculate path; take care to avoid doubling-up slashes. func_stripname '' '/' "$func_relative_path_result" func_relative_path_result=$func_stripname_result func_stripname '/' '/' "$func_relative_path_tcancelled" if test "x$func_stripname_result" != x ; then func_relative_path_result=${func_relative_path_result}/${func_stripname_result} fi # Normalisation. If bindir is libdir, return empty string, # else relative path ending with a slash; either way, target # file name can be directly appended. if test ! -z "$func_relative_path_result"; then func_stripname './' '' "$func_relative_path_result/" func_relative_path_result=$func_stripname_result fi } # The name of this program: func_dirname_and_basename "$progpath" progname=$func_basename_result # Make sure we have an absolute path for reexecution: case $progpath in [\\/]*|[A-Za-z]:\\*) ;; *[\\/]*) progdir=$func_dirname_result progdir=`cd "$progdir" && pwd` progpath="$progdir/$progname" ;; *) save_IFS="$IFS" IFS=${PATH_SEPARATOR-:} for progdir in $PATH; do IFS="$save_IFS" test -x "$progdir/$progname" && break done IFS="$save_IFS" test -n "$progdir" || progdir=`pwd` progpath="$progdir/$progname" ;; esac # Sed substitution that helps us do robust quoting. It backslashifies # metacharacters that are still active within double-quoted strings. Xsed="${SED}"' -e 1s/^X//' sed_quote_subst='s/\([`"$\\]\)/\\\1/g' # Same as above, but do not quote variable references. double_quote_subst='s/\(["`\\]\)/\\\1/g' # Sed substitution that turns a string into a regex matching for the # string literally. sed_make_literal_regex='s,[].[^$\\*\/],\\&,g' # Sed substitution that converts a w32 file name or path # which contains forward slashes, into one that contains # (escaped) backslashes. A very naive implementation. lt_sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g' # Re-`\' parameter expansions in output of double_quote_subst that were # `\'-ed in input to the same. If an odd number of `\' preceded a '$' # in input to double_quote_subst, that '$' was protected from expansion. # Since each input `\' is now two `\'s, look for any number of runs of # four `\'s followed by two `\'s and then a '$'. `\' that '$'. bs='\\' bs2='\\\\' bs4='\\\\\\\\' dollar='\$' sed_double_backslash="\ s/$bs4/&\\ /g s/^$bs2$dollar/$bs&/ s/\\([^$bs]\\)$bs2$dollar/\\1$bs2$bs$dollar/g s/\n//g" # Standard options: opt_dry_run=false opt_help=false opt_quiet=false opt_verbose=false opt_warning=: # func_echo arg... # Echo program name prefixed message, along with the current mode # name if it has been set yet. func_echo () { $ECHO "$progname: ${opt_mode+$opt_mode: }$*" } # func_verbose arg... # Echo program name prefixed message in verbose mode only. func_verbose () { $opt_verbose && func_echo ${1+"$@"} # A bug in bash halts the script if the last line of a function # fails when set -e is in force, so we need another command to # work around that: : } # func_echo_all arg... # Invoke $ECHO with all args, space-separated. func_echo_all () { $ECHO "$*" } # func_error arg... # Echo program name prefixed message to standard error. func_error () { $ECHO "$progname: ${opt_mode+$opt_mode: }"${1+"$@"} 1>&2 } # func_warning arg... # Echo program name prefixed warning message to standard error. func_warning () { $opt_warning && $ECHO "$progname: ${opt_mode+$opt_mode: }warning: "${1+"$@"} 1>&2 # bash bug again: : } # func_fatal_error arg... # Echo program name prefixed message to standard error, and exit. func_fatal_error () { func_error ${1+"$@"} exit $EXIT_FAILURE } # func_fatal_help arg... # Echo program name prefixed message to standard error, followed by # a help hint, and exit. func_fatal_help () { func_error ${1+"$@"} func_fatal_error "$help" } help="Try \`$progname --help' for more information." ## default # func_grep expression filename # Check whether EXPRESSION matches any line of FILENAME, without output. func_grep () { $GREP "$1" "$2" >/dev/null 2>&1 } # func_mkdir_p directory-path # Make sure the entire path to DIRECTORY-PATH is available. func_mkdir_p () { my_directory_path="$1" my_dir_list= if test -n "$my_directory_path" && test "$opt_dry_run" != ":"; then # Protect directory names starting with `-' case $my_directory_path in -*) my_directory_path="./$my_directory_path" ;; esac # While some portion of DIR does not yet exist... while test ! -d "$my_directory_path"; do # ...make a list in topmost first order. Use a colon delimited # list incase some portion of path contains whitespace. my_dir_list="$my_directory_path:$my_dir_list" # If the last portion added has no slash in it, the list is done case $my_directory_path in */*) ;; *) break ;; esac # ...otherwise throw away the child directory and loop my_directory_path=`$ECHO "$my_directory_path" | $SED -e "$dirname"` done my_dir_list=`$ECHO "$my_dir_list" | $SED 's,:*$,,'` save_mkdir_p_IFS="$IFS"; IFS=':' for my_dir in $my_dir_list; do IFS="$save_mkdir_p_IFS" # mkdir can fail with a `File exist' error if two processes # try to create one of the directories concurrently. Don't # stop in that case! $MKDIR "$my_dir" 2>/dev/null || : done IFS="$save_mkdir_p_IFS" # Bail out if we (or some other process) failed to create a directory. test -d "$my_directory_path" || \ func_fatal_error "Failed to create \`$1'" fi } # func_mktempdir [string] # Make a temporary directory that won't clash with other running # libtool processes, and avoids race conditions if possible. If # given, STRING is the basename for that directory. func_mktempdir () { my_template="${TMPDIR-/tmp}/${1-$progname}" if test "$opt_dry_run" = ":"; then # Return a directory name, but don't create it in dry-run mode my_tmpdir="${my_template}-$$" else # If mktemp works, use that first and foremost my_tmpdir=`mktemp -d "${my_template}-XXXXXXXX" 2>/dev/null` if test ! -d "$my_tmpdir"; then # Failing that, at least try and use $RANDOM to avoid a race my_tmpdir="${my_template}-${RANDOM-0}$$" save_mktempdir_umask=`umask` umask 0077 $MKDIR "$my_tmpdir" umask $save_mktempdir_umask fi # If we're not in dry-run mode, bomb out on failure test -d "$my_tmpdir" || \ func_fatal_error "cannot create temporary directory \`$my_tmpdir'" fi $ECHO "$my_tmpdir" } # func_quote_for_eval arg # Aesthetically quote ARG to be evaled later. # This function returns two values: FUNC_QUOTE_FOR_EVAL_RESULT # is double-quoted, suitable for a subsequent eval, whereas # FUNC_QUOTE_FOR_EVAL_UNQUOTED_RESULT has merely all characters # which are still active within double quotes backslashified. func_quote_for_eval () { case $1 in *[\\\`\"\$]*) func_quote_for_eval_unquoted_result=`$ECHO "$1" | $SED "$sed_quote_subst"` ;; *) func_quote_for_eval_unquoted_result="$1" ;; esac case $func_quote_for_eval_unquoted_result in # Double-quote args containing shell metacharacters to delay # word splitting, command substitution and and variable # expansion for a subsequent eval. # Many Bourne shells cannot handle close brackets correctly # in scan sets, so we specify it separately. *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") func_quote_for_eval_result="\"$func_quote_for_eval_unquoted_result\"" ;; *) func_quote_for_eval_result="$func_quote_for_eval_unquoted_result" esac } # func_quote_for_expand arg # Aesthetically quote ARG to be evaled later; same as above, # but do not quote variable references. func_quote_for_expand () { case $1 in *[\\\`\"]*) my_arg=`$ECHO "$1" | $SED \ -e "$double_quote_subst" -e "$sed_double_backslash"` ;; *) my_arg="$1" ;; esac case $my_arg in # Double-quote args containing shell metacharacters to delay # word splitting and command substitution for a subsequent eval. # Many Bourne shells cannot handle close brackets correctly # in scan sets, so we specify it separately. *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") my_arg="\"$my_arg\"" ;; esac func_quote_for_expand_result="$my_arg" } # func_show_eval cmd [fail_exp] # Unless opt_silent is true, then output CMD. Then, if opt_dryrun is # not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP # is given, then evaluate it. func_show_eval () { my_cmd="$1" my_fail_exp="${2-:}" ${opt_silent-false} || { func_quote_for_expand "$my_cmd" eval "func_echo $func_quote_for_expand_result" } if ${opt_dry_run-false}; then :; else eval "$my_cmd" my_status=$? if test "$my_status" -eq 0; then :; else eval "(exit $my_status); $my_fail_exp" fi fi } # func_show_eval_locale cmd [fail_exp] # Unless opt_silent is true, then output CMD. Then, if opt_dryrun is # not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP # is given, then evaluate it. Use the saved locale for evaluation. func_show_eval_locale () { my_cmd="$1" my_fail_exp="${2-:}" ${opt_silent-false} || { func_quote_for_expand "$my_cmd" eval "func_echo $func_quote_for_expand_result" } if ${opt_dry_run-false}; then :; else eval "$lt_user_locale $my_cmd" my_status=$? eval "$lt_safe_locale" if test "$my_status" -eq 0; then :; else eval "(exit $my_status); $my_fail_exp" fi fi } # func_tr_sh # Turn $1 into a string suitable for a shell variable name. # Result is stored in $func_tr_sh_result. All characters # not in the set a-zA-Z0-9_ are replaced with '_'. Further, # if $1 begins with a digit, a '_' is prepended as well. func_tr_sh () { case $1 in [0-9]* | *[!a-zA-Z0-9_]*) func_tr_sh_result=`$ECHO "$1" | $SED 's/^\([0-9]\)/_\1/; s/[^a-zA-Z0-9_]/_/g'` ;; * ) func_tr_sh_result=$1 ;; esac } # func_version # Echo version message to standard output and exit. func_version () { $opt_debug $SED -n '/(C)/!b go :more /\./!{ N s/\n# / / b more } :go /^# '$PROGRAM' (GNU /,/# warranty; / { s/^# // s/^# *$// s/\((C)\)[ 0-9,-]*\( [1-9][0-9]*\)/\1\2/ p }' < "$progpath" exit $? } # func_usage # Echo short help message to standard output and exit. func_usage () { $opt_debug $SED -n '/^# Usage:/,/^# *.*--help/ { s/^# // s/^# *$// s/\$progname/'$progname'/ p }' < "$progpath" echo $ECHO "run \`$progname --help | more' for full usage" exit $? } # func_help [NOEXIT] # Echo long help message to standard output and exit, # unless 'noexit' is passed as argument. func_help () { $opt_debug $SED -n '/^# Usage:/,/# Report bugs to/ { :print s/^# // s/^# *$// s*\$progname*'$progname'* s*\$host*'"$host"'* s*\$SHELL*'"$SHELL"'* s*\$LTCC*'"$LTCC"'* s*\$LTCFLAGS*'"$LTCFLAGS"'* s*\$LD*'"$LD"'* s/\$with_gnu_ld/'"$with_gnu_ld"'/ s/\$automake_version/'"`(${AUTOMAKE-automake} --version) 2>/dev/null |$SED 1q`"'/ s/\$autoconf_version/'"`(${AUTOCONF-autoconf} --version) 2>/dev/null |$SED 1q`"'/ p d } /^# .* home page:/b print /^# General help using/b print ' < "$progpath" ret=$? if test -z "$1"; then exit $ret fi } # func_missing_arg argname # Echo program name prefixed message to standard error and set global # exit_cmd. func_missing_arg () { $opt_debug func_error "missing argument for $1." exit_cmd=exit } # func_split_short_opt shortopt # Set func_split_short_opt_name and func_split_short_opt_arg shell # variables after splitting SHORTOPT after the 2nd character. func_split_short_opt () { my_sed_short_opt='1s/^\(..\).*$/\1/;q' my_sed_short_rest='1s/^..\(.*\)$/\1/;q' func_split_short_opt_name=`$ECHO "$1" | $SED "$my_sed_short_opt"` func_split_short_opt_arg=`$ECHO "$1" | $SED "$my_sed_short_rest"` } # func_split_short_opt may be replaced by extended shell implementation # func_split_long_opt longopt # Set func_split_long_opt_name and func_split_long_opt_arg shell # variables after splitting LONGOPT at the `=' sign. func_split_long_opt () { my_sed_long_opt='1s/^\(--[^=]*\)=.*/\1/;q' my_sed_long_arg='1s/^--[^=]*=//' func_split_long_opt_name=`$ECHO "$1" | $SED "$my_sed_long_opt"` func_split_long_opt_arg=`$ECHO "$1" | $SED "$my_sed_long_arg"` } # func_split_long_opt may be replaced by extended shell implementation exit_cmd=: magic="%%%MAGIC variable%%%" magic_exe="%%%MAGIC EXE variable%%%" # Global variables. nonopt= preserve_args= lo2o="s/\\.lo\$/.${objext}/" o2lo="s/\\.${objext}\$/.lo/" extracted_archives= extracted_serial=0 # If this variable is set in any of the actions, the command in it # will be execed at the end. This prevents here-documents from being # left over by shells. exec_cmd= # func_append var value # Append VALUE to the end of shell variable VAR. func_append () { eval "${1}=\$${1}\${2}" } # func_append may be replaced by extended shell implementation # func_append_quoted var value # Quote VALUE and append to the end of shell variable VAR, separated # by a space. func_append_quoted () { func_quote_for_eval "${2}" eval "${1}=\$${1}\\ \$func_quote_for_eval_result" } # func_append_quoted may be replaced by extended shell implementation # func_arith arithmetic-term... func_arith () { func_arith_result=`expr "${@}"` } # func_arith may be replaced by extended shell implementation # func_len string # STRING may not start with a hyphen. func_len () { func_len_result=`expr "${1}" : ".*" 2>/dev/null || echo $max_cmd_len` } # func_len may be replaced by extended shell implementation # func_lo2o object func_lo2o () { func_lo2o_result=`$ECHO "${1}" | $SED "$lo2o"` } # func_lo2o may be replaced by extended shell implementation # func_xform libobj-or-source func_xform () { func_xform_result=`$ECHO "${1}" | $SED 's/\.[^.]*$/.lo/'` } # func_xform may be replaced by extended shell implementation # func_fatal_configuration arg... # Echo program name prefixed message to standard error, followed by # a configuration failure hint, and exit. func_fatal_configuration () { func_error ${1+"$@"} func_error "See the $PACKAGE documentation for more information." func_fatal_error "Fatal configuration error." } # func_config # Display the configuration for all the tags in this script. func_config () { re_begincf='^# ### BEGIN LIBTOOL' re_endcf='^# ### END LIBTOOL' # Default configuration. $SED "1,/$re_begincf CONFIG/d;/$re_endcf CONFIG/,\$d" < "$progpath" # Now print the configurations for the tags. for tagname in $taglist; do $SED -n "/$re_begincf TAG CONFIG: $tagname\$/,/$re_endcf TAG CONFIG: $tagname\$/p" < "$progpath" done exit $? } # func_features # Display the features supported by this script. func_features () { echo "host: $host" if test "$build_libtool_libs" = yes; then echo "enable shared libraries" else echo "disable shared libraries" fi if test "$build_old_libs" = yes; then echo "enable static libraries" else echo "disable static libraries" fi exit $? } # func_enable_tag tagname # Verify that TAGNAME is valid, and either flag an error and exit, or # enable the TAGNAME tag. We also add TAGNAME to the global $taglist # variable here. func_enable_tag () { # Global variable: tagname="$1" re_begincf="^# ### BEGIN LIBTOOL TAG CONFIG: $tagname\$" re_endcf="^# ### END LIBTOOL TAG CONFIG: $tagname\$" sed_extractcf="/$re_begincf/,/$re_endcf/p" # Validate tagname. case $tagname in *[!-_A-Za-z0-9,/]*) func_fatal_error "invalid tag name: $tagname" ;; esac # Don't test for the "default" C tag, as we know it's # there but not specially marked. case $tagname in CC) ;; *) if $GREP "$re_begincf" "$progpath" >/dev/null 2>&1; then taglist="$taglist $tagname" # Evaluate the configuration. Be careful to quote the path # and the sed script, to avoid splitting on whitespace, but # also don't use non-portable quotes within backquotes within # quotes we have to do it in 2 steps: extractedcf=`$SED -n -e "$sed_extractcf" < "$progpath"` eval "$extractedcf" else func_error "ignoring unknown tag $tagname" fi ;; esac } # func_check_version_match # Ensure that we are using m4 macros, and libtool script from the same # release of libtool. func_check_version_match () { if test "$package_revision" != "$macro_revision"; then if test "$VERSION" != "$macro_version"; then if test -z "$macro_version"; then cat >&2 <<_LT_EOF $progname: Version mismatch error. This is $PACKAGE $VERSION, but the $progname: definition of this LT_INIT comes from an older release. $progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION $progname: and run autoconf again. _LT_EOF else cat >&2 <<_LT_EOF $progname: Version mismatch error. This is $PACKAGE $VERSION, but the $progname: definition of this LT_INIT comes from $PACKAGE $macro_version. $progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION $progname: and run autoconf again. _LT_EOF fi else cat >&2 <<_LT_EOF $progname: Version mismatch error. This is $PACKAGE $VERSION, revision $package_revision, $progname: but the definition of this LT_INIT comes from revision $macro_revision. $progname: You should recreate aclocal.m4 with macros from revision $package_revision $progname: of $PACKAGE $VERSION and run autoconf again. _LT_EOF fi exit $EXIT_MISMATCH fi } # Shorthand for --mode=foo, only valid as the first argument case $1 in clean|clea|cle|cl) shift; set dummy --mode clean ${1+"$@"}; shift ;; compile|compil|compi|comp|com|co|c) shift; set dummy --mode compile ${1+"$@"}; shift ;; execute|execut|execu|exec|exe|ex|e) shift; set dummy --mode execute ${1+"$@"}; shift ;; finish|finis|fini|fin|fi|f) shift; set dummy --mode finish ${1+"$@"}; shift ;; install|instal|insta|inst|ins|in|i) shift; set dummy --mode install ${1+"$@"}; shift ;; link|lin|li|l) shift; set dummy --mode link ${1+"$@"}; shift ;; uninstall|uninstal|uninsta|uninst|unins|unin|uni|un|u) shift; set dummy --mode uninstall ${1+"$@"}; shift ;; esac # Option defaults: opt_debug=: opt_dry_run=false opt_config=false opt_preserve_dup_deps=false opt_features=false opt_finish=false opt_help=false opt_help_all=false opt_silent=: opt_warning=: opt_verbose=: opt_silent=false opt_verbose=false # Parse options once, thoroughly. This comes as soon as possible in the # script to make things like `--version' happen as quickly as we can. { # this just eases exit handling while test $# -gt 0; do opt="$1" shift case $opt in --debug|-x) opt_debug='set -x' func_echo "enabling shell trace mode" $opt_debug ;; --dry-run|--dryrun|-n) opt_dry_run=: ;; --config) opt_config=: func_config ;; --dlopen|-dlopen) optarg="$1" opt_dlopen="${opt_dlopen+$opt_dlopen }$optarg" shift ;; --preserve-dup-deps) opt_preserve_dup_deps=: ;; --features) opt_features=: func_features ;; --finish) opt_finish=: set dummy --mode finish ${1+"$@"}; shift ;; --help) opt_help=: ;; --help-all) opt_help_all=: opt_help=': help-all' ;; --mode) test $# = 0 && func_missing_arg $opt && break optarg="$1" opt_mode="$optarg" case $optarg in # Valid mode arguments: clean|compile|execute|finish|install|link|relink|uninstall) ;; # Catch anything else as an error *) func_error "invalid argument for $opt" exit_cmd=exit break ;; esac shift ;; --no-silent|--no-quiet) opt_silent=false func_append preserve_args " $opt" ;; --no-warning|--no-warn) opt_warning=false func_append preserve_args " $opt" ;; --no-verbose) opt_verbose=false func_append preserve_args " $opt" ;; --silent|--quiet) opt_silent=: func_append preserve_args " $opt" opt_verbose=false ;; --verbose|-v) opt_verbose=: func_append preserve_args " $opt" opt_silent=false ;; --tag) test $# = 0 && func_missing_arg $opt && break optarg="$1" opt_tag="$optarg" func_append preserve_args " $opt $optarg" func_enable_tag "$optarg" shift ;; -\?|-h) func_usage ;; --help) func_help ;; --version) func_version ;; # Separate optargs to long options: --*=*) func_split_long_opt "$opt" set dummy "$func_split_long_opt_name" "$func_split_long_opt_arg" ${1+"$@"} shift ;; # Separate non-argument short options: -\?*|-h*|-n*|-v*) func_split_short_opt "$opt" set dummy "$func_split_short_opt_name" "-$func_split_short_opt_arg" ${1+"$@"} shift ;; --) break ;; -*) func_fatal_help "unrecognized option \`$opt'" ;; *) set dummy "$opt" ${1+"$@"}; shift; break ;; esac done # Validate options: # save first non-option argument if test "$#" -gt 0; then nonopt="$opt" shift fi # preserve --debug test "$opt_debug" = : || func_append preserve_args " --debug" case $host in *cygwin* | *mingw* | *pw32* | *cegcc*) # don't eliminate duplications in $postdeps and $predeps opt_duplicate_compiler_generated_deps=: ;; *) opt_duplicate_compiler_generated_deps=$opt_preserve_dup_deps ;; esac $opt_help || { # Sanity checks first: func_check_version_match if test "$build_libtool_libs" != yes && test "$build_old_libs" != yes; then func_fatal_configuration "not configured to build any kind of library" fi # Darwin sucks eval std_shrext=\"$shrext_cmds\" # Only execute mode is allowed to have -dlopen flags. if test -n "$opt_dlopen" && test "$opt_mode" != execute; then func_error "unrecognized option \`-dlopen'" $ECHO "$help" 1>&2 exit $EXIT_FAILURE fi # Change the help message to a mode-specific one. generic_help="$help" help="Try \`$progname --help --mode=$opt_mode' for more information." } # Bail if the options were screwed $exit_cmd $EXIT_FAILURE } ## ----------- ## ## Main. ## ## ----------- ## # func_lalib_p file # True iff FILE is a libtool `.la' library or `.lo' object file. # This function is only a basic sanity check; it will hardly flush out # determined imposters. func_lalib_p () { test -f "$1" && $SED -e 4q "$1" 2>/dev/null \ | $GREP "^# Generated by .*$PACKAGE" > /dev/null 2>&1 } # func_lalib_unsafe_p file # True iff FILE is a libtool `.la' library or `.lo' object file. # This function implements the same check as func_lalib_p without # resorting to external programs. To this end, it redirects stdin and # closes it afterwards, without saving the original file descriptor. # As a safety measure, use it only where a negative result would be # fatal anyway. Works if `file' does not exist. func_lalib_unsafe_p () { lalib_p=no if test -f "$1" && test -r "$1" && exec 5<&0 <"$1"; then for lalib_p_l in 1 2 3 4 do read lalib_p_line case "$lalib_p_line" in \#\ Generated\ by\ *$PACKAGE* ) lalib_p=yes; break;; esac done exec 0<&5 5<&- fi test "$lalib_p" = yes } # func_ltwrapper_script_p file # True iff FILE is a libtool wrapper script # This function is only a basic sanity check; it will hardly flush out # determined imposters. func_ltwrapper_script_p () { func_lalib_p "$1" } # func_ltwrapper_executable_p file # True iff FILE is a libtool wrapper executable # This function is only a basic sanity check; it will hardly flush out # determined imposters. func_ltwrapper_executable_p () { func_ltwrapper_exec_suffix= case $1 in *.exe) ;; *) func_ltwrapper_exec_suffix=.exe ;; esac $GREP "$magic_exe" "$1$func_ltwrapper_exec_suffix" >/dev/null 2>&1 } # func_ltwrapper_scriptname file # Assumes file is an ltwrapper_executable # uses $file to determine the appropriate filename for a # temporary ltwrapper_script. func_ltwrapper_scriptname () { func_dirname_and_basename "$1" "" "." func_stripname '' '.exe' "$func_basename_result" func_ltwrapper_scriptname_result="$func_dirname_result/$objdir/${func_stripname_result}_ltshwrapper" } # func_ltwrapper_p file # True iff FILE is a libtool wrapper script or wrapper executable # This function is only a basic sanity check; it will hardly flush out # determined imposters. func_ltwrapper_p () { func_ltwrapper_script_p "$1" || func_ltwrapper_executable_p "$1" } # func_execute_cmds commands fail_cmd # Execute tilde-delimited COMMANDS. # If FAIL_CMD is given, eval that upon failure. # FAIL_CMD may read-access the current command in variable CMD! func_execute_cmds () { $opt_debug save_ifs=$IFS; IFS='~' for cmd in $1; do IFS=$save_ifs eval cmd=\"$cmd\" func_show_eval "$cmd" "${2-:}" done IFS=$save_ifs } # func_source file # Source FILE, adding directory component if necessary. # Note that it is not necessary on cygwin/mingw to append a dot to # FILE even if both FILE and FILE.exe exist: automatic-append-.exe # behavior happens only for exec(3), not for open(2)! Also, sourcing # `FILE.' does not work on cygwin managed mounts. func_source () { $opt_debug case $1 in */* | *\\*) . "$1" ;; *) . "./$1" ;; esac } # func_resolve_sysroot PATH # Replace a leading = in PATH with a sysroot. Store the result into # func_resolve_sysroot_result func_resolve_sysroot () { func_resolve_sysroot_result=$1 case $func_resolve_sysroot_result in =*) func_stripname '=' '' "$func_resolve_sysroot_result" func_resolve_sysroot_result=$lt_sysroot$func_stripname_result ;; esac } # func_replace_sysroot PATH # If PATH begins with the sysroot, replace it with = and # store the result into func_replace_sysroot_result. func_replace_sysroot () { case "$lt_sysroot:$1" in ?*:"$lt_sysroot"*) func_stripname "$lt_sysroot" '' "$1" func_replace_sysroot_result="=$func_stripname_result" ;; *) # Including no sysroot. func_replace_sysroot_result=$1 ;; esac } # func_infer_tag arg # Infer tagged configuration to use if any are available and # if one wasn't chosen via the "--tag" command line option. # Only attempt this if the compiler in the base compile # command doesn't match the default compiler. # arg is usually of the form 'gcc ...' func_infer_tag () { $opt_debug if test -n "$available_tags" && test -z "$tagname"; then CC_quoted= for arg in $CC; do func_append_quoted CC_quoted "$arg" done CC_expanded=`func_echo_all $CC` CC_quoted_expanded=`func_echo_all $CC_quoted` case $@ in # Blanks in the command may have been stripped by the calling shell, # but not from the CC environment variable when configure was run. " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \ " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*) ;; # Blanks at the start of $base_compile will cause this to fail # if we don't check for them as well. *) for z in $available_tags; do if $GREP "^# ### BEGIN LIBTOOL TAG CONFIG: $z$" < "$progpath" > /dev/null; then # Evaluate the configuration. eval "`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $progpath`" CC_quoted= for arg in $CC; do # Double-quote args containing other shell metacharacters. func_append_quoted CC_quoted "$arg" done CC_expanded=`func_echo_all $CC` CC_quoted_expanded=`func_echo_all $CC_quoted` case "$@ " in " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \ " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*) # The compiler in the base compile command matches # the one in the tagged configuration. # Assume this is the tagged configuration we want. tagname=$z break ;; esac fi done # If $tagname still isn't set, then no tagged configuration # was found and let the user know that the "--tag" command # line option must be used. if test -z "$tagname"; then func_echo "unable to infer tagged configuration" func_fatal_error "specify a tag with \`--tag'" # else # func_verbose "using $tagname tagged configuration" fi ;; esac fi } # func_write_libtool_object output_name pic_name nonpic_name # Create a libtool object file (analogous to a ".la" file), # but don't create it if we're doing a dry run. func_write_libtool_object () { write_libobj=${1} if test "$build_libtool_libs" = yes; then write_lobj=\'${2}\' else write_lobj=none fi if test "$build_old_libs" = yes; then write_oldobj=\'${3}\' else write_oldobj=none fi $opt_dry_run || { cat >${write_libobj}T <<EOF # $write_libobj - a libtool object file # Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION # # Please DO NOT delete this file! # It is necessary for linking the library. # Name of the PIC object. pic_object=$write_lobj # Name of the non-PIC object non_pic_object=$write_oldobj EOF $MV "${write_libobj}T" "${write_libobj}" } } ################################################## # FILE NAME AND PATH CONVERSION HELPER FUNCTIONS # ################################################## # func_convert_core_file_wine_to_w32 ARG # Helper function used by file name conversion functions when $build is *nix, # and $host is mingw, cygwin, or some other w32 environment. Relies on a # correctly configured wine environment available, with the winepath program # in $build's $PATH. # # ARG is the $build file name to be converted to w32 format. # Result is available in $func_convert_core_file_wine_to_w32_result, and will # be empty on error (or when ARG is empty) func_convert_core_file_wine_to_w32 () { $opt_debug func_convert_core_file_wine_to_w32_result="$1" if test -n "$1"; then # Unfortunately, winepath does not exit with a non-zero error code, so we # are forced to check the contents of stdout. On the other hand, if the # command is not found, the shell will set an exit code of 127 and print # *an error message* to stdout. So we must check for both error code of # zero AND non-empty stdout, which explains the odd construction: func_convert_core_file_wine_to_w32_tmp=`winepath -w "$1" 2>/dev/null` if test "$?" -eq 0 && test -n "${func_convert_core_file_wine_to_w32_tmp}"; then func_convert_core_file_wine_to_w32_result=`$ECHO "$func_convert_core_file_wine_to_w32_tmp" | $SED -e "$lt_sed_naive_backslashify"` else func_convert_core_file_wine_to_w32_result= fi fi } # end: func_convert_core_file_wine_to_w32 # func_convert_core_path_wine_to_w32 ARG # Helper function used by path conversion functions when $build is *nix, and # $host is mingw, cygwin, or some other w32 environment. Relies on a correctly # configured wine environment available, with the winepath program in $build's # $PATH. Assumes ARG has no leading or trailing path separator characters. # # ARG is path to be converted from $build format to win32. # Result is available in $func_convert_core_path_wine_to_w32_result. # Unconvertible file (directory) names in ARG are skipped; if no directory names # are convertible, then the result may be empty. func_convert_core_path_wine_to_w32 () { $opt_debug # unfortunately, winepath doesn't convert paths, only file names func_convert_core_path_wine_to_w32_result="" if test -n "$1"; then oldIFS=$IFS IFS=: for func_convert_core_path_wine_to_w32_f in $1; do IFS=$oldIFS func_convert_core_file_wine_to_w32 "$func_convert_core_path_wine_to_w32_f" if test -n "$func_convert_core_file_wine_to_w32_result" ; then if test -z "$func_convert_core_path_wine_to_w32_result"; then func_convert_core_path_wine_to_w32_result="$func_convert_core_file_wine_to_w32_result" else func_append func_convert_core_path_wine_to_w32_result ";$func_convert_core_file_wine_to_w32_result" fi fi done IFS=$oldIFS fi } # end: func_convert_core_path_wine_to_w32 # func_cygpath ARGS... # Wrapper around calling the cygpath program via LT_CYGPATH. This is used when # when (1) $build is *nix and Cygwin is hosted via a wine environment; or (2) # $build is MSYS and $host is Cygwin, or (3) $build is Cygwin. In case (1) or # (2), returns the Cygwin file name or path in func_cygpath_result (input # file name or path is assumed to be in w32 format, as previously converted # from $build's *nix or MSYS format). In case (3), returns the w32 file name # or path in func_cygpath_result (input file name or path is assumed to be in # Cygwin format). Returns an empty string on error. # # ARGS are passed to cygpath, with the last one being the file name or path to # be converted. # # Specify the absolute *nix (or w32) name to cygpath in the LT_CYGPATH # environment variable; do not put it in $PATH. func_cygpath () { $opt_debug if test -n "$LT_CYGPATH" && test -f "$LT_CYGPATH"; then func_cygpath_result=`$LT_CYGPATH "$@" 2>/dev/null` if test "$?" -ne 0; then # on failure, ensure result is empty func_cygpath_result= fi else func_cygpath_result= func_error "LT_CYGPATH is empty or specifies non-existent file: \`$LT_CYGPATH'" fi } #end: func_cygpath # func_convert_core_msys_to_w32 ARG # Convert file name or path ARG from MSYS format to w32 format. Return # result in func_convert_core_msys_to_w32_result. func_convert_core_msys_to_w32 () { $opt_debug # awkward: cmd appends spaces to result func_convert_core_msys_to_w32_result=`( cmd //c echo "$1" ) 2>/dev/null | $SED -e 's/[ ]*$//' -e "$lt_sed_naive_backslashify"` } #end: func_convert_core_msys_to_w32 # func_convert_file_check ARG1 ARG2 # Verify that ARG1 (a file name in $build format) was converted to $host # format in ARG2. Otherwise, emit an error message, but continue (resetting # func_to_host_file_result to ARG1). func_convert_file_check () { $opt_debug if test -z "$2" && test -n "$1" ; then func_error "Could not determine host file name corresponding to" func_error " \`$1'" func_error "Continuing, but uninstalled executables may not work." # Fallback: func_to_host_file_result="$1" fi } # end func_convert_file_check # func_convert_path_check FROM_PATHSEP TO_PATHSEP FROM_PATH TO_PATH # Verify that FROM_PATH (a path in $build format) was converted to $host # format in TO_PATH. Otherwise, emit an error message, but continue, resetting # func_to_host_file_result to a simplistic fallback value (see below). func_convert_path_check () { $opt_debug if test -z "$4" && test -n "$3"; then func_error "Could not determine the host path corresponding to" func_error " \`$3'" func_error "Continuing, but uninstalled executables may not work." # Fallback. This is a deliberately simplistic "conversion" and # should not be "improved". See libtool.info. if test "x$1" != "x$2"; then lt_replace_pathsep_chars="s|$1|$2|g" func_to_host_path_result=`echo "$3" | $SED -e "$lt_replace_pathsep_chars"` else func_to_host_path_result="$3" fi fi } # end func_convert_path_check # func_convert_path_front_back_pathsep FRONTPAT BACKPAT REPL ORIG # Modifies func_to_host_path_result by prepending REPL if ORIG matches FRONTPAT # and appending REPL if ORIG matches BACKPAT. func_convert_path_front_back_pathsep () { $opt_debug case $4 in $1 ) func_to_host_path_result="$3$func_to_host_path_result" ;; esac case $4 in $2 ) func_append func_to_host_path_result "$3" ;; esac } # end func_convert_path_front_back_pathsep ################################################## # $build to $host FILE NAME CONVERSION FUNCTIONS # ################################################## # invoked via `$to_host_file_cmd ARG' # # In each case, ARG is the path to be converted from $build to $host format. # Result will be available in $func_to_host_file_result. # func_to_host_file ARG # Converts the file name ARG from $build format to $host format. Return result # in func_to_host_file_result. func_to_host_file () { $opt_debug $to_host_file_cmd "$1" } # end func_to_host_file # func_to_tool_file ARG LAZY # converts the file name ARG from $build format to toolchain format. Return # result in func_to_tool_file_result. If the conversion in use is listed # in (the comma separated) LAZY, no conversion takes place. func_to_tool_file () { $opt_debug case ,$2, in *,"$to_tool_file_cmd",*) func_to_tool_file_result=$1 ;; *) $to_tool_file_cmd "$1" func_to_tool_file_result=$func_to_host_file_result ;; esac } # end func_to_tool_file # func_convert_file_noop ARG # Copy ARG to func_to_host_file_result. func_convert_file_noop () { func_to_host_file_result="$1" } # end func_convert_file_noop # func_convert_file_msys_to_w32 ARG # Convert file name ARG from (mingw) MSYS to (mingw) w32 format; automatic # conversion to w32 is not available inside the cwrapper. Returns result in # func_to_host_file_result. func_convert_file_msys_to_w32 () { $opt_debug func_to_host_file_result="$1" if test -n "$1"; then func_convert_core_msys_to_w32 "$1" func_to_host_file_result="$func_convert_core_msys_to_w32_result" fi func_convert_file_check "$1" "$func_to_host_file_result" } # end func_convert_file_msys_to_w32 # func_convert_file_cygwin_to_w32 ARG # Convert file name ARG from Cygwin to w32 format. Returns result in # func_to_host_file_result. func_convert_file_cygwin_to_w32 () { $opt_debug func_to_host_file_result="$1" if test -n "$1"; then # because $build is cygwin, we call "the" cygpath in $PATH; no need to use # LT_CYGPATH in this case. func_to_host_file_result=`cygpath -m "$1"` fi func_convert_file_check "$1" "$func_to_host_file_result" } # end func_convert_file_cygwin_to_w32 # func_convert_file_nix_to_w32 ARG # Convert file name ARG from *nix to w32 format. Requires a wine environment # and a working winepath. Returns result in func_to_host_file_result. func_convert_file_nix_to_w32 () { $opt_debug func_to_host_file_result="$1" if test -n "$1"; then func_convert_core_file_wine_to_w32 "$1" func_to_host_file_result="$func_convert_core_file_wine_to_w32_result" fi func_convert_file_check "$1" "$func_to_host_file_result" } # end func_convert_file_nix_to_w32 # func_convert_file_msys_to_cygwin ARG # Convert file name ARG from MSYS to Cygwin format. Requires LT_CYGPATH set. # Returns result in func_to_host_file_result. func_convert_file_msys_to_cygwin () { $opt_debug func_to_host_file_result="$1" if test -n "$1"; then func_convert_core_msys_to_w32 "$1" func_cygpath -u "$func_convert_core_msys_to_w32_result" func_to_host_file_result="$func_cygpath_result" fi func_convert_file_check "$1" "$func_to_host_file_result" } # end func_convert_file_msys_to_cygwin # func_convert_file_nix_to_cygwin ARG # Convert file name ARG from *nix to Cygwin format. Requires Cygwin installed # in a wine environment, working winepath, and LT_CYGPATH set. Returns result # in func_to_host_file_result. func_convert_file_nix_to_cygwin () { $opt_debug func_to_host_file_result="$1" if test -n "$1"; then # convert from *nix to w32, then use cygpath to convert from w32 to cygwin. func_convert_core_file_wine_to_w32 "$1" func_cygpath -u "$func_convert_core_file_wine_to_w32_result" func_to_host_file_result="$func_cygpath_result" fi func_convert_file_check "$1" "$func_to_host_file_result" } # end func_convert_file_nix_to_cygwin ############################################# # $build to $host PATH CONVERSION FUNCTIONS # ############################################# # invoked via `$to_host_path_cmd ARG' # # In each case, ARG is the path to be converted from $build to $host format. # The result will be available in $func_to_host_path_result. # # Path separators are also converted from $build format to $host format. If # ARG begins or ends with a path separator character, it is preserved (but # converted to $host format) on output. # # All path conversion functions are named using the following convention: # file name conversion function : func_convert_file_X_to_Y () # path conversion function : func_convert_path_X_to_Y () # where, for any given $build/$host combination the 'X_to_Y' value is the # same. If conversion functions are added for new $build/$host combinations, # the two new functions must follow this pattern, or func_init_to_host_path_cmd # will break. # func_init_to_host_path_cmd # Ensures that function "pointer" variable $to_host_path_cmd is set to the # appropriate value, based on the value of $to_host_file_cmd. to_host_path_cmd= func_init_to_host_path_cmd () { $opt_debug if test -z "$to_host_path_cmd"; then func_stripname 'func_convert_file_' '' "$to_host_file_cmd" to_host_path_cmd="func_convert_path_${func_stripname_result}" fi } # func_to_host_path ARG # Converts the path ARG from $build format to $host format. Return result # in func_to_host_path_result. func_to_host_path () { $opt_debug func_init_to_host_path_cmd $to_host_path_cmd "$1" } # end func_to_host_path # func_convert_path_noop ARG # Copy ARG to func_to_host_path_result. func_convert_path_noop () { func_to_host_path_result="$1" } # end func_convert_path_noop # func_convert_path_msys_to_w32 ARG # Convert path ARG from (mingw) MSYS to (mingw) w32 format; automatic # conversion to w32 is not available inside the cwrapper. Returns result in # func_to_host_path_result. func_convert_path_msys_to_w32 () { $opt_debug func_to_host_path_result="$1" if test -n "$1"; then # Remove leading and trailing path separator characters from ARG. MSYS # behavior is inconsistent here; cygpath turns them into '.;' and ';.'; # and winepath ignores them completely. func_stripname : : "$1" func_to_host_path_tmp1=$func_stripname_result func_convert_core_msys_to_w32 "$func_to_host_path_tmp1" func_to_host_path_result="$func_convert_core_msys_to_w32_result" func_convert_path_check : ";" \ "$func_to_host_path_tmp1" "$func_to_host_path_result" func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" fi } # end func_convert_path_msys_to_w32 # func_convert_path_cygwin_to_w32 ARG # Convert path ARG from Cygwin to w32 format. Returns result in # func_to_host_file_result. func_convert_path_cygwin_to_w32 () { $opt_debug func_to_host_path_result="$1" if test -n "$1"; then # See func_convert_path_msys_to_w32: func_stripname : : "$1" func_to_host_path_tmp1=$func_stripname_result func_to_host_path_result=`cygpath -m -p "$func_to_host_path_tmp1"` func_convert_path_check : ";" \ "$func_to_host_path_tmp1" "$func_to_host_path_result" func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" fi } # end func_convert_path_cygwin_to_w32 # func_convert_path_nix_to_w32 ARG # Convert path ARG from *nix to w32 format. Requires a wine environment and # a working winepath. Returns result in func_to_host_file_result. func_convert_path_nix_to_w32 () { $opt_debug func_to_host_path_result="$1" if test -n "$1"; then # See func_convert_path_msys_to_w32: func_stripname : : "$1" func_to_host_path_tmp1=$func_stripname_result func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1" func_to_host_path_result="$func_convert_core_path_wine_to_w32_result" func_convert_path_check : ";" \ "$func_to_host_path_tmp1" "$func_to_host_path_result" func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" fi } # end func_convert_path_nix_to_w32 # func_convert_path_msys_to_cygwin ARG # Convert path ARG from MSYS to Cygwin format. Requires LT_CYGPATH set. # Returns result in func_to_host_file_result. func_convert_path_msys_to_cygwin () { $opt_debug func_to_host_path_result="$1" if test -n "$1"; then # See func_convert_path_msys_to_w32: func_stripname : : "$1" func_to_host_path_tmp1=$func_stripname_result func_convert_core_msys_to_w32 "$func_to_host_path_tmp1" func_cygpath -u -p "$func_convert_core_msys_to_w32_result" func_to_host_path_result="$func_cygpath_result" func_convert_path_check : : \ "$func_to_host_path_tmp1" "$func_to_host_path_result" func_convert_path_front_back_pathsep ":*" "*:" : "$1" fi } # end func_convert_path_msys_to_cygwin # func_convert_path_nix_to_cygwin ARG # Convert path ARG from *nix to Cygwin format. Requires Cygwin installed in a # a wine environment, working winepath, and LT_CYGPATH set. Returns result in # func_to_host_file_result. func_convert_path_nix_to_cygwin () { $opt_debug func_to_host_path_result="$1" if test -n "$1"; then # Remove leading and trailing path separator characters from # ARG. msys behavior is inconsistent here, cygpath turns them # into '.;' and ';.', and winepath ignores them completely. func_stripname : : "$1" func_to_host_path_tmp1=$func_stripname_result func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1" func_cygpath -u -p "$func_convert_core_path_wine_to_w32_result" func_to_host_path_result="$func_cygpath_result" func_convert_path_check : : \ "$func_to_host_path_tmp1" "$func_to_host_path_result" func_convert_path_front_back_pathsep ":*" "*:" : "$1" fi } # end func_convert_path_nix_to_cygwin # func_mode_compile arg... func_mode_compile () { $opt_debug # Get the compilation command and the source file. base_compile= srcfile="$nonopt" # always keep a non-empty value in "srcfile" suppress_opt=yes suppress_output= arg_mode=normal libobj= later= pie_flag= for arg do case $arg_mode in arg ) # do not "continue". Instead, add this to base_compile lastarg="$arg" arg_mode=normal ;; target ) libobj="$arg" arg_mode=normal continue ;; normal ) # Accept any command-line options. case $arg in -o) test -n "$libobj" && \ func_fatal_error "you cannot specify \`-o' more than once" arg_mode=target continue ;; -pie | -fpie | -fPIE) func_append pie_flag " $arg" continue ;; -shared | -static | -prefer-pic | -prefer-non-pic) func_append later " $arg" continue ;; -no-suppress) suppress_opt=no continue ;; -Xcompiler) arg_mode=arg # the next one goes into the "base_compile" arg list continue # The current "srcfile" will either be retained or ;; # replaced later. I would guess that would be a bug. -Wc,*) func_stripname '-Wc,' '' "$arg" args=$func_stripname_result lastarg= save_ifs="$IFS"; IFS=',' for arg in $args; do IFS="$save_ifs" func_append_quoted lastarg "$arg" done IFS="$save_ifs" func_stripname ' ' '' "$lastarg" lastarg=$func_stripname_result # Add the arguments to base_compile. func_append base_compile " $lastarg" continue ;; *) # Accept the current argument as the source file. # The previous "srcfile" becomes the current argument. # lastarg="$srcfile" srcfile="$arg" ;; esac # case $arg ;; esac # case $arg_mode # Aesthetically quote the previous argument. func_append_quoted base_compile "$lastarg" done # for arg case $arg_mode in arg) func_fatal_error "you must specify an argument for -Xcompile" ;; target) func_fatal_error "you must specify a target with \`-o'" ;; *) # Get the name of the library object. test -z "$libobj" && { func_basename "$srcfile" libobj="$func_basename_result" } ;; esac # Recognize several different file suffixes. # If the user specifies -o file.o, it is replaced with file.lo case $libobj in *.[cCFSifmso] | \ *.ada | *.adb | *.ads | *.asm | \ *.c++ | *.cc | *.ii | *.class | *.cpp | *.cxx | \ *.[fF][09]? | *.for | *.java | *.go | *.obj | *.sx | *.cu | *.cup) func_xform "$libobj" libobj=$func_xform_result ;; esac case $libobj in *.lo) func_lo2o "$libobj"; obj=$func_lo2o_result ;; *) func_fatal_error "cannot determine name of library object from \`$libobj'" ;; esac func_infer_tag $base_compile for arg in $later; do case $arg in -shared) test "$build_libtool_libs" != yes && \ func_fatal_configuration "can not build a shared library" build_old_libs=no continue ;; -static) build_libtool_libs=no build_old_libs=yes continue ;; -prefer-pic) pic_mode=yes continue ;; -prefer-non-pic) pic_mode=no continue ;; esac done func_quote_for_eval "$libobj" test "X$libobj" != "X$func_quote_for_eval_result" \ && $ECHO "X$libobj" | $GREP '[]~#^*{};<>?"'"'"' &()|`$[]' \ && func_warning "libobj name \`$libobj' may not contain shell special characters." func_dirname_and_basename "$obj" "/" "" objname="$func_basename_result" xdir="$func_dirname_result" lobj=${xdir}$objdir/$objname test -z "$base_compile" && \ func_fatal_help "you must specify a compilation command" # Delete any leftover library objects. if test "$build_old_libs" = yes; then removelist="$obj $lobj $libobj ${libobj}T" else removelist="$lobj $libobj ${libobj}T" fi # On Cygwin there's no "real" PIC flag so we must build both object types case $host_os in cygwin* | mingw* | pw32* | os2* | cegcc*) pic_mode=default ;; esac if test "$pic_mode" = no && test "$deplibs_check_method" != pass_all; then # non-PIC code in shared libraries is not supported pic_mode=default fi # Calculate the filename of the output object if compiler does # not support -o with -c if test "$compiler_c_o" = no; then output_obj=`$ECHO "$srcfile" | $SED 's%^.*/%%; s%\.[^.]*$%%'`.${objext} lockfile="$output_obj.lock" else output_obj= need_locks=no lockfile= fi # Lock this critical section if it is needed # We use this script file to make the link, it avoids creating a new file if test "$need_locks" = yes; then until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do func_echo "Waiting for $lockfile to be removed" sleep 2 done elif test "$need_locks" = warn; then if test -f "$lockfile"; then $ECHO "\ *** ERROR, $lockfile exists and contains: `cat $lockfile 2>/dev/null` This indicates that another process is trying to use the same temporary object file, and libtool could not work around it because your compiler does not support \`-c' and \`-o' together. If you repeat this compilation, it may succeed, by chance, but you had better avoid parallel builds (make -j) in this platform, or get a better compiler." $opt_dry_run || $RM $removelist exit $EXIT_FAILURE fi func_append removelist " $output_obj" $ECHO "$srcfile" > "$lockfile" fi $opt_dry_run || $RM $removelist func_append removelist " $lockfile" trap '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' 1 2 15 func_to_tool_file "$srcfile" func_convert_file_msys_to_w32 srcfile=$func_to_tool_file_result func_quote_for_eval "$srcfile" qsrcfile=$func_quote_for_eval_result # Only build a PIC object if we are building libtool libraries. if test "$build_libtool_libs" = yes; then # Without this assignment, base_compile gets emptied. fbsd_hideous_sh_bug=$base_compile if test "$pic_mode" != no; then command="$base_compile $qsrcfile $pic_flag" else # Don't build PIC code command="$base_compile $qsrcfile" fi func_mkdir_p "$xdir$objdir" if test -z "$output_obj"; then # Place PIC objects in $objdir func_append command " -o $lobj" fi func_show_eval_locale "$command" \ 'test -n "$output_obj" && $RM $removelist; exit $EXIT_FAILURE' if test "$need_locks" = warn && test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then $ECHO "\ *** ERROR, $lockfile contains: `cat $lockfile 2>/dev/null` but it should contain: $srcfile This indicates that another process is trying to use the same temporary object file, and libtool could not work around it because your compiler does not support \`-c' and \`-o' together. If you repeat this compilation, it may succeed, by chance, but you had better avoid parallel builds (make -j) in this platform, or get a better compiler." $opt_dry_run || $RM $removelist exit $EXIT_FAILURE fi # Just move the object if needed, then go on to compile the next one if test -n "$output_obj" && test "X$output_obj" != "X$lobj"; then func_show_eval '$MV "$output_obj" "$lobj"' \ 'error=$?; $opt_dry_run || $RM $removelist; exit $error' fi # Allow error messages only from the first compilation. if test "$suppress_opt" = yes; then suppress_output=' >/dev/null 2>&1' fi fi # Only build a position-dependent object if we build old libraries. if test "$build_old_libs" = yes; then if test "$pic_mode" != yes; then # Don't build PIC code command="$base_compile $qsrcfile$pie_flag" else command="$base_compile $qsrcfile $pic_flag" fi if test "$compiler_c_o" = yes; then func_append command " -o $obj" fi # Suppress compiler output if we already did a PIC compilation. func_append command "$suppress_output" func_show_eval_locale "$command" \ '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' if test "$need_locks" = warn && test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then $ECHO "\ *** ERROR, $lockfile contains: `cat $lockfile 2>/dev/null` but it should contain: $srcfile This indicates that another process is trying to use the same temporary object file, and libtool could not work around it because your compiler does not support \`-c' and \`-o' together. If you repeat this compilation, it may succeed, by chance, but you had better avoid parallel builds (make -j) in this platform, or get a better compiler." $opt_dry_run || $RM $removelist exit $EXIT_FAILURE fi # Just move the object if needed if test -n "$output_obj" && test "X$output_obj" != "X$obj"; then func_show_eval '$MV "$output_obj" "$obj"' \ 'error=$?; $opt_dry_run || $RM $removelist; exit $error' fi fi $opt_dry_run || { func_write_libtool_object "$libobj" "$objdir/$objname" "$objname" # Unlock the critical section if it was locked if test "$need_locks" != no; then removelist=$lockfile $RM "$lockfile" fi } exit $EXIT_SUCCESS } $opt_help || { test "$opt_mode" = compile && func_mode_compile ${1+"$@"} } func_mode_help () { # We need to display help for each of the modes. case $opt_mode in "") # Generic help is extracted from the usage comments # at the start of this file. func_help ;; clean) $ECHO \ "Usage: $progname [OPTION]... --mode=clean RM [RM-OPTION]... FILE... Remove files from the build directory. RM is the name of the program to use to delete files associated with each FILE (typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed to RM. If FILE is a libtool library, object or program, all the files associated with it are deleted. Otherwise, only FILE itself is deleted using RM." ;; compile) $ECHO \ "Usage: $progname [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE Compile a source file into a libtool library object. This mode accepts the following additional options: -o OUTPUT-FILE set the output file name to OUTPUT-FILE -no-suppress do not suppress compiler output for multiple passes -prefer-pic try to build PIC objects only -prefer-non-pic try to build non-PIC objects only -shared do not build a \`.o' file suitable for static linking -static only build a \`.o' file suitable for static linking -Wc,FLAG pass FLAG directly to the compiler COMPILE-COMMAND is a command to be used in creating a \`standard' object file from the given SOURCEFILE. The output file name is determined by removing the directory component from SOURCEFILE, then substituting the C source code suffix \`.c' with the library object suffix, \`.lo'." ;; execute) $ECHO \ "Usage: $progname [OPTION]... --mode=execute COMMAND [ARGS]... Automatically set library path, then run a program. This mode accepts the following additional options: -dlopen FILE add the directory containing FILE to the library path This mode sets the library path environment variable according to \`-dlopen' flags. If any of the ARGS are libtool executable wrappers, then they are translated into their corresponding uninstalled binary, and any of their required library directories are added to the library path. Then, COMMAND is executed, with ARGS as arguments." ;; finish) $ECHO \ "Usage: $progname [OPTION]... --mode=finish [LIBDIR]... Complete the installation of libtool libraries. Each LIBDIR is a directory that contains libtool libraries. The commands that this mode executes may require superuser privileges. Use the \`--dry-run' option if you just want to see what would be executed." ;; install) $ECHO \ "Usage: $progname [OPTION]... --mode=install INSTALL-COMMAND... Install executables or libraries. INSTALL-COMMAND is the installation command. The first component should be either the \`install' or \`cp' program. The following components of INSTALL-COMMAND are treated specially: -inst-prefix-dir PREFIX-DIR Use PREFIX-DIR as a staging area for installation The rest of the components are interpreted as arguments to that command (only BSD-compatible install options are recognized)." ;; link) $ECHO \ "Usage: $progname [OPTION]... --mode=link LINK-COMMAND... Link object files or libraries together to form another library, or to create an executable program. LINK-COMMAND is a command using the C compiler that you would use to create a program from several object files. The following components of LINK-COMMAND are treated specially: -all-static do not do any dynamic linking at all -avoid-version do not add a version suffix if possible -bindir BINDIR specify path to binaries directory (for systems where libraries must be found in the PATH setting at runtime) -dlopen FILE \`-dlpreopen' FILE if it cannot be dlopened at runtime -dlpreopen FILE link in FILE and add its symbols to lt_preloaded_symbols -export-dynamic allow symbols from OUTPUT-FILE to be resolved with dlsym(3) -export-symbols SYMFILE try to export only the symbols listed in SYMFILE -export-symbols-regex REGEX try to export only the symbols matching REGEX -LLIBDIR search LIBDIR for required installed libraries -lNAME OUTPUT-FILE requires the installed library libNAME -module build a library that can dlopened -no-fast-install disable the fast-install mode -no-install link a not-installable executable -no-undefined declare that a library does not refer to external symbols -o OUTPUT-FILE create OUTPUT-FILE from the specified objects -objectlist FILE Use a list of object files found in FILE to specify objects -precious-files-regex REGEX don't remove output files matching REGEX -release RELEASE specify package release information -rpath LIBDIR the created library will eventually be installed in LIBDIR -R[ ]LIBDIR add LIBDIR to the runtime path of programs and libraries -shared only do dynamic linking of libtool libraries -shrext SUFFIX override the standard shared library file extension -static do not do any dynamic linking of uninstalled libtool libraries -static-libtool-libs do not do any dynamic linking of libtool libraries -version-info CURRENT[:REVISION[:AGE]] specify library version info [each variable defaults to 0] -weak LIBNAME declare that the target provides the LIBNAME interface -Wc,FLAG -Xcompiler FLAG pass linker-specific FLAG directly to the compiler -Wl,FLAG -Xlinker FLAG pass linker-specific FLAG directly to the linker -XCClinker FLAG pass link-specific FLAG to the compiler driver (CC) All other options (arguments beginning with \`-') are ignored. Every other argument is treated as a filename. Files ending in \`.la' are treated as uninstalled libtool libraries, other files are standard or library object files. If the OUTPUT-FILE ends in \`.la', then a libtool library is created, only library objects (\`.lo' files) may be specified, and \`-rpath' is required, except when creating a convenience library. If OUTPUT-FILE ends in \`.a' or \`.lib', then a standard library is created using \`ar' and \`ranlib', or on Windows using \`lib'. If OUTPUT-FILE ends in \`.lo' or \`.${objext}', then a reloadable object file is created, otherwise an executable program is created." ;; uninstall) $ECHO \ "Usage: $progname [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE... Remove libraries from an installation directory. RM is the name of the program to use to delete files associated with each FILE (typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed to RM. If FILE is a libtool library, all the files associated with it are deleted. Otherwise, only FILE itself is deleted using RM." ;; *) func_fatal_help "invalid operation mode \`$opt_mode'" ;; esac echo $ECHO "Try \`$progname --help' for more information about other modes." } # Now that we've collected a possible --mode arg, show help if necessary if $opt_help; then if test "$opt_help" = :; then func_mode_help else { func_help noexit for opt_mode in compile link execute install finish uninstall clean; do func_mode_help done } | sed -n '1p; 2,$s/^Usage:/ or: /p' { func_help noexit for opt_mode in compile link execute install finish uninstall clean; do echo func_mode_help done } | sed '1d /^When reporting/,/^Report/{ H d } $x /information about other modes/d /more detailed .*MODE/d s/^Usage:.*--mode=\([^ ]*\) .*/Description of \1 mode:/' fi exit $? fi # func_mode_execute arg... func_mode_execute () { $opt_debug # The first argument is the command name. cmd="$nonopt" test -z "$cmd" && \ func_fatal_help "you must specify a COMMAND" # Handle -dlopen flags immediately. for file in $opt_dlopen; do test -f "$file" \ || func_fatal_help "\`$file' is not a file" dir= case $file in *.la) func_resolve_sysroot "$file" file=$func_resolve_sysroot_result # Check to see that this really is a libtool archive. func_lalib_unsafe_p "$file" \ || func_fatal_help "\`$lib' is not a valid libtool archive" # Read the libtool library. dlname= library_names= func_source "$file" # Skip this library if it cannot be dlopened. if test -z "$dlname"; then # Warn if it was a shared library. test -n "$library_names" && \ func_warning "\`$file' was not linked with \`-export-dynamic'" continue fi func_dirname "$file" "" "." dir="$func_dirname_result" if test -f "$dir/$objdir/$dlname"; then func_append dir "/$objdir" else if test ! -f "$dir/$dlname"; then func_fatal_error "cannot find \`$dlname' in \`$dir' or \`$dir/$objdir'" fi fi ;; *.lo) # Just add the directory containing the .lo file. func_dirname "$file" "" "." dir="$func_dirname_result" ;; *) func_warning "\`-dlopen' is ignored for non-libtool libraries and objects" continue ;; esac # Get the absolute pathname. absdir=`cd "$dir" && pwd` test -n "$absdir" && dir="$absdir" # Now add the directory to shlibpath_var. if eval "test -z \"\$$shlibpath_var\""; then eval "$shlibpath_var=\"\$dir\"" else eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\"" fi done # This variable tells wrapper scripts just to set shlibpath_var # rather than running their programs. libtool_execute_magic="$magic" # Check if any of the arguments is a wrapper script. args= for file do case $file in -* | *.la | *.lo ) ;; *) # Do a test to see if this is really a libtool program. if func_ltwrapper_script_p "$file"; then func_source "$file" # Transform arg to wrapped name. file="$progdir/$program" elif func_ltwrapper_executable_p "$file"; then func_ltwrapper_scriptname "$file" func_source "$func_ltwrapper_scriptname_result" # Transform arg to wrapped name. file="$progdir/$program" fi ;; esac # Quote arguments (to preserve shell metacharacters). func_append_quoted args "$file" done if test "X$opt_dry_run" = Xfalse; then if test -n "$shlibpath_var"; then # Export the shlibpath_var. eval "export $shlibpath_var" fi # Restore saved environment variables for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES do eval "if test \"\${save_$lt_var+set}\" = set; then $lt_var=\$save_$lt_var; export $lt_var else $lt_unset $lt_var fi" done # Now prepare to actually exec the command. exec_cmd="\$cmd$args" else # Display what would be done. if test -n "$shlibpath_var"; then eval "\$ECHO \"\$shlibpath_var=\$$shlibpath_var\"" echo "export $shlibpath_var" fi $ECHO "$cmd$args" exit $EXIT_SUCCESS fi } test "$opt_mode" = execute && func_mode_execute ${1+"$@"} # func_mode_finish arg... func_mode_finish () { $opt_debug libs= libdirs= admincmds= for opt in "$nonopt" ${1+"$@"} do if test -d "$opt"; then func_append libdirs " $opt" elif test -f "$opt"; then if func_lalib_unsafe_p "$opt"; then func_append libs " $opt" else func_warning "\`$opt' is not a valid libtool archive" fi else func_fatal_error "invalid argument \`$opt'" fi done if test -n "$libs"; then if test -n "$lt_sysroot"; then sysroot_regex=`$ECHO "$lt_sysroot" | $SED "$sed_make_literal_regex"` sysroot_cmd="s/\([ ']\)$sysroot_regex/\1/g;" else sysroot_cmd= fi # Remove sysroot references if $opt_dry_run; then for lib in $libs; do echo "removing references to $lt_sysroot and \`=' prefixes from $lib" done else tmpdir=`func_mktempdir` for lib in $libs; do sed -e "${sysroot_cmd} s/\([ ']-[LR]\)=/\1/g; s/\([ ']\)=/\1/g" $lib \ > $tmpdir/tmp-la mv -f $tmpdir/tmp-la $lib done ${RM}r "$tmpdir" fi fi if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then for libdir in $libdirs; do if test -n "$finish_cmds"; then # Do each command in the finish commands. func_execute_cmds "$finish_cmds" 'admincmds="$admincmds '"$cmd"'"' fi if test -n "$finish_eval"; then # Do the single finish_eval. eval cmds=\"$finish_eval\" $opt_dry_run || eval "$cmds" || func_append admincmds " $cmds" fi done fi # Exit here if they wanted silent mode. $opt_silent && exit $EXIT_SUCCESS if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then echo "----------------------------------------------------------------------" echo "Libraries have been installed in:" for libdir in $libdirs; do $ECHO " $libdir" done echo echo "If you ever happen to want to link against installed libraries" echo "in a given directory, LIBDIR, you must either use libtool, and" echo "specify the full pathname of the library, or use the \`-LLIBDIR'" echo "flag during linking and do at least one of the following:" if test -n "$shlibpath_var"; then echo " - add LIBDIR to the \`$shlibpath_var' environment variable" echo " during execution" fi if test -n "$runpath_var"; then echo " - add LIBDIR to the \`$runpath_var' environment variable" echo " during linking" fi if test -n "$hardcode_libdir_flag_spec"; then libdir=LIBDIR eval flag=\"$hardcode_libdir_flag_spec\" $ECHO " - use the \`$flag' linker flag" fi if test -n "$admincmds"; then $ECHO " - have your system administrator run these commands:$admincmds" fi if test -f /etc/ld.so.conf; then echo " - have your system administrator add LIBDIR to \`/etc/ld.so.conf'" fi echo echo "See any operating system documentation about shared libraries for" case $host in solaris2.[6789]|solaris2.1[0-9]) echo "more information, such as the ld(1), crle(1) and ld.so(8) manual" echo "pages." ;; *) echo "more information, such as the ld(1) and ld.so(8) manual pages." ;; esac echo "----------------------------------------------------------------------" fi exit $EXIT_SUCCESS } test "$opt_mode" = finish && func_mode_finish ${1+"$@"} # func_mode_install arg... func_mode_install () { $opt_debug # There may be an optional sh(1) argument at the beginning of # install_prog (especially on Windows NT). if test "$nonopt" = "$SHELL" || test "$nonopt" = /bin/sh || # Allow the use of GNU shtool's install command. case $nonopt in *shtool*) :;; *) false;; esac; then # Aesthetically quote it. func_quote_for_eval "$nonopt" install_prog="$func_quote_for_eval_result " arg=$1 shift else install_prog= arg=$nonopt fi # The real first argument should be the name of the installation program. # Aesthetically quote it. func_quote_for_eval "$arg" func_append install_prog "$func_quote_for_eval_result" install_shared_prog=$install_prog case " $install_prog " in *[\\\ /]cp\ *) install_cp=: ;; *) install_cp=false ;; esac # We need to accept at least all the BSD install flags. dest= files= opts= prev= install_type= isdir=no stripme= no_mode=: for arg do arg2= if test -n "$dest"; then func_append files " $dest" dest=$arg continue fi case $arg in -d) isdir=yes ;; -f) if $install_cp; then :; else prev=$arg fi ;; -g | -m | -o) prev=$arg ;; -s) stripme=" -s" continue ;; -*) ;; *) # If the previous option needed an argument, then skip it. if test -n "$prev"; then if test "x$prev" = x-m && test -n "$install_override_mode"; then arg2=$install_override_mode no_mode=false fi prev= else dest=$arg continue fi ;; esac # Aesthetically quote the argument. func_quote_for_eval "$arg" func_append install_prog " $func_quote_for_eval_result" if test -n "$arg2"; then func_quote_for_eval "$arg2" fi func_append install_shared_prog " $func_quote_for_eval_result" done test -z "$install_prog" && \ func_fatal_help "you must specify an install program" test -n "$prev" && \ func_fatal_help "the \`$prev' option requires an argument" if test -n "$install_override_mode" && $no_mode; then if $install_cp; then :; else func_quote_for_eval "$install_override_mode" func_append install_shared_prog " -m $func_quote_for_eval_result" fi fi if test -z "$files"; then if test -z "$dest"; then func_fatal_help "no file or destination specified" else func_fatal_help "you must specify a destination" fi fi # Strip any trailing slash from the destination. func_stripname '' '/' "$dest" dest=$func_stripname_result # Check to see that the destination is a directory. test -d "$dest" && isdir=yes if test "$isdir" = yes; then destdir="$dest" destname= else func_dirname_and_basename "$dest" "" "." destdir="$func_dirname_result" destname="$func_basename_result" # Not a directory, so check to see that there is only one file specified. set dummy $files; shift test "$#" -gt 1 && \ func_fatal_help "\`$dest' is not a directory" fi case $destdir in [\\/]* | [A-Za-z]:[\\/]*) ;; *) for file in $files; do case $file in *.lo) ;; *) func_fatal_help "\`$destdir' must be an absolute directory name" ;; esac done ;; esac # This variable tells wrapper scripts just to set variables rather # than running their programs. libtool_install_magic="$magic" staticlibs= future_libdirs= current_libdirs= for file in $files; do # Do each installation. case $file in *.$libext) # Do the static libraries later. func_append staticlibs " $file" ;; *.la) func_resolve_sysroot "$file" file=$func_resolve_sysroot_result # Check to see that this really is a libtool archive. func_lalib_unsafe_p "$file" \ || func_fatal_help "\`$file' is not a valid libtool archive" library_names= old_library= relink_command= func_source "$file" # Add the libdir to current_libdirs if it is the destination. if test "X$destdir" = "X$libdir"; then case "$current_libdirs " in *" $libdir "*) ;; *) func_append current_libdirs " $libdir" ;; esac else # Note the libdir as a future libdir. case "$future_libdirs " in *" $libdir "*) ;; *) func_append future_libdirs " $libdir" ;; esac fi func_dirname "$file" "/" "" dir="$func_dirname_result" func_append dir "$objdir" if test -n "$relink_command"; then # Determine the prefix the user has applied to our future dir. inst_prefix_dir=`$ECHO "$destdir" | $SED -e "s%$libdir\$%%"` # Don't allow the user to place us outside of our expected # location b/c this prevents finding dependent libraries that # are installed to the same prefix. # At present, this check doesn't affect windows .dll's that # are installed into $libdir/../bin (currently, that works fine) # but it's something to keep an eye on. test "$inst_prefix_dir" = "$destdir" && \ func_fatal_error "error: cannot install \`$file' to a directory not ending in $libdir" if test -n "$inst_prefix_dir"; then # Stick the inst_prefix_dir data into the link command. relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%-inst-prefix-dir $inst_prefix_dir%"` else relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%%"` fi func_warning "relinking \`$file'" func_show_eval "$relink_command" \ 'func_fatal_error "error: relink \`$file'\'' with the above command before installing it"' fi # See the names of the shared library. set dummy $library_names; shift if test -n "$1"; then realname="$1" shift srcname="$realname" test -n "$relink_command" && srcname="$realname"T # Install the shared library and build the symlinks. func_show_eval "$install_shared_prog $dir/$srcname $destdir/$realname" \ 'exit $?' tstripme="$stripme" case $host_os in cygwin* | mingw* | pw32* | cegcc*) case $realname in *.dll.a) tstripme="" ;; esac ;; esac if test -n "$tstripme" && test -n "$striplib"; then func_show_eval "$striplib $destdir/$realname" 'exit $?' fi if test "$#" -gt 0; then # Delete the old symlinks, and create new ones. # Try `ln -sf' first, because the `ln' binary might depend on # the symlink we replace! Solaris /bin/ln does not understand -f, # so we also need to try rm && ln -s. for linkname do test "$linkname" != "$realname" \ && func_show_eval "(cd $destdir && { $LN_S -f $realname $linkname || { $RM $linkname && $LN_S $realname $linkname; }; })" done fi # Do each command in the postinstall commands. lib="$destdir/$realname" func_execute_cmds "$postinstall_cmds" 'exit $?' fi # Install the pseudo-library for information purposes. func_basename "$file" name="$func_basename_result" instname="$dir/$name"i func_show_eval "$install_prog $instname $destdir/$name" 'exit $?' # Maybe install the static library, too. test -n "$old_library" && func_append staticlibs " $dir/$old_library" ;; *.lo) # Install (i.e. copy) a libtool object. # Figure out destination file name, if it wasn't already specified. if test -n "$destname"; then destfile="$destdir/$destname" else func_basename "$file" destfile="$func_basename_result" destfile="$destdir/$destfile" fi # Deduce the name of the destination old-style object file. case $destfile in *.lo) func_lo2o "$destfile" staticdest=$func_lo2o_result ;; *.$objext) staticdest="$destfile" destfile= ;; *) func_fatal_help "cannot copy a libtool object to \`$destfile'" ;; esac # Install the libtool object if requested. test -n "$destfile" && \ func_show_eval "$install_prog $file $destfile" 'exit $?' # Install the old object if enabled. if test "$build_old_libs" = yes; then # Deduce the name of the old-style object file. func_lo2o "$file" staticobj=$func_lo2o_result func_show_eval "$install_prog \$staticobj \$staticdest" 'exit $?' fi exit $EXIT_SUCCESS ;; *) # Figure out destination file name, if it wasn't already specified. if test -n "$destname"; then destfile="$destdir/$destname" else func_basename "$file" destfile="$func_basename_result" destfile="$destdir/$destfile" fi # If the file is missing, and there is a .exe on the end, strip it # because it is most likely a libtool script we actually want to # install stripped_ext="" case $file in *.exe) if test ! -f "$file"; then func_stripname '' '.exe' "$file" file=$func_stripname_result stripped_ext=".exe" fi ;; esac # Do a test to see if this is really a libtool program. case $host in *cygwin* | *mingw*) if func_ltwrapper_executable_p "$file"; then func_ltwrapper_scriptname "$file" wrapper=$func_ltwrapper_scriptname_result else func_stripname '' '.exe' "$file" wrapper=$func_stripname_result fi ;; *) wrapper=$file ;; esac if func_ltwrapper_script_p "$wrapper"; then notinst_deplibs= relink_command= func_source "$wrapper" # Check the variables that should have been set. test -z "$generated_by_libtool_version" && \ func_fatal_error "invalid libtool wrapper script \`$wrapper'" finalize=yes for lib in $notinst_deplibs; do # Check to see that each library is installed. libdir= if test -f "$lib"; then func_source "$lib" fi libfile="$libdir/"`$ECHO "$lib" | $SED 's%^.*/%%g'` ### testsuite: skip nested quoting test if test -n "$libdir" && test ! -f "$libfile"; then func_warning "\`$lib' has not been installed in \`$libdir'" finalize=no fi done relink_command= func_source "$wrapper" outputname= if test "$fast_install" = no && test -n "$relink_command"; then $opt_dry_run || { if test "$finalize" = yes; then tmpdir=`func_mktempdir` func_basename "$file$stripped_ext" file="$func_basename_result" outputname="$tmpdir/$file" # Replace the output file specification. relink_command=`$ECHO "$relink_command" | $SED 's%@OUTPUT@%'"$outputname"'%g'` $opt_silent || { func_quote_for_expand "$relink_command" eval "func_echo $func_quote_for_expand_result" } if eval "$relink_command"; then : else func_error "error: relink \`$file' with the above command before installing it" $opt_dry_run || ${RM}r "$tmpdir" continue fi file="$outputname" else func_warning "cannot relink \`$file'" fi } else # Install the binary that we compiled earlier. file=`$ECHO "$file$stripped_ext" | $SED "s%\([^/]*\)$%$objdir/\1%"` fi fi # remove .exe since cygwin /usr/bin/install will append another # one anyway case $install_prog,$host in */usr/bin/install*,*cygwin*) case $file:$destfile in *.exe:*.exe) # this is ok ;; *.exe:*) destfile=$destfile.exe ;; *:*.exe) func_stripname '' '.exe' "$destfile" destfile=$func_stripname_result ;; esac ;; esac func_show_eval "$install_prog\$stripme \$file \$destfile" 'exit $?' $opt_dry_run || if test -n "$outputname"; then ${RM}r "$tmpdir" fi ;; esac done for file in $staticlibs; do func_basename "$file" name="$func_basename_result" # Set up the ranlib parameters. oldlib="$destdir/$name" func_to_tool_file "$oldlib" func_convert_file_msys_to_w32 tool_oldlib=$func_to_tool_file_result func_show_eval "$install_prog \$file \$oldlib" 'exit $?' if test -n "$stripme" && test -n "$old_striplib"; then func_show_eval "$old_striplib $tool_oldlib" 'exit $?' fi # Do each command in the postinstall commands. func_execute_cmds "$old_postinstall_cmds" 'exit $?' done test -n "$future_libdirs" && \ func_warning "remember to run \`$progname --finish$future_libdirs'" if test -n "$current_libdirs"; then # Maybe just do a dry run. $opt_dry_run && current_libdirs=" -n$current_libdirs" exec_cmd='$SHELL $progpath $preserve_args --finish$current_libdirs' else exit $EXIT_SUCCESS fi } test "$opt_mode" = install && func_mode_install ${1+"$@"} # func_generate_dlsyms outputname originator pic_p # Extract symbols from dlprefiles and create ${outputname}S.o with # a dlpreopen symbol table. func_generate_dlsyms () { $opt_debug my_outputname="$1" my_originator="$2" my_pic_p="${3-no}" my_prefix=`$ECHO "$my_originator" | sed 's%[^a-zA-Z0-9]%_%g'` my_dlsyms= if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then if test -n "$NM" && test -n "$global_symbol_pipe"; then my_dlsyms="${my_outputname}S.c" else func_error "not configured to extract global symbols from dlpreopened files" fi fi if test -n "$my_dlsyms"; then case $my_dlsyms in "") ;; *.c) # Discover the nlist of each of the dlfiles. nlist="$output_objdir/${my_outputname}.nm" func_show_eval "$RM $nlist ${nlist}S ${nlist}T" # Parse the name list into a source file. func_verbose "creating $output_objdir/$my_dlsyms" $opt_dry_run || $ECHO > "$output_objdir/$my_dlsyms" "\ /* $my_dlsyms - symbol resolution table for \`$my_outputname' dlsym emulation. */ /* Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION */ #ifdef __cplusplus extern \"C\" { #endif #if defined(__GNUC__) && (((__GNUC__ == 4) && (__GNUC_MINOR__ >= 4)) || (__GNUC__ > 4)) #pragma GCC diagnostic ignored \"-Wstrict-prototypes\" #endif /* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ #if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE) /* DATA imports from DLLs on WIN32 con't be const, because runtime relocations are performed -- see ld's documentation on pseudo-relocs. */ # define LT_DLSYM_CONST #elif defined(__osf__) /* This system does not cope well with relocations in const data. */ # define LT_DLSYM_CONST #else # define LT_DLSYM_CONST const #endif /* External symbol declarations for the compiler. */\ " if test "$dlself" = yes; then func_verbose "generating symbol list for \`$output'" $opt_dry_run || echo ': @PROGRAM@ ' > "$nlist" # Add our own program objects to the symbol list. progfiles=`$ECHO "$objs$old_deplibs" | $SP2NL | $SED "$lo2o" | $NL2SP` for progfile in $progfiles; do func_to_tool_file "$progfile" func_convert_file_msys_to_w32 func_verbose "extracting global C symbols from \`$func_to_tool_file_result'" $opt_dry_run || eval "$NM $func_to_tool_file_result | $global_symbol_pipe >> '$nlist'" done if test -n "$exclude_expsyms"; then $opt_dry_run || { eval '$EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T' eval '$MV "$nlist"T "$nlist"' } fi if test -n "$export_symbols_regex"; then $opt_dry_run || { eval '$EGREP -e "$export_symbols_regex" "$nlist" > "$nlist"T' eval '$MV "$nlist"T "$nlist"' } fi # Prepare the list of exported symbols if test -z "$export_symbols"; then export_symbols="$output_objdir/$outputname.exp" $opt_dry_run || { $RM $export_symbols eval "${SED} -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"' case $host in *cygwin* | *mingw* | *cegcc* ) eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' eval 'cat "$export_symbols" >> "$output_objdir/$outputname.def"' ;; esac } else $opt_dry_run || { eval "${SED} -e 's/\([].[*^$]\)/\\\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$outputname.exp"' eval '$GREP -f "$output_objdir/$outputname.exp" < "$nlist" > "$nlist"T' eval '$MV "$nlist"T "$nlist"' case $host in *cygwin* | *mingw* | *cegcc* ) eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' eval 'cat "$nlist" >> "$output_objdir/$outputname.def"' ;; esac } fi fi for dlprefile in $dlprefiles; do func_verbose "extracting global C symbols from \`$dlprefile'" func_basename "$dlprefile" name="$func_basename_result" case $host in *cygwin* | *mingw* | *cegcc* ) # if an import library, we need to obtain dlname if func_win32_import_lib_p "$dlprefile"; then func_tr_sh "$dlprefile" eval "curr_lafile=\$libfile_$func_tr_sh_result" dlprefile_dlbasename="" if test -n "$curr_lafile" && func_lalib_p "$curr_lafile"; then # Use subshell, to avoid clobbering current variable values dlprefile_dlname=`source "$curr_lafile" && echo "$dlname"` if test -n "$dlprefile_dlname" ; then func_basename "$dlprefile_dlname" dlprefile_dlbasename="$func_basename_result" else # no lafile. user explicitly requested -dlpreopen <import library>. $sharedlib_from_linklib_cmd "$dlprefile" dlprefile_dlbasename=$sharedlib_from_linklib_result fi fi $opt_dry_run || { if test -n "$dlprefile_dlbasename" ; then eval '$ECHO ": $dlprefile_dlbasename" >> "$nlist"' else func_warning "Could not compute DLL name from $name" eval '$ECHO ": $name " >> "$nlist"' fi func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe | $SED -e '/I __imp/d' -e 's/I __nm_/D /;s/_nm__//' >> '$nlist'" } else # not an import lib $opt_dry_run || { eval '$ECHO ": $name " >> "$nlist"' func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'" } fi ;; *) $opt_dry_run || { eval '$ECHO ": $name " >> "$nlist"' func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'" } ;; esac done $opt_dry_run || { # Make sure we have at least an empty file. test -f "$nlist" || : > "$nlist" if test -n "$exclude_expsyms"; then $EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T $MV "$nlist"T "$nlist" fi # Try sorting and uniquifying the output. if $GREP -v "^: " < "$nlist" | if sort -k 3 </dev/null >/dev/null 2>&1; then sort -k 3 else sort +2 fi | uniq > "$nlist"S; then : else $GREP -v "^: " < "$nlist" > "$nlist"S fi if test -f "$nlist"S; then eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$my_dlsyms"' else echo '/* NONE */' >> "$output_objdir/$my_dlsyms" fi echo >> "$output_objdir/$my_dlsyms" "\ /* The mapping between symbol names and symbols. */ typedef struct { const char *name; void *address; } lt_dlsymlist; extern LT_DLSYM_CONST lt_dlsymlist lt_${my_prefix}_LTX_preloaded_symbols[]; LT_DLSYM_CONST lt_dlsymlist lt_${my_prefix}_LTX_preloaded_symbols[] = {\ { \"$my_originator\", (void *) 0 }," case $need_lib_prefix in no) eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$my_dlsyms" ;; *) eval "$global_symbol_to_c_name_address_lib_prefix" < "$nlist" >> "$output_objdir/$my_dlsyms" ;; esac echo >> "$output_objdir/$my_dlsyms" "\ {0, (void *) 0} }; /* This works around a problem in FreeBSD linker */ #ifdef FREEBSD_WORKAROUND static const void *lt_preloaded_setup() { return lt_${my_prefix}_LTX_preloaded_symbols; } #endif #ifdef __cplusplus } #endif\ " } # !$opt_dry_run pic_flag_for_symtable= case "$compile_command " in *" -static "*) ;; *) case $host in # compiling the symbol table file with pic_flag works around # a FreeBSD bug that causes programs to crash when -lm is # linked before any other PIC object. But we must not use # pic_flag when linking with -static. The problem exists in # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1. *-*-freebsd2.*|*-*-freebsd3.0*|*-*-freebsdelf3.0*) pic_flag_for_symtable=" $pic_flag -DFREEBSD_WORKAROUND" ;; *-*-hpux*) pic_flag_for_symtable=" $pic_flag" ;; *) if test "X$my_pic_p" != Xno; then pic_flag_for_symtable=" $pic_flag" fi ;; esac ;; esac symtab_cflags= for arg in $LTCFLAGS; do case $arg in -pie | -fpie | -fPIE) ;; *) func_append symtab_cflags " $arg" ;; esac done # Now compile the dynamic symbol file. func_show_eval '(cd $output_objdir && $LTCC$symtab_cflags -c$no_builtin_flag$pic_flag_for_symtable "$my_dlsyms")' 'exit $?' # Clean up the generated files. func_show_eval '$RM "$output_objdir/$my_dlsyms" "$nlist" "${nlist}S" "${nlist}T"' # Transform the symbol file into the correct name. symfileobj="$output_objdir/${my_outputname}S.$objext" case $host in *cygwin* | *mingw* | *cegcc* ) if test -f "$output_objdir/$my_outputname.def"; then compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"` finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"` else compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"` finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"` fi ;; *) compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"` finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"` ;; esac ;; *) func_fatal_error "unknown suffix for \`$my_dlsyms'" ;; esac else # We keep going just in case the user didn't refer to # lt_preloaded_symbols. The linker will fail if global_symbol_pipe # really was required. # Nullify the symbol file. compile_command=`$ECHO "$compile_command" | $SED "s% @SYMFILE@%%"` finalize_command=`$ECHO "$finalize_command" | $SED "s% @SYMFILE@%%"` fi } # func_win32_libid arg # return the library type of file 'arg' # # Need a lot of goo to handle *both* DLLs and import libs # Has to be a shell function in order to 'eat' the argument # that is supplied when $file_magic_command is called. # Despite the name, also deal with 64 bit binaries. func_win32_libid () { $opt_debug win32_libid_type="unknown" win32_fileres=`file -L $1 2>/dev/null` case $win32_fileres in *ar\ archive\ import\ library*) # definitely import win32_libid_type="x86 archive import" ;; *ar\ archive*) # could be an import, or static # Keep the egrep pattern in sync with the one in _LT_CHECK_MAGIC_METHOD. if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null | $EGREP 'file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' >/dev/null; then func_to_tool_file "$1" func_convert_file_msys_to_w32 win32_nmres=`eval $NM -f posix -A \"$func_to_tool_file_result\" | $SED -n -e ' 1,100{ / I /{ s,.*,import, p q } }'` case $win32_nmres in import*) win32_libid_type="x86 archive import";; *) win32_libid_type="x86 archive static";; esac fi ;; *DLL*) win32_libid_type="x86 DLL" ;; *executable*) # but shell scripts are "executable" too... case $win32_fileres in *MS\ Windows\ PE\ Intel*) win32_libid_type="x86 DLL" ;; esac ;; esac $ECHO "$win32_libid_type" } # func_cygming_dll_for_implib ARG # # Platform-specific function to extract the # name of the DLL associated with the specified # import library ARG. # Invoked by eval'ing the libtool variable # $sharedlib_from_linklib_cmd # Result is available in the variable # $sharedlib_from_linklib_result func_cygming_dll_for_implib () { $opt_debug sharedlib_from_linklib_result=`$DLLTOOL --identify-strict --identify "$1"` } # func_cygming_dll_for_implib_fallback_core SECTION_NAME LIBNAMEs # # The is the core of a fallback implementation of a # platform-specific function to extract the name of the # DLL associated with the specified import library LIBNAME. # # SECTION_NAME is either .idata$6 or .idata$7, depending # on the platform and compiler that created the implib. # # Echos the name of the DLL associated with the # specified import library. func_cygming_dll_for_implib_fallback_core () { $opt_debug match_literal=`$ECHO "$1" | $SED "$sed_make_literal_regex"` $OBJDUMP -s --section "$1" "$2" 2>/dev/null | $SED '/^Contents of section '"$match_literal"':/{ # Place marker at beginning of archive member dllname section s/.*/====MARK====/ p d } # These lines can sometimes be longer than 43 characters, but # are always uninteresting /:[ ]*file format pe[i]\{,1\}-/d /^In archive [^:]*:/d # Ensure marker is printed /^====MARK====/p # Remove all lines with less than 43 characters /^.\{43\}/!d # From remaining lines, remove first 43 characters s/^.\{43\}//' | $SED -n ' # Join marker and all lines until next marker into a single line /^====MARK====/ b para H $ b para b :para x s/\n//g # Remove the marker s/^====MARK====// # Remove trailing dots and whitespace s/[\. \t]*$// # Print /./p' | # we now have a list, one entry per line, of the stringified # contents of the appropriate section of all members of the # archive which possess that section. Heuristic: eliminate # all those which have a first or second character that is # a '.' (that is, objdump's representation of an unprintable # character.) This should work for all archives with less than # 0x302f exports -- but will fail for DLLs whose name actually # begins with a literal '.' or a single character followed by # a '.'. # # Of those that remain, print the first one. $SED -e '/^\./d;/^.\./d;q' } # func_cygming_gnu_implib_p ARG # This predicate returns with zero status (TRUE) if # ARG is a GNU/binutils-style import library. Returns # with nonzero status (FALSE) otherwise. func_cygming_gnu_implib_p () { $opt_debug func_to_tool_file "$1" func_convert_file_msys_to_w32 func_cygming_gnu_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $EGREP ' (_head_[A-Za-z0-9_]+_[ad]l*|[A-Za-z0-9_]+_[ad]l*_iname)$'` test -n "$func_cygming_gnu_implib_tmp" } # func_cygming_ms_implib_p ARG # This predicate returns with zero status (TRUE) if # ARG is an MS-style import library. Returns # with nonzero status (FALSE) otherwise. func_cygming_ms_implib_p () { $opt_debug func_to_tool_file "$1" func_convert_file_msys_to_w32 func_cygming_ms_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $GREP '_NULL_IMPORT_DESCRIPTOR'` test -n "$func_cygming_ms_implib_tmp" } # func_cygming_dll_for_implib_fallback ARG # Platform-specific function to extract the # name of the DLL associated with the specified # import library ARG. # # This fallback implementation is for use when $DLLTOOL # does not support the --identify-strict option. # Invoked by eval'ing the libtool variable # $sharedlib_from_linklib_cmd # Result is available in the variable # $sharedlib_from_linklib_result func_cygming_dll_for_implib_fallback () { $opt_debug if func_cygming_gnu_implib_p "$1" ; then # binutils import library sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$7' "$1"` elif func_cygming_ms_implib_p "$1" ; then # ms-generated import library sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$6' "$1"` else # unknown sharedlib_from_linklib_result="" fi } # func_extract_an_archive dir oldlib func_extract_an_archive () { $opt_debug f_ex_an_ar_dir="$1"; shift f_ex_an_ar_oldlib="$1" if test "$lock_old_archive_extraction" = yes; then lockfile=$f_ex_an_ar_oldlib.lock until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do func_echo "Waiting for $lockfile to be removed" sleep 2 done fi func_show_eval "(cd \$f_ex_an_ar_dir && $AR x \"\$f_ex_an_ar_oldlib\")" \ 'stat=$?; rm -f "$lockfile"; exit $stat' if test "$lock_old_archive_extraction" = yes; then $opt_dry_run || rm -f "$lockfile" fi if ($AR t "$f_ex_an_ar_oldlib" | sort | sort -uc >/dev/null 2>&1); then : else func_fatal_error "object name conflicts in archive: $f_ex_an_ar_dir/$f_ex_an_ar_oldlib" fi } # func_extract_archives gentop oldlib ... func_extract_archives () { $opt_debug my_gentop="$1"; shift my_oldlibs=${1+"$@"} my_oldobjs="" my_xlib="" my_xabs="" my_xdir="" for my_xlib in $my_oldlibs; do # Extract the objects. case $my_xlib in [\\/]* | [A-Za-z]:[\\/]*) my_xabs="$my_xlib" ;; *) my_xabs=`pwd`"/$my_xlib" ;; esac func_basename "$my_xlib" my_xlib="$func_basename_result" my_xlib_u=$my_xlib while :; do case " $extracted_archives " in *" $my_xlib_u "*) func_arith $extracted_serial + 1 extracted_serial=$func_arith_result my_xlib_u=lt$extracted_serial-$my_xlib ;; *) break ;; esac done extracted_archives="$extracted_archives $my_xlib_u" my_xdir="$my_gentop/$my_xlib_u" func_mkdir_p "$my_xdir" case $host in *-darwin*) func_verbose "Extracting $my_xabs" # Do not bother doing anything if just a dry run $opt_dry_run || { darwin_orig_dir=`pwd` cd $my_xdir || exit $? darwin_archive=$my_xabs darwin_curdir=`pwd` darwin_base_archive=`basename "$darwin_archive"` darwin_arches=`$LIPO -info "$darwin_archive" 2>/dev/null | $GREP Architectures 2>/dev/null || true` if test -n "$darwin_arches"; then darwin_arches=`$ECHO "$darwin_arches" | $SED -e 's/.*are://'` darwin_arch= func_verbose "$darwin_base_archive has multiple architectures $darwin_arches" for darwin_arch in $darwin_arches ; do func_mkdir_p "unfat-$$/${darwin_base_archive}-${darwin_arch}" $LIPO -thin $darwin_arch -output "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" "${darwin_archive}" cd "unfat-$$/${darwin_base_archive}-${darwin_arch}" func_extract_an_archive "`pwd`" "${darwin_base_archive}" cd "$darwin_curdir" $RM "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" done # $darwin_arches ## Okay now we've a bunch of thin objects, gotta fatten them up :) darwin_filelist=`find unfat-$$ -type f -name \*.o -print -o -name \*.lo -print | $SED -e "$basename" | sort -u` darwin_file= darwin_files= for darwin_file in $darwin_filelist; do darwin_files=`find unfat-$$ -name $darwin_file -print | sort | $NL2SP` $LIPO -create -output "$darwin_file" $darwin_files done # $darwin_filelist $RM -rf unfat-$$ cd "$darwin_orig_dir" else cd $darwin_orig_dir func_extract_an_archive "$my_xdir" "$my_xabs" fi # $darwin_arches } # !$opt_dry_run ;; *) func_extract_an_archive "$my_xdir" "$my_xabs" ;; esac my_oldobjs="$my_oldobjs "`find $my_xdir -name \*.$objext -print -o -name \*.lo -print | sort | $NL2SP` done func_extract_archives_result="$my_oldobjs" } # func_emit_wrapper [arg=no] # # Emit a libtool wrapper script on stdout. # Don't directly open a file because we may want to # incorporate the script contents within a cygwin/mingw # wrapper executable. Must ONLY be called from within # func_mode_link because it depends on a number of variables # set therein. # # ARG is the value that the WRAPPER_SCRIPT_BELONGS_IN_OBJDIR # variable will take. If 'yes', then the emitted script # will assume that the directory in which it is stored is # the $objdir directory. This is a cygwin/mingw-specific # behavior. func_emit_wrapper () { func_emit_wrapper_arg1=${1-no} $ECHO "\ #! $SHELL # $output - temporary wrapper script for $objdir/$outputname # Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION # # The $output program cannot be directly executed until all the libtool # libraries that it depends on are installed. # # This wrapper script should never be moved out of the build directory. # If it is, it will not operate correctly. # Sed substitution that helps us do robust quoting. It backslashifies # metacharacters that are still active within double-quoted strings. sed_quote_subst='$sed_quote_subst' # Be Bourne compatible if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Zsh 3.x and 4.x performs word splitting on \${1+\"\$@\"}, which # is contrary to our usage. Disable this feature. alias -g '\${1+\"\$@\"}'='\"\$@\"' setopt NO_GLOB_SUBST else case \`(set -o) 2>/dev/null\` in *posix*) set -o posix;; esac fi BIN_SH=xpg4; export BIN_SH # for Tru64 DUALCASE=1; export DUALCASE # for MKS sh # The HP-UX ksh and POSIX shell print the target directory to stdout # if CDPATH is set. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH relink_command=\"$relink_command\" # This environment variable determines our operation mode. if test \"\$libtool_install_magic\" = \"$magic\"; then # install mode needs the following variables: generated_by_libtool_version='$macro_version' notinst_deplibs='$notinst_deplibs' else # When we are sourced in execute mode, \$file and \$ECHO are already set. if test \"\$libtool_execute_magic\" != \"$magic\"; then file=\"\$0\"" qECHO=`$ECHO "$ECHO" | $SED "$sed_quote_subst"` $ECHO "\ # A function that is used when there is no print builtin or printf. func_fallback_echo () { eval 'cat <<_LTECHO_EOF \$1 _LTECHO_EOF' } ECHO=\"$qECHO\" fi # Very basic option parsing. These options are (a) specific to # the libtool wrapper, (b) are identical between the wrapper # /script/ and the wrapper /executable/ which is used only on # windows platforms, and (c) all begin with the string "--lt-" # (application programs are unlikely to have options which match # this pattern). # # There are only two supported options: --lt-debug and # --lt-dump-script. There is, deliberately, no --lt-help. # # The first argument to this parsing function should be the # script's $0 value, followed by "$@". lt_option_debug= func_parse_lt_options () { lt_script_arg0=\$0 shift for lt_opt do case \"\$lt_opt\" in --lt-debug) lt_option_debug=1 ;; --lt-dump-script) lt_dump_D=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%/[^/]*$%%'\` test \"X\$lt_dump_D\" = \"X\$lt_script_arg0\" && lt_dump_D=. lt_dump_F=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%^.*/%%'\` cat \"\$lt_dump_D/\$lt_dump_F\" exit 0 ;; --lt-*) \$ECHO \"Unrecognized --lt- option: '\$lt_opt'\" 1>&2 exit 1 ;; esac done # Print the debug banner immediately: if test -n \"\$lt_option_debug\"; then echo \"${outputname}:${output}:\${LINENO}: libtool wrapper (GNU $PACKAGE$TIMESTAMP) $VERSION\" 1>&2 fi } # Used when --lt-debug. Prints its arguments to stdout # (redirection is the responsibility of the caller) func_lt_dump_args () { lt_dump_args_N=1; for lt_arg do \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[\$lt_dump_args_N]: \$lt_arg\" lt_dump_args_N=\`expr \$lt_dump_args_N + 1\` done } # Core function for launching the target application func_exec_program_core () { " case $host in # Backslashes separate directories on plain windows *-*-mingw | *-*-os2* | *-cegcc*) $ECHO "\ if test -n \"\$lt_option_debug\"; then \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[0]: \$progdir\\\\\$program\" 1>&2 func_lt_dump_args \${1+\"\$@\"} 1>&2 fi exec \"\$progdir\\\\\$program\" \${1+\"\$@\"} " ;; *) $ECHO "\ if test -n \"\$lt_option_debug\"; then \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[0]: \$progdir/\$program\" 1>&2 func_lt_dump_args \${1+\"\$@\"} 1>&2 fi exec \"\$progdir/\$program\" \${1+\"\$@\"} " ;; esac $ECHO "\ \$ECHO \"\$0: cannot exec \$program \$*\" 1>&2 exit 1 } # A function to encapsulate launching the target application # Strips options in the --lt-* namespace from \$@ and # launches target application with the remaining arguments. func_exec_program () { case \" \$* \" in *\\ --lt-*) for lt_wr_arg do case \$lt_wr_arg in --lt-*) ;; *) set x \"\$@\" \"\$lt_wr_arg\"; shift;; esac shift done ;; esac func_exec_program_core \${1+\"\$@\"} } # Parse options func_parse_lt_options \"\$0\" \${1+\"\$@\"} # Find the directory that this script lives in. thisdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*$%%'\` test \"x\$thisdir\" = \"x\$file\" && thisdir=. # Follow symbolic links until we get to the real thisdir. file=\`ls -ld \"\$file\" | $SED -n 's/.*-> //p'\` while test -n \"\$file\"; do destdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*\$%%'\` # If there was a directory component, then change thisdir. if test \"x\$destdir\" != \"x\$file\"; then case \"\$destdir\" in [\\\\/]* | [A-Za-z]:[\\\\/]*) thisdir=\"\$destdir\" ;; *) thisdir=\"\$thisdir/\$destdir\" ;; esac fi file=\`\$ECHO \"\$file\" | $SED 's%^.*/%%'\` file=\`ls -ld \"\$thisdir/\$file\" | $SED -n 's/.*-> //p'\` done # Usually 'no', except on cygwin/mingw when embedded into # the cwrapper. WRAPPER_SCRIPT_BELONGS_IN_OBJDIR=$func_emit_wrapper_arg1 if test \"\$WRAPPER_SCRIPT_BELONGS_IN_OBJDIR\" = \"yes\"; then # special case for '.' if test \"\$thisdir\" = \".\"; then thisdir=\`pwd\` fi # remove .libs from thisdir case \"\$thisdir\" in *[\\\\/]$objdir ) thisdir=\`\$ECHO \"\$thisdir\" | $SED 's%[\\\\/][^\\\\/]*$%%'\` ;; $objdir ) thisdir=. ;; esac fi # Try to get the absolute directory name. absdir=\`cd \"\$thisdir\" && pwd\` test -n \"\$absdir\" && thisdir=\"\$absdir\" " if test "$fast_install" = yes; then $ECHO "\ program=lt-'$outputname'$exeext progdir=\"\$thisdir/$objdir\" if test ! -f \"\$progdir/\$program\" || { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | ${SED} 1q\`; \\ test \"X\$file\" != \"X\$progdir/\$program\"; }; then file=\"\$\$-\$program\" if test ! -d \"\$progdir\"; then $MKDIR \"\$progdir\" else $RM \"\$progdir/\$file\" fi" $ECHO "\ # relink executable if necessary if test -n \"\$relink_command\"; then if relink_command_output=\`eval \$relink_command 2>&1\`; then : else $ECHO \"\$relink_command_output\" >&2 $RM \"\$progdir/\$file\" exit 1 fi fi $MV \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null || { $RM \"\$progdir/\$program\"; $MV \"\$progdir/\$file\" \"\$progdir/\$program\"; } $RM \"\$progdir/\$file\" fi" else $ECHO "\ program='$outputname' progdir=\"\$thisdir/$objdir\" " fi $ECHO "\ if test -f \"\$progdir/\$program\"; then" # fixup the dll searchpath if we need to. # # Fix the DLL searchpath if we need to. Do this before prepending # to shlibpath, because on Windows, both are PATH and uninstalled # libraries must come first. if test -n "$dllsearchpath"; then $ECHO "\ # Add the dll search path components to the executable PATH PATH=$dllsearchpath:\$PATH " fi # Export our shlibpath_var if we have one. if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then $ECHO "\ # Add our own library path to $shlibpath_var $shlibpath_var=\"$temp_rpath\$$shlibpath_var\" # Some systems cannot cope with colon-terminated $shlibpath_var # The second colon is a workaround for a bug in BeOS R4 sed $shlibpath_var=\`\$ECHO \"\$$shlibpath_var\" | $SED 's/::*\$//'\` export $shlibpath_var " fi $ECHO "\ if test \"\$libtool_execute_magic\" != \"$magic\"; then # Run the actual program with our arguments. func_exec_program \${1+\"\$@\"} fi else # The program doesn't exist. \$ECHO \"\$0: error: \\\`\$progdir/\$program' does not exist\" 1>&2 \$ECHO \"This script is just a wrapper for \$program.\" 1>&2 \$ECHO \"See the $PACKAGE documentation for more information.\" 1>&2 exit 1 fi fi\ " } # func_emit_cwrapperexe_src # emit the source code for a wrapper executable on stdout # Must ONLY be called from within func_mode_link because # it depends on a number of variable set therein. func_emit_cwrapperexe_src () { cat <<EOF /* $cwrappersource - temporary wrapper executable for $objdir/$outputname Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION The $output program cannot be directly executed until all the libtool libraries that it depends on are installed. This wrapper executable should never be moved out of the build directory. If it is, it will not operate correctly. */ EOF cat <<"EOF" #ifdef _MSC_VER # define _CRT_SECURE_NO_DEPRECATE 1 #endif #include <stdio.h> #include <stdlib.h> #ifdef _MSC_VER # include <direct.h> # include <process.h> # include <io.h> #else # include <unistd.h> # include <stdint.h> # ifdef __CYGWIN__ # include <io.h> # endif #endif #include <malloc.h> #include <stdarg.h> #include <assert.h> #include <string.h> #include <ctype.h> #include <errno.h> #include <fcntl.h> #include <sys/stat.h> /* declarations of non-ANSI functions */ #if defined(__MINGW32__) # ifdef __STRICT_ANSI__ int _putenv (const char *); # endif #elif defined(__CYGWIN__) # ifdef __STRICT_ANSI__ char *realpath (const char *, char *); int putenv (char *); int setenv (const char *, const char *, int); # endif /* #elif defined (other platforms) ... */ #endif /* portability defines, excluding path handling macros */ #if defined(_MSC_VER) # define setmode _setmode # define stat _stat # define chmod _chmod # define getcwd _getcwd # define putenv _putenv # define S_IXUSR _S_IEXEC # ifndef _INTPTR_T_DEFINED # define _INTPTR_T_DEFINED # define intptr_t int # endif #elif defined(__MINGW32__) # define setmode _setmode # define stat _stat # define chmod _chmod # define getcwd _getcwd # define putenv _putenv #elif defined(__CYGWIN__) # define HAVE_SETENV # define FOPEN_WB "wb" /* #elif defined (other platforms) ... */ #endif #if defined(PATH_MAX) # define LT_PATHMAX PATH_MAX #elif defined(MAXPATHLEN) # define LT_PATHMAX MAXPATHLEN #else # define LT_PATHMAX 1024 #endif #ifndef S_IXOTH # define S_IXOTH 0 #endif #ifndef S_IXGRP # define S_IXGRP 0 #endif /* path handling portability macros */ #ifndef DIR_SEPARATOR # define DIR_SEPARATOR '/' # define PATH_SEPARATOR ':' #endif #if defined (_WIN32) || defined (__MSDOS__) || defined (__DJGPP__) || \ defined (__OS2__) # define HAVE_DOS_BASED_FILE_SYSTEM # define FOPEN_WB "wb" # ifndef DIR_SEPARATOR_2 # define DIR_SEPARATOR_2 '\\' # endif # ifndef PATH_SEPARATOR_2 # define PATH_SEPARATOR_2 ';' # endif #endif #ifndef DIR_SEPARATOR_2 # define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR) #else /* DIR_SEPARATOR_2 */ # define IS_DIR_SEPARATOR(ch) \ (((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2)) #endif /* DIR_SEPARATOR_2 */ #ifndef PATH_SEPARATOR_2 # define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR) #else /* PATH_SEPARATOR_2 */ # define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR_2) #endif /* PATH_SEPARATOR_2 */ #ifndef FOPEN_WB # define FOPEN_WB "w" #endif #ifndef _O_BINARY # define _O_BINARY 0 #endif #define XMALLOC(type, num) ((type *) xmalloc ((num) * sizeof(type))) #define XFREE(stale) do { \ if (stale) { free ((void *) stale); stale = 0; } \ } while (0) #if defined(LT_DEBUGWRAPPER) static int lt_debug = 1; #else static int lt_debug = 0; #endif const char *program_name = "libtool-wrapper"; /* in case xstrdup fails */ void *xmalloc (size_t num); char *xstrdup (const char *string); const char *base_name (const char *name); char *find_executable (const char *wrapper); char *chase_symlinks (const char *pathspec); int make_executable (const char *path); int check_executable (const char *path); char *strendzap (char *str, const char *pat); void lt_debugprintf (const char *file, int line, const char *fmt, ...); void lt_fatal (const char *file, int line, const char *message, ...); static const char *nonnull (const char *s); static const char *nonempty (const char *s); void lt_setenv (const char *name, const char *value); char *lt_extend_str (const char *orig_value, const char *add, int to_end); void lt_update_exe_path (const char *name, const char *value); void lt_update_lib_path (const char *name, const char *value); char **prepare_spawn (char **argv); void lt_dump_script (FILE *f); EOF cat <<EOF volatile const char * MAGIC_EXE = "$magic_exe"; const char * LIB_PATH_VARNAME = "$shlibpath_var"; EOF if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then func_to_host_path "$temp_rpath" cat <<EOF const char * LIB_PATH_VALUE = "$func_to_host_path_result"; EOF else cat <<"EOF" const char * LIB_PATH_VALUE = ""; EOF fi if test -n "$dllsearchpath"; then func_to_host_path "$dllsearchpath:" cat <<EOF const char * EXE_PATH_VARNAME = "PATH"; const char * EXE_PATH_VALUE = "$func_to_host_path_result"; EOF else cat <<"EOF" const char * EXE_PATH_VARNAME = ""; const char * EXE_PATH_VALUE = ""; EOF fi if test "$fast_install" = yes; then cat <<EOF const char * TARGET_PROGRAM_NAME = "lt-$outputname"; /* hopefully, no .exe */ EOF else cat <<EOF const char * TARGET_PROGRAM_NAME = "$outputname"; /* hopefully, no .exe */ EOF fi cat <<"EOF" #define LTWRAPPER_OPTION_PREFIX "--lt-" static const char *ltwrapper_option_prefix = LTWRAPPER_OPTION_PREFIX; static const char *dumpscript_opt = LTWRAPPER_OPTION_PREFIX "dump-script"; static const char *debug_opt = LTWRAPPER_OPTION_PREFIX "debug"; int main (int argc, char *argv[]) { char **newargz; int newargc; char *tmp_pathspec; char *actual_cwrapper_path; char *actual_cwrapper_name; char *target_name; char *lt_argv_zero; intptr_t rval = 127; int i; program_name = (char *) xstrdup (base_name (argv[0])); newargz = XMALLOC (char *, argc + 1); /* very simple arg parsing; don't want to rely on getopt * also, copy all non cwrapper options to newargz, except * argz[0], which is handled differently */ newargc=0; for (i = 1; i < argc; i++) { if (strcmp (argv[i], dumpscript_opt) == 0) { EOF case "$host" in *mingw* | *cygwin* ) # make stdout use "unix" line endings echo " setmode(1,_O_BINARY);" ;; esac cat <<"EOF" lt_dump_script (stdout); return 0; } if (strcmp (argv[i], debug_opt) == 0) { lt_debug = 1; continue; } if (strcmp (argv[i], ltwrapper_option_prefix) == 0) { /* however, if there is an option in the LTWRAPPER_OPTION_PREFIX namespace, but it is not one of the ones we know about and have already dealt with, above (inluding dump-script), then report an error. Otherwise, targets might begin to believe they are allowed to use options in the LTWRAPPER_OPTION_PREFIX namespace. The first time any user complains about this, we'll need to make LTWRAPPER_OPTION_PREFIX a configure-time option or a configure.ac-settable value. */ lt_fatal (__FILE__, __LINE__, "unrecognized %s option: '%s'", ltwrapper_option_prefix, argv[i]); } /* otherwise ... */ newargz[++newargc] = xstrdup (argv[i]); } newargz[++newargc] = NULL; EOF cat <<EOF /* The GNU banner must be the first non-error debug message */ lt_debugprintf (__FILE__, __LINE__, "libtool wrapper (GNU $PACKAGE$TIMESTAMP) $VERSION\n"); EOF cat <<"EOF" lt_debugprintf (__FILE__, __LINE__, "(main) argv[0]: %s\n", argv[0]); lt_debugprintf (__FILE__, __LINE__, "(main) program_name: %s\n", program_name); tmp_pathspec = find_executable (argv[0]); if (tmp_pathspec == NULL) lt_fatal (__FILE__, __LINE__, "couldn't find %s", argv[0]); lt_debugprintf (__FILE__, __LINE__, "(main) found exe (before symlink chase) at: %s\n", tmp_pathspec); actual_cwrapper_path = chase_symlinks (tmp_pathspec); lt_debugprintf (__FILE__, __LINE__, "(main) found exe (after symlink chase) at: %s\n", actual_cwrapper_path); XFREE (tmp_pathspec); actual_cwrapper_name = xstrdup (base_name (actual_cwrapper_path)); strendzap (actual_cwrapper_path, actual_cwrapper_name); /* wrapper name transforms */ strendzap (actual_cwrapper_name, ".exe"); tmp_pathspec = lt_extend_str (actual_cwrapper_name, ".exe", 1); XFREE (actual_cwrapper_name); actual_cwrapper_name = tmp_pathspec; tmp_pathspec = 0; /* target_name transforms -- use actual target program name; might have lt- prefix */ target_name = xstrdup (base_name (TARGET_PROGRAM_NAME)); strendzap (target_name, ".exe"); tmp_pathspec = lt_extend_str (target_name, ".exe", 1); XFREE (target_name); target_name = tmp_pathspec; tmp_pathspec = 0; lt_debugprintf (__FILE__, __LINE__, "(main) libtool target name: %s\n", target_name); EOF cat <<EOF newargz[0] = XMALLOC (char, (strlen (actual_cwrapper_path) + strlen ("$objdir") + 1 + strlen (actual_cwrapper_name) + 1)); strcpy (newargz[0], actual_cwrapper_path); strcat (newargz[0], "$objdir"); strcat (newargz[0], "/"); EOF cat <<"EOF" /* stop here, and copy so we don't have to do this twice */ tmp_pathspec = xstrdup (newargz[0]); /* do NOT want the lt- prefix here, so use actual_cwrapper_name */ strcat (newargz[0], actual_cwrapper_name); /* DO want the lt- prefix here if it exists, so use target_name */ lt_argv_zero = lt_extend_str (tmp_pathspec, target_name, 1); XFREE (tmp_pathspec); tmp_pathspec = NULL; EOF case $host_os in mingw*) cat <<"EOF" { char* p; while ((p = strchr (newargz[0], '\\')) != NULL) { *p = '/'; } while ((p = strchr (lt_argv_zero, '\\')) != NULL) { *p = '/'; } } EOF ;; esac cat <<"EOF" XFREE (target_name); XFREE (actual_cwrapper_path); XFREE (actual_cwrapper_name); lt_setenv ("BIN_SH", "xpg4"); /* for Tru64 */ lt_setenv ("DUALCASE", "1"); /* for MSK sh */ /* Update the DLL searchpath. EXE_PATH_VALUE ($dllsearchpath) must be prepended before (that is, appear after) LIB_PATH_VALUE ($temp_rpath) because on Windows, both *_VARNAMEs are PATH but uninstalled libraries must come first. */ lt_update_exe_path (EXE_PATH_VARNAME, EXE_PATH_VALUE); lt_update_lib_path (LIB_PATH_VARNAME, LIB_PATH_VALUE); lt_debugprintf (__FILE__, __LINE__, "(main) lt_argv_zero: %s\n", nonnull (lt_argv_zero)); for (i = 0; i < newargc; i++) { lt_debugprintf (__FILE__, __LINE__, "(main) newargz[%d]: %s\n", i, nonnull (newargz[i])); } EOF case $host_os in mingw*) cat <<"EOF" /* execv doesn't actually work on mingw as expected on unix */ newargz = prepare_spawn (newargz); rval = _spawnv (_P_WAIT, lt_argv_zero, (const char * const *) newargz); if (rval == -1) { /* failed to start process */ lt_debugprintf (__FILE__, __LINE__, "(main) failed to launch target \"%s\": %s\n", lt_argv_zero, nonnull (strerror (errno))); return 127; } return rval; EOF ;; *) cat <<"EOF" execv (lt_argv_zero, newargz); return rval; /* =127, but avoids unused variable warning */ EOF ;; esac cat <<"EOF" } void * xmalloc (size_t num) { void *p = (void *) malloc (num); if (!p) lt_fatal (__FILE__, __LINE__, "memory exhausted"); return p; } char * xstrdup (const char *string) { return string ? strcpy ((char *) xmalloc (strlen (string) + 1), string) : NULL; } const char * base_name (const char *name) { const char *base; #if defined (HAVE_DOS_BASED_FILE_SYSTEM) /* Skip over the disk name in MSDOS pathnames. */ if (isalpha ((unsigned char) name[0]) && name[1] == ':') name += 2; #endif for (base = name; *name; name++) if (IS_DIR_SEPARATOR (*name)) base = name + 1; return base; } int check_executable (const char *path) { struct stat st; lt_debugprintf (__FILE__, __LINE__, "(check_executable): %s\n", nonempty (path)); if ((!path) || (!*path)) return 0; if ((stat (path, &st) >= 0) && (st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH))) return 1; else return 0; } int make_executable (const char *path) { int rval = 0; struct stat st; lt_debugprintf (__FILE__, __LINE__, "(make_executable): %s\n", nonempty (path)); if ((!path) || (!*path)) return 0; if (stat (path, &st) >= 0) { rval = chmod (path, st.st_mode | S_IXOTH | S_IXGRP | S_IXUSR); } return rval; } /* Searches for the full path of the wrapper. Returns newly allocated full path name if found, NULL otherwise Does not chase symlinks, even on platforms that support them. */ char * find_executable (const char *wrapper) { int has_slash = 0; const char *p; const char *p_next; /* static buffer for getcwd */ char tmp[LT_PATHMAX + 1]; int tmp_len; char *concat_name; lt_debugprintf (__FILE__, __LINE__, "(find_executable): %s\n", nonempty (wrapper)); if ((wrapper == NULL) || (*wrapper == '\0')) return NULL; /* Absolute path? */ #if defined (HAVE_DOS_BASED_FILE_SYSTEM) if (isalpha ((unsigned char) wrapper[0]) && wrapper[1] == ':') { concat_name = xstrdup (wrapper); if (check_executable (concat_name)) return concat_name; XFREE (concat_name); } else { #endif if (IS_DIR_SEPARATOR (wrapper[0])) { concat_name = xstrdup (wrapper); if (check_executable (concat_name)) return concat_name; XFREE (concat_name); } #if defined (HAVE_DOS_BASED_FILE_SYSTEM) } #endif for (p = wrapper; *p; p++) if (*p == '/') { has_slash = 1; break; } if (!has_slash) { /* no slashes; search PATH */ const char *path = getenv ("PATH"); if (path != NULL) { for (p = path; *p; p = p_next) { const char *q; size_t p_len; for (q = p; *q; q++) if (IS_PATH_SEPARATOR (*q)) break; p_len = q - p; p_next = (*q == '\0' ? q : q + 1); if (p_len == 0) { /* empty path: current directory */ if (getcwd (tmp, LT_PATHMAX) == NULL) lt_fatal (__FILE__, __LINE__, "getcwd failed: %s", nonnull (strerror (errno))); tmp_len = strlen (tmp); concat_name = XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1); memcpy (concat_name, tmp, tmp_len); concat_name[tmp_len] = '/'; strcpy (concat_name + tmp_len + 1, wrapper); } else { concat_name = XMALLOC (char, p_len + 1 + strlen (wrapper) + 1); memcpy (concat_name, p, p_len); concat_name[p_len] = '/'; strcpy (concat_name + p_len + 1, wrapper); } if (check_executable (concat_name)) return concat_name; XFREE (concat_name); } } /* not found in PATH; assume curdir */ } /* Relative path | not found in path: prepend cwd */ if (getcwd (tmp, LT_PATHMAX) == NULL) lt_fatal (__FILE__, __LINE__, "getcwd failed: %s", nonnull (strerror (errno))); tmp_len = strlen (tmp); concat_name = XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1); memcpy (concat_name, tmp, tmp_len); concat_name[tmp_len] = '/'; strcpy (concat_name + tmp_len + 1, wrapper); if (check_executable (concat_name)) return concat_name; XFREE (concat_name); return NULL; } char * chase_symlinks (const char *pathspec) { #ifndef S_ISLNK return xstrdup (pathspec); #else char buf[LT_PATHMAX]; struct stat s; char *tmp_pathspec = xstrdup (pathspec); char *p; int has_symlinks = 0; while (strlen (tmp_pathspec) && !has_symlinks) { lt_debugprintf (__FILE__, __LINE__, "checking path component for symlinks: %s\n", tmp_pathspec); if (lstat (tmp_pathspec, &s) == 0) { if (S_ISLNK (s.st_mode) != 0) { has_symlinks = 1; break; } /* search backwards for last DIR_SEPARATOR */ p = tmp_pathspec + strlen (tmp_pathspec) - 1; while ((p > tmp_pathspec) && (!IS_DIR_SEPARATOR (*p))) p--; if ((p == tmp_pathspec) && (!IS_DIR_SEPARATOR (*p))) { /* no more DIR_SEPARATORS left */ break; } *p = '\0'; } else { lt_fatal (__FILE__, __LINE__, "error accessing file \"%s\": %s", tmp_pathspec, nonnull (strerror (errno))); } } XFREE (tmp_pathspec); if (!has_symlinks) { return xstrdup (pathspec); } tmp_pathspec = realpath (pathspec, buf); if (tmp_pathspec == 0) { lt_fatal (__FILE__, __LINE__, "could not follow symlinks for %s", pathspec); } return xstrdup (tmp_pathspec); #endif } char * strendzap (char *str, const char *pat) { size_t len, patlen; assert (str != NULL); assert (pat != NULL); len = strlen (str); patlen = strlen (pat); if (patlen <= len) { str += len - patlen; if (strcmp (str, pat) == 0) *str = '\0'; } return str; } void lt_debugprintf (const char *file, int line, const char *fmt, ...) { va_list args; if (lt_debug) { (void) fprintf (stderr, "%s:%s:%d: ", program_name, file, line); va_start (args, fmt); (void) vfprintf (stderr, fmt, args); va_end (args); } } static void lt_error_core (int exit_status, const char *file, int line, const char *mode, const char *message, va_list ap) { fprintf (stderr, "%s:%s:%d: %s: ", program_name, file, line, mode); vfprintf (stderr, message, ap); fprintf (stderr, ".\n"); if (exit_status >= 0) exit (exit_status); } void lt_fatal (const char *file, int line, const char *message, ...) { va_list ap; va_start (ap, message); lt_error_core (EXIT_FAILURE, file, line, "FATAL", message, ap); va_end (ap); } static const char * nonnull (const char *s) { return s ? s : "(null)"; } static const char * nonempty (const char *s) { return (s && !*s) ? "(empty)" : nonnull (s); } void lt_setenv (const char *name, const char *value) { lt_debugprintf (__FILE__, __LINE__, "(lt_setenv) setting '%s' to '%s'\n", nonnull (name), nonnull (value)); { #ifdef HAVE_SETENV /* always make a copy, for consistency with !HAVE_SETENV */ char *str = xstrdup (value); setenv (name, str, 1); #else int len = strlen (name) + 1 + strlen (value) + 1; char *str = XMALLOC (char, len); sprintf (str, "%s=%s", name, value); if (putenv (str) != EXIT_SUCCESS) { XFREE (str); } #endif } } char * lt_extend_str (const char *orig_value, const char *add, int to_end) { char *new_value; if (orig_value && *orig_value) { int orig_value_len = strlen (orig_value); int add_len = strlen (add); new_value = XMALLOC (char, add_len + orig_value_len + 1); if (to_end) { strcpy (new_value, orig_value); strcpy (new_value + orig_value_len, add); } else { strcpy (new_value, add); strcpy (new_value + add_len, orig_value); } } else { new_value = xstrdup (add); } return new_value; } void lt_update_exe_path (const char *name, const char *value) { lt_debugprintf (__FILE__, __LINE__, "(lt_update_exe_path) modifying '%s' by prepending '%s'\n", nonnull (name), nonnull (value)); if (name && *name && value && *value) { char *new_value = lt_extend_str (getenv (name), value, 0); /* some systems can't cope with a ':'-terminated path #' */ int len = strlen (new_value); while (((len = strlen (new_value)) > 0) && IS_PATH_SEPARATOR (new_value[len-1])) { new_value[len-1] = '\0'; } lt_setenv (name, new_value); XFREE (new_value); } } void lt_update_lib_path (const char *name, const char *value) { lt_debugprintf (__FILE__, __LINE__, "(lt_update_lib_path) modifying '%s' by prepending '%s'\n", nonnull (name), nonnull (value)); if (name && *name && value && *value) { char *new_value = lt_extend_str (getenv (name), value, 0); lt_setenv (name, new_value); XFREE (new_value); } } EOF case $host_os in mingw*) cat <<"EOF" /* Prepares an argument vector before calling spawn(). Note that spawn() does not by itself call the command interpreter (getenv ("COMSPEC") != NULL ? getenv ("COMSPEC") : ({ OSVERSIONINFO v; v.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); GetVersionEx(&v); v.dwPlatformId == VER_PLATFORM_WIN32_NT; }) ? "cmd.exe" : "command.com"). Instead it simply concatenates the arguments, separated by ' ', and calls CreateProcess(). We must quote the arguments since Win32 CreateProcess() interprets characters like ' ', '\t', '\\', '"' (but not '<' and '>') in a special way: - Space and tab are interpreted as delimiters. They are not treated as delimiters if they are surrounded by double quotes: "...". - Unescaped double quotes are removed from the input. Their only effect is that within double quotes, space and tab are treated like normal characters. - Backslashes not followed by double quotes are not special. - But 2*n+1 backslashes followed by a double quote become n backslashes followed by a double quote (n >= 0): \" -> " \\\" -> \" \\\\\" -> \\" */ #define SHELL_SPECIAL_CHARS "\"\\ \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037" #define SHELL_SPACE_CHARS " \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037" char ** prepare_spawn (char **argv) { size_t argc; char **new_argv; size_t i; /* Count number of arguments. */ for (argc = 0; argv[argc] != NULL; argc++) ; /* Allocate new argument vector. */ new_argv = XMALLOC (char *, argc + 1); /* Put quoted arguments into the new argument vector. */ for (i = 0; i < argc; i++) { const char *string = argv[i]; if (string[0] == '\0') new_argv[i] = xstrdup ("\"\""); else if (strpbrk (string, SHELL_SPECIAL_CHARS) != NULL) { int quote_around = (strpbrk (string, SHELL_SPACE_CHARS) != NULL); size_t length; unsigned int backslashes; const char *s; char *quoted_string; char *p; length = 0; backslashes = 0; if (quote_around) length++; for (s = string; *s != '\0'; s++) { char c = *s; if (c == '"') length += backslashes + 1; length++; if (c == '\\') backslashes++; else backslashes = 0; } if (quote_around) length += backslashes + 1; quoted_string = XMALLOC (char, length + 1); p = quoted_string; backslashes = 0; if (quote_around) *p++ = '"'; for (s = string; *s != '\0'; s++) { char c = *s; if (c == '"') { unsigned int j; for (j = backslashes + 1; j > 0; j--) *p++ = '\\'; } *p++ = c; if (c == '\\') backslashes++; else backslashes = 0; } if (quote_around) { unsigned int j; for (j = backslashes; j > 0; j--) *p++ = '\\'; *p++ = '"'; } *p = '\0'; new_argv[i] = quoted_string; } else new_argv[i] = (char *) string; } new_argv[argc] = NULL; return new_argv; } EOF ;; esac cat <<"EOF" void lt_dump_script (FILE* f) { EOF func_emit_wrapper yes | $SED -n -e ' s/^\(.\{79\}\)\(..*\)/\1\ \2/ h s/\([\\"]\)/\\\1/g s/$/\\n/ s/\([^\n]*\).*/ fputs ("\1", f);/p g D' cat <<"EOF" } EOF } # end: func_emit_cwrapperexe_src # func_win32_import_lib_p ARG # True if ARG is an import lib, as indicated by $file_magic_cmd func_win32_import_lib_p () { $opt_debug case `eval $file_magic_cmd \"\$1\" 2>/dev/null | $SED -e 10q` in *import*) : ;; *) false ;; esac } # func_mode_link arg... func_mode_link () { $opt_debug case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) # It is impossible to link a dll without this setting, and # we shouldn't force the makefile maintainer to figure out # which system we are compiling for in order to pass an extra # flag for every libtool invocation. # allow_undefined=no # FIXME: Unfortunately, there are problems with the above when trying # to make a dll which has undefined symbols, in which case not # even a static library is built. For now, we need to specify # -no-undefined on the libtool link line when we can be certain # that all symbols are satisfied, otherwise we get a static library. allow_undefined=yes ;; *) allow_undefined=yes ;; esac libtool_args=$nonopt base_compile="$nonopt $@" compile_command=$nonopt finalize_command=$nonopt compile_rpath= finalize_rpath= compile_shlibpath= finalize_shlibpath= convenience= old_convenience= deplibs= old_deplibs= compiler_flags= linker_flags= dllsearchpath= lib_search_path=`pwd` inst_prefix_dir= new_inherited_linker_flags= avoid_version=no bindir= dlfiles= dlprefiles= dlself=no export_dynamic=no export_symbols= export_symbols_regex= generated= libobjs= ltlibs= module=no no_install=no objs= non_pic_objects= precious_files_regex= prefer_static_libs=no preload=no prev= prevarg= release= rpath= xrpath= perm_rpath= temp_rpath= thread_safe=no vinfo= vinfo_number=no weak_libs= single_module="${wl}-single_module" func_infer_tag $base_compile # We need to know -static, to get the right output filenames. for arg do case $arg in -shared) test "$build_libtool_libs" != yes && \ func_fatal_configuration "can not build a shared library" build_old_libs=no break ;; -all-static | -static | -static-libtool-libs) case $arg in -all-static) if test "$build_libtool_libs" = yes && test -z "$link_static_flag"; then func_warning "complete static linking is impossible in this configuration" fi if test -n "$link_static_flag"; then dlopen_self=$dlopen_self_static fi prefer_static_libs=yes ;; -static) if test -z "$pic_flag" && test -n "$link_static_flag"; then dlopen_self=$dlopen_self_static fi prefer_static_libs=built ;; -static-libtool-libs) if test -z "$pic_flag" && test -n "$link_static_flag"; then dlopen_self=$dlopen_self_static fi prefer_static_libs=yes ;; esac build_libtool_libs=no build_old_libs=yes break ;; esac done # See if our shared archives depend on static archives. test -n "$old_archive_from_new_cmds" && build_old_libs=yes # Go through the arguments, transforming them on the way. while test "$#" -gt 0; do arg="$1" shift func_quote_for_eval "$arg" qarg=$func_quote_for_eval_unquoted_result func_append libtool_args " $func_quote_for_eval_result" # If the previous option needs an argument, assign it. if test -n "$prev"; then case $prev in output) func_append compile_command " @OUTPUT@" func_append finalize_command " @OUTPUT@" ;; esac case $prev in bindir) bindir="$arg" prev= continue ;; dlfiles|dlprefiles) if test "$preload" = no; then # Add the symbol object into the linking commands. func_append compile_command " @SYMFILE@" func_append finalize_command " @SYMFILE@" preload=yes fi case $arg in *.la | *.lo) ;; # We handle these cases below. force) if test "$dlself" = no; then dlself=needless export_dynamic=yes fi prev= continue ;; self) if test "$prev" = dlprefiles; then dlself=yes elif test "$prev" = dlfiles && test "$dlopen_self" != yes; then dlself=yes else dlself=needless export_dynamic=yes fi prev= continue ;; *) if test "$prev" = dlfiles; then func_append dlfiles " $arg" else func_append dlprefiles " $arg" fi prev= continue ;; esac ;; expsyms) export_symbols="$arg" test -f "$arg" \ || func_fatal_error "symbol file \`$arg' does not exist" prev= continue ;; expsyms_regex) export_symbols_regex="$arg" prev= continue ;; framework) case $host in *-*-darwin*) case "$deplibs " in *" $qarg.ltframework "*) ;; *) func_append deplibs " $qarg.ltframework" # this is fixed later ;; esac ;; esac prev= continue ;; inst_prefix) inst_prefix_dir="$arg" prev= continue ;; objectlist) if test -f "$arg"; then save_arg=$arg moreargs= for fil in `cat "$save_arg"` do # func_append moreargs " $fil" arg=$fil # A libtool-controlled object. # Check to see that this really is a libtool object. if func_lalib_unsafe_p "$arg"; then pic_object= non_pic_object= # Read the .lo file func_source "$arg" if test -z "$pic_object" || test -z "$non_pic_object" || test "$pic_object" = none && test "$non_pic_object" = none; then func_fatal_error "cannot find name of object for \`$arg'" fi # Extract subdirectory from the argument. func_dirname "$arg" "/" "" xdir="$func_dirname_result" if test "$pic_object" != none; then # Prepend the subdirectory the object is found in. pic_object="$xdir$pic_object" if test "$prev" = dlfiles; then if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then func_append dlfiles " $pic_object" prev= continue else # If libtool objects are unsupported, then we need to preload. prev=dlprefiles fi fi # CHECK ME: I think I busted this. -Ossama if test "$prev" = dlprefiles; then # Preload the old-style object. func_append dlprefiles " $pic_object" prev= fi # A PIC object. func_append libobjs " $pic_object" arg="$pic_object" fi # Non-PIC object. if test "$non_pic_object" != none; then # Prepend the subdirectory the object is found in. non_pic_object="$xdir$non_pic_object" # A standard non-PIC object func_append non_pic_objects " $non_pic_object" if test -z "$pic_object" || test "$pic_object" = none ; then arg="$non_pic_object" fi else # If the PIC object exists, use it instead. # $xdir was prepended to $pic_object above. non_pic_object="$pic_object" func_append non_pic_objects " $non_pic_object" fi else # Only an error if not doing a dry-run. if $opt_dry_run; then # Extract subdirectory from the argument. func_dirname "$arg" "/" "" xdir="$func_dirname_result" func_lo2o "$arg" pic_object=$xdir$objdir/$func_lo2o_result non_pic_object=$xdir$func_lo2o_result func_append libobjs " $pic_object" func_append non_pic_objects " $non_pic_object" else func_fatal_error "\`$arg' is not a valid libtool object" fi fi done else func_fatal_error "link input file \`$arg' does not exist" fi arg=$save_arg prev= continue ;; precious_regex) precious_files_regex="$arg" prev= continue ;; release) release="-$arg" prev= continue ;; rpath | xrpath) # We need an absolute path. case $arg in [\\/]* | [A-Za-z]:[\\/]*) ;; *) func_fatal_error "only absolute run-paths are allowed" ;; esac if test "$prev" = rpath; then case "$rpath " in *" $arg "*) ;; *) func_append rpath " $arg" ;; esac else case "$xrpath " in *" $arg "*) ;; *) func_append xrpath " $arg" ;; esac fi prev= continue ;; shrext) shrext_cmds="$arg" prev= continue ;; weak) func_append weak_libs " $arg" prev= continue ;; xcclinker) func_append linker_flags " $qarg" func_append compiler_flags " $qarg" prev= func_append compile_command " $qarg" func_append finalize_command " $qarg" continue ;; xcompiler) func_append compiler_flags " $qarg" prev= func_append compile_command " $qarg" func_append finalize_command " $qarg" continue ;; xlinker) func_append linker_flags " $qarg" func_append compiler_flags " $wl$qarg" prev= func_append compile_command " $wl$qarg" func_append finalize_command " $wl$qarg" continue ;; *) eval "$prev=\"\$arg\"" prev= continue ;; esac fi # test -n "$prev" prevarg="$arg" case $arg in -all-static) if test -n "$link_static_flag"; then # See comment for -static flag below, for more details. func_append compile_command " $link_static_flag" func_append finalize_command " $link_static_flag" fi continue ;; -allow-undefined) # FIXME: remove this flag sometime in the future. func_fatal_error "\`-allow-undefined' must not be used because it is the default" ;; -avoid-version) avoid_version=yes continue ;; -bindir) prev=bindir continue ;; -dlopen) prev=dlfiles continue ;; -dlpreopen) prev=dlprefiles continue ;; -export-dynamic) export_dynamic=yes continue ;; -export-symbols | -export-symbols-regex) if test -n "$export_symbols" || test -n "$export_symbols_regex"; then func_fatal_error "more than one -exported-symbols argument is not allowed" fi if test "X$arg" = "X-export-symbols"; then prev=expsyms else prev=expsyms_regex fi continue ;; -framework) prev=framework continue ;; -inst-prefix-dir) prev=inst_prefix continue ;; # The native IRIX linker understands -LANG:*, -LIST:* and -LNO:* # so, if we see these flags be careful not to treat them like -L -L[A-Z][A-Z]*:*) case $with_gcc/$host in no/*-*-irix* | /*-*-irix*) func_append compile_command " $arg" func_append finalize_command " $arg" ;; esac continue ;; -L*) func_stripname "-L" '' "$arg" if test -z "$func_stripname_result"; then if test "$#" -gt 0; then func_fatal_error "require no space between \`-L' and \`$1'" else func_fatal_error "need path for \`-L' option" fi fi func_resolve_sysroot "$func_stripname_result" dir=$func_resolve_sysroot_result # We need an absolute path. case $dir in [\\/]* | [A-Za-z]:[\\/]*) ;; *) absdir=`cd "$dir" && pwd` test -z "$absdir" && \ func_fatal_error "cannot determine absolute directory name of \`$dir'" dir="$absdir" ;; esac case "$deplibs " in *" -L$dir "* | *" $arg "*) # Will only happen for absolute or sysroot arguments ;; *) # Preserve sysroot, but never include relative directories case $dir in [\\/]* | [A-Za-z]:[\\/]* | =*) func_append deplibs " $arg" ;; *) func_append deplibs " -L$dir" ;; esac func_append lib_search_path " $dir" ;; esac case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) testbindir=`$ECHO "$dir" | $SED 's*/lib$*/bin*'` case :$dllsearchpath: in *":$dir:"*) ;; ::) dllsearchpath=$dir;; *) func_append dllsearchpath ":$dir";; esac case :$dllsearchpath: in *":$testbindir:"*) ;; ::) dllsearchpath=$testbindir;; *) func_append dllsearchpath ":$testbindir";; esac ;; esac continue ;; -l*) if test "X$arg" = "X-lc" || test "X$arg" = "X-lm"; then case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-beos* | *-cegcc* | *-*-haiku*) # These systems don't actually have a C or math library (as such) continue ;; *-*-os2*) # These systems don't actually have a C library (as such) test "X$arg" = "X-lc" && continue ;; *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) # Do not include libc due to us having libc/libc_r. test "X$arg" = "X-lc" && continue ;; *-*-rhapsody* | *-*-darwin1.[012]) # Rhapsody C and math libraries are in the System framework func_append deplibs " System.ltframework" continue ;; *-*-sco3.2v5* | *-*-sco5v6*) # Causes problems with __ctype test "X$arg" = "X-lc" && continue ;; *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) # Compiler inserts libc in the correct place for threads to work test "X$arg" = "X-lc" && continue ;; esac elif test "X$arg" = "X-lc_r"; then case $host in *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) # Do not include libc_r directly, use -pthread flag. continue ;; esac fi func_append deplibs " $arg" continue ;; -module) module=yes continue ;; # Tru64 UNIX uses -model [arg] to determine the layout of C++ # classes, name mangling, and exception handling. # Darwin uses the -arch flag to determine output architecture. -model|-arch|-isysroot|--sysroot) func_append compiler_flags " $arg" func_append compile_command " $arg" func_append finalize_command " $arg" prev=xcompiler continue ;; -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \ |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*) func_append compiler_flags " $arg" func_append compile_command " $arg" func_append finalize_command " $arg" case "$new_inherited_linker_flags " in *" $arg "*) ;; * ) func_append new_inherited_linker_flags " $arg" ;; esac continue ;; -multi_module) single_module="${wl}-multi_module" continue ;; -no-fast-install) fast_install=no continue ;; -no-install) case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-darwin* | *-cegcc*) # The PATH hackery in wrapper scripts is required on Windows # and Darwin in order for the loader to find any dlls it needs. func_warning "\`-no-install' is ignored for $host" func_warning "assuming \`-no-fast-install' instead" fast_install=no ;; *) no_install=yes ;; esac continue ;; -no-undefined) allow_undefined=no continue ;; -objectlist) prev=objectlist continue ;; -o) prev=output ;; -precious-files-regex) prev=precious_regex continue ;; -release) prev=release continue ;; -rpath) prev=rpath continue ;; -R) prev=xrpath continue ;; -R*) func_stripname '-R' '' "$arg" dir=$func_stripname_result # We need an absolute path. case $dir in [\\/]* | [A-Za-z]:[\\/]*) ;; =*) func_stripname '=' '' "$dir" dir=$lt_sysroot$func_stripname_result ;; *) func_fatal_error "only absolute run-paths are allowed" ;; esac case "$xrpath " in *" $dir "*) ;; *) func_append xrpath " $dir" ;; esac continue ;; -shared) # The effects of -shared are defined in a previous loop. continue ;; -shrext) prev=shrext continue ;; -static | -static-libtool-libs) # The effects of -static are defined in a previous loop. # We used to do the same as -all-static on platforms that # didn't have a PIC flag, but the assumption that the effects # would be equivalent was wrong. It would break on at least # Digital Unix and AIX. continue ;; -thread-safe) thread_safe=yes continue ;; -version-info) prev=vinfo continue ;; -version-number) prev=vinfo vinfo_number=yes continue ;; -weak) prev=weak continue ;; -Wc,*) func_stripname '-Wc,' '' "$arg" args=$func_stripname_result arg= save_ifs="$IFS"; IFS=',' for flag in $args; do IFS="$save_ifs" func_quote_for_eval "$flag" func_append arg " $func_quote_for_eval_result" func_append compiler_flags " $func_quote_for_eval_result" done IFS="$save_ifs" func_stripname ' ' '' "$arg" arg=$func_stripname_result ;; -Wl,*) func_stripname '-Wl,' '' "$arg" args=$func_stripname_result arg= save_ifs="$IFS"; IFS=',' for flag in $args; do IFS="$save_ifs" func_quote_for_eval "$flag" func_append arg " $wl$func_quote_for_eval_result" func_append compiler_flags " $wl$func_quote_for_eval_result" func_append linker_flags " $func_quote_for_eval_result" done IFS="$save_ifs" func_stripname ' ' '' "$arg" arg=$func_stripname_result ;; -Xcompiler) prev=xcompiler continue ;; -Xlinker) prev=xlinker continue ;; -XCClinker) prev=xcclinker continue ;; # -msg_* for osf cc -msg_*) func_quote_for_eval "$arg" arg="$func_quote_for_eval_result" ;; # Flags to be passed through unchanged, with rationale: # -64, -mips[0-9] enable 64-bit mode for the SGI compiler # -r[0-9][0-9]* specify processor for the SGI compiler # -xarch=*, -xtarget=* enable 64-bit mode for the Sun compiler # +DA*, +DD* enable 64-bit mode for the HP compiler # -q* compiler args for the IBM compiler # -m*, -t[45]*, -txscale* architecture-specific flags for GCC # -F/path path to uninstalled frameworks, gcc on darwin # -p, -pg, --coverage, -fprofile-* profiling flags for GCC # @file GCC response files # -tp=* Portland pgcc target processor selection # --sysroot=* for sysroot support # -O*, -flto*, -fwhopr*, -fuse-linker-plugin GCC link-time optimization -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \ -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*|-tp=*|--sysroot=*| \ -O*|-flto*|-fwhopr*|-fuse-linker-plugin) func_quote_for_eval "$arg" arg="$func_quote_for_eval_result" func_append compile_command " $arg" func_append finalize_command " $arg" func_append compiler_flags " $arg" continue ;; # Some other compiler flag. -* | +*) func_quote_for_eval "$arg" arg="$func_quote_for_eval_result" ;; *.$objext) # A standard object. func_append objs " $arg" ;; *.lo) # A libtool-controlled object. # Check to see that this really is a libtool object. if func_lalib_unsafe_p "$arg"; then pic_object= non_pic_object= # Read the .lo file func_source "$arg" if test -z "$pic_object" || test -z "$non_pic_object" || test "$pic_object" = none && test "$non_pic_object" = none; then func_fatal_error "cannot find name of object for \`$arg'" fi # Extract subdirectory from the argument. func_dirname "$arg" "/" "" xdir="$func_dirname_result" if test "$pic_object" != none; then # Prepend the subdirectory the object is found in. pic_object="$xdir$pic_object" if test "$prev" = dlfiles; then if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then func_append dlfiles " $pic_object" prev= continue else # If libtool objects are unsupported, then we need to preload. prev=dlprefiles fi fi # CHECK ME: I think I busted this. -Ossama if test "$prev" = dlprefiles; then # Preload the old-style object. func_append dlprefiles " $pic_object" prev= fi # A PIC object. func_append libobjs " $pic_object" arg="$pic_object" fi # Non-PIC object. if test "$non_pic_object" != none; then # Prepend the subdirectory the object is found in. non_pic_object="$xdir$non_pic_object" # A standard non-PIC object func_append non_pic_objects " $non_pic_object" if test -z "$pic_object" || test "$pic_object" = none ; then arg="$non_pic_object" fi else # If the PIC object exists, use it instead. # $xdir was prepended to $pic_object above. non_pic_object="$pic_object" func_append non_pic_objects " $non_pic_object" fi else # Only an error if not doing a dry-run. if $opt_dry_run; then # Extract subdirectory from the argument. func_dirname "$arg" "/" "" xdir="$func_dirname_result" func_lo2o "$arg" pic_object=$xdir$objdir/$func_lo2o_result non_pic_object=$xdir$func_lo2o_result func_append libobjs " $pic_object" func_append non_pic_objects " $non_pic_object" else func_fatal_error "\`$arg' is not a valid libtool object" fi fi ;; *.$libext) # An archive. func_append deplibs " $arg" func_append old_deplibs " $arg" continue ;; *.la) # A libtool-controlled library. func_resolve_sysroot "$arg" if test "$prev" = dlfiles; then # This library was specified with -dlopen. func_append dlfiles " $func_resolve_sysroot_result" prev= elif test "$prev" = dlprefiles; then # The library was specified with -dlpreopen. func_append dlprefiles " $func_resolve_sysroot_result" prev= else func_append deplibs " $func_resolve_sysroot_result" fi continue ;; # Some other compiler argument. *) # Unknown arguments in both finalize_command and compile_command need # to be aesthetically quoted because they are evaled later. func_quote_for_eval "$arg" arg="$func_quote_for_eval_result" ;; esac # arg # Now actually substitute the argument into the commands. if test -n "$arg"; then func_append compile_command " $arg" func_append finalize_command " $arg" fi done # argument parsing loop test -n "$prev" && \ func_fatal_help "the \`$prevarg' option requires an argument" if test "$export_dynamic" = yes && test -n "$export_dynamic_flag_spec"; then eval arg=\"$export_dynamic_flag_spec\" func_append compile_command " $arg" func_append finalize_command " $arg" fi oldlibs= # calculate the name of the file, without its directory func_basename "$output" outputname="$func_basename_result" libobjs_save="$libobjs" if test -n "$shlibpath_var"; then # get the directories listed in $shlibpath_var eval shlib_search_path=\`\$ECHO \"\${$shlibpath_var}\" \| \$SED \'s/:/ /g\'\` else shlib_search_path= fi eval sys_lib_search_path=\"$sys_lib_search_path_spec\" eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\" func_dirname "$output" "/" "" output_objdir="$func_dirname_result$objdir" func_to_tool_file "$output_objdir/" tool_output_objdir=$func_to_tool_file_result # Create the object directory. func_mkdir_p "$output_objdir" # Determine the type of output case $output in "") func_fatal_help "you must specify an output file" ;; *.$libext) linkmode=oldlib ;; *.lo | *.$objext) linkmode=obj ;; *.la) linkmode=lib ;; *) linkmode=prog ;; # Anything else should be a program. esac specialdeplibs= libs= # Find all interdependent deplibs by searching for libraries # that are linked more than once (e.g. -la -lb -la) for deplib in $deplibs; do if $opt_preserve_dup_deps ; then case "$libs " in *" $deplib "*) func_append specialdeplibs " $deplib" ;; esac fi func_append libs " $deplib" done if test "$linkmode" = lib; then libs="$predeps $libs $compiler_lib_search_path $postdeps" # Compute libraries that are listed more than once in $predeps # $postdeps and mark them as special (i.e., whose duplicates are # not to be eliminated). pre_post_deps= if $opt_duplicate_compiler_generated_deps; then for pre_post_dep in $predeps $postdeps; do case "$pre_post_deps " in *" $pre_post_dep "*) func_append specialdeplibs " $pre_post_deps" ;; esac func_append pre_post_deps " $pre_post_dep" done fi pre_post_deps= fi deplibs= newdependency_libs= newlib_search_path= need_relink=no # whether we're linking any uninstalled libtool libraries notinst_deplibs= # not-installed libtool libraries notinst_path= # paths that contain not-installed libtool libraries case $linkmode in lib) passes="conv dlpreopen link" for file in $dlfiles $dlprefiles; do case $file in *.la) ;; *) func_fatal_help "libraries can \`-dlopen' only libtool libraries: $file" ;; esac done ;; prog) compile_deplibs= finalize_deplibs= alldeplibs=no newdlfiles= newdlprefiles= passes="conv scan dlopen dlpreopen link" ;; *) passes="conv" ;; esac for pass in $passes; do # The preopen pass in lib mode reverses $deplibs; put it back here # so that -L comes before libs that need it for instance... if test "$linkmode,$pass" = "lib,link"; then ## FIXME: Find the place where the list is rebuilt in the wrong ## order, and fix it there properly tmp_deplibs= for deplib in $deplibs; do tmp_deplibs="$deplib $tmp_deplibs" done deplibs="$tmp_deplibs" fi if test "$linkmode,$pass" = "lib,link" || test "$linkmode,$pass" = "prog,scan"; then libs="$deplibs" deplibs= fi if test "$linkmode" = prog; then case $pass in dlopen) libs="$dlfiles" ;; dlpreopen) libs="$dlprefiles" ;; link) libs="$deplibs %DEPLIBS%" test "X$link_all_deplibs" != Xno && libs="$libs $dependency_libs" ;; esac fi if test "$linkmode,$pass" = "lib,dlpreopen"; then # Collect and forward deplibs of preopened libtool libs for lib in $dlprefiles; do # Ignore non-libtool-libs dependency_libs= func_resolve_sysroot "$lib" case $lib in *.la) func_source "$func_resolve_sysroot_result" ;; esac # Collect preopened libtool deplibs, except any this library # has declared as weak libs for deplib in $dependency_libs; do func_basename "$deplib" deplib_base=$func_basename_result case " $weak_libs " in *" $deplib_base "*) ;; *) func_append deplibs " $deplib" ;; esac done done libs="$dlprefiles" fi if test "$pass" = dlopen; then # Collect dlpreopened libraries save_deplibs="$deplibs" deplibs= fi for deplib in $libs; do lib= found=no case $deplib in -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \ |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*) if test "$linkmode,$pass" = "prog,link"; then compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else func_append compiler_flags " $deplib" if test "$linkmode" = lib ; then case "$new_inherited_linker_flags " in *" $deplib "*) ;; * ) func_append new_inherited_linker_flags " $deplib" ;; esac fi fi continue ;; -l*) if test "$linkmode" != lib && test "$linkmode" != prog; then func_warning "\`-l' is ignored for archives/objects" continue fi func_stripname '-l' '' "$deplib" name=$func_stripname_result if test "$linkmode" = lib; then searchdirs="$newlib_search_path $lib_search_path $compiler_lib_search_dirs $sys_lib_search_path $shlib_search_path" else searchdirs="$newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path" fi for searchdir in $searchdirs; do for search_ext in .la $std_shrext .so .a; do # Search the libtool library lib="$searchdir/lib${name}${search_ext}" if test -f "$lib"; then if test "$search_ext" = ".la"; then found=yes else found=no fi break 2 fi done done if test "$found" != yes; then # deplib doesn't seem to be a libtool library if test "$linkmode,$pass" = "prog,link"; then compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else deplibs="$deplib $deplibs" test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs" fi continue else # deplib is a libtool library # If $allow_libtool_libs_with_static_runtimes && $deplib is a stdlib, # We need to do some special things here, and not later. if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then case " $predeps $postdeps " in *" $deplib "*) if func_lalib_p "$lib"; then library_names= old_library= func_source "$lib" for l in $old_library $library_names; do ll="$l" done if test "X$ll" = "X$old_library" ; then # only static version available found=no func_dirname "$lib" "" "." ladir="$func_dirname_result" lib=$ladir/$old_library if test "$linkmode,$pass" = "prog,link"; then compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else deplibs="$deplib $deplibs" test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs" fi continue fi fi ;; *) ;; esac fi fi ;; # -l *.ltframework) if test "$linkmode,$pass" = "prog,link"; then compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else deplibs="$deplib $deplibs" if test "$linkmode" = lib ; then case "$new_inherited_linker_flags " in *" $deplib "*) ;; * ) func_append new_inherited_linker_flags " $deplib" ;; esac fi fi continue ;; -L*) case $linkmode in lib) deplibs="$deplib $deplibs" test "$pass" = conv && continue newdependency_libs="$deplib $newdependency_libs" func_stripname '-L' '' "$deplib" func_resolve_sysroot "$func_stripname_result" func_append newlib_search_path " $func_resolve_sysroot_result" ;; prog) if test "$pass" = conv; then deplibs="$deplib $deplibs" continue fi if test "$pass" = scan; then deplibs="$deplib $deplibs" else compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" fi func_stripname '-L' '' "$deplib" func_resolve_sysroot "$func_stripname_result" func_append newlib_search_path " $func_resolve_sysroot_result" ;; *) func_warning "\`-L' is ignored for archives/objects" ;; esac # linkmode continue ;; # -L -R*) if test "$pass" = link; then func_stripname '-R' '' "$deplib" func_resolve_sysroot "$func_stripname_result" dir=$func_resolve_sysroot_result # Make sure the xrpath contains only unique directories. case "$xrpath " in *" $dir "*) ;; *) func_append xrpath " $dir" ;; esac fi deplibs="$deplib $deplibs" continue ;; *.la) func_resolve_sysroot "$deplib" lib=$func_resolve_sysroot_result ;; *.$libext) if test "$pass" = conv; then deplibs="$deplib $deplibs" continue fi case $linkmode in lib) # Linking convenience modules into shared libraries is allowed, # but linking other static libraries is non-portable. case " $dlpreconveniencelibs " in *" $deplib "*) ;; *) valid_a_lib=no case $deplibs_check_method in match_pattern*) set dummy $deplibs_check_method; shift match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"` if eval "\$ECHO \"$deplib\"" 2>/dev/null | $SED 10q \ | $EGREP "$match_pattern_regex" > /dev/null; then valid_a_lib=yes fi ;; pass_all) valid_a_lib=yes ;; esac if test "$valid_a_lib" != yes; then echo $ECHO "*** Warning: Trying to link with static lib archive $deplib." echo "*** I have the capability to make that library automatically link in when" echo "*** you link to this library. But I can only do this if you have a" echo "*** shared version of the library, which you do not appear to have" echo "*** because the file extensions .$libext of this argument makes me believe" echo "*** that it is just a static archive that I should not use here." else echo $ECHO "*** Warning: Linking the shared library $output against the" $ECHO "*** static library $deplib is not portable!" deplibs="$deplib $deplibs" fi ;; esac continue ;; prog) if test "$pass" != link; then deplibs="$deplib $deplibs" else compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" fi continue ;; esac # linkmode ;; # *.$libext *.lo | *.$objext) if test "$pass" = conv; then deplibs="$deplib $deplibs" elif test "$linkmode" = prog; then if test "$pass" = dlpreopen || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then # If there is no dlopen support or we're linking statically, # we need to preload. func_append newdlprefiles " $deplib" compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else func_append newdlfiles " $deplib" fi fi continue ;; %DEPLIBS%) alldeplibs=yes continue ;; esac # case $deplib if test "$found" = yes || test -f "$lib"; then : else func_fatal_error "cannot find the library \`$lib' or unhandled argument \`$deplib'" fi # Check to see that this really is a libtool archive. func_lalib_unsafe_p "$lib" \ || func_fatal_error "\`$lib' is not a valid libtool archive" func_dirname "$lib" "" "." ladir="$func_dirname_result" dlname= dlopen= dlpreopen= libdir= library_names= old_library= inherited_linker_flags= # If the library was installed with an old release of libtool, # it will not redefine variables installed, or shouldnotlink installed=yes shouldnotlink=no avoidtemprpath= # Read the .la file func_source "$lib" # Convert "-framework foo" to "foo.ltframework" if test -n "$inherited_linker_flags"; then tmp_inherited_linker_flags=`$ECHO "$inherited_linker_flags" | $SED 's/-framework \([^ $]*\)/\1.ltframework/g'` for tmp_inherited_linker_flag in $tmp_inherited_linker_flags; do case " $new_inherited_linker_flags " in *" $tmp_inherited_linker_flag "*) ;; *) func_append new_inherited_linker_flags " $tmp_inherited_linker_flag";; esac done fi dependency_libs=`$ECHO " $dependency_libs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` if test "$linkmode,$pass" = "lib,link" || test "$linkmode,$pass" = "prog,scan" || { test "$linkmode" != prog && test "$linkmode" != lib; }; then test -n "$dlopen" && func_append dlfiles " $dlopen" test -n "$dlpreopen" && func_append dlprefiles " $dlpreopen" fi if test "$pass" = conv; then # Only check for convenience libraries deplibs="$lib $deplibs" if test -z "$libdir"; then if test -z "$old_library"; then func_fatal_error "cannot find name of link library for \`$lib'" fi # It is a libtool convenience library, so add in its objects. func_append convenience " $ladir/$objdir/$old_library" func_append old_convenience " $ladir/$objdir/$old_library" tmp_libs= for deplib in $dependency_libs; do deplibs="$deplib $deplibs" if $opt_preserve_dup_deps ; then case "$tmp_libs " in *" $deplib "*) func_append specialdeplibs " $deplib" ;; esac fi func_append tmp_libs " $deplib" done elif test "$linkmode" != prog && test "$linkmode" != lib; then func_fatal_error "\`$lib' is not a convenience library" fi continue fi # $pass = conv # Get the name of the library we link against. linklib= if test -n "$old_library" && { test "$prefer_static_libs" = yes || test "$prefer_static_libs,$installed" = "built,no"; }; then linklib=$old_library else for l in $old_library $library_names; do linklib="$l" done fi if test -z "$linklib"; then func_fatal_error "cannot find name of link library for \`$lib'" fi # This library was specified with -dlopen. if test "$pass" = dlopen; then if test -z "$libdir"; then func_fatal_error "cannot -dlopen a convenience library: \`$lib'" fi if test -z "$dlname" || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then # If there is no dlname, no dlopen support or we're linking # statically, we need to preload. We also need to preload any # dependent libraries so libltdl's deplib preloader doesn't # bomb out in the load deplibs phase. func_append dlprefiles " $lib $dependency_libs" else func_append newdlfiles " $lib" fi continue fi # $pass = dlopen # We need an absolute path. case $ladir in [\\/]* | [A-Za-z]:[\\/]*) abs_ladir="$ladir" ;; *) abs_ladir=`cd "$ladir" && pwd` if test -z "$abs_ladir"; then func_warning "cannot determine absolute directory name of \`$ladir'" func_warning "passing it literally to the linker, although it might fail" abs_ladir="$ladir" fi ;; esac func_basename "$lib" laname="$func_basename_result" # Find the relevant object directory and library name. if test "X$installed" = Xyes; then if test ! -f "$lt_sysroot$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then func_warning "library \`$lib' was moved." dir="$ladir" absdir="$abs_ladir" libdir="$abs_ladir" else dir="$lt_sysroot$libdir" absdir="$lt_sysroot$libdir" fi test "X$hardcode_automatic" = Xyes && avoidtemprpath=yes else if test ! -f "$ladir/$objdir/$linklib" && test -f "$abs_ladir/$linklib"; then dir="$ladir" absdir="$abs_ladir" # Remove this search path later func_append notinst_path " $abs_ladir" else dir="$ladir/$objdir" absdir="$abs_ladir/$objdir" # Remove this search path later func_append notinst_path " $abs_ladir" fi fi # $installed = yes func_stripname 'lib' '.la' "$laname" name=$func_stripname_result # This library was specified with -dlpreopen. if test "$pass" = dlpreopen; then if test -z "$libdir" && test "$linkmode" = prog; then func_fatal_error "only libraries may -dlpreopen a convenience library: \`$lib'" fi case "$host" in # special handling for platforms with PE-DLLs. *cygwin* | *mingw* | *cegcc* ) # Linker will automatically link against shared library if both # static and shared are present. Therefore, ensure we extract # symbols from the import library if a shared library is present # (otherwise, the dlopen module name will be incorrect). We do # this by putting the import library name into $newdlprefiles. # We recover the dlopen module name by 'saving' the la file # name in a special purpose variable, and (later) extracting the # dlname from the la file. if test -n "$dlname"; then func_tr_sh "$dir/$linklib" eval "libfile_$func_tr_sh_result=\$abs_ladir/\$laname" func_append newdlprefiles " $dir/$linklib" else func_append newdlprefiles " $dir/$old_library" # Keep a list of preopened convenience libraries to check # that they are being used correctly in the link pass. test -z "$libdir" && \ func_append dlpreconveniencelibs " $dir/$old_library" fi ;; * ) # Prefer using a static library (so that no silly _DYNAMIC symbols # are required to link). if test -n "$old_library"; then func_append newdlprefiles " $dir/$old_library" # Keep a list of preopened convenience libraries to check # that they are being used correctly in the link pass. test -z "$libdir" && \ func_append dlpreconveniencelibs " $dir/$old_library" # Otherwise, use the dlname, so that lt_dlopen finds it. elif test -n "$dlname"; then func_append newdlprefiles " $dir/$dlname" else func_append newdlprefiles " $dir/$linklib" fi ;; esac fi # $pass = dlpreopen if test -z "$libdir"; then # Link the convenience library if test "$linkmode" = lib; then deplibs="$dir/$old_library $deplibs" elif test "$linkmode,$pass" = "prog,link"; then compile_deplibs="$dir/$old_library $compile_deplibs" finalize_deplibs="$dir/$old_library $finalize_deplibs" else deplibs="$lib $deplibs" # used for prog,scan pass fi continue fi if test "$linkmode" = prog && test "$pass" != link; then func_append newlib_search_path " $ladir" deplibs="$lib $deplibs" linkalldeplibs=no if test "$link_all_deplibs" != no || test -z "$library_names" || test "$build_libtool_libs" = no; then linkalldeplibs=yes fi tmp_libs= for deplib in $dependency_libs; do case $deplib in -L*) func_stripname '-L' '' "$deplib" func_resolve_sysroot "$func_stripname_result" func_append newlib_search_path " $func_resolve_sysroot_result" ;; esac # Need to link against all dependency_libs? if test "$linkalldeplibs" = yes; then deplibs="$deplib $deplibs" else # Need to hardcode shared library paths # or/and link against static libraries newdependency_libs="$deplib $newdependency_libs" fi if $opt_preserve_dup_deps ; then case "$tmp_libs " in *" $deplib "*) func_append specialdeplibs " $deplib" ;; esac fi func_append tmp_libs " $deplib" done # for deplib continue fi # $linkmode = prog... if test "$linkmode,$pass" = "prog,link"; then if test -n "$library_names" && { { test "$prefer_static_libs" = no || test "$prefer_static_libs,$installed" = "built,yes"; } || test -z "$old_library"; }; then # We need to hardcode the library path if test -n "$shlibpath_var" && test -z "$avoidtemprpath" ; then # Make sure the rpath contains only unique directories. case "$temp_rpath:" in *"$absdir:"*) ;; *) func_append temp_rpath "$absdir:" ;; esac fi # Hardcode the library path. # Skip directories that are in the system default run-time # search path. case " $sys_lib_dlsearch_path " in *" $absdir "*) ;; *) case "$compile_rpath " in *" $absdir "*) ;; *) func_append compile_rpath " $absdir" ;; esac ;; esac case " $sys_lib_dlsearch_path " in *" $libdir "*) ;; *) case "$finalize_rpath " in *" $libdir "*) ;; *) func_append finalize_rpath " $libdir" ;; esac ;; esac fi # $linkmode,$pass = prog,link... if test "$alldeplibs" = yes && { test "$deplibs_check_method" = pass_all || { test "$build_libtool_libs" = yes && test -n "$library_names"; }; }; then # We only need to search for static libraries continue fi fi link_static=no # Whether the deplib will be linked statically use_static_libs=$prefer_static_libs if test "$use_static_libs" = built && test "$installed" = yes; then use_static_libs=no fi if test -n "$library_names" && { test "$use_static_libs" = no || test -z "$old_library"; }; then case $host in *cygwin* | *mingw* | *cegcc*) # No point in relinking DLLs because paths are not encoded func_append notinst_deplibs " $lib" need_relink=no ;; *) if test "$installed" = no; then func_append notinst_deplibs " $lib" need_relink=yes fi ;; esac # This is a shared library # Warn about portability, can't link against -module's on some # systems (darwin). Don't bleat about dlopened modules though! dlopenmodule="" for dlpremoduletest in $dlprefiles; do if test "X$dlpremoduletest" = "X$lib"; then dlopenmodule="$dlpremoduletest" break fi done if test -z "$dlopenmodule" && test "$shouldnotlink" = yes && test "$pass" = link; then echo if test "$linkmode" = prog; then $ECHO "*** Warning: Linking the executable $output against the loadable module" else $ECHO "*** Warning: Linking the shared library $output against the loadable module" fi $ECHO "*** $linklib is not portable!" fi if test "$linkmode" = lib && test "$hardcode_into_libs" = yes; then # Hardcode the library path. # Skip directories that are in the system default run-time # search path. case " $sys_lib_dlsearch_path " in *" $absdir "*) ;; *) case "$compile_rpath " in *" $absdir "*) ;; *) func_append compile_rpath " $absdir" ;; esac ;; esac case " $sys_lib_dlsearch_path " in *" $libdir "*) ;; *) case "$finalize_rpath " in *" $libdir "*) ;; *) func_append finalize_rpath " $libdir" ;; esac ;; esac fi if test -n "$old_archive_from_expsyms_cmds"; then # figure out the soname set dummy $library_names shift realname="$1" shift libname=`eval "\\$ECHO \"$libname_spec\""` # use dlname if we got it. it's perfectly good, no? if test -n "$dlname"; then soname="$dlname" elif test -n "$soname_spec"; then # bleh windows case $host in *cygwin* | mingw* | *cegcc*) func_arith $current - $age major=$func_arith_result versuffix="-$major" ;; esac eval soname=\"$soname_spec\" else soname="$realname" fi # Make a new name for the extract_expsyms_cmds to use soroot="$soname" func_basename "$soroot" soname="$func_basename_result" func_stripname 'lib' '.dll' "$soname" newlib=libimp-$func_stripname_result.a # If the library has no export list, then create one now if test -f "$output_objdir/$soname-def"; then : else func_verbose "extracting exported symbol list from \`$soname'" func_execute_cmds "$extract_expsyms_cmds" 'exit $?' fi # Create $newlib if test -f "$output_objdir/$newlib"; then :; else func_verbose "generating import library for \`$soname'" func_execute_cmds "$old_archive_from_expsyms_cmds" 'exit $?' fi # make sure the library variables are pointing to the new library dir=$output_objdir linklib=$newlib fi # test -n "$old_archive_from_expsyms_cmds" if test "$linkmode" = prog || test "$opt_mode" != relink; then add_shlibpath= add_dir= add= lib_linked=yes case $hardcode_action in immediate | unsupported) if test "$hardcode_direct" = no; then add="$dir/$linklib" case $host in *-*-sco3.2v5.0.[024]*) add_dir="-L$dir" ;; *-*-sysv4*uw2*) add_dir="-L$dir" ;; *-*-sysv5OpenUNIX* | *-*-sysv5UnixWare7.[01].[10]* | \ *-*-unixware7*) add_dir="-L$dir" ;; *-*-darwin* ) # if the lib is a (non-dlopened) module then we can not # link against it, someone is ignoring the earlier warnings if /usr/bin/file -L $add 2> /dev/null | $GREP ": [^:]* bundle" >/dev/null ; then if test "X$dlopenmodule" != "X$lib"; then $ECHO "*** Warning: lib $linklib is a module, not a shared library" if test -z "$old_library" ; then echo echo "*** And there doesn't seem to be a static archive available" echo "*** The link will probably fail, sorry" else add="$dir/$old_library" fi elif test -n "$old_library"; then add="$dir/$old_library" fi fi esac elif test "$hardcode_minus_L" = no; then case $host in *-*-sunos*) add_shlibpath="$dir" ;; esac add_dir="-L$dir" add="-l$name" elif test "$hardcode_shlibpath_var" = no; then add_shlibpath="$dir" add="-l$name" else lib_linked=no fi ;; relink) if test "$hardcode_direct" = yes && test "$hardcode_direct_absolute" = no; then add="$dir/$linklib" elif test "$hardcode_minus_L" = yes; then add_dir="-L$absdir" # Try looking first in the location we're being installed to. if test -n "$inst_prefix_dir"; then case $libdir in [\\/]*) func_append add_dir " -L$inst_prefix_dir$libdir" ;; esac fi add="-l$name" elif test "$hardcode_shlibpath_var" = yes; then add_shlibpath="$dir" add="-l$name" else lib_linked=no fi ;; *) lib_linked=no ;; esac if test "$lib_linked" != yes; then func_fatal_configuration "unsupported hardcode properties" fi if test -n "$add_shlibpath"; then case :$compile_shlibpath: in *":$add_shlibpath:"*) ;; *) func_append compile_shlibpath "$add_shlibpath:" ;; esac fi if test "$linkmode" = prog; then test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs" test -n "$add" && compile_deplibs="$add $compile_deplibs" else test -n "$add_dir" && deplibs="$add_dir $deplibs" test -n "$add" && deplibs="$add $deplibs" if test "$hardcode_direct" != yes && test "$hardcode_minus_L" != yes && test "$hardcode_shlibpath_var" = yes; then case :$finalize_shlibpath: in *":$libdir:"*) ;; *) func_append finalize_shlibpath "$libdir:" ;; esac fi fi fi if test "$linkmode" = prog || test "$opt_mode" = relink; then add_shlibpath= add_dir= add= # Finalize command for both is simple: just hardcode it. if test "$hardcode_direct" = yes && test "$hardcode_direct_absolute" = no; then add="$libdir/$linklib" elif test "$hardcode_minus_L" = yes; then add_dir="-L$libdir" add="-l$name" elif test "$hardcode_shlibpath_var" = yes; then case :$finalize_shlibpath: in *":$libdir:"*) ;; *) func_append finalize_shlibpath "$libdir:" ;; esac add="-l$name" elif test "$hardcode_automatic" = yes; then if test -n "$inst_prefix_dir" && test -f "$inst_prefix_dir$libdir/$linklib" ; then add="$inst_prefix_dir$libdir/$linklib" else add="$libdir/$linklib" fi else # We cannot seem to hardcode it, guess we'll fake it. add_dir="-L$libdir" # Try looking first in the location we're being installed to. if test -n "$inst_prefix_dir"; then case $libdir in [\\/]*) func_append add_dir " -L$inst_prefix_dir$libdir" ;; esac fi add="-l$name" fi if test "$linkmode" = prog; then test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs" test -n "$add" && finalize_deplibs="$add $finalize_deplibs" else test -n "$add_dir" && deplibs="$add_dir $deplibs" test -n "$add" && deplibs="$add $deplibs" fi fi elif test "$linkmode" = prog; then # Here we assume that one of hardcode_direct or hardcode_minus_L # is not unsupported. This is valid on all known static and # shared platforms. if test "$hardcode_direct" != unsupported; then test -n "$old_library" && linklib="$old_library" compile_deplibs="$dir/$linklib $compile_deplibs" finalize_deplibs="$dir/$linklib $finalize_deplibs" else compile_deplibs="-l$name -L$dir $compile_deplibs" finalize_deplibs="-l$name -L$dir $finalize_deplibs" fi elif test "$build_libtool_libs" = yes; then # Not a shared library if test "$deplibs_check_method" != pass_all; then # We're trying link a shared library against a static one # but the system doesn't support it. # Just print a warning and add the library to dependency_libs so # that the program can be linked against the static library. echo $ECHO "*** Warning: This system can not link to static lib archive $lib." echo "*** I have the capability to make that library automatically link in when" echo "*** you link to this library. But I can only do this if you have a" echo "*** shared version of the library, which you do not appear to have." if test "$module" = yes; then echo "*** But as you try to build a module library, libtool will still create " echo "*** a static module, that should work as long as the dlopening application" echo "*** is linked with the -dlopen flag to resolve symbols at runtime." if test -z "$global_symbol_pipe"; then echo echo "*** However, this would only work if libtool was able to extract symbol" echo "*** lists from a program, using \`nm' or equivalent, but libtool could" echo "*** not find such a program. So, this module is probably useless." echo "*** \`nm' from GNU binutils and a full rebuild may help." fi if test "$build_old_libs" = no; then build_libtool_libs=module build_old_libs=yes else build_libtool_libs=no fi fi else deplibs="$dir/$old_library $deplibs" link_static=yes fi fi # link shared/static library? if test "$linkmode" = lib; then if test -n "$dependency_libs" && { test "$hardcode_into_libs" != yes || test "$build_old_libs" = yes || test "$link_static" = yes; }; then # Extract -R from dependency_libs temp_deplibs= for libdir in $dependency_libs; do case $libdir in -R*) func_stripname '-R' '' "$libdir" temp_xrpath=$func_stripname_result case " $xrpath " in *" $temp_xrpath "*) ;; *) func_append xrpath " $temp_xrpath";; esac;; *) func_append temp_deplibs " $libdir";; esac done dependency_libs="$temp_deplibs" fi func_append newlib_search_path " $absdir" # Link against this library test "$link_static" = no && newdependency_libs="$abs_ladir/$laname $newdependency_libs" # ... and its dependency_libs tmp_libs= for deplib in $dependency_libs; do newdependency_libs="$deplib $newdependency_libs" case $deplib in -L*) func_stripname '-L' '' "$deplib" func_resolve_sysroot "$func_stripname_result";; *) func_resolve_sysroot "$deplib" ;; esac if $opt_preserve_dup_deps ; then case "$tmp_libs " in *" $func_resolve_sysroot_result "*) func_append specialdeplibs " $func_resolve_sysroot_result" ;; esac fi func_append tmp_libs " $func_resolve_sysroot_result" done if test "$link_all_deplibs" != no; then # Add the search paths of all dependency libraries for deplib in $dependency_libs; do path= case $deplib in -L*) path="$deplib" ;; *.la) func_resolve_sysroot "$deplib" deplib=$func_resolve_sysroot_result func_dirname "$deplib" "" "." dir=$func_dirname_result # We need an absolute path. case $dir in [\\/]* | [A-Za-z]:[\\/]*) absdir="$dir" ;; *) absdir=`cd "$dir" && pwd` if test -z "$absdir"; then func_warning "cannot determine absolute directory name of \`$dir'" absdir="$dir" fi ;; esac if $GREP "^installed=no" $deplib > /dev/null; then case $host in *-*-darwin*) depdepl= eval deplibrary_names=`${SED} -n -e 's/^library_names=\(.*\)$/\1/p' $deplib` if test -n "$deplibrary_names" ; then for tmp in $deplibrary_names ; do depdepl=$tmp done if test -f "$absdir/$objdir/$depdepl" ; then depdepl="$absdir/$objdir/$depdepl" darwin_install_name=`${OTOOL} -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'` if test -z "$darwin_install_name"; then darwin_install_name=`${OTOOL64} -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'` fi func_append compiler_flags " ${wl}-dylib_file ${wl}${darwin_install_name}:${depdepl}" func_append linker_flags " -dylib_file ${darwin_install_name}:${depdepl}" path= fi fi ;; *) path="-L$absdir/$objdir" ;; esac else eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` test -z "$libdir" && \ func_fatal_error "\`$deplib' is not a valid libtool archive" test "$absdir" != "$libdir" && \ func_warning "\`$deplib' seems to be moved" path="-L$absdir" fi ;; esac case " $deplibs " in *" $path "*) ;; *) deplibs="$path $deplibs" ;; esac done fi # link_all_deplibs != no fi # linkmode = lib done # for deplib in $libs if test "$pass" = link; then if test "$linkmode" = "prog"; then compile_deplibs="$new_inherited_linker_flags $compile_deplibs" finalize_deplibs="$new_inherited_linker_flags $finalize_deplibs" else compiler_flags="$compiler_flags "`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` fi fi dependency_libs="$newdependency_libs" if test "$pass" = dlpreopen; then # Link the dlpreopened libraries before other libraries for deplib in $save_deplibs; do deplibs="$deplib $deplibs" done fi if test "$pass" != dlopen; then if test "$pass" != conv; then # Make sure lib_search_path contains only unique directories. lib_search_path= for dir in $newlib_search_path; do case "$lib_search_path " in *" $dir "*) ;; *) func_append lib_search_path " $dir" ;; esac done newlib_search_path= fi if test "$linkmode,$pass" != "prog,link"; then vars="deplibs" else vars="compile_deplibs finalize_deplibs" fi for var in $vars dependency_libs; do # Add libraries to $var in reverse order eval tmp_libs=\"\$$var\" new_libs= for deplib in $tmp_libs; do # FIXME: Pedantically, this is the right thing to do, so # that some nasty dependency loop isn't accidentally # broken: #new_libs="$deplib $new_libs" # Pragmatically, this seems to cause very few problems in # practice: case $deplib in -L*) new_libs="$deplib $new_libs" ;; -R*) ;; *) # And here is the reason: when a library appears more # than once as an explicit dependence of a library, or # is implicitly linked in more than once by the # compiler, it is considered special, and multiple # occurrences thereof are not removed. Compare this # with having the same library being listed as a # dependency of multiple other libraries: in this case, # we know (pedantically, we assume) the library does not # need to be listed more than once, so we keep only the # last copy. This is not always right, but it is rare # enough that we require users that really mean to play # such unportable linking tricks to link the library # using -Wl,-lname, so that libtool does not consider it # for duplicate removal. case " $specialdeplibs " in *" $deplib "*) new_libs="$deplib $new_libs" ;; *) case " $new_libs " in *" $deplib "*) ;; *) new_libs="$deplib $new_libs" ;; esac ;; esac ;; esac done tmp_libs= for deplib in $new_libs; do case $deplib in -L*) case " $tmp_libs " in *" $deplib "*) ;; *) func_append tmp_libs " $deplib" ;; esac ;; *) func_append tmp_libs " $deplib" ;; esac done eval $var=\"$tmp_libs\" done # for var fi # Last step: remove runtime libs from dependency_libs # (they stay in deplibs) tmp_libs= for i in $dependency_libs ; do case " $predeps $postdeps $compiler_lib_search_path " in *" $i "*) i="" ;; esac if test -n "$i" ; then func_append tmp_libs " $i" fi done dependency_libs=$tmp_libs done # for pass if test "$linkmode" = prog; then dlfiles="$newdlfiles" fi if test "$linkmode" = prog || test "$linkmode" = lib; then dlprefiles="$newdlprefiles" fi case $linkmode in oldlib) if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then func_warning "\`-dlopen' is ignored for archives" fi case " $deplibs" in *\ -l* | *\ -L*) func_warning "\`-l' and \`-L' are ignored for archives" ;; esac test -n "$rpath" && \ func_warning "\`-rpath' is ignored for archives" test -n "$xrpath" && \ func_warning "\`-R' is ignored for archives" test -n "$vinfo" && \ func_warning "\`-version-info/-version-number' is ignored for archives" test -n "$release" && \ func_warning "\`-release' is ignored for archives" test -n "$export_symbols$export_symbols_regex" && \ func_warning "\`-export-symbols' is ignored for archives" # Now set the variables for building old libraries. build_libtool_libs=no oldlibs="$output" func_append objs "$old_deplibs" ;; lib) # Make sure we only generate libraries of the form `libNAME.la'. case $outputname in lib*) func_stripname 'lib' '.la' "$outputname" name=$func_stripname_result eval shared_ext=\"$shrext_cmds\" eval libname=\"$libname_spec\" ;; *) test "$module" = no && \ func_fatal_help "libtool library \`$output' must begin with \`lib'" if test "$need_lib_prefix" != no; then # Add the "lib" prefix for modules if required func_stripname '' '.la' "$outputname" name=$func_stripname_result eval shared_ext=\"$shrext_cmds\" eval libname=\"$libname_spec\" else func_stripname '' '.la' "$outputname" libname=$func_stripname_result fi ;; esac if test -n "$objs"; then if test "$deplibs_check_method" != pass_all; then func_fatal_error "cannot build libtool library \`$output' from non-libtool objects on this host:$objs" else echo $ECHO "*** Warning: Linking the shared library $output against the non-libtool" $ECHO "*** objects $objs is not portable!" func_append libobjs " $objs" fi fi test "$dlself" != no && \ func_warning "\`-dlopen self' is ignored for libtool libraries" set dummy $rpath shift test "$#" -gt 1 && \ func_warning "ignoring multiple \`-rpath's for a libtool library" install_libdir="$1" oldlibs= if test -z "$rpath"; then if test "$build_libtool_libs" = yes; then # Building a libtool convenience library. # Some compilers have problems with a `.al' extension so # convenience libraries should have the same extension an # archive normally would. oldlibs="$output_objdir/$libname.$libext $oldlibs" build_libtool_libs=convenience build_old_libs=yes fi test -n "$vinfo" && \ func_warning "\`-version-info/-version-number' is ignored for convenience libraries" test -n "$release" && \ func_warning "\`-release' is ignored for convenience libraries" else # Parse the version information argument. save_ifs="$IFS"; IFS=':' set dummy $vinfo 0 0 0 shift IFS="$save_ifs" test -n "$7" && \ func_fatal_help "too many parameters to \`-version-info'" # convert absolute version numbers to libtool ages # this retains compatibility with .la files and attempts # to make the code below a bit more comprehensible case $vinfo_number in yes) number_major="$1" number_minor="$2" number_revision="$3" # # There are really only two kinds -- those that # use the current revision as the major version # and those that subtract age and use age as # a minor version. But, then there is irix # which has an extra 1 added just for fun # case $version_type in # correct linux to gnu/linux during the next big refactor darwin|linux|osf|windows|none) func_arith $number_major + $number_minor current=$func_arith_result age="$number_minor" revision="$number_revision" ;; freebsd-aout|freebsd-elf|qnx|sunos) current="$number_major" revision="$number_minor" age="0" ;; irix|nonstopux) func_arith $number_major + $number_minor current=$func_arith_result age="$number_minor" revision="$number_minor" lt_irix_increment=no ;; *) func_fatal_configuration "$modename: unknown library version type \`$version_type'" ;; esac ;; no) current="$1" revision="$2" age="$3" ;; esac # Check that each of the things are valid numbers. case $current in 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; *) func_error "CURRENT \`$current' must be a nonnegative integer" func_fatal_error "\`$vinfo' is not valid version information" ;; esac case $revision in 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; *) func_error "REVISION \`$revision' must be a nonnegative integer" func_fatal_error "\`$vinfo' is not valid version information" ;; esac case $age in 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; *) func_error "AGE \`$age' must be a nonnegative integer" func_fatal_error "\`$vinfo' is not valid version information" ;; esac if test "$age" -gt "$current"; then func_error "AGE \`$age' is greater than the current interface number \`$current'" func_fatal_error "\`$vinfo' is not valid version information" fi # Calculate the version variables. major= versuffix= verstring= case $version_type in none) ;; darwin) # Like Linux, but with the current version available in # verstring for coding it into the library header func_arith $current - $age major=.$func_arith_result versuffix="$major.$age.$revision" # Darwin ld doesn't like 0 for these options... func_arith $current + 1 minor_current=$func_arith_result xlcverstring="${wl}-compatibility_version ${wl}$minor_current ${wl}-current_version ${wl}$minor_current.$revision" verstring="-compatibility_version $minor_current -current_version $minor_current.$revision" ;; freebsd-aout) major=".$current" versuffix=".$current.$revision"; ;; freebsd-elf) major=.`expr $current - $age` versuffix="$major" ;; defunct_by_ts_B51007_freebsd-elf) major=".$current" versuffix=".$current"; ;; netbsd) # ts B51007 : to get library.so.N.nn major=.`expr $current - $age` versuffix="$major.$age" ;; irix | nonstopux) if test "X$lt_irix_increment" = "Xno"; then func_arith $current - $age else func_arith $current - $age + 1 fi major=$func_arith_result case $version_type in nonstopux) verstring_prefix=nonstopux ;; *) verstring_prefix=sgi ;; esac verstring="$verstring_prefix$major.$revision" # Add in all the interfaces that we are compatible with. loop=$revision while test "$loop" -ne 0; do func_arith $revision - $loop iface=$func_arith_result func_arith $loop - 1 loop=$func_arith_result verstring="$verstring_prefix$major.$iface:$verstring" done # Before this point, $major must not contain `.'. major=.$major versuffix="$major.$revision" ;; linux) # correct to gnu/linux during the next big refactor func_arith $current - $age major=.$func_arith_result versuffix="$major.$age.$revision" ;; osf) func_arith $current - $age major=.$func_arith_result versuffix=".$current.$age.$revision" verstring="$current.$age.$revision" # Add in all the interfaces that we are compatible with. loop=$age while test "$loop" -ne 0; do func_arith $current - $loop iface=$func_arith_result func_arith $loop - 1 loop=$func_arith_result verstring="$verstring:${iface}.0" done # Make executables depend on our current version. func_append verstring ":${current}.0" ;; qnx) major=".$current" versuffix=".$current" ;; sunos) major=".$current" versuffix=".$current.$revision" ;; windows) # Use '-' rather than '.', since we only want one # extension on DOS 8.3 filesystems. func_arith $current - $age major=$func_arith_result versuffix="-$major" ;; *) func_fatal_configuration "unknown library version type \`$version_type'" ;; esac # Clear the version info if we defaulted, and they specified a release. if test -z "$vinfo" && test -n "$release"; then major= case $version_type in darwin) # we can't check for "0.0" in archive_cmds due to quoting # problems, so we reset it completely verstring= ;; *) verstring="0.0" ;; esac if test "$need_version" = no; then versuffix= else versuffix=".0.0" fi fi # Remove version info from name if versioning should be avoided if test "$avoid_version" = yes && test "$need_version" = no; then major= versuffix= verstring="" fi # Check to see if the archive will have undefined symbols. if test "$allow_undefined" = yes; then if test "$allow_undefined_flag" = unsupported; then func_warning "undefined symbols not allowed in $host shared libraries" build_libtool_libs=no build_old_libs=yes fi else # Don't allow undefined symbols. allow_undefined_flag="$no_undefined_flag" fi fi func_generate_dlsyms "$libname" "$libname" "yes" func_append libobjs " $symfileobj" test "X$libobjs" = "X " && libobjs= if test "$opt_mode" != relink; then # Remove our outputs, but don't remove object files since they # may have been created when compiling PIC objects. removelist= tempremovelist=`$ECHO "$output_objdir/*"` for p in $tempremovelist; do case $p in *.$objext | *.gcno) ;; $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/${libname}${release}.*) if test "X$precious_files_regex" != "X"; then if $ECHO "$p" | $EGREP -e "$precious_files_regex" >/dev/null 2>&1 then continue fi fi func_append removelist " $p" ;; *) ;; esac done test -n "$removelist" && \ func_show_eval "${RM}r \$removelist" fi # Now set the variables for building old libraries. if test "$build_old_libs" = yes && test "$build_libtool_libs" != convenience ; then func_append oldlibs " $output_objdir/$libname.$libext" # Transform .lo files to .o files. oldobjs="$objs "`$ECHO "$libobjs" | $SP2NL | $SED "/\.${libext}$/d; $lo2o" | $NL2SP` fi # Eliminate all temporary directories. #for path in $notinst_path; do # lib_search_path=`$ECHO "$lib_search_path " | $SED "s% $path % %g"` # deplibs=`$ECHO "$deplibs " | $SED "s% -L$path % %g"` # dependency_libs=`$ECHO "$dependency_libs " | $SED "s% -L$path % %g"` #done if test -n "$xrpath"; then # If the user specified any rpath flags, then add them. temp_xrpath= for libdir in $xrpath; do func_replace_sysroot "$libdir" func_append temp_xrpath " -R$func_replace_sysroot_result" case "$finalize_rpath " in *" $libdir "*) ;; *) func_append finalize_rpath " $libdir" ;; esac done if test "$hardcode_into_libs" != yes || test "$build_old_libs" = yes; then dependency_libs="$temp_xrpath $dependency_libs" fi fi # Make sure dlfiles contains only unique files that won't be dlpreopened old_dlfiles="$dlfiles" dlfiles= for lib in $old_dlfiles; do case " $dlprefiles $dlfiles " in *" $lib "*) ;; *) func_append dlfiles " $lib" ;; esac done # Make sure dlprefiles contains only unique files old_dlprefiles="$dlprefiles" dlprefiles= for lib in $old_dlprefiles; do case "$dlprefiles " in *" $lib "*) ;; *) func_append dlprefiles " $lib" ;; esac done if test "$build_libtool_libs" = yes; then if test -n "$rpath"; then case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos* | *-cegcc* | *-*-haiku*) # these systems don't actually have a c library (as such)! ;; *-*-rhapsody* | *-*-darwin1.[012]) # Rhapsody C library is in the System framework func_append deplibs " System.ltframework" ;; *-*-netbsd*) # Don't link with libc until the a.out ld.so is fixed. ;; *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) # Do not include libc due to us having libc/libc_r. ;; *-*-sco3.2v5* | *-*-sco5v6*) # Causes problems with __ctype ;; *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) # Compiler inserts libc in the correct place for threads to work ;; *) # Add libc to deplibs on all other systems if necessary. if test "$build_libtool_need_lc" = "yes"; then func_append deplibs " -lc" fi ;; esac fi # Transform deplibs into only deplibs that can be linked in shared. name_save=$name libname_save=$libname release_save=$release versuffix_save=$versuffix major_save=$major # I'm not sure if I'm treating the release correctly. I think # release should show up in the -l (ie -lgmp5) so we don't want to # add it in twice. Is that correct? release="" versuffix="" major="" newdeplibs= droppeddeps=no case $deplibs_check_method in pass_all) # Don't check for shared/static. Everything works. # This might be a little naive. We might want to check # whether the library exists or not. But this is on # osf3 & osf4 and I'm not really sure... Just # implementing what was already the behavior. newdeplibs=$deplibs ;; test_compile) # This code stresses the "libraries are programs" paradigm to its # limits. Maybe even breaks it. We compile a program, linking it # against the deplibs as a proxy for the library. Then we can check # whether they linked in statically or dynamically with ldd. $opt_dry_run || $RM conftest.c cat > conftest.c <<EOF int main() { return 0; } EOF $opt_dry_run || $RM conftest if $LTCC $LTCFLAGS -o conftest conftest.c $deplibs; then ldd_output=`ldd conftest` for i in $deplibs; do case $i in -l*) func_stripname -l '' "$i" name=$func_stripname_result if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then case " $predeps $postdeps " in *" $i "*) func_append newdeplibs " $i" i="" ;; esac fi if test -n "$i" ; then libname=`eval "\\$ECHO \"$libname_spec\""` deplib_matches=`eval "\\$ECHO \"$library_names_spec\""` set dummy $deplib_matches; shift deplib_match=$1 if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0 ; then func_append newdeplibs " $i" else droppeddeps=yes echo $ECHO "*** Warning: dynamic linker does not accept needed library $i." echo "*** I have the capability to make that library automatically link in when" echo "*** you link to this library. But I can only do this if you have a" echo "*** shared version of the library, which I believe you do not have" echo "*** because a test_compile did reveal that the linker did not use it for" echo "*** its dynamic dependency list that programs get resolved with at runtime." fi fi ;; *) func_append newdeplibs " $i" ;; esac done else # Error occurred in the first compile. Let's try to salvage # the situation: Compile a separate program for each library. for i in $deplibs; do case $i in -l*) func_stripname -l '' "$i" name=$func_stripname_result $opt_dry_run || $RM conftest if $LTCC $LTCFLAGS -o conftest conftest.c $i; then ldd_output=`ldd conftest` if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then case " $predeps $postdeps " in *" $i "*) func_append newdeplibs " $i" i="" ;; esac fi if test -n "$i" ; then libname=`eval "\\$ECHO \"$libname_spec\""` deplib_matches=`eval "\\$ECHO \"$library_names_spec\""` set dummy $deplib_matches; shift deplib_match=$1 if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0 ; then func_append newdeplibs " $i" else droppeddeps=yes echo $ECHO "*** Warning: dynamic linker does not accept needed library $i." echo "*** I have the capability to make that library automatically link in when" echo "*** you link to this library. But I can only do this if you have a" echo "*** shared version of the library, which you do not appear to have" echo "*** because a test_compile did reveal that the linker did not use this one" echo "*** as a dynamic dependency that programs can get resolved with at runtime." fi fi else droppeddeps=yes echo $ECHO "*** Warning! Library $i is needed by this library but I was not able to" echo "*** make it link in! You will probably need to install it or some" echo "*** library that it depends on before this library will be fully" echo "*** functional. Installing it before continuing would be even better." fi ;; *) func_append newdeplibs " $i" ;; esac done fi ;; file_magic*) set dummy $deplibs_check_method; shift file_magic_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"` for a_deplib in $deplibs; do case $a_deplib in -l*) func_stripname -l '' "$a_deplib" name=$func_stripname_result if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then case " $predeps $postdeps " in *" $a_deplib "*) func_append newdeplibs " $a_deplib" a_deplib="" ;; esac fi if test -n "$a_deplib" ; then libname=`eval "\\$ECHO \"$libname_spec\""` if test -n "$file_magic_glob"; then libnameglob=`func_echo_all "$libname" | $SED -e $file_magic_glob` else libnameglob=$libname fi test "$want_nocaseglob" = yes && nocaseglob=`shopt -p nocaseglob` for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do if test "$want_nocaseglob" = yes; then shopt -s nocaseglob potential_libs=`ls $i/$libnameglob[.-]* 2>/dev/null` $nocaseglob else potential_libs=`ls $i/$libnameglob[.-]* 2>/dev/null` fi for potent_lib in $potential_libs; do # Follow soft links. if ls -lLd "$potent_lib" 2>/dev/null | $GREP " -> " >/dev/null; then continue fi # The statement above tries to avoid entering an # endless loop below, in case of cyclic links. # We might still enter an endless loop, since a link # loop can be closed while we follow links, # but so what? potlib="$potent_lib" while test -h "$potlib" 2>/dev/null; do potliblink=`ls -ld $potlib | ${SED} 's/.* -> //'` case $potliblink in [\\/]* | [A-Za-z]:[\\/]*) potlib="$potliblink";; *) potlib=`$ECHO "$potlib" | $SED 's,[^/]*$,,'`"$potliblink";; esac done if eval $file_magic_cmd \"\$potlib\" 2>/dev/null | $SED -e 10q | $EGREP "$file_magic_regex" > /dev/null; then func_append newdeplibs " $a_deplib" a_deplib="" break 2 fi done done fi if test -n "$a_deplib" ; then droppeddeps=yes echo $ECHO "*** Warning: linker path does not have real file for library $a_deplib." echo "*** I have the capability to make that library automatically link in when" echo "*** you link to this library. But I can only do this if you have a" echo "*** shared version of the library, which you do not appear to have" echo "*** because I did check the linker path looking for a file starting" if test -z "$potlib" ; then $ECHO "*** with $libname but no candidates were found. (...for file magic test)" else $ECHO "*** with $libname and none of the candidates passed a file format test" $ECHO "*** using a file magic. Last file checked: $potlib" fi fi ;; *) # Add a -L argument. func_append newdeplibs " $a_deplib" ;; esac done # Gone through all deplibs. ;; match_pattern*) set dummy $deplibs_check_method; shift match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"` for a_deplib in $deplibs; do case $a_deplib in -l*) func_stripname -l '' "$a_deplib" name=$func_stripname_result if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then case " $predeps $postdeps " in *" $a_deplib "*) func_append newdeplibs " $a_deplib" a_deplib="" ;; esac fi if test -n "$a_deplib" ; then libname=`eval "\\$ECHO \"$libname_spec\""` for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do potential_libs=`ls $i/$libname[.-]* 2>/dev/null` for potent_lib in $potential_libs; do potlib="$potent_lib" # see symlink-check above in file_magic test if eval "\$ECHO \"$potent_lib\"" 2>/dev/null | $SED 10q | \ $EGREP "$match_pattern_regex" > /dev/null; then func_append newdeplibs " $a_deplib" a_deplib="" break 2 fi done done fi if test -n "$a_deplib" ; then droppeddeps=yes echo $ECHO "*** Warning: linker path does not have real file for library $a_deplib." echo "*** I have the capability to make that library automatically link in when" echo "*** you link to this library. But I can only do this if you have a" echo "*** shared version of the library, which you do not appear to have" echo "*** because I did check the linker path looking for a file starting" if test -z "$potlib" ; then $ECHO "*** with $libname but no candidates were found. (...for regex pattern test)" else $ECHO "*** with $libname and none of the candidates passed a file format test" $ECHO "*** using a regex pattern. Last file checked: $potlib" fi fi ;; *) # Add a -L argument. func_append newdeplibs " $a_deplib" ;; esac done # Gone through all deplibs. ;; none | unknown | *) newdeplibs="" tmp_deplibs=`$ECHO " $deplibs" | $SED 's/ -lc$//; s/ -[LR][^ ]*//g'` if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then for i in $predeps $postdeps ; do # can't use Xsed below, because $i might contain '/' tmp_deplibs=`$ECHO " $tmp_deplibs" | $SED "s,$i,,"` done fi case $tmp_deplibs in *[!\ \ ]*) echo if test "X$deplibs_check_method" = "Xnone"; then echo "*** Warning: inter-library dependencies are not supported in this platform." else echo "*** Warning: inter-library dependencies are not known to be supported." fi echo "*** All declared inter-library dependencies are being dropped." droppeddeps=yes ;; esac ;; esac versuffix=$versuffix_save major=$major_save release=$release_save libname=$libname_save name=$name_save case $host in *-*-rhapsody* | *-*-darwin1.[012]) # On Rhapsody replace the C library with the System framework newdeplibs=`$ECHO " $newdeplibs" | $SED 's/ -lc / System.ltframework /'` ;; esac if test "$droppeddeps" = yes; then if test "$module" = yes; then echo echo "*** Warning: libtool could not satisfy all declared inter-library" $ECHO "*** dependencies of module $libname. Therefore, libtool will create" echo "*** a static module, that should work as long as the dlopening" echo "*** application is linked with the -dlopen flag." if test -z "$global_symbol_pipe"; then echo echo "*** However, this would only work if libtool was able to extract symbol" echo "*** lists from a program, using \`nm' or equivalent, but libtool could" echo "*** not find such a program. So, this module is probably useless." echo "*** \`nm' from GNU binutils and a full rebuild may help." fi if test "$build_old_libs" = no; then oldlibs="$output_objdir/$libname.$libext" build_libtool_libs=module build_old_libs=yes else build_libtool_libs=no fi else echo "*** The inter-library dependencies that have been dropped here will be" echo "*** automatically added whenever a program is linked with this library" echo "*** or is declared to -dlopen it." if test "$allow_undefined" = no; then echo echo "*** Since this library must not contain undefined symbols," echo "*** because either the platform does not support them or" echo "*** it was explicitly requested with -no-undefined," echo "*** libtool will only create a static version of it." if test "$build_old_libs" = no; then oldlibs="$output_objdir/$libname.$libext" build_libtool_libs=module build_old_libs=yes else build_libtool_libs=no fi fi fi fi # Done checking deplibs! deplibs=$newdeplibs fi # Time to change all our "foo.ltframework" stuff back to "-framework foo" case $host in *-*-darwin*) newdeplibs=`$ECHO " $newdeplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` new_inherited_linker_flags=`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` deplibs=`$ECHO " $deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` ;; esac # move library search paths that coincide with paths to not yet # installed libraries to the beginning of the library search list new_libs= for path in $notinst_path; do case " $new_libs " in *" -L$path/$objdir "*) ;; *) case " $deplibs " in *" -L$path/$objdir "*) func_append new_libs " -L$path/$objdir" ;; esac ;; esac done for deplib in $deplibs; do case $deplib in -L*) case " $new_libs " in *" $deplib "*) ;; *) func_append new_libs " $deplib" ;; esac ;; *) func_append new_libs " $deplib" ;; esac done deplibs="$new_libs" # All the library-specific variables (install_libdir is set above). library_names= old_library= dlname= # Test again, we may have decided not to build it any more if test "$build_libtool_libs" = yes; then # Remove ${wl} instances when linking with ld. # FIXME: should test the right _cmds variable. case $archive_cmds in *\$LD\ *) wl= ;; esac if test "$hardcode_into_libs" = yes; then # Hardcode the library paths hardcode_libdirs= dep_rpath= rpath="$finalize_rpath" test "$opt_mode" != relink && rpath="$compile_rpath$rpath" for libdir in $rpath; do if test -n "$hardcode_libdir_flag_spec"; then if test -n "$hardcode_libdir_separator"; then func_replace_sysroot "$libdir" libdir=$func_replace_sysroot_result if test -z "$hardcode_libdirs"; then hardcode_libdirs="$libdir" else # Just accumulate the unique libdirs. case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) ;; *) func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" ;; esac fi else eval flag=\"$hardcode_libdir_flag_spec\" func_append dep_rpath " $flag" fi elif test -n "$runpath_var"; then case "$perm_rpath " in *" $libdir "*) ;; *) func_append perm_rpath " $libdir" ;; esac fi done # Substitute the hardcoded libdirs into the rpath. if test -n "$hardcode_libdir_separator" && test -n "$hardcode_libdirs"; then libdir="$hardcode_libdirs" eval "dep_rpath=\"$hardcode_libdir_flag_spec\"" fi if test -n "$runpath_var" && test -n "$perm_rpath"; then # We should set the runpath_var. rpath= for dir in $perm_rpath; do func_append rpath "$dir:" done eval "$runpath_var='$rpath\$$runpath_var'; export $runpath_var" fi test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs" fi shlibpath="$finalize_shlibpath" test "$opt_mode" != relink && shlibpath="$compile_shlibpath$shlibpath" if test -n "$shlibpath"; then eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var" fi # Get the real and link names of the library. eval shared_ext=\"$shrext_cmds\" eval library_names=\"$library_names_spec\" set dummy $library_names shift realname="$1" shift if test -n "$soname_spec"; then eval soname=\"$soname_spec\" else soname="$realname" fi if test -z "$dlname"; then dlname=$soname fi lib="$output_objdir/$realname" linknames= for link do func_append linknames " $link" done # Use standard objects if they are pic test -z "$pic_flag" && libobjs=`$ECHO "$libobjs" | $SP2NL | $SED "$lo2o" | $NL2SP` test "X$libobjs" = "X " && libobjs= delfiles= if test -n "$export_symbols" && test -n "$include_expsyms"; then $opt_dry_run || cp "$export_symbols" "$output_objdir/$libname.uexp" export_symbols="$output_objdir/$libname.uexp" func_append delfiles " $export_symbols" fi orig_export_symbols= case $host_os in cygwin* | mingw* | cegcc*) if test -n "$export_symbols" && test -z "$export_symbols_regex"; then # exporting using user supplied symfile if test "x`$SED 1q $export_symbols`" != xEXPORTS; then # and it's NOT already a .def file. Must figure out # which of the given symbols are data symbols and tag # them as such. So, trigger use of export_symbols_cmds. # export_symbols gets reassigned inside the "prepare # the list of exported symbols" if statement, so the # include_expsyms logic still works. orig_export_symbols="$export_symbols" export_symbols= always_export_symbols=yes fi fi ;; esac # Prepare the list of exported symbols if test -z "$export_symbols"; then if test "$always_export_symbols" = yes || test -n "$export_symbols_regex"; then func_verbose "generating symbol list for \`$libname.la'" export_symbols="$output_objdir/$libname.exp" $opt_dry_run || $RM $export_symbols cmds=$export_symbols_cmds save_ifs="$IFS"; IFS='~' for cmd1 in $cmds; do IFS="$save_ifs" # Take the normal branch if the nm_file_list_spec branch # doesn't work or if tool conversion is not needed. case $nm_file_list_spec~$to_tool_file_cmd in *~func_convert_file_noop | *~func_convert_file_msys_to_w32 | ~*) try_normal_branch=yes eval cmd=\"$cmd1\" func_len " $cmd" len=$func_len_result ;; *) try_normal_branch=no ;; esac if test "$try_normal_branch" = yes \ && { test "$len" -lt "$max_cmd_len" \ || test "$max_cmd_len" -le -1; } then func_show_eval "$cmd" 'exit $?' skipped_export=false elif test -n "$nm_file_list_spec"; then func_basename "$output" output_la=$func_basename_result save_libobjs=$libobjs save_output=$output output=${output_objdir}/${output_la}.nm func_to_tool_file "$output" libobjs=$nm_file_list_spec$func_to_tool_file_result func_append delfiles " $output" func_verbose "creating $NM input file list: $output" for obj in $save_libobjs; do func_to_tool_file "$obj" $ECHO "$func_to_tool_file_result" done > "$output" eval cmd=\"$cmd1\" func_show_eval "$cmd" 'exit $?' output=$save_output libobjs=$save_libobjs skipped_export=false else # The command line is too long to execute in one step. func_verbose "using reloadable object file for export list..." skipped_export=: # Break out early, otherwise skipped_export may be # set to false by a later but shorter cmd. break fi done IFS="$save_ifs" if test -n "$export_symbols_regex" && test "X$skipped_export" != "X:"; then func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' func_show_eval '$MV "${export_symbols}T" "$export_symbols"' fi fi fi if test -n "$export_symbols" && test -n "$include_expsyms"; then tmp_export_symbols="$export_symbols" test -n "$orig_export_symbols" && tmp_export_symbols="$orig_export_symbols" $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"' fi if test "X$skipped_export" != "X:" && test -n "$orig_export_symbols"; then # The given exports_symbols file has to be filtered, so filter it. func_verbose "filter symbol list for \`$libname.la' to tag DATA exports" # FIXME: $output_objdir/$libname.filter potentially contains lots of # 's' commands which not all seds can handle. GNU sed should be fine # though. Also, the filter scales superlinearly with the number of # global variables. join(1) would be nice here, but unfortunately # isn't a blessed tool. $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter func_append delfiles " $export_symbols $output_objdir/$libname.filter" export_symbols=$output_objdir/$libname.def $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols fi tmp_deplibs= for test_deplib in $deplibs; do case " $convenience " in *" $test_deplib "*) ;; *) func_append tmp_deplibs " $test_deplib" ;; esac done deplibs="$tmp_deplibs" if test -n "$convenience"; then if test -n "$whole_archive_flag_spec" && test "$compiler_needs_object" = yes && test -z "$libobjs"; then # extract the archives, so we have objects to list. # TODO: could optimize this to just extract one archive. whole_archive_flag_spec= fi if test -n "$whole_archive_flag_spec"; then save_libobjs=$libobjs eval libobjs=\"\$libobjs $whole_archive_flag_spec\" test "X$libobjs" = "X " && libobjs= else gentop="$output_objdir/${outputname}x" func_append generated " $gentop" func_extract_archives $gentop $convenience func_append libobjs " $func_extract_archives_result" test "X$libobjs" = "X " && libobjs= fi fi if test "$thread_safe" = yes && test -n "$thread_safe_flag_spec"; then eval flag=\"$thread_safe_flag_spec\" func_append linker_flags " $flag" fi # Make a backup of the uninstalled library when relinking if test "$opt_mode" = relink; then $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}U && $MV $realname ${realname}U)' || exit $? fi # Do each of the archive commands. if test "$module" = yes && test -n "$module_cmds" ; then if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then eval test_cmds=\"$module_expsym_cmds\" cmds=$module_expsym_cmds else eval test_cmds=\"$module_cmds\" cmds=$module_cmds fi else if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then eval test_cmds=\"$archive_expsym_cmds\" cmds=$archive_expsym_cmds else eval test_cmds=\"$archive_cmds\" cmds=$archive_cmds fi fi if test "X$skipped_export" != "X:" && func_len " $test_cmds" && len=$func_len_result && test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then : else # The command line is too long to link in one step, link piecewise # or, if using GNU ld and skipped_export is not :, use a linker # script. # Save the value of $output and $libobjs because we want to # use them later. If we have whole_archive_flag_spec, we # want to use save_libobjs as it was before # whole_archive_flag_spec was expanded, because we can't # assume the linker understands whole_archive_flag_spec. # This may have to be revisited, in case too many # convenience libraries get linked in and end up exceeding # the spec. if test -z "$convenience" || test -z "$whole_archive_flag_spec"; then save_libobjs=$libobjs fi save_output=$output func_basename "$output" output_la=$func_basename_result # Clear the reloadable object creation command queue and # initialize k to one. test_cmds= concat_cmds= objlist= last_robj= k=1 if test -n "$save_libobjs" && test "X$skipped_export" != "X:" && test "$with_gnu_ld" = yes; then output=${output_objdir}/${output_la}.lnkscript func_verbose "creating GNU ld script: $output" echo 'INPUT (' > $output for obj in $save_libobjs do func_to_tool_file "$obj" $ECHO "$func_to_tool_file_result" >> $output done echo ')' >> $output func_append delfiles " $output" func_to_tool_file "$output" output=$func_to_tool_file_result elif test -n "$save_libobjs" && test "X$skipped_export" != "X:" && test "X$file_list_spec" != X; then output=${output_objdir}/${output_la}.lnk func_verbose "creating linker input file list: $output" : > $output set x $save_libobjs shift firstobj= if test "$compiler_needs_object" = yes; then firstobj="$1 " shift fi for obj do func_to_tool_file "$obj" $ECHO "$func_to_tool_file_result" >> $output done func_append delfiles " $output" func_to_tool_file "$output" output=$firstobj\"$file_list_spec$func_to_tool_file_result\" else if test -n "$save_libobjs"; then func_verbose "creating reloadable object files..." output=$output_objdir/$output_la-${k}.$objext eval test_cmds=\"$reload_cmds\" func_len " $test_cmds" len0=$func_len_result len=$len0 # Loop over the list of objects to be linked. for obj in $save_libobjs do func_len " $obj" func_arith $len + $func_len_result len=$func_arith_result if test "X$objlist" = X || test "$len" -lt "$max_cmd_len"; then func_append objlist " $obj" else # The command $test_cmds is almost too long, add a # command to the queue. if test "$k" -eq 1 ; then # The first file doesn't have a previous command to add. reload_objs=$objlist eval concat_cmds=\"$reload_cmds\" else # All subsequent reloadable object files will link in # the last one created. reload_objs="$objlist $last_robj" eval concat_cmds=\"\$concat_cmds~$reload_cmds~\$RM $last_robj\" fi last_robj=$output_objdir/$output_la-${k}.$objext func_arith $k + 1 k=$func_arith_result output=$output_objdir/$output_la-${k}.$objext objlist=" $obj" func_len " $last_robj" func_arith $len0 + $func_len_result len=$func_arith_result fi done # Handle the remaining objects by creating one last # reloadable object file. All subsequent reloadable object # files will link in the last one created. test -z "$concat_cmds" || concat_cmds=$concat_cmds~ reload_objs="$objlist $last_robj" eval concat_cmds=\"\${concat_cmds}$reload_cmds\" if test -n "$last_robj"; then eval concat_cmds=\"\${concat_cmds}~\$RM $last_robj\" fi func_append delfiles " $output" else output= fi if ${skipped_export-false}; then func_verbose "generating symbol list for \`$libname.la'" export_symbols="$output_objdir/$libname.exp" $opt_dry_run || $RM $export_symbols libobjs=$output # Append the command to create the export file. test -z "$concat_cmds" || concat_cmds=$concat_cmds~ eval concat_cmds=\"\$concat_cmds$export_symbols_cmds\" if test -n "$last_robj"; then eval concat_cmds=\"\$concat_cmds~\$RM $last_robj\" fi fi test -n "$save_libobjs" && func_verbose "creating a temporary reloadable object file: $output" # Loop through the commands generated above and execute them. save_ifs="$IFS"; IFS='~' for cmd in $concat_cmds; do IFS="$save_ifs" $opt_silent || { func_quote_for_expand "$cmd" eval "func_echo $func_quote_for_expand_result" } $opt_dry_run || eval "$cmd" || { lt_exit=$? # Restore the uninstalled library and exit if test "$opt_mode" = relink; then ( cd "$output_objdir" && \ $RM "${realname}T" && \ $MV "${realname}U" "$realname" ) fi exit $lt_exit } done IFS="$save_ifs" if test -n "$export_symbols_regex" && ${skipped_export-false}; then func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' func_show_eval '$MV "${export_symbols}T" "$export_symbols"' fi fi if ${skipped_export-false}; then if test -n "$export_symbols" && test -n "$include_expsyms"; then tmp_export_symbols="$export_symbols" test -n "$orig_export_symbols" && tmp_export_symbols="$orig_export_symbols" $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"' fi if test -n "$orig_export_symbols"; then # The given exports_symbols file has to be filtered, so filter it. func_verbose "filter symbol list for \`$libname.la' to tag DATA exports" # FIXME: $output_objdir/$libname.filter potentially contains lots of # 's' commands which not all seds can handle. GNU sed should be fine # though. Also, the filter scales superlinearly with the number of # global variables. join(1) would be nice here, but unfortunately # isn't a blessed tool. $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter func_append delfiles " $export_symbols $output_objdir/$libname.filter" export_symbols=$output_objdir/$libname.def $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols fi fi libobjs=$output # Restore the value of output. output=$save_output if test -n "$convenience" && test -n "$whole_archive_flag_spec"; then eval libobjs=\"\$libobjs $whole_archive_flag_spec\" test "X$libobjs" = "X " && libobjs= fi # Expand the library linking commands again to reset the # value of $libobjs for piecewise linking. # Do each of the archive commands. if test "$module" = yes && test -n "$module_cmds" ; then if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then cmds=$module_expsym_cmds else cmds=$module_cmds fi else if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then cmds=$archive_expsym_cmds else cmds=$archive_cmds fi fi fi if test -n "$delfiles"; then # Append the command to remove temporary files to $cmds. eval cmds=\"\$cmds~\$RM $delfiles\" fi # Add any objects from preloaded convenience libraries if test -n "$dlprefiles"; then gentop="$output_objdir/${outputname}x" func_append generated " $gentop" func_extract_archives $gentop $dlprefiles func_append libobjs " $func_extract_archives_result" test "X$libobjs" = "X " && libobjs= fi save_ifs="$IFS"; IFS='~' for cmd in $cmds; do IFS="$save_ifs" eval cmd=\"$cmd\" $opt_silent || { func_quote_for_expand "$cmd" eval "func_echo $func_quote_for_expand_result" } $opt_dry_run || eval "$cmd" || { lt_exit=$? # Restore the uninstalled library and exit if test "$opt_mode" = relink; then ( cd "$output_objdir" && \ $RM "${realname}T" && \ $MV "${realname}U" "$realname" ) fi exit $lt_exit } done IFS="$save_ifs" # Restore the uninstalled library and exit if test "$opt_mode" = relink; then $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}T && $MV $realname ${realname}T && $MV ${realname}U $realname)' || exit $? if test -n "$convenience"; then if test -z "$whole_archive_flag_spec"; then func_show_eval '${RM}r "$gentop"' fi fi exit $EXIT_SUCCESS fi # Create links to the real library. for linkname in $linknames; do if test "$realname" != "$linkname"; then func_show_eval '(cd "$output_objdir" && $RM "$linkname" && $LN_S "$realname" "$linkname")' 'exit $?' fi done # If -module or -export-dynamic was specified, set the dlname. if test "$module" = yes || test "$export_dynamic" = yes; then # On all known operating systems, these are identical. dlname="$soname" fi fi ;; obj) if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then func_warning "\`-dlopen' is ignored for objects" fi case " $deplibs" in *\ -l* | *\ -L*) func_warning "\`-l' and \`-L' are ignored for objects" ;; esac test -n "$rpath" && \ func_warning "\`-rpath' is ignored for objects" test -n "$xrpath" && \ func_warning "\`-R' is ignored for objects" test -n "$vinfo" && \ func_warning "\`-version-info' is ignored for objects" test -n "$release" && \ func_warning "\`-release' is ignored for objects" case $output in *.lo) test -n "$objs$old_deplibs" && \ func_fatal_error "cannot build library object \`$output' from non-libtool objects" libobj=$output func_lo2o "$libobj" obj=$func_lo2o_result ;; *) libobj= obj="$output" ;; esac # Delete the old objects. $opt_dry_run || $RM $obj $libobj # Objects from convenience libraries. This assumes # single-version convenience libraries. Whenever we create # different ones for PIC/non-PIC, this we'll have to duplicate # the extraction. reload_conv_objs= gentop= # reload_cmds runs $LD directly, so let us get rid of # -Wl from whole_archive_flag_spec and hope we can get by with # turning comma into space.. wl= if test -n "$convenience"; then if test -n "$whole_archive_flag_spec"; then eval tmp_whole_archive_flags=\"$whole_archive_flag_spec\" reload_conv_objs=$reload_objs\ `$ECHO "$tmp_whole_archive_flags" | $SED 's|,| |g'` else gentop="$output_objdir/${obj}x" func_append generated " $gentop" func_extract_archives $gentop $convenience reload_conv_objs="$reload_objs $func_extract_archives_result" fi fi # If we're not building shared, we need to use non_pic_objs test "$build_libtool_libs" != yes && libobjs="$non_pic_objects" # Create the old-style object. reload_objs="$objs$old_deplibs "`$ECHO "$libobjs" | $SP2NL | $SED "/\.${libext}$/d; /\.lib$/d; $lo2o" | $NL2SP`" $reload_conv_objs" ### testsuite: skip nested quoting test output="$obj" func_execute_cmds "$reload_cmds" 'exit $?' # Exit if we aren't doing a library object file. if test -z "$libobj"; then if test -n "$gentop"; then func_show_eval '${RM}r "$gentop"' fi exit $EXIT_SUCCESS fi if test "$build_libtool_libs" != yes; then if test -n "$gentop"; then func_show_eval '${RM}r "$gentop"' fi # Create an invalid libtool object if no PIC, so that we don't # accidentally link it into a program. # $show "echo timestamp > $libobj" # $opt_dry_run || eval "echo timestamp > $libobj" || exit $? exit $EXIT_SUCCESS fi if test -n "$pic_flag" || test "$pic_mode" != default; then # Only do commands if we really have different PIC objects. reload_objs="$libobjs $reload_conv_objs" output="$libobj" func_execute_cmds "$reload_cmds" 'exit $?' fi if test -n "$gentop"; then func_show_eval '${RM}r "$gentop"' fi exit $EXIT_SUCCESS ;; prog) case $host in *cygwin*) func_stripname '' '.exe' "$output" output=$func_stripname_result.exe;; esac test -n "$vinfo" && \ func_warning "\`-version-info' is ignored for programs" test -n "$release" && \ func_warning "\`-release' is ignored for programs" test "$preload" = yes \ && test "$dlopen_support" = unknown \ && test "$dlopen_self" = unknown \ && test "$dlopen_self_static" = unknown && \ func_warning "\`LT_INIT([dlopen])' not used. Assuming no dlopen support." case $host in *-*-rhapsody* | *-*-darwin1.[012]) # On Rhapsody replace the C library is the System framework compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's/ -lc / System.ltframework /'` finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's/ -lc / System.ltframework /'` ;; esac case $host in *-*-darwin*) # Don't allow lazy linking, it breaks C++ global constructors # But is supposedly fixed on 10.4 or later (yay!). if test "$tagname" = CXX ; then case ${MACOSX_DEPLOYMENT_TARGET-10.0} in 10.[0123]) func_append compile_command " ${wl}-bind_at_load" func_append finalize_command " ${wl}-bind_at_load" ;; esac fi # Time to change all our "foo.ltframework" stuff back to "-framework foo" compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` ;; esac # move library search paths that coincide with paths to not yet # installed libraries to the beginning of the library search list new_libs= for path in $notinst_path; do case " $new_libs " in *" -L$path/$objdir "*) ;; *) case " $compile_deplibs " in *" -L$path/$objdir "*) func_append new_libs " -L$path/$objdir" ;; esac ;; esac done for deplib in $compile_deplibs; do case $deplib in -L*) case " $new_libs " in *" $deplib "*) ;; *) func_append new_libs " $deplib" ;; esac ;; *) func_append new_libs " $deplib" ;; esac done compile_deplibs="$new_libs" func_append compile_command " $compile_deplibs" func_append finalize_command " $finalize_deplibs" if test -n "$rpath$xrpath"; then # If the user specified any rpath flags, then add them. for libdir in $rpath $xrpath; do # This is the magic to use -rpath. case "$finalize_rpath " in *" $libdir "*) ;; *) func_append finalize_rpath " $libdir" ;; esac done fi # Now hardcode the library paths rpath= hardcode_libdirs= for libdir in $compile_rpath $finalize_rpath; do if test -n "$hardcode_libdir_flag_spec"; then if test -n "$hardcode_libdir_separator"; then if test -z "$hardcode_libdirs"; then hardcode_libdirs="$libdir" else # Just accumulate the unique libdirs. case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) ;; *) func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" ;; esac fi else eval flag=\"$hardcode_libdir_flag_spec\" func_append rpath " $flag" fi elif test -n "$runpath_var"; then case "$perm_rpath " in *" $libdir "*) ;; *) func_append perm_rpath " $libdir" ;; esac fi case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) testbindir=`${ECHO} "$libdir" | ${SED} -e 's*/lib$*/bin*'` case :$dllsearchpath: in *":$libdir:"*) ;; ::) dllsearchpath=$libdir;; *) func_append dllsearchpath ":$libdir";; esac case :$dllsearchpath: in *":$testbindir:"*) ;; ::) dllsearchpath=$testbindir;; *) func_append dllsearchpath ":$testbindir";; esac ;; esac done # Substitute the hardcoded libdirs into the rpath. if test -n "$hardcode_libdir_separator" && test -n "$hardcode_libdirs"; then libdir="$hardcode_libdirs" eval rpath=\" $hardcode_libdir_flag_spec\" fi compile_rpath="$rpath" rpath= hardcode_libdirs= for libdir in $finalize_rpath; do if test -n "$hardcode_libdir_flag_spec"; then if test -n "$hardcode_libdir_separator"; then if test -z "$hardcode_libdirs"; then hardcode_libdirs="$libdir" else # Just accumulate the unique libdirs. case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) ;; *) func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" ;; esac fi else eval flag=\"$hardcode_libdir_flag_spec\" func_append rpath " $flag" fi elif test -n "$runpath_var"; then case "$finalize_perm_rpath " in *" $libdir "*) ;; *) func_append finalize_perm_rpath " $libdir" ;; esac fi done # Substitute the hardcoded libdirs into the rpath. if test -n "$hardcode_libdir_separator" && test -n "$hardcode_libdirs"; then libdir="$hardcode_libdirs" eval rpath=\" $hardcode_libdir_flag_spec\" fi finalize_rpath="$rpath" if test -n "$libobjs" && test "$build_old_libs" = yes; then # Transform all the library objects into standard objects. compile_command=`$ECHO "$compile_command" | $SP2NL | $SED "$lo2o" | $NL2SP` finalize_command=`$ECHO "$finalize_command" | $SP2NL | $SED "$lo2o" | $NL2SP` fi func_generate_dlsyms "$outputname" "@PROGRAM@" "no" # template prelinking step if test -n "$prelink_cmds"; then func_execute_cmds "$prelink_cmds" 'exit $?' fi wrappers_required=yes case $host in *cegcc* | *mingw32ce*) # Disable wrappers for cegcc and mingw32ce hosts, we are cross compiling anyway. wrappers_required=no ;; *cygwin* | *mingw* ) if test "$build_libtool_libs" != yes; then wrappers_required=no fi ;; *) if test "$need_relink" = no || test "$build_libtool_libs" != yes; then wrappers_required=no fi ;; esac if test "$wrappers_required" = no; then # Replace the output file specification. compile_command=`$ECHO "$compile_command" | $SED 's%@OUTPUT@%'"$output"'%g'` link_command="$compile_command$compile_rpath" # We have no uninstalled library dependencies, so finalize right now. exit_status=0 func_show_eval "$link_command" 'exit_status=$?' if test -n "$postlink_cmds"; then func_to_tool_file "$output" postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` func_execute_cmds "$postlink_cmds" 'exit $?' fi # Delete the generated files. if test -f "$output_objdir/${outputname}S.${objext}"; then func_show_eval '$RM "$output_objdir/${outputname}S.${objext}"' fi exit $exit_status fi if test -n "$compile_shlibpath$finalize_shlibpath"; then compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command" fi if test -n "$finalize_shlibpath"; then finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command" fi compile_var= finalize_var= if test -n "$runpath_var"; then if test -n "$perm_rpath"; then # We should set the runpath_var. rpath= for dir in $perm_rpath; do func_append rpath "$dir:" done compile_var="$runpath_var=\"$rpath\$$runpath_var\" " fi if test -n "$finalize_perm_rpath"; then # We should set the runpath_var. rpath= for dir in $finalize_perm_rpath; do func_append rpath "$dir:" done finalize_var="$runpath_var=\"$rpath\$$runpath_var\" " fi fi if test "$no_install" = yes; then # We don't need to create a wrapper script. link_command="$compile_var$compile_command$compile_rpath" # Replace the output file specification. link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output"'%g'` # Delete the old output file. $opt_dry_run || $RM $output # Link the executable and exit func_show_eval "$link_command" 'exit $?' if test -n "$postlink_cmds"; then func_to_tool_file "$output" postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` func_execute_cmds "$postlink_cmds" 'exit $?' fi exit $EXIT_SUCCESS fi if test "$hardcode_action" = relink; then # Fast installation is not supported link_command="$compile_var$compile_command$compile_rpath" relink_command="$finalize_var$finalize_command$finalize_rpath" func_warning "this platform does not like uninstalled shared libraries" func_warning "\`$output' will be relinked during installation" else if test "$fast_install" != no; then link_command="$finalize_var$compile_command$finalize_rpath" if test "$fast_install" = yes; then relink_command=`$ECHO "$compile_var$compile_command$compile_rpath" | $SED 's%@OUTPUT@%\$progdir/\$file%g'` else # fast_install is set to needless relink_command= fi else link_command="$compile_var$compile_command$compile_rpath" relink_command="$finalize_var$finalize_command$finalize_rpath" fi fi # Replace the output file specification. link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'` # Delete the old output files. $opt_dry_run || $RM $output $output_objdir/$outputname $output_objdir/lt-$outputname func_show_eval "$link_command" 'exit $?' if test -n "$postlink_cmds"; then func_to_tool_file "$output_objdir/$outputname" postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` func_execute_cmds "$postlink_cmds" 'exit $?' fi # Now create the wrapper script. func_verbose "creating $output" # Quote the relink command for shipping. if test -n "$relink_command"; then # Preserve any variables that may affect compiler behavior for var in $variables_saved_for_relink; do if eval test -z \"\${$var+set}\"; then relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command" elif eval var_value=\$$var; test -z "$var_value"; then relink_command="$var=; export $var; $relink_command" else func_quote_for_eval "$var_value" relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command" fi done relink_command="(cd `pwd`; $relink_command)" relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"` fi # Only actually do things if not in dry run mode. $opt_dry_run || { # win32 will think the script is a binary if it has # a .exe suffix, so we strip it off here. case $output in *.exe) func_stripname '' '.exe' "$output" output=$func_stripname_result ;; esac # test for cygwin because mv fails w/o .exe extensions case $host in *cygwin*) exeext=.exe func_stripname '' '.exe' "$outputname" outputname=$func_stripname_result ;; *) exeext= ;; esac case $host in *cygwin* | *mingw* ) func_dirname_and_basename "$output" "" "." output_name=$func_basename_result output_path=$func_dirname_result cwrappersource="$output_path/$objdir/lt-$output_name.c" cwrapper="$output_path/$output_name.exe" $RM $cwrappersource $cwrapper trap "$RM $cwrappersource $cwrapper; exit $EXIT_FAILURE" 1 2 15 func_emit_cwrapperexe_src > $cwrappersource # The wrapper executable is built using the $host compiler, # because it contains $host paths and files. If cross- # compiling, it, like the target executable, must be # executed on the $host or under an emulation environment. $opt_dry_run || { $LTCC $LTCFLAGS -o $cwrapper $cwrappersource $STRIP $cwrapper } # Now, create the wrapper script for func_source use: func_ltwrapper_scriptname $cwrapper $RM $func_ltwrapper_scriptname_result trap "$RM $func_ltwrapper_scriptname_result; exit $EXIT_FAILURE" 1 2 15 $opt_dry_run || { # note: this script will not be executed, so do not chmod. if test "x$build" = "x$host" ; then $cwrapper --lt-dump-script > $func_ltwrapper_scriptname_result else func_emit_wrapper no > $func_ltwrapper_scriptname_result fi } ;; * ) $RM $output trap "$RM $output; exit $EXIT_FAILURE" 1 2 15 func_emit_wrapper no > $output chmod +x $output ;; esac } exit $EXIT_SUCCESS ;; esac # See if we need to build an old-fashioned archive. for oldlib in $oldlibs; do if test "$build_libtool_libs" = convenience; then oldobjs="$libobjs_save $symfileobj" addlibs="$convenience" build_libtool_libs=no else if test "$build_libtool_libs" = module; then oldobjs="$libobjs_save" build_libtool_libs=no else oldobjs="$old_deplibs $non_pic_objects" if test "$preload" = yes && test -f "$symfileobj"; then func_append oldobjs " $symfileobj" fi fi addlibs="$old_convenience" fi if test -n "$addlibs"; then gentop="$output_objdir/${outputname}x" func_append generated " $gentop" func_extract_archives $gentop $addlibs func_append oldobjs " $func_extract_archives_result" fi # Do each command in the archive commands. if test -n "$old_archive_from_new_cmds" && test "$build_libtool_libs" = yes; then cmds=$old_archive_from_new_cmds else # Add any objects from preloaded convenience libraries if test -n "$dlprefiles"; then gentop="$output_objdir/${outputname}x" func_append generated " $gentop" func_extract_archives $gentop $dlprefiles func_append oldobjs " $func_extract_archives_result" fi # POSIX demands no paths to be encoded in archives. We have # to avoid creating archives with duplicate basenames if we # might have to extract them afterwards, e.g., when creating a # static archive out of a convenience library, or when linking # the entirety of a libtool archive into another (currently # not supported by libtool). if (for obj in $oldobjs do func_basename "$obj" $ECHO "$func_basename_result" done | sort | sort -uc >/dev/null 2>&1); then : else echo "copying selected object files to avoid basename conflicts..." gentop="$output_objdir/${outputname}x" func_append generated " $gentop" func_mkdir_p "$gentop" save_oldobjs=$oldobjs oldobjs= counter=1 for obj in $save_oldobjs do func_basename "$obj" objbase="$func_basename_result" case " $oldobjs " in " ") oldobjs=$obj ;; *[\ /]"$objbase "*) while :; do # Make sure we don't pick an alternate name that also # overlaps. newobj=lt$counter-$objbase func_arith $counter + 1 counter=$func_arith_result case " $oldobjs " in *[\ /]"$newobj "*) ;; *) if test ! -f "$gentop/$newobj"; then break; fi ;; esac done func_show_eval "ln $obj $gentop/$newobj || cp $obj $gentop/$newobj" func_append oldobjs " $gentop/$newobj" ;; *) func_append oldobjs " $obj" ;; esac done fi func_to_tool_file "$oldlib" func_convert_file_msys_to_w32 tool_oldlib=$func_to_tool_file_result eval cmds=\"$old_archive_cmds\" func_len " $cmds" len=$func_len_result if test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then cmds=$old_archive_cmds elif test -n "$archiver_list_spec"; then func_verbose "using command file archive linking..." for obj in $oldobjs do func_to_tool_file "$obj" $ECHO "$func_to_tool_file_result" done > $output_objdir/$libname.libcmd func_to_tool_file "$output_objdir/$libname.libcmd" oldobjs=" $archiver_list_spec$func_to_tool_file_result" cmds=$old_archive_cmds else # the command line is too long to link in one step, link in parts func_verbose "using piecewise archive linking..." save_RANLIB=$RANLIB RANLIB=: objlist= concat_cmds= save_oldobjs=$oldobjs oldobjs= # Is there a better way of finding the last object in the list? for obj in $save_oldobjs do last_oldobj=$obj done eval test_cmds=\"$old_archive_cmds\" func_len " $test_cmds" len0=$func_len_result len=$len0 for obj in $save_oldobjs do func_len " $obj" func_arith $len + $func_len_result len=$func_arith_result func_append objlist " $obj" if test "$len" -lt "$max_cmd_len"; then : else # the above command should be used before it gets too long oldobjs=$objlist if test "$obj" = "$last_oldobj" ; then RANLIB=$save_RANLIB fi test -z "$concat_cmds" || concat_cmds=$concat_cmds~ eval concat_cmds=\"\${concat_cmds}$old_archive_cmds\" objlist= len=$len0 fi done RANLIB=$save_RANLIB oldobjs=$objlist if test "X$oldobjs" = "X" ; then eval cmds=\"\$concat_cmds\" else eval cmds=\"\$concat_cmds~\$old_archive_cmds\" fi fi fi func_execute_cmds "$cmds" 'exit $?' done test -n "$generated" && \ func_show_eval "${RM}r$generated" # Now create the libtool archive. case $output in *.la) old_library= test "$build_old_libs" = yes && old_library="$libname.$libext" func_verbose "creating $output" # Preserve any variables that may affect compiler behavior for var in $variables_saved_for_relink; do if eval test -z \"\${$var+set}\"; then relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command" elif eval var_value=\$$var; test -z "$var_value"; then relink_command="$var=; export $var; $relink_command" else func_quote_for_eval "$var_value" relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command" fi done # Quote the link command for shipping. relink_command="(cd `pwd`; $SHELL $progpath $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)" relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"` if test "$hardcode_automatic" = yes ; then relink_command= fi # Only create the output if not a dry run. $opt_dry_run || { for installed in no yes; do if test "$installed" = yes; then if test -z "$install_libdir"; then break fi output="$output_objdir/$outputname"i # Replace all uninstalled libtool libraries with the installed ones newdependency_libs= for deplib in $dependency_libs; do case $deplib in *.la) func_basename "$deplib" name="$func_basename_result" func_resolve_sysroot "$deplib" eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $func_resolve_sysroot_result` test -z "$libdir" && \ func_fatal_error "\`$deplib' is not a valid libtool archive" func_append newdependency_libs " ${lt_sysroot:+=}$libdir/$name" ;; -L*) func_stripname -L '' "$deplib" func_replace_sysroot "$func_stripname_result" func_append newdependency_libs " -L$func_replace_sysroot_result" ;; -R*) func_stripname -R '' "$deplib" func_replace_sysroot "$func_stripname_result" func_append newdependency_libs " -R$func_replace_sysroot_result" ;; *) func_append newdependency_libs " $deplib" ;; esac done dependency_libs="$newdependency_libs" newdlfiles= for lib in $dlfiles; do case $lib in *.la) func_basename "$lib" name="$func_basename_result" eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` test -z "$libdir" && \ func_fatal_error "\`$lib' is not a valid libtool archive" func_append newdlfiles " ${lt_sysroot:+=}$libdir/$name" ;; *) func_append newdlfiles " $lib" ;; esac done dlfiles="$newdlfiles" newdlprefiles= for lib in $dlprefiles; do case $lib in *.la) # Only pass preopened files to the pseudo-archive (for # eventual linking with the app. that links it) if we # didn't already link the preopened objects directly into # the library: func_basename "$lib" name="$func_basename_result" eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` test -z "$libdir" && \ func_fatal_error "\`$lib' is not a valid libtool archive" func_append newdlprefiles " ${lt_sysroot:+=}$libdir/$name" ;; esac done dlprefiles="$newdlprefiles" else newdlfiles= for lib in $dlfiles; do case $lib in [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;; *) abs=`pwd`"/$lib" ;; esac func_append newdlfiles " $abs" done dlfiles="$newdlfiles" newdlprefiles= for lib in $dlprefiles; do case $lib in [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;; *) abs=`pwd`"/$lib" ;; esac func_append newdlprefiles " $abs" done dlprefiles="$newdlprefiles" fi $RM $output # place dlname in correct position for cygwin # In fact, it would be nice if we could use this code for all target # systems that can't hard-code library paths into their executables # and that have no shared library path variable independent of PATH, # but it turns out we can't easily determine that from inspecting # libtool variables, so we have to hard-code the OSs to which it # applies here; at the moment, that means platforms that use the PE # object format with DLL files. See the long comment at the top of # tests/bindir.at for full details. tdlname=$dlname case $host,$output,$installed,$module,$dlname in *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll | *cegcc*,*lai,yes,no,*.dll) # If a -bindir argument was supplied, place the dll there. if test "x$bindir" != x ; then func_relative_path "$install_libdir" "$bindir" tdlname=$func_relative_path_result$dlname else # Otherwise fall back on heuristic. tdlname=../bin/$dlname fi ;; esac $ECHO > $output "\ # $outputname - a libtool library file # Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION # # Please DO NOT delete this file! # It is necessary for linking the library. # The name that we can dlopen(3). dlname='$tdlname' # Names of this library. library_names='$library_names' # The name of the static archive. old_library='$old_library' # Linker flags that can not go in dependency_libs. inherited_linker_flags='$new_inherited_linker_flags' # Libraries that this one depends upon. dependency_libs='$dependency_libs' # Names of additional weak libraries provided by this library weak_library_names='$weak_libs' # Version information for $libname. current=$current age=$age revision=$revision # Is this an already installed library? installed=$installed # Should we warn about portability when linking against -modules? shouldnotlink=$module # Files to dlopen/dlpreopen dlopen='$dlfiles' dlpreopen='$dlprefiles' # Directory that this library needs to be installed in: libdir='$install_libdir'" if test "$installed" = no && test "$need_relink" = yes; then $ECHO >> $output "\ relink_command=\"$relink_command\"" fi done } # Do a symbolic link so that the libtool archive can be found in # LD_LIBRARY_PATH before the program is installed. func_show_eval '( cd "$output_objdir" && $RM "$outputname" && $LN_S "../$outputname" "$outputname" )' 'exit $?' ;; esac exit $EXIT_SUCCESS } { test "$opt_mode" = link || test "$opt_mode" = relink; } && func_mode_link ${1+"$@"} # func_mode_uninstall arg... func_mode_uninstall () { $opt_debug RM="$nonopt" files= rmforce= exit_status=0 # This variable tells wrapper scripts just to set variables rather # than running their programs. libtool_install_magic="$magic" for arg do case $arg in -f) func_append RM " $arg"; rmforce=yes ;; -*) func_append RM " $arg" ;; *) func_append files " $arg" ;; esac done test -z "$RM" && \ func_fatal_help "you must specify an RM program" rmdirs= for file in $files; do func_dirname "$file" "" "." dir="$func_dirname_result" if test "X$dir" = X.; then odir="$objdir" else odir="$dir/$objdir" fi func_basename "$file" name="$func_basename_result" test "$opt_mode" = uninstall && odir="$dir" # Remember odir for removal later, being careful to avoid duplicates if test "$opt_mode" = clean; then case " $rmdirs " in *" $odir "*) ;; *) func_append rmdirs " $odir" ;; esac fi # Don't error if the file doesn't exist and rm -f was used. if { test -L "$file"; } >/dev/null 2>&1 || { test -h "$file"; } >/dev/null 2>&1 || test -f "$file"; then : elif test -d "$file"; then exit_status=1 continue elif test "$rmforce" = yes; then continue fi rmfiles="$file" case $name in *.la) # Possibly a libtool archive, so verify it. if func_lalib_p "$file"; then func_source $dir/$name # Delete the libtool libraries and symlinks. for n in $library_names; do func_append rmfiles " $odir/$n" done test -n "$old_library" && func_append rmfiles " $odir/$old_library" case "$opt_mode" in clean) case " $library_names " in *" $dlname "*) ;; *) test -n "$dlname" && func_append rmfiles " $odir/$dlname" ;; esac test -n "$libdir" && func_append rmfiles " $odir/$name $odir/${name}i" ;; uninstall) if test -n "$library_names"; then # Do each command in the postuninstall commands. func_execute_cmds "$postuninstall_cmds" 'test "$rmforce" = yes || exit_status=1' fi if test -n "$old_library"; then # Do each command in the old_postuninstall commands. func_execute_cmds "$old_postuninstall_cmds" 'test "$rmforce" = yes || exit_status=1' fi # FIXME: should reinstall the best remaining shared library. ;; esac fi ;; *.lo) # Possibly a libtool object, so verify it. if func_lalib_p "$file"; then # Read the .lo file func_source $dir/$name # Add PIC object to the list of files to remove. if test -n "$pic_object" && test "$pic_object" != none; then func_append rmfiles " $dir/$pic_object" fi # Add non-PIC object to the list of files to remove. if test -n "$non_pic_object" && test "$non_pic_object" != none; then func_append rmfiles " $dir/$non_pic_object" fi fi ;; *) if test "$opt_mode" = clean ; then noexename=$name case $file in *.exe) func_stripname '' '.exe' "$file" file=$func_stripname_result func_stripname '' '.exe' "$name" noexename=$func_stripname_result # $file with .exe has already been added to rmfiles, # add $file without .exe func_append rmfiles " $file" ;; esac # Do a test to see if this is a libtool program. if func_ltwrapper_p "$file"; then if func_ltwrapper_executable_p "$file"; then func_ltwrapper_scriptname "$file" relink_command= func_source $func_ltwrapper_scriptname_result func_append rmfiles " $func_ltwrapper_scriptname_result" else relink_command= func_source $dir/$noexename fi # note $name still contains .exe if it was in $file originally # as does the version of $file that was added into $rmfiles func_append rmfiles " $odir/$name $odir/${name}S.${objext}" if test "$fast_install" = yes && test -n "$relink_command"; then func_append rmfiles " $odir/lt-$name" fi if test "X$noexename" != "X$name" ; then func_append rmfiles " $odir/lt-${noexename}.c" fi fi fi ;; esac func_show_eval "$RM $rmfiles" 'exit_status=1' done # Try to remove the ${objdir}s in the directories where we deleted files for dir in $rmdirs; do if test -d "$dir"; then func_show_eval "rmdir $dir >/dev/null 2>&1" fi done exit $exit_status } { test "$opt_mode" = uninstall || test "$opt_mode" = clean; } && func_mode_uninstall ${1+"$@"} test -z "$opt_mode" && { help="$generic_help" func_fatal_help "you must specify a MODE" } test -z "$exec_cmd" && \ func_fatal_help "invalid operation mode \`$opt_mode'" if test -n "$exec_cmd"; then eval exec "$exec_cmd" exit $EXIT_FAILURE fi exit $exit_status # The TAGs below are defined such that we never get into a situation # in which we disable both kinds of libraries. Given conflicting # choices, we go for a static library, that is the most portable, # since we can't tell whether shared libraries were disabled because # the user asked for that or because the platform doesn't support # them. This is particularly important on AIX, because we don't # support having both static and shared libraries enabled at the same # time on that platform, so we default to a shared-only configuration. # If a disable-shared tag is given, we'll fallback to a static-only # configuration. But we'll never go from static-only to shared-only. # ### BEGIN LIBTOOL TAG CONFIG: disable-shared build_libtool_libs=no build_old_libs=yes # ### END LIBTOOL TAG CONFIG: disable-shared # ### BEGIN LIBTOOL TAG CONFIG: disable-static build_old_libs=`case $build_libtool_libs in yes) echo no;; *) echo yes;; esac` # ### END LIBTOOL TAG CONFIG: disable-static # Local Variables: # mode:shell-script # sh-indentation:2 # End: # vi:sw=2 ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������libburn-1.4.2/libburn/������������������������������������������������������������������������������0000755�0001757�0001751�00000000000�12652650103�011621� 5����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������libburn-1.4.2/libburn/init.h������������������������������������������������������������������������0000644�0001757�0001751�00000003270�12652644224�012666� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */ /* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens Copyright (c) 2006 - 2013 Thomas Schmitt <scdbackup@gmx.net> Provided under GPL version 2 or later. */ #ifndef BURN__INIT_H #define BURN__INIT_H extern int burn_running; extern double lib_start_time; /** Indicator for burn_drive_get_status() wether a signal hit parts of the thread team. 0= all works well , 1 to 5 = waiting for eventual signal on control thread > 5 = do abort now -1 = control thread has been informed */ extern volatile int burn_global_abort_level; extern int burn_global_abort_signum; extern void *burn_global_signal_handle; extern burn_abort_handler_t burn_global_signal_handler; extern int burn_builtin_signal_action; /* burn_set_signal_handling() */ extern volatile int burn_builtin_triggered_action; /* burn_is_aborting() */ /* ts B00225 */ /* @return 0= no abort pending , 1= not control thread , -1= surprisingly burn_abort returned */ int burn_init_catch_on_abort(int flag); /* ts B10606 */ void *burn_alloc_mem(size_t size, size_t count, int flag); #define BURN_ALLOC_MEM(pt, typ, count) { \ pt= (typ *) burn_alloc_mem(sizeof(typ), (size_t) (count), 0); \ if(pt == NULL) { \ ret= -1; goto ex; \ } } #define BURN_ALLOC_MEM_VOID(pt, typ, count) { \ pt= (typ *) burn_alloc_mem(sizeof(typ), (size_t) (count), 0); \ if(pt == NULL) { \ goto ex; \ } } #define BURN_FREE_MEM(pt) { \ if(pt != NULL) \ free((char *) pt); \ } /* B20122 */ int burn_grab_prepare_sig_action(int *signal_action_mem, int flag); int burn_grab_restore_sig_action(int signal_action_mem, int flag); #endif /* BURN__INIT_H */ ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������libburn-1.4.2/libburn/toc.h�������������������������������������������������������������������������0000644�0001757�0001751�00000003363�12652644224�012513� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */ /* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens Provided under GPL version 2 or later. */ #ifndef __TOC_H #define __TOC_H struct command; #include "libburn.h" #include "structure.h" /* return if a given entry refers to a track position */ #define TOC_ENTRY_IS_TRACK(drive, entrynum) \ ((drive)->toc_entry[entrynum].point < 100) /* return if a given entry is in audio or data format */ #define TOC_ENTRY_IS_AUDIO(drive, entrynum) \ (~(drive)->toc_entry[entrynum].control & 4) /* return the point value for a given entry number */ #define TOC_POINT(drive, entrynum) ((drive)->toc_entry[entrynum].point) /* return the track struct for a given entry number */ #define TOC_TRACK(drive, entrynum) \ ((drive)->track[TOC_POINT(drive, entrynum) - 1]) /* return the lba of a toc entry */ #define TOC_ENTRY_PLBA(drive, entrynum) \ burn_msf_to_lba((drive)->toc_entry[(entrynum)].pmin, \ (drive)->toc_entry[(entrynum)].psec, \ (drive)->toc_entry[(entrynum)].pframe) /* flags for the q subchannel control field */ #define TOC_CONTROL_AUDIO (0) #define TOC_CONTROL_DATA (1 << 2) #define TOC_CONTROL_AUDIO_TWO_CHANNELS (0) #define TOC_CONTROL_AUDIO_FOUR_CHANNELS (1 << 3) #define TOC_CONTROL_AUDIO_PRE_EMPHASIS (1 << 0) #define TOC_CONTROL_DATA_RECORDED_UNINTERRUPTED (0) #define TOC_CONTROL_DATA_RECORDED_INCREMENT (1 << 0) #define TOC_CONTROL_COPY_PROHIBITED (0) #define TOC_CONTROL_COPY_PERMITTED (1 << 1) /** read a sector from each track on disc to determine modes @param d The drive. */ void toc_find_modes(struct burn_drive *d); #endif /*__TOC_H*/ �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������libburn-1.4.2/libburn/structure.c�������������������������������������������������������������������0000644�0001757�0001751�00000147333�12652644224�013767� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ /* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens Copyright (c) 2006 - 2014 Thomas Schmitt <scdbackup@gmx.net> Provided under GPL version 2 or later. */ #ifdef HAVE_CONFIG_H #include "../config.h" #endif /* ts A61008 */ /* #include <a ssert.h> */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <ctype.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #include <errno.h> /* ts B41126 : O_BINARY is needed for Cygwin but undefined elsewhere */ #ifndef O_BINARY #define O_BINARY 0 #endif #include "libburn.h" #include "structure.h" #include "write.h" #include "debug.h" #include "init.h" #include "util.h" #include "transport.h" #include "mmc.h" #include "libdax_msgs.h" extern struct libdax_msgs *libdax_messenger; /* ts A61008 : replaced Assert by if and return 0 */ /* a ssert(!(pos > BURN_POS_END)); */ #define RESIZE(TO, NEW, pos) {\ void *tmp;\ \ if (pos > BURN_POS_END)\ return 0;\ if (pos == BURN_POS_END)\ pos = TO->NEW##s;\ if ((int) pos > TO->NEW##s)\ return 0;\ \ tmp = realloc(TO->NEW, sizeof(struct NEW *) * (TO->NEW##s + 1));\ if (!tmp)\ return 0;\ TO->NEW = tmp;\ memmove(TO->NEW + pos + 1, TO->NEW + pos,\ sizeof(struct NEW *) * (TO->NEW##s - pos));\ TO->NEW##s++;\ } struct burn_disc *burn_disc_create(void) { struct burn_disc *d; d = calloc(1, sizeof(struct burn_disc)); if (d == NULL) /* ts A70825 */ return NULL; d->refcnt = 1; d->sessions = 0; d->session = NULL; #ifdef Libburn_disc_with_incomplete_sessioN d->incomplete_sessions= 0; #endif return d; } void burn_disc_free(struct burn_disc *d) { d->refcnt--; if (d->refcnt == 0) { /* dec refs on all elements */ int i; for (i = 0; i < d->sessions; i++) burn_session_free(d->session[i]); free(d->session); free(d); } } struct burn_session *burn_session_create(void) { struct burn_session *s; int i; s = calloc(1, sizeof(struct burn_session)); if (s == NULL) /* ts A70825 */ return NULL; s->firsttrack = 1; s->lasttrack = 0; s->refcnt = 1; s->tracks = 0; s->track = NULL; s->hidefirst = 0; for (i = 0; i < 8; i++) { s->cdtext[i] = NULL; s->cdtext_language[i] = 0x00; /* Unknown */ s->cdtext_char_code[i] = 0x00; /* ISO-8859-1 */ s->cdtext_copyright[i] = 0x00; } s->cdtext_language[0] = 0x09; /* Single-block default is English */ s->mediacatalog[0] = 0; return s; } void burn_session_hide_first_track(struct burn_session *s, int onoff) { s->hidefirst = onoff; } void burn_session_free(struct burn_session *s) { int i; s->refcnt--; if (s->refcnt == 0) { /* dec refs on all elements */ for (i = 0; i < s->tracks; i++) burn_track_free(s->track[i]); for (i = 0; i < 8; i++) burn_cdtext_free(&(s->cdtext[i])); free(s->track); free(s); } } int burn_disc_add_session(struct burn_disc *d, struct burn_session *s, unsigned int pos) { RESIZE(d, session, pos); d->session[pos] = s; s->refcnt++; return 1; } /* ts A81202: this function was in the API but not implemented. */ int burn_disc_remove_session(struct burn_disc *d, struct burn_session *s) { int i, skip = 0; if (d->session == NULL) return 0; for (i = 0; i < d->sessions; i++) { if (s == d->session[i]) { skip++; continue; } d->session[i - skip] = d->session[i]; } if (!skip) return 0; burn_session_free(s); d->sessions--; return 1; } struct burn_track *burn_track_create(void) { struct burn_track *t; int i; t = calloc(1, sizeof(struct burn_track)); if (t == NULL) /* ts A70825 */ return NULL; t->refcnt = 1; t->indices = 0; for (i = 0; i < 100; i++) t->index[i] = 0x7fffffff; t->offset = 0; t->offsetcount = 0; t->tail = 0; t->tailcount = 0; t->mode = BURN_MODE1; t->isrc.has_isrc = 0; t->pad = 1; /* ts A70213 */ t->fill_up_media = 0; /* ts A70218 */ t->default_size = 0; t->entry = NULL; t->source = NULL; t->eos = 0; /* ts A61101 */ t->sourcecount = 0; t->writecount = 0; t->written_sectors = 0; /* ts A61031 */ t->open_ended = 0; t->track_data_done = 0; /* ts B10103 */ t->end_on_premature_eoi = 0; t->pregap1 = 0; t->pregap2 = 0; t->pregap2_size = 150; t->postgap = 0; t->postgap_size = 150; /* ts A61024 */ t->swap_source_bytes = 0; /* ts B11206 */ for (i = 0; i < 8; i++) t->cdtext[i] = NULL; return t; } void burn_track_free(struct burn_track *t) { int i; t->refcnt--; if (t->refcnt == 0) { /* dec refs on all elements */ if (t->source) burn_source_free(t->source); for (i = 0; i < 8; i++) burn_cdtext_free(&(t->cdtext[i])); free(t); } } int burn_session_add_track(struct burn_session *s, struct burn_track *t, unsigned int pos) { RESIZE(s, track, pos); s->track[pos] = t; t->refcnt++; return 1; } int burn_session_remove_track(struct burn_session *s, struct burn_track *t) { struct burn_track **tmp; int i, pos = -1; /* ts A61008 */ /* a ssert(s->track != NULL); */ if (s->track == NULL) return 0; burn_track_free(t); /* Find the position */ for (i = 0; i < s->tracks; i++) { if (t == s->track[i]) { pos = i; break; } } if (pos == -1) return 0; /* Is it the last track? */ if (pos != s->tracks - 1) { memmove(&s->track[pos], &s->track[pos + 1], sizeof(struct burn_track *) * (s->tracks - (pos + 1))); } s->tracks--; tmp = realloc(s->track, sizeof(struct burn_track *) * s->tracks); if (tmp) s->track = tmp; return 1; } void burn_structure_print_disc(struct burn_disc *d) { int i; char msg[40]; 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++) { burn_structure_print_session(d->session[i]); } } void burn_structure_print_session(struct burn_session *s) { int i; char msg[40]; 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++) { burn_structure_print_track(s->track[i]); } } void burn_structure_print_track(struct burn_track *t) { char msg[80]; 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, int pad, int mode) { int type_to_form(int mode, unsigned char *ctladr, int *form); int burn_sector_length(int tracktype); unsigned char ctladr; int form = -1; /* unchanged form will be considered an error too */ char msg[80]; type_to_form(mode, &ctladr, &form); if (form == -1 || burn_sector_length(mode) <= 0) { sprintf(msg, "Attempt to set track mode to unusable value 0x%X", (unsigned int) mode); libdax_msgs_submit(libdax_messenger, -1, 0x00020115, LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH, msg, 0, 0); return; } t->offset = offset; t->pad = pad; t->mode = mode; t->tail = tail; } /* ts A61024 */ int burn_track_set_byte_swap(struct burn_track *t, int swap_source_bytes) { if (swap_source_bytes != 0 && swap_source_bytes != 1) return 0; t->swap_source_bytes = swap_source_bytes; return 1; } /* ts A90911 : API */ int burn_track_set_cdxa_conv(struct burn_track *t, int value) { if (value < 0 || value > 1) return 0; t->cdxa_conversion = value; return 1; } void burn_track_set_isrc(struct burn_track *t, char *country, char *owner, unsigned char year, unsigned int serial) { int i; /* ts B11226 */ t->isrc.has_isrc = 0; for (i = 0; i < 2; ++i) { /* ts A61008 : This is always true */ /* a ssert((country[i] >= '0' || country[i] < '9') && (country[i] >= 'a' || country[i] < 'z') && (country[i] >= 'A' || country[i] < 'Z')); */ /* ts A61008 : now coordinated with sector.c: char_to_isrc() */ if (! ((country[i] >= '0' && country[i] <= '9') || (country[i] >= 'a' && country[i] <= 'z') || (country[i] >= 'A' && country[i] <= 'Z') ) ) goto is_not_allowed; t->isrc.country[i] = country[i]; } for (i = 0; i < 3; ++i) { /* ts A61008 : This is always true */ /* a ssert((owner[i] >= '0' || owner[i] < '9') && (owner[i] >= 'a' || owner[i] < 'z') && (owner[i] >= 'A' || owner[i] < 'Z')); */ /* ts A61008 : now coordinated with sector.c: char_to_isrc() */ if (! ((owner[i] >= '0' && owner[i] <= '9') || (owner[i] >= 'a' && owner[i] <= 'z') || (owner[i] >= 'A' && owner[i] <= 'Z') ) ) goto is_not_allowed; t->isrc.owner[i] = owner[i]; } /* ts A61008 */ /* a ssert(year <= 99); */ if (year > 99) goto is_not_allowed; t->isrc.year = year; /* ts A61008 */ /* a ssert(serial <= 99999); */ if (serial > 99999) goto is_not_allowed; t->isrc.serial = serial; /* ts A61008 */ t->isrc.has_isrc = 1; return; is_not_allowed:; libdax_msgs_submit(libdax_messenger, -1, 0x00020114, LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH, "Attempt to set ISRC with bad data", 0, 0); return; } /* ts B11226 API */ int burn_track_set_isrc_string(struct burn_track *t, char isrc[13], int flag) { unsigned char year; unsigned int serial = 2000000000; if (strlen(isrc) != 12 || isrc[5] < '0' || isrc[5] > '9' || isrc[6] < '0' || isrc[6] > '9') { libdax_msgs_submit(libdax_messenger, -1, 0x00020114, LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH, "Attempt to set ISRC with bad data", 0, 0); return 0; } year = (isrc[5] - '0') * 10 + (isrc[6] - '0'); isrc[12] = 0; sscanf(isrc + 7, "%u", &serial); burn_track_set_isrc(t, isrc, isrc + 2, year, serial); return t->isrc.has_isrc; } void burn_track_clear_isrc(struct burn_track *t) { t->isrc.has_isrc = 0; } /* ts B20103 API */ int burn_track_set_index(struct burn_track *t, int index_number, unsigned int relative_lba, int flag) { if (index_number < 0 || index_number > 99) { libdax_msgs_submit(libdax_messenger, -1, 0x0002019a, LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH, "Bad track index number", 0, 0); return 0; } /* >>> if track size known : check index */; t->index[index_number] = relative_lba; if (index_number >= t->indices) t->indices = index_number + 1; return 1; } /* ts B20103 API */ int burn_track_clear_indice(struct burn_track *t, int flag) { int i; for (i = 0; i < 100; i++) t->index[i] = 0x7fffffff; t->indices = 0; return 1; } /* ts B20110 API */ int burn_track_set_pregap_size(struct burn_track *t, int size, int flag) { t->pregap2 = (size >= 0); t->pregap2_size = size; return 1; } /* ts B20111 API */ int burn_track_set_postgap_size(struct burn_track *t, int size, int flag) { t->postgap = (size >= 0); t->postgap_size = size; return 1; } /* ts B20119: outsourced from burn_track_get_sectors() @param flag bit0= do not add post-gap */ int burn_track_get_sectors_2(struct burn_track *t, int flag) { /* ts A70125 : was int */ off_t size = 0; int sectors, seclen; seclen = burn_sector_length(t->mode); if (t->cdxa_conversion == 1) /* ts A90911 : will read blocks of 2056 bytes and write 2048 */ seclen += 8; if (t->source != NULL) { /* ts A80808 : mending sigsegv */ size = t->offset + t->source->get_size(t->source) + t->tail; /* ts B20119 : adding post-gap */ if (t->postgap && !(flag & 1)) size += t->postgap_size; } else if(t->entry != NULL) { /* ts A80808 : all burn_toc_entry of track starts should now have (extensions_valid & 1), even those from CD. */ if (t->entry->extensions_valid & 1) size = ((off_t) t->entry->track_blocks) * (off_t) 2048; } sectors = size / seclen; if (size % seclen) sectors++; return sectors; } int burn_track_get_sectors(struct burn_track *t) { return burn_track_get_sectors_2(t, 0); } /* ts A70125 */ int burn_track_set_sectors(struct burn_track *t, int sectors) { off_t size, seclen; int ret; seclen = burn_sector_length(t->mode); size = seclen * (off_t) sectors - (off_t) t->offset - (off_t) t->tail; if (size < 0) return 0; ret = t->source->set_size(t->source, size); t->open_ended = (t->source->get_size(t->source) <= 0); return ret; } /* ts A70218 , API since A70328 */ int burn_track_set_size(struct burn_track *t, off_t size) { if (t->source == NULL) return 0; if (t->source->set_size == NULL) return 0; t->open_ended = (size <= 0); return t->source->set_size(t->source, size); } /* ts A70213 */ int burn_track_set_fillup(struct burn_track *t, int fill_up_media) { t->fill_up_media = fill_up_media; if (fill_up_media) t->open_ended = 0; return 1; } /* ts A70213 */ /** @param flag bit0= force new size even if existing track size is larger */ int burn_track_apply_fillup(struct burn_track *t, off_t max_size, int flag) { int max_sectors, ret = 2; char msg[80]; if (t->fill_up_media <= 0) return 2; max_sectors = max_size / 2048; if (burn_track_get_sectors(t) < max_sectors || (flag & 1)) { sprintf(msg, "Setting total track size to %ds (payload %ds)\n", max_sectors & 0x7fffffff, (int) ((t->source->get_size(t->source) / 2048) & 0x7fffffff)); libdax_msgs_submit(libdax_messenger, -1, 0x00000002, LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_ZERO, msg, 0, 0); ret = burn_track_set_sectors(t, max_sectors); t->open_ended = 0; } return ret; } /* ts A61031 */ int burn_track_is_open_ended(struct burn_track *t) { return !!t->open_ended; } /* ts A70218 : API */ int burn_track_set_default_size(struct burn_track *t, off_t size) { t->default_size = size; return 1; } /* ts A70218 */ off_t burn_track_get_default_size(struct burn_track *t) { return t->default_size; } /* ts A61101 : API function */ int burn_track_get_counters(struct burn_track *t, off_t *read_bytes, off_t *written_bytes) { /* fprintf(stderr, "libburn_experimental: sizeof(off_t)=%d\n", sizeof(off_t)); */ *read_bytes = t->sourcecount; *written_bytes = t->writecount; return 1; } /* ts A61031 */ int burn_track_is_data_done(struct burn_track *t) { return !!t->track_data_done; } int burn_track_get_shortage(struct burn_track *t) { int size; int seclen; seclen = burn_sector_length(t->mode); size = t->offset + t->source->get_size(t->source) + t->tail; if (size % seclen) return seclen - size % seclen; return 0; } int burn_session_get_sectors(struct burn_session *s) { int sectors = 0, i; for (i = 0; i < s->tracks; i++) sectors += burn_track_get_sectors(s->track[i]); return sectors; } int burn_disc_get_sectors(struct burn_disc *d) { int sectors = 0, i; for (i = 0; i < d->sessions; i++) sectors += burn_session_get_sectors(d->session[i]); return sectors; } void burn_track_get_entry(struct burn_track *t, struct burn_toc_entry *entry) { if (t->entry == NULL) memset(entry, 0, sizeof(struct burn_toc_entry)); else memcpy(entry, t->entry, sizeof(struct burn_toc_entry)); } void burn_session_get_leadout_entry(struct burn_session *s, struct burn_toc_entry *entry) { if (s->leadout_entry == NULL) memset(entry, 0, sizeof(struct burn_toc_entry)); else memcpy(entry, s->leadout_entry, sizeof(struct burn_toc_entry)); } struct burn_session **burn_disc_get_sessions(struct burn_disc *d, int *num) { #ifdef Libburn_disc_with_incomplete_sessioN *num = d->sessions - d->incomplete_sessions; #else *num = d->sessions; #endif return d->session; } /* ts B30112 : API */ int burn_disc_get_incomplete_sessions(struct burn_disc *d) { #ifdef Libburn_disc_with_incomplete_sessioN return d->incomplete_sessions; #else return 0; #endif } struct burn_track **burn_session_get_tracks(struct burn_session *s, int *num) { *num = s->tracks; return s->track; } int burn_track_get_mode(struct burn_track *track) { return track->mode; } int burn_session_get_hidefirst(struct burn_session *session) { return session->hidefirst; } /* ts A80808 : Enhance CD toc to DVD toc */ int burn_disc_cd_toc_extensions(struct burn_drive *drive, int flag) { int sidx= 0, tidx= 0, ret, track_offset, alloc_len = 34; struct burn_toc_entry *entry, *prev_entry= NULL; struct burn_disc *d; /* ts A81126 : ticket 146 : There was a SIGSEGV in here */ char *msg_data = NULL, *msg; struct buffer *buf = NULL; d = drive->disc; BURN_ALLOC_MEM(msg_data, char, 321); BURN_ALLOC_MEM(buf, struct buffer, 1); strcpy(msg_data, "Damaged CD table-of-content detected and truncated."); strcat(msg_data, " In burn_disc_cd_toc_extensions: "); msg = msg_data + strlen(msg_data); if (d->session == NULL) { strcpy(msg, "d->session == NULL"); goto failure; } if (d->sessions <= 0) { ret = 1; goto ex; } for (sidx = 0; sidx < d->sessions; sidx++) { track_offset = burn_session_get_start_tno(d->session[sidx], 0); if (track_offset <= 0) track_offset = 1; if (d->session[sidx] == NULL) { sprintf(msg, "d->session[%d of %d] == NULL", sidx, d->sessions); goto failure; } if (d->session[sidx]->track == NULL) { sprintf(msg, "d->session[%d of %d]->track == NULL", sidx, d->sessions); goto failure; } if (d->session[sidx]->leadout_entry == NULL) { sprintf(msg, " Session %d of %d: Leadout entry missing.", sidx, d->sessions); goto failure; } for (tidx = 0; tidx < d->session[sidx]->tracks + 1; tidx++) { if (tidx < d->session[sidx]->tracks) { if (d->session[sidx]->track[tidx] == NULL) { sprintf(msg, "d->session[%d of %d]->track[%d of %d] == NULL", sidx, d->sessions, tidx, d->session[sidx]->tracks); goto failure; } entry = d->session[sidx]->track[tidx]->entry; if (entry == NULL) { sprintf(msg, "session %d of %d, track %d of %d, entry == NULL", sidx, d->sessions, tidx, d->session[sidx]->tracks); goto failure; } } else entry = d->session[sidx]->leadout_entry; entry->session_msb = 0; entry->point_msb = 0; entry->start_lba = burn_msf_to_lba(entry->pmin, entry->psec, entry->pframe); if (tidx > 0) { prev_entry->track_blocks = entry->start_lba - prev_entry->start_lba; /* The drive might know size restrictions like pre-gaps */ ret = mmc_read_track_info(drive, tidx - 1 + track_offset, buf, alloc_len); if (ret > 0) { ret = mmc_four_char_to_int( buf->data + 24); if (ret < prev_entry->track_blocks && ((!drive->current_is_cd_profile) || ret < prev_entry->track_blocks - 2)) prev_entry->track_blocks = ret; } prev_entry->extensions_valid |= 1; } if (tidx == d->session[sidx]->tracks) { entry->session_msb = 0; entry->point_msb = 0; entry->track_blocks = 0; entry->extensions_valid |= 1; } prev_entry = entry; } } {ret = 1; goto ex;} failure: libdax_msgs_submit(libdax_messenger, -1, 0x0002015f, LIBDAX_MSGS_SEV_MISHAP, LIBDAX_MSGS_PRIO_HIGH, msg_data, 0, 0); d->sessions= sidx; ret = 0; ex:; BURN_FREE_MEM(buf); BURN_FREE_MEM(msg_data); return ret; } /* ts B20107 API */ int burn_session_set_start_tno(struct burn_session *session, int tno, int flag) { if (tno < 1 || tno > 99) { libdax_msgs_submit(libdax_messenger, -1, 0x0002019b, LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH, "CD start track number exceeds range of 1 to 99", 0, 0); return 0; } if (tno + session->tracks - 1 > 99) { libdax_msgs_submit(libdax_messenger, -1, 0x0002019b, LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH, "CD track number exceeds 99", 0, 0); return 0; } session->firsttrack = tno; return 1; } /* ts B20108 API */ int burn_session_get_start_tno(struct burn_session *session, int flag) { return (int) session->firsttrack; } struct burn_cdtext *burn_cdtext_create(void) { struct burn_cdtext *t; int i; t = burn_alloc_mem(sizeof(struct burn_cdtext), 1, 0); if (t == NULL) return NULL; for(i = 0; i < Libburn_pack_num_typeS; i ++) { t->payload[i] = NULL; t->length[i] = 0; } return t; } void burn_cdtext_free(struct burn_cdtext **cdtext) { struct burn_cdtext *t; int i; t = *cdtext; if (t == NULL) return; for (i = 0; i < Libburn_pack_num_typeS; i++) if (t->payload[i] != NULL) free(t->payload[i]); free(t); } static int burn_cdtext_name_to_type(char *pack_type_name) { int i, j; static char *pack_type_names[] = { Libburn_pack_type_nameS }; for (i = 0; i < Libburn_pack_num_typeS; i++) { if (pack_type_names[i][0] == 0) continue; for (j = 0; pack_type_names[i][j]; j++) if (pack_type_names[i][j] != pack_type_name[j] && tolower(pack_type_names[i][j]) != pack_type_name[j]) break; if (pack_type_names[i][j] == 0) return Libburn_pack_type_basE + i; } return -1; } /* @param flag bit0= double byte characters */ static int burn_cdtext_set(struct burn_cdtext **cdtext, int pack_type, char *pack_type_name, unsigned char *payload, int length, int flag) { int i; struct burn_cdtext *t; if (pack_type_name != NULL) if (pack_type_name[0]) pack_type = burn_cdtext_name_to_type(pack_type_name); if (pack_type < Libburn_pack_type_basE || pack_type >= Libburn_pack_type_basE + Libburn_pack_num_typeS) { libdax_msgs_submit(libdax_messenger, -1, 0x0002018c, LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH, "CD-TEXT pack type out of range", 0, 0); return 0; } t = *cdtext; if (t == NULL) { *cdtext = t = burn_cdtext_create(); if (t == NULL) return -1; } i = pack_type - Libburn_pack_type_basE; if (t->payload[i] != NULL) free(t->payload[i]); t->payload[i] = burn_alloc_mem((size_t) length, 1, 0); if (t->payload[i] == NULL) return -1; memcpy(t->payload[i], payload, length); t->length[i] = length; t->flags = (t->flags & ~(1 << i)) | (flag & (1 << i)); return 1; } /* @return 1=single byte char , 2= double byte char , <=0 error */ static int burn_cdtext_get(struct burn_cdtext *t, int pack_type, char *pack_type_name, unsigned char **payload, int *length, int flag) { if (pack_type_name != NULL) if (pack_type_name[0]) pack_type = burn_cdtext_name_to_type(pack_type_name); if (pack_type < Libburn_pack_type_basE || pack_type >= Libburn_pack_type_basE + Libburn_pack_num_typeS) { libdax_msgs_submit(libdax_messenger, -1, 0x0002018c, LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH, "CD-TEXT pack type out of range", 0, 0); return 0; } *payload = t->payload[pack_type - Libburn_pack_type_basE]; *length = t->length[pack_type - Libburn_pack_type_basE]; return 1 + ((t->flags >> (pack_type - Libburn_pack_type_basE)) & 1); } static int burn_cdtext_check_blockno(int block) { if (block < 0 || block > 7) { libdax_msgs_submit(libdax_messenger, -1, 0x0002018d, LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH, "CD-TEXT block number out of range", 0, 0); return 0; } return 1; } /* ts B11206 API */ /* @param flag bit0= double byte characters */ int burn_track_set_cdtext(struct burn_track *t, int block, int pack_type, char *pack_type_name, unsigned char *payload, int length, int flag) { int ret; if (burn_cdtext_check_blockno(block) <= 0) return 0; ret = burn_cdtext_set(&(t->cdtext[block]), pack_type, pack_type_name, payload, length, flag & 1); return ret; } /* ts B11206 API */ /* @return 1=single byte char , 2= double byte char , <=0 error */ int burn_track_get_cdtext(struct burn_track *t, int block, int pack_type, char *pack_type_name, unsigned char **payload, int *length, int flag) { int ret; if (burn_cdtext_check_blockno(block) <= 0) return 0; if (t->cdtext[block] == NULL) { *payload = NULL; *length = 0; return 1; } ret = burn_cdtext_get(t->cdtext[block], pack_type, pack_type_name, payload, length, 0); return ret; } /* ts B11206 API */ int burn_track_dispose_cdtext(struct burn_track *t, int block) { int i; if (block == -1) { for (i= 0; i < 8; i++) burn_cdtext_free(&(t->cdtext[i])); return 1; } if (burn_cdtext_check_blockno(block) <= 0) return 0; burn_cdtext_free(&(t->cdtext[0])); return 1; } /* ts B11206 API */ /* @param flag bit0= double byte characters */ int burn_session_set_cdtext(struct burn_session *s, int block, int pack_type, char *pack_type_name, unsigned char *payload, int length, int flag) { int ret; if (burn_cdtext_check_blockno(block) <= 0) return 0; ret = burn_cdtext_set(&(s->cdtext[block]), pack_type, pack_type_name, payload, length, flag & 1); return ret; } /* ts B11206 API */ /* @return 1=single byte char , 2= double byte char , <=0 error */ int burn_session_get_cdtext(struct burn_session *s, int block, int pack_type, char *pack_type_name, unsigned char **payload, int *length, int flag) { int ret; if (burn_cdtext_check_blockno(block) <= 0) return 0; if (s->cdtext[block] == NULL) { *payload = NULL; *length = 0; return 1; } ret = burn_cdtext_get(s->cdtext[block], pack_type, pack_type_name, payload, length, 0); return ret; } /* ts B11206 API */ int burn_session_set_cdtext_par(struct burn_session *s, int char_codes[8], int copyrights[8], int block_languages[8], int flag) { int i; for (i = 0; i < 8; i++) { if (char_codes[i] >= 0 && char_codes[i] <= 255) s->cdtext_char_code[i] = char_codes[i]; if (copyrights[i] >= 0 && copyrights[i] <= 255) s->cdtext_copyright[i] = copyrights[i]; if (block_languages[i] >= 0 && block_languages[i] <= 255) s->cdtext_language[i] = block_languages[i]; } return 1; } /* ts B11206 API */ int burn_session_get_cdtext_par(struct burn_session *s, int char_codes[8], int copyrights[8], int block_languages[8], int flag) { int i; for (i = 0; i < 8; i++) { char_codes[i] = s->cdtext_char_code[i]; copyrights[i] = s->cdtext_copyright[i]; block_languages[i]= s->cdtext_language[i]; } return 1; } /* ts B11206 API */ int burn_session_dispose_cdtext(struct burn_session *s, int block) { int i; if (block == -1) { for (i= 0; i < 8; i++) { burn_session_dispose_cdtext(s, i); s->cdtext_char_code[i] = 0x01; /* 7 bit ASCII */ s->cdtext_copyright[i] = 0; s->cdtext_language[i] = 0; } return 1; } if (burn_cdtext_check_blockno(block) <= 0) return 0; burn_cdtext_free(&(s->cdtext[block])); s->cdtext_language[block] = 0x09; /* english */ return 1; } /* --------------------- Reading CDRWIN cue sheet files ----------------- */ struct burn_cue_file_cursor { char *cdtextfile; char *source_file; off_t source_size; struct burn_source *file_source; int fifo_size; struct burn_source *fifo; int swap_audio_bytes; int no_cdtext; int no_catalog_isrc; int start_track_no; struct burn_source *offst_source; int current_file_ba; int current_index_ba; struct burn_track *prev_track; int prev_file_ba; int prev_block_size; struct burn_track *track; int track_no; int track_current_index; int track_has_source; int block_size; int block_size_locked; int track_mode; int flags; }; static int cue_crs_new(struct burn_cue_file_cursor **reply, int flag) { int ret; struct burn_cue_file_cursor *crs; BURN_ALLOC_MEM(crs, struct burn_cue_file_cursor, 1); crs->cdtextfile = NULL; crs->source_file = NULL; crs->source_size = -1; crs->file_source = NULL; crs->fifo_size = 0; crs->fifo = NULL; crs->swap_audio_bytes = 0; crs->no_cdtext = 0; crs->no_catalog_isrc = 0; crs->start_track_no = 1; crs->offst_source = NULL; crs->current_file_ba = -1000000000; crs->current_index_ba = -1000000000; crs->prev_track = NULL; crs->prev_file_ba = -1000000000; crs->prev_block_size = 0; crs->track = NULL; crs->track_no = 0; crs->track_current_index = -1; crs->track_has_source = 0; crs->block_size = 0; crs->block_size_locked = 0; crs->track_mode = 0; crs->flags = 0; *reply = crs; ret = 1; ex:; return ret; } static int cue_crs_destroy(struct burn_cue_file_cursor **victim, int flag) { struct burn_cue_file_cursor *crs; if (*victim == NULL) return 2; crs = *victim; if (crs->cdtextfile != NULL) free(crs->cdtextfile); if (crs->source_file != NULL) free(crs->source_file); if (crs->file_source != NULL) burn_source_free(crs->file_source); if (crs->fifo != NULL) burn_source_free(crs->fifo); if (crs->offst_source != NULL) burn_source_free(crs->offst_source); if (crs->prev_track != NULL) burn_track_free(crs->prev_track); if (crs->track != NULL) burn_track_free(crs->track); BURN_FREE_MEM(crs); *victim = NULL; return 1; } static char *cue_unquote_text(char *text, int flag) { char *ept, *spt; spt = text; for (ept = text + strlen(text); ept > text; ept--) if (*(ept - 1) != 32 && *(ept - 1) != 9) break; if (text[0] == '"') { spt = text + 1; if (ept > spt) if (*(ept - 1) == '"') ept--; } *ept = 0; return spt; } /* @param flag bit0= insist in having a track object bit1= remove quotation marks if present */ static int cue_set_cdtext(struct burn_session *session, struct burn_track *track, int pack_type, char *text, struct burn_cue_file_cursor *crs, int flag) { int ret; char *payload; if (crs->no_cdtext == 1) { libdax_msgs_submit(libdax_messenger, -1, 0x00020195, LIBDAX_MSGS_SEV_WARNING, LIBDAX_MSGS_PRIO_HIGH, "In cue sheet file: Being set to ignore all CD-TEXT aspects", 0, 0); crs->no_cdtext = 2; } if (crs->no_cdtext) return 2; if ((flag & 1) && track == NULL) { libdax_msgs_submit(libdax_messenger, -1, 0x00020192, LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH, "Track attribute set before first track in cue sheet file", 0, 0); ret = 0; goto ex; } if (flag & 2) payload = cue_unquote_text(text, 0); else payload = text; if (track != NULL) { ret = burn_track_set_cdtext(track, 0, pack_type, "", (unsigned char *) payload, strlen(payload) + 1, 0); } else { ret = burn_session_set_cdtext(session, 0, pack_type, "", (unsigned char *) payload, strlen(payload) + 1, 0); } ex:; return ret; } static int cue_attach_track(struct burn_session *session, struct burn_cue_file_cursor *crs, int flag) { int ret; if (crs->track == NULL) return 2; if (!crs->track_has_source) { libdax_msgs_submit(libdax_messenger, -1, 0x00020194, LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH, "In cue sheet file: TRACK without INDEX 01", 0, 0); return 0; } if (crs->track_current_index < 1) { libdax_msgs_submit(libdax_messenger, -1, 0x00020192, LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH, "No INDEX 01 defined for last TRACK in cue sheet file", 0, 0); return 0; } if (session->tracks == 0) { crs->start_track_no = crs->track_no; ret = burn_session_set_start_tno(session, crs->track_no, 0); if (ret <= 0) return ret; } if (session->tracks + crs->start_track_no - 1 > 99) { libdax_msgs_submit(libdax_messenger, -1, 0x0002019b, LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH, "CD track number exceeds 99", 0, 0); return 0; } ret = burn_session_add_track(session, crs->track, BURN_POS_END); if (ret <= 0) return ret; if (crs->prev_track != NULL) burn_track_free(crs->prev_track); /* release reference */ crs->prev_track = crs->track; crs->prev_file_ba = crs->current_file_ba; crs->prev_block_size = crs->block_size; crs->track = NULL; crs->track_current_index = -1; crs->track_has_source = 0; crs->current_file_ba = -1; crs->current_index_ba = -1; if (!crs->block_size_locked) crs->block_size = 0; return 1; } /* @param flag bit0= do not alter the content of *payload do not change *payload */ static int cue_read_number(char **payload, int *number, int flag) { int ret, at_end = 0; char *apt, *msg = NULL; for(apt = *payload; *apt != 0 && *apt != 32 && *apt != 9; apt++); if (*apt == 0) at_end = 1; else if (!(flag & 1)) *apt = 0; ret = sscanf(*payload, "%d", number); if (ret != 1) { BURN_ALLOC_MEM(msg, char, 4096); sprintf(msg, "Unsuitable number in cue sheet file: '%.4000s'", *payload); libdax_msgs_submit(libdax_messenger, -1, 0x00020194, LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH, burn_printify(msg), 0, 0); ret = 0; goto ex; } /* Find start of next argument */ if (!at_end) for (apt++; *apt == 32 || *apt == 9; apt++); if (!(flag & 1)) *payload = apt; ret = 1; ex: BURN_FREE_MEM(msg); return ret; } /* @param flag bit0-7: desired type : 0=any , 1=.wav */ static int cue_open_audioxtr(char *path, struct burn_cue_file_cursor *crs, int *fd, int flag) { struct libdax_audioxtr *xtr= NULL; char *fmt, *fmt_info; int ret, num_channels, sample_rate, bits_per_sample, msb_first; char *msg = NULL; BURN_ALLOC_MEM(msg, char, 4096); ret= libdax_audioxtr_new(&xtr, path, 0); if (ret <= 0) goto ex; libdax_audioxtr_get_id(xtr, &fmt, &fmt_info, &num_channels, &sample_rate, &bits_per_sample, &msb_first, 0); if ((flag & 255) == 1) { if (strcmp(fmt, ".wav") != 0) { sprintf(msg, "In cue sheet: Not recognized as WAVE : FILE '%.4000s'", path); libdax_msgs_submit(libdax_messenger, -1, 0x00020193, LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH, burn_printify(msg), 0, 0); ret = 0; goto ex; } } ret = libdax_audioxtr_get_size(xtr, &(crs->source_size), 0); if (ret <= 0) { sprintf(msg, "In cue sheet: Cannot get payload size of FILE '%.4000s'", path); libdax_msgs_submit(libdax_messenger, -1, 0x00020193, LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH, burn_printify(msg), 0, 0); ret = 0; goto ex; } ret = libdax_audioxtr_detach_fd(xtr, fd, 0); if (ret <= 0) { sprintf(msg, "In cue sheet: Cannot represent payload as plain fd: FILE '%.4000s'", path); libdax_msgs_submit(libdax_messenger, -1, 0x00020193, LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH, burn_printify(msg), 0, 0); ret = 0; goto ex; } crs->swap_audio_bytes = (msb_first == 1); ret = 1; ex: if (xtr != NULL) libdax_audioxtr_destroy(&xtr, 0); BURN_FREE_MEM(msg); return ret; } /* @param flag bit0-7: desired type : 0=any , 1=.wav bit8= open by libdax_audioxtr functions */ static int cue_create_file_source(char *path, struct burn_cue_file_cursor *crs, int flag) { int fd, ret; char *msg = NULL; BURN_ALLOC_MEM(msg, char, 4096); if (flag & 256) { ret = cue_open_audioxtr(path, crs, &fd, flag & 255); if (ret <= 0) goto ex; } else { fd = open(path, O_RDONLY | O_BINARY); if (fd == -1) { sprintf(msg, "In cue sheet: Cannot open FILE '%.4000s'", path); libdax_msgs_submit(libdax_messenger, -1, 0x00020193, LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH, burn_printify(msg), errno, 0); ret = 0; goto ex; } } crs->file_source = burn_fd_source_new(fd, -1, crs->source_size); if (crs->file_source == NULL) { ret = -1; goto ex; } ret = 1; ex:; BURN_FREE_MEM(msg); return ret; } static int cue_read_timepoint_lba(char *apt, char *purpose, int *file_ba, int flag) { int ret, minute, second, frame; char *msg = NULL, msf[3], *msf_pt; BURN_ALLOC_MEM(msg, char, 4096); if (strlen(apt) < 8) { no_time_point:; sprintf(msg, "Inappropriate cue sheet file %s '%.4000s'", purpose, apt); libdax_msgs_submit(libdax_messenger, -1, 0x00020194, LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH, burn_printify(msg), 0, 0); ret = 0; goto ex; } if (apt[2] != ':' || apt[5] != ':' || (apt[8] != 0 && apt[8] != 32 && apt[8] != 9)) goto no_time_point; msf[2] = 0; msf_pt = msf; strncpy(msf, apt, 2); ret = cue_read_number(&msf_pt, &minute, 1); if (ret <= 0) goto ex; strncpy(msf, apt + 3, 2); ret = cue_read_number(&msf_pt, &second, 1); if (ret <= 0) goto ex; strncpy(msf, apt + 6, 2); ret = cue_read_number(&msf_pt, &frame, 1); if (ret <= 0) goto ex; *file_ba = ((minute * 60) + second ) * 75 + frame; ret = 1; ex:; BURN_FREE_MEM(msg); return ret; } static int cue_check_for_track(struct burn_cue_file_cursor *crs, char *cmd, int flag) { int ret; char *msg = NULL; if (crs->track == NULL) { BURN_ALLOC_MEM(msg, char, 4096); sprintf(msg, "In cue sheet file: %s found before TRACK", cmd); libdax_msgs_submit(libdax_messenger, -1, 0x00020192, LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH, msg, 0, 0); ret = 0; goto ex; } ret = 1; ex:; BURN_FREE_MEM(msg); return ret; } static int cue_interpret_line(struct burn_session *session, char *line, struct burn_cue_file_cursor *crs, int flag) { int ret, mode, index_no, file_ba, chunks; int block_size, step, audio_xtr = 0; off_t size; char *cmd, *apt, *msg = NULL, *cpt, *filetype; struct burn_source *src, *inp_src; enum burn_source_status source_status; struct stat stbuf; BURN_ALLOC_MEM(msg, char, 4096); if (line[0] == 0 || line[0] == '#') { ret = 1; goto ex; } for (cmd = line; *cmd == 32 || *cmd == 9; cmd++); for(apt = cmd; *apt != 0 && *apt != 32 && *apt != 9; apt++); if (*apt != 0) { *apt = 0; for (apt++; *apt == 32 || *apt == 9; apt++); } if (strcmp(cmd, "ARRANGER") == 0) { ret = cue_set_cdtext(session, crs->track, 0x84, apt, crs, 2); if (ret <= 0) goto ex; } else if (strcmp(cmd, "CATALOG") == 0) { for (cpt = apt; (cpt - apt) < 13 && *cpt == (*cpt & 0x7f); cpt++); if ((cpt - apt) < 13) { libdax_msgs_submit(libdax_messenger, -1, 0x00020194, LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH, "In cue sheet file: Inappropriate content of CATALOG", 0, 0); ret = 0; goto ex; } ret = cue_set_cdtext(session, NULL, 0x8e, apt, crs, 0); if (ret <= 0) goto ex; if (!crs->no_catalog_isrc) { memcpy(session->mediacatalog, apt, 13); session->mediacatalog[13] = 0; } } else if (strcmp(cmd, "CDTEXTFILE") == 0) { if (crs->no_cdtext) { ret = 1; goto ex; } apt = cue_unquote_text(apt, 0); if (crs->cdtextfile != NULL) free(crs->cdtextfile); crs->cdtextfile = strdup(apt); if (crs->cdtextfile == NULL) { out_of_mem:; libdax_msgs_submit(libdax_messenger, -1, 0x00000003, LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH, "Out of virtual memory", 0, 0); ret = -1; goto ex; } } else if (strcmp(cmd, "COMPOSER") == 0) { ret = cue_set_cdtext(session, crs->track, 0x83, apt, crs, 2); if (ret <= 0) goto ex; } else if (strcmp(cmd, "FILE") == 0) { if (crs->file_source != NULL) { libdax_msgs_submit(libdax_messenger, -1, 0x00020192, LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH, "In cue sheet file: Multiple occurences of FILE", 0, 0); ret = 0; goto ex; } /* Obtain type */ for (cpt = apt + (strlen(apt) - 1); cpt > apt && (*cpt == 32 || *cpt == 9); cpt--); cpt[1] = 0; for (; cpt > apt && *cpt != 32 && *cpt != 9; cpt--); if (cpt <= apt) { libdax_msgs_submit(libdax_messenger, -1, 0x00020194, LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH, "In cue sheet file: FILE without type word", 0, 0); ret = 0; goto ex; } *cpt = 0; filetype = cpt + 1; if (strcmp(filetype, "BINARY") == 0) { crs->swap_audio_bytes = 0; } else if (strcmp(filetype, "MOTOROLA") == 0) { crs->swap_audio_bytes = 1; } else if (strcmp(filetype, "WAVE") == 0) { audio_xtr = 0x101; } else { sprintf(msg, "In cue sheet file: Unsupported FILE type '%.4000s'", filetype); libdax_msgs_submit(libdax_messenger, -1, 0x00020197, LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH, burn_printify(msg), 0, 0); ret = 0; goto ex; } apt = cue_unquote_text(apt, 0); if (*apt == 0) ret = -1; else ret = stat(apt, &stbuf); if (ret == -1) { not_usable_file:; sprintf(msg, "In cue sheet file: Unusable FILE '%.4000s'", apt); libdax_msgs_submit(libdax_messenger, -1, 0x00020194, LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH, burn_printify(msg), 0, 0); ret = 0; goto ex; } if (!S_ISREG(stbuf.st_mode)) goto not_usable_file; crs->source_size = stbuf.st_size; if (crs->source_file != NULL) free(crs->source_file); crs->source_file = strdup(apt); if (crs->source_file == NULL) goto out_of_mem; ret = cue_create_file_source(apt, crs, audio_xtr); if (ret <= 0) goto ex; } else if (strcmp(cmd, "FLAGS") == 0) { ret = cue_check_for_track(crs, cmd, 0); if (ret <= 0) goto ex; while (*apt) { if (strncmp(apt, "DCP", 3) == 0) { crs->track_mode |= BURN_COPY; step = 3; } else if (strncmp(apt, "4CH", 3) == 0) { crs->track_mode |= BURN_4CH; step = 3; } else if (strncmp(apt, "PRE", 3) == 0) { crs->track_mode |= BURN_PREEMPHASIS; step = 3; } else if (strncmp(apt, "SCMS", 4) == 0) { crs->track_mode |= BURN_SCMS; step = 4; } else { bad_flags:; for (cpt = apt; *cpt != 32 && *cpt != 9 && *cpt != 0; cpt++); *cpt = 0; sprintf(msg, "In cue sheet file: Unknown FLAGS option '%.4000s'", apt); libdax_msgs_submit(libdax_messenger, -1, 0x00020194, LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH, burn_printify(msg), 0, 0); ret = 0; goto ex; } /* Look for start of next word */ if (apt[step] != 0 && apt[step] != 32 && apt[step] != 9) goto bad_flags; for (apt += step; *apt == 32 || *apt == 9; apt++); } burn_track_define_data(crs->track, 0, 0, 1, crs->track_mode); } else if (strcmp(cmd, "INDEX") == 0) { ret = cue_check_for_track(crs, cmd, 0); if (ret <= 0) goto ex; ret = cue_read_number(&apt, &index_no, 0); if (ret <= 0) goto ex; ret = cue_read_timepoint_lba(apt, "index time point", &file_ba, 0); if (ret <= 0) goto ex; if (file_ba < crs->prev_file_ba) { overlapping_ba:; libdax_msgs_submit(libdax_messenger, -1, 0x00020192, LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH, "Backward INDEX address in cue sheet file", 0, 0); ret = 0; goto ex; } if (file_ba < crs->current_index_ba) goto overlapping_ba; if (crs->prev_track != NULL && crs->track_current_index < 0) { size = (file_ba - crs->prev_file_ba) * crs->prev_block_size; if (size <= 0) goto overlapping_ba; burn_track_set_size(crs->prev_track, size); } if (crs->track_current_index + 1 != index_no && !(crs->track_current_index < 0 && index_no <= 1)) { libdax_msgs_submit(libdax_messenger, -1, 0x00020192, LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH, "Unacceptable INDEX number in cue sheet file", 0, 0); ret = 0; goto ex; } crs->track_current_index = index_no; if (crs->current_file_ba < 0) crs->current_file_ba = file_ba; crs->current_index_ba = file_ba; /* Set index address relative to track source start */ ret = burn_track_set_index(crs->track, index_no, file_ba - crs->current_file_ba, 0); if (ret <= 0) goto ex; if (crs->track_has_source) { ret = 1; goto ex; } if (crs->block_size_locked && crs->fifo == NULL && crs->fifo_size > 0) { /* Now that the block size is known from TRACK: Create fifo and use it for creating the offset sources. This will fixate the block size to one common value. */ chunks = crs->fifo_size / crs->block_size + !!(crs->fifo_size % crs->block_size); if (chunks < 4) chunks = 4; crs->fifo = burn_fifo_source_new(crs->file_source, crs->block_size, chunks, 0); if (crs->fifo == NULL) { ret = -1; goto ex; } } if (crs->fifo != NULL) inp_src = crs->fifo; else inp_src = crs->file_source; src = burn_offst_source_new(inp_src, crs->offst_source, (off_t) (file_ba * crs->block_size), (off_t) 0, 1); if (src == NULL) goto out_of_mem; /* >>> Alternative to above fifo creation: Create a fifo for each track track. This will be necessary if mixed-mode sessions get supporded. */; source_status = burn_track_set_source(crs->track, src); if (source_status != BURN_SOURCE_OK) { ret = -1; goto ex; } /* Switch current source in crs */ if (crs->offst_source != NULL) burn_source_free(crs->offst_source); crs->offst_source = src; crs->track_has_source = 1; } else if (strcmp(cmd, "ISRC") == 0) { ret = cue_check_for_track(crs, cmd, 0); if (ret <= 0) goto ex; ret = cue_set_cdtext(session, crs->track, 0x8e, apt, crs, 1 | 2); if (ret <= 0) goto ex; if (!crs->no_catalog_isrc) { ret = burn_track_set_isrc_string(crs->track, apt, 0); if (ret <= 0) goto ex; } } else if (strcmp(cmd, "MESSAGE") == 0) { ret = cue_set_cdtext(session, crs->track, 0x85, apt, crs, 2); if (ret <= 0) goto ex; } else if (strcmp(cmd, "PERFORMER") == 0) { ret = cue_set_cdtext(session, crs->track, 0x81, apt, crs, 2); if (ret <= 0) goto ex; } else if (strcmp(cmd, "POSTGAP") == 0) { ret = cue_check_for_track(crs, cmd, 0); if (ret <= 0) goto ex; ret = cue_read_timepoint_lba(apt, "post-gap duration", &file_ba, 0); if (ret <= 0) goto ex; ret = burn_track_set_postgap_size(crs->track, file_ba, 0); if (ret <= 0) goto ex; } else if (strcmp(cmd, "PREGAP") == 0) { ret = cue_check_for_track(crs, cmd, 0); if (ret <= 0) goto ex; ret = cue_read_timepoint_lba(apt, "pre-gap duration", &file_ba, 0); if (ret <= 0) goto ex; ret = burn_track_set_pregap_size(crs->track, file_ba, 0); if (ret <= 0) goto ex; } else if (strcmp(cmd, "REM") == 0) { ; } else if (strcmp(cmd, "SONGWRITER") == 0) { ret = cue_set_cdtext(session, crs->track, 0x82, apt, crs, 2); if (ret <= 0) goto ex; } else if (strcmp(cmd, "TITLE") == 0) { ret = cue_set_cdtext(session, crs->track, 0x80, apt, crs, 2); if (ret <= 0) goto ex; } else if (strcmp(cmd, "TRACK") == 0) { if (crs->file_source == NULL) { libdax_msgs_submit(libdax_messenger, -1, 0x00020192, LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH, "No FILE defined before TRACK in cue sheet file", 0, 0); ret = 0; goto ex; } /* Attach previous track to session */ ret = cue_attach_track(session, crs, 0); if (ret <= 0) goto ex; /* Create new track */; ret = cue_read_number(&apt, &(crs->track_no), 0); if (ret <= 0) goto ex; if (crs->track_no < 1 || crs->track_no > 99) { sprintf(msg, "Inappropriate cue sheet file track number %d", crs->track_no); libdax_msgs_submit(libdax_messenger, -1, 0x00020194, LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH, burn_printify(msg), 0, 0); ret = 0; goto ex; } if (strcmp(apt, "AUDIO") == 0) { mode = BURN_AUDIO; block_size = 2352; } else if (strcmp(apt, "MODE1/2048") == 0) { mode = BURN_MODE1; block_size = 2048; } else { sprintf(msg, "Unsupported cue sheet file track datatype '%.4000s'", apt); libdax_msgs_submit(libdax_messenger, -1, 0x00020197, LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH, burn_printify(msg), 0, 0); ret = 0; goto ex; } if (block_size != crs->block_size && crs->block_size > 0 && crs->block_size_locked) { libdax_msgs_submit(libdax_messenger, -1, 0x00020197, LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH, "In cue sheet file: Unsupported mix track block sizes", 0, 0); ret = 0; goto ex; } crs->block_size = block_size; crs->track = burn_track_create(); if (crs->track == NULL) goto out_of_mem; crs->track_has_source = 0; crs->track_mode = mode; burn_track_define_data(crs->track, 0, 0, 1, mode); if (mode & BURN_AUDIO) burn_track_set_byte_swap(crs->track, !!crs->swap_audio_bytes); } else { sprintf(msg, "Unknown cue sheet file command '%.4000s'", line); libdax_msgs_submit(libdax_messenger, -1, 0x00020191, LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH, burn_printify(msg), 0, 0); ret = 0; goto ex; } ret = 1; ex:; BURN_FREE_MEM(msg); return ret; } /* ts B11216 API */ /* @param flag bit0= do not attach CD-TEXT information to session and tracks bit1= do not attach CATALOG to session or ISRC to track for writing to Q sub-channel */ int burn_session_by_cue_file(struct burn_session *session, char *path, int fifo_size, struct burn_source **fifo, unsigned char **text_packs, int *num_packs, int flag) { int ret, num_tracks, i, pack_type, length, double_byte = 0; int line_counter = 0; struct burn_track **tracks; char *msg = NULL, *line = NULL; unsigned char *payload; struct stat stbuf; FILE *fp = NULL; struct burn_cue_file_cursor *crs = NULL; static unsigned char dummy_cdtext[2] = {0, 0}; if (fifo != NULL) *fifo = NULL; if (text_packs != NULL) *text_packs = NULL; *num_packs = 0; BURN_ALLOC_MEM(msg, char, 4096); BURN_ALLOC_MEM(line, char, 4096); ret = cue_crs_new(&crs, 0); if (ret <= 0) goto ex; crs->no_cdtext = (flag & 1); crs->no_catalog_isrc = !!(flag & 2); crs->fifo_size = fifo_size; crs->block_size_locked = 1; /* No mixed sessions for now */ tracks = burn_session_get_tracks(session, &num_tracks); if (num_tracks > 0) { sprintf(msg, "Cue sheet file reader called while session has already defined tracks"); libdax_msgs_submit(libdax_messenger, -1, 0x00020196, LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH, burn_printify(msg), 0, 0); ret = 0; goto ex; } if (stat(path, &stbuf) == -1) { cannot_open:; sprintf(msg, "Cannot open cue sheet file '%.4000s'", path); libdax_msgs_submit(libdax_messenger, -1, 0x00020193, LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH, burn_printify(msg), errno, 0); ret = 0; goto ex; } if (!S_ISREG(stbuf.st_mode)) { sprintf(msg, "File is not of usable type: Cue sheet file '%.4000s'", path); libdax_msgs_submit(libdax_messenger, -1, 0x00020193, LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH, burn_printify(msg), 0, 0); ret = 0; goto ex; } fp = fopen(path, "rb"); if (fp == NULL) goto cannot_open; while (1) { if (burn_sfile_fgets(line, 4095, fp) == NULL) { if (!ferror(fp)) break; sprintf(msg, "Cannot read all bytes from cue sheet file '%.4000s'", path); libdax_msgs_submit(libdax_messenger, -1, 0x00020193, LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH, burn_printify(msg), 0, 0); ret = 0; goto ex; } line_counter++; ret = cue_interpret_line(session, line, crs, 0); if (ret <= 0) { sprintf(msg, "Cue sheet file '%.4000s': Reading aborted after line %d", path, line_counter); libdax_msgs_submit(libdax_messenger, -1, 0x00020199, LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH, burn_printify(msg), 0, 0); goto ex; } } /* Attach last track to session */ if (crs->track != NULL) { /* Set track size up to end of file */ if (crs->current_file_ba < 0 || crs->track_current_index < 1) { libdax_msgs_submit(libdax_messenger, -1, 0x00020192, LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH, "No INDEX 01 defined for last TRACK in cue sheet file", 0, 0); ret = 0; goto ex; } if (crs->current_file_ba * crs->block_size >= crs->source_size) { libdax_msgs_submit(libdax_messenger, -1, 0x00020194, LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH, "TRACK start time point exceeds size of FILE from cue sheet file", 0, 0); ret = 0; goto ex; } ret = burn_track_set_size(crs->track, crs->source_size - (off_t) (crs->current_file_ba * crs->block_size)); if (ret <= 0) goto ex; ret = cue_attach_track(session, crs, 0); if (ret <= 0) goto ex; } if (crs->cdtextfile != NULL) { if (text_packs == NULL) { /* >>> Warn of ignored text packs */; } else { ret = burn_cdtext_from_packfile(crs->cdtextfile, text_packs, num_packs, 0); if (ret <= 0) goto ex; } } /* Check which tracks have data of pack types where session has not */ tracks = burn_session_get_tracks(session, &num_tracks); for (pack_type = 0x80; pack_type < 0x8f; pack_type++) { if (pack_type > 0x86 && pack_type != 0x8e) continue; ret = burn_session_get_cdtext(session, 0, pack_type, "", &payload, &length, 0); if (ret <= 0) goto ex; if (payload != NULL) continue; for (i = 0; i < num_tracks; i++) { ret = burn_track_get_cdtext(tracks[i], 0, pack_type, "", &payload, &length, 0); if (ret <= 0) goto ex; double_byte = (ret > 1); if (payload != NULL) break; } if (i < num_tracks) { ret = burn_session_set_cdtext(session, 0, pack_type, "", dummy_cdtext, 1 + double_byte, double_byte); if (ret <= 0) goto ex; } } ret = 1; ex: if (ret <= 0) { tracks = burn_session_get_tracks(session, &num_tracks); for (i = 0; i < num_tracks; i++) burn_track_free(tracks[i]); if(text_packs != NULL) { if(*text_packs != NULL) free(*text_packs); *text_packs = NULL; *num_packs = 0; } } else { if (fifo != NULL) { *fifo = crs->fifo; crs->fifo = NULL; } } cue_crs_destroy(&crs, 0); BURN_FREE_MEM(line); BURN_FREE_MEM(msg); if (fp != NULL) fclose(fp); return ret; } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������libburn-1.4.2/libburn/cleanup.c���������������������������������������������������������������������0000644�0001757�0001751�00000013461�12652644224�013350� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* cleanup.c , Copyright 2006 - 2011 Thomas Schmitt <scdbackup@gmx.net> A signal handler which cleans up an application and exits. Provided under GPLv2+ license within GPL projects, BSD license elsewise. */ /* cc -g -o cleanup -DCleanup_standalonE cleanup.c */ #ifdef HAVE_CONFIG_H #include "../config.h" #endif #include <sys/types.h> #include <stdlib.h> #include <unistd.h> #include <stdio.h> #include <string.h> #include <errno.h> #include <signal.h> typedef void (*sighandler_t)(int); #include "cleanup.h" #ifndef Cleanup_has_no_libburn_os_H #include "../libburn/os.h" /* see os.h for name of particular os-*.h where this is defined */ static int signal_list[]= { BURN_OS_SIGNAL_MACRO_LIST , -1}; static char *signal_name_list[]= { BURN_OS_SIGNAL_NAME_LIST , "@"}; static int signal_list_count= BURN_OS_SIGNAL_COUNT; static int non_signal_list[]= { BURN_OS_NON_SIGNAL_MACRO_LIST, -1}; static int non_signal_list_count= BURN_OS_NON_SIGNAL_COUNT; #else /* ! Cleanup_has_no_libburn_os_H */ /* Outdated. GNU/Linux only. For backward compatibility with pre-libburn-0.2.3 */ /* Signals to be caught */ static int signal_list[]= { SIGHUP, SIGINT, SIGQUIT, SIGILL, SIGABRT, SIGFPE, SIGSEGV, SIGPIPE, SIGALRM, SIGTERM, SIGUSR1, SIGUSR2, SIGXCPU, SIGTSTP, SIGTTIN, SIGTTOU, SIGBUS, SIGPOLL, SIGPROF, SIGSYS, SIGTRAP, SIGVTALRM, SIGXCPU, SIGXFSZ, -1 }; static char *signal_name_list[]= { "SIGHUP", "SIGINT", "SIGQUIT", "SIGILL", "SIGABRT", "SIGFPE", "SIGSEGV", "SIGPIPE", "SIGALRM", "SIGTERM", "SIGUSR1", "SIGUSR2", "SIGXCPU", "SIGTSTP", "SIGTTIN", "SIGTTOU", "SIGBUS", "SIGPOLL", "SIGPROF", "SIGSYS", "SIGTRAP", "SIGVTALRM", "SIGXCPU", "SIGXFSZ", "@" }; static int signal_list_count= 24; /* Signals not to be caught */ static int non_signal_list[]= { SIGKILL, SIGCHLD, SIGSTOP, SIGURG, SIGWINCH, -1 }; static int non_signal_list_count= 5; #endif /* Cleanup_has_no_libburn_os_H */ /* run time dynamic part */ static char cleanup_msg[4096]= {""}; static int cleanup_exiting= 0; static int cleanup_has_reported= -1234567890; static void *cleanup_app_handle= NULL; static Cleanup_app_handler_T cleanup_app_handler= NULL; static int cleanup_perform_app_handler_first= 0; static int Cleanup_handler_exit(int exit_value, int signum, int flag) { int ret; if(cleanup_msg[0]!=0 && cleanup_has_reported!=signum) { fprintf(stderr,"\n%s\n",cleanup_msg); cleanup_has_reported= signum; } if(cleanup_perform_app_handler_first) if(cleanup_app_handler!=NULL) { ret= (*cleanup_app_handler)(cleanup_app_handle,signum,0); if(ret==2 || ret==-2) return(2); } if(cleanup_exiting) { fprintf(stderr,"cleanup: ABORT : repeat by pid=%.f, signum=%d\n", (double) getpid(), signum); return(0); } cleanup_exiting= 1; alarm(0); if(!cleanup_perform_app_handler_first) if(cleanup_app_handler!=NULL) { ret= (*cleanup_app_handler)(cleanup_app_handle,signum,0); if(ret==2 || ret==-2) return(2); } exit(exit_value); } static void Cleanup_handler_generic(int signum) { int i; sprintf(cleanup_msg,"UNIX-SIGNAL caught: %d errno= %d",signum,errno); for(i= 0; i<signal_list_count; i++) if(signum==signal_list[i]) { sprintf(cleanup_msg,"UNIX-SIGNAL: %s errno= %d", signal_name_list[i],errno); break; } Cleanup_handler_exit(1,signum,0); } static char *Cleanup_signo_to_name(int signo) { int i; for(i= 0; i < signal_list_count; i++) if(signal_list[i] == signo) return(signal_name_list[i]); return(""); } int Cleanup_set_handlers(void *handle, Cleanup_app_handler_T handler, int flag) /* bit0= set to default handlers bit1= set to ignore bit2= set cleanup_perform_app_handler_first bit3= set SIGABRT to handler (makes sense with bits 0 or 1) bit8= set SIGPIPE to SIGIGN */ { int i,j,max_sig= -1,min_sig= 0x7fffffff; char *sig_name; sighandler_t sig_handler; cleanup_msg[0]= 0; cleanup_app_handle= handle; cleanup_app_handler= handler; /* <<< make cleanup_exiting thread safe to get rid of this */ if(flag&4) cleanup_perform_app_handler_first= 1; if(flag&1) sig_handler= SIG_DFL; else if(flag&2) sig_handler= SIG_IGN; else sig_handler= Cleanup_handler_generic; /* set all signal numbers between the lowest and highest in the list except those in the non-signal list */ for(i= 0; i<signal_list_count; i++) { if(signal_list[i]>max_sig) max_sig= signal_list[i]; if(signal_list[i]<min_sig) min_sig= signal_list[i]; } for(i= min_sig; i<=max_sig; i++) { for(j= 0; j<non_signal_list_count; j++) if(i==non_signal_list[j]) break; if(j>=non_signal_list_count) { /* Avoid to use particular SIG macros which might not be defined. If they are defined, then their names are in the name list. */ if(flag & (8 | 256)) sig_name= Cleanup_signo_to_name(i); else sig_name= ""; if((flag & 8) && strcmp(sig_name, "SIGABRT") == 0) signal(i,Cleanup_handler_generic); else if((flag & 256) && strcmp(sig_name, "SIGPIPE") == 0) signal(i, SIG_IGN); else signal(i,sig_handler); } } return(1); } #ifdef Cleanup_standalonE struct Demo_apP { char *msg; }; int Demo_app_handler(struct Demo_apP *demoapp, int signum, int flag) { printf("Handling exit of demo application on signal %d. msg=\"%s\"\n", signum,demoapp->msg); return(1); } main() { struct Demo_apP demoapp; demoapp.msg= "Good Bye"; Cleanup_set_handlers(&demoapp,(Cleanup_app_handler_T) Demo_app_handler,0); if(1) { /* change to 0 in order to wait for external signals */ char *cpt= NULL, c= ' '; printf("Intentionally provoking SIGSEGV ...\n"); c= *cpt; printf("Strange: The system ignored a SIGSEGV: c= %u\n", (unsigned int) c); } else { printf("killme: %d\n",getpid()); sleep(3600); } Cleanup_set_handlers(NULL,NULL,1); exit(0); } #endif /* Cleanup_standalonE */ ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������libburn-1.4.2/libburn/null.c������������������������������������������������������������������������0000644�0001757�0001751�00000001336�12652644224�012671� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */ /* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens Provided under GPL version 2 or later. */ #ifdef HAVE_CONFIG_H #include "../config.h" #endif #include "null.h" #include "libburn.h" #include <stdlib.h> #include <string.h> int null_read(struct burn_source *source, unsigned char *buffer, int size) { memset(buffer, 0, size); return size; } struct burn_source *burn_null_source_new(void) { struct burn_source *src; src = calloc(1, sizeof(struct burn_source)); src->refcount = 1; src->read = null_read; src->read_sub = NULL; src->get_size = 0; /* ts A70126 */ src->set_size = NULL; src->free_data = NULL; src->data = NULL; return src; } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������libburn-1.4.2/libburn/sg-libcdio.c������������������������������������������������������������������0000644�0001757�0001751�00000067113�12652644224�013740� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */ /* Copyright (c) 2009 - 2014 Thomas Schmitt <scdbackup@gmx.net> Provided under GPL version 2 or later. */ /* This is the main operating system dependent SCSI part of libburn. It implements the transport level aspects of SCSI control and command i/o. Present implementation: GNU libcdio , for X/Open compliant operating systems PORTING: Porting libburn typically will consist of adding a new operating system case to the following switcher files: os.h Operating system specific libburn definitions and declarations. sg.c Operating system dependent transport level modules. and of deriving the following system specific files from existing examples: os-*.h Included by os.h. You will need some general system knowledge about signals and knowledge about the storage object needs of your transport level module sg-*.c. sg-*.c This source module. You will need special system knowledge about how to detect all potentially available drives, how to open them, eventually how to exclusively reserve them, how to perform SCSI transactions, how to inquire the (pseudo-)SCSI driver. You will not need to care about CD burning, MMC or other high-level SCSI aspects. Said sg-*.c operations are defined by a public function interface, which has to be implemented in a way that provides libburn with the desired services: sg_id_string() returns an id string of the SCSI transport adapter. It may be called before initialization but then may return only a preliminary id. sg_initialize() performs global initialization of the SCSI transport adapter and eventually needed operating system facilities. Checks for compatibility of supporting software components. sg_shutdown() performs global finalizations and releases golbally aquired resources. sg_give_next_adr() iterates over the set of potentially useful drive address strings. scsi_enumerate_drives() brings all available, not-whitelist-banned, and accessible drives into libburn's list of drives. sg_dispose_drive() finalizes adapter specifics of struct burn_drive on destruction. Releases resources which were aquired underneath scsi_enumerate_drives(). sg_drive_is_open() tells wether libburn has the given drive in use. sg_grab() opens the drive for SCSI commands and ensures undisturbed access. sg_release() closes a drive opened by sg_grab() sg_issue_command() sends a SCSI command to the drive, receives reply, and evaluates wether the command succeeded or shall be retried or finally failed. sg_obtain_scsi_adr() tries to obtain SCSI address parameters. burn_os_is_2k_seekrw() tells whether the given path leads to a file object that can be used in 2 kB granularity by lseek(2), read(2), and possibly write(2) if not read-only.. E.g. a USB stick or a hard disk. burn_os_stdio_capacity() estimates the emulated media space of stdio-drives. burn_os_open_track_src() opens a disk file in a way that offers best throughput with file reading and/or SCSI write command transmission. burn_os_alloc_buffer() allocates a memory area that is suitable for file descriptors issued by burn_os_open_track_src(). The buffer size may be rounded up for alignment reasons. burn_os_free_buffer() delete a buffer obtained by burn_os_alloc_buffer(). Porting hints are marked by the text "PORTING:". Send feedback to libburn-hackers@pykix.org . */ #ifdef HAVE_CONFIG_H #include "../config.h" #endif /** PORTING : ------- OS dependent headers and definitions ------ */ #include <unistd.h> #include <stdio.h> #include <sys/types.h> #include <errno.h> #include <fcntl.h> #include <sys/stat.h> #include <string.h> #include <stdlib.h> #ifdef Libburn_os_has_statvfS #include <sys/statvfs.h> #endif /* Libburn_os_has_stavtfS */ #ifdef __linux /* for ioctl(BLKGETSIZE) */ #include <sys/ioctl.h> #include <linux/fs.h> #endif #ifdef __FreeBSD__ #define Libburn_is_on_freebsD 1 #endif #ifdef __FreeBSD_kernel__ #define Libburn_is_on_freebsD 1 #endif #ifdef Libburn_is_on_freebsD /* To avoid ATAPI devices */ #define Libburn_guess_freebsd_atapi_devicE 1 /* To obtain size of disk-like devices */ #include <sys/disk.h> /* DIOCGMEDIASIZE */ #endif /* Libburn_is_on_freebsD */ #define Libburn_guess_freebsd_atapi_devicE 1 #ifdef sun #define Libburn_is_on_solariS 1 #endif #ifdef __sun #define Libburn_is_on_solariS 1 #endif /* Proposal by Rocky Bernstein to avoid macro clashes with cdio_config.h */ #define __CDIO_CONFIG_H__ 1 #include <cdio/cdio.h> #include <cdio/logging.h> #include <cdio/mmc.h> /* ts B41126 : O_BINARY is needed for Cygwin but undefined elsewhere */ #ifndef O_BINARY #define O_BINARY 0 #endif /* The waiting time before eventually retrying a failed SCSI command. Before each retry wait Libburn_sg_linux_retry_incR longer than with the previous one. */ #define Libburn_sg_libcdio_retry_usleeP 100000 #define Libburn_sg_libcdio_retry_incR 100000 /** PORTING : ------ libburn portable headers and definitions ----- */ #include "transport.h" #include "drive.h" #include "sg.h" #include "spc.h" /* collides with symbols of <cdio/mmc.h> #include "mmc.h" */ #include "sbc.h" #include "debug.h" #include "toc.h" #include "util.h" #include "init.h" #include "libdax_msgs.h" extern struct libdax_msgs *libdax_messenger; /* is in portable part of libburn */ int burn_drive_is_banned(char *device_address); int burn_drive_resolve_link(char *path, char adr[], int *recursion_count, int flag); /* drive.c */ /* Whether to log SCSI commands: bit0= log in /tmp/libburn_sg_command_log bit1= log to stderr bit2= flush every line */ extern int burn_sg_log_scsi; /* ------------------------------------------------------------------------ */ /* PORTING: Private definitions. Port only if needed by public functions. */ /* (Public functions are listed below) */ /* ------------------------------------------------------------------------ */ /* Storage object is in libburn/init.c whether to strive for exclusive access to the drive */ extern int burn_sg_open_o_excl; /* ------------------------------------------------------------------------ */ /* PORTING: Private functions. Port only if needed by public functions */ /* (Public functions are listed below) */ /* ------------------------------------------------------------------------ */ static int sg_close_drive(struct burn_drive * d) { CdIo_t *p_cdio; if (d->p_cdio != NULL) { p_cdio = (CdIo_t *) d->p_cdio; cdio_destroy(p_cdio); d->p_cdio = NULL; } return 0; } static int sg_give_next_adr_raw(burn_drive_enumerator_t *idx, char adr[], int adr_size, int initialize) { char **pos; int count = 0; if (initialize == 1) { idx->pos = idx->ppsz_cd_drives = cdio_get_devices(DRIVER_DEVICE); if (idx->ppsz_cd_drives == NULL) return 0; for (pos = idx->ppsz_cd_drives ; pos != NULL; pos++) { if (*pos == NULL) break; count++; } } else if (initialize == -1) { if (idx->ppsz_cd_drives != NULL) if (*(idx->ppsz_cd_drives) != NULL) cdio_free_device_list(idx->ppsz_cd_drives); idx->ppsz_cd_drives = NULL; } #ifdef Libburn_guess_freebsd_atapi_devicE try_next:; #endif if (idx->pos == NULL) return 0; if (*(idx->pos) == NULL) return 0; #ifdef Libburn_guess_freebsd_atapi_devicE if (strncmp(*(idx->pos), "/dev/acd", 8) == 0) { (idx->pos)++; goto try_next; } #endif if ((ssize_t) strlen(*(idx->pos)) >= adr_size) return -1; strcpy(adr, *(idx->pos)); (idx->pos)++; return 1; } /* ----------------------------------------------------------------------- */ /* PORTING: Private functions which contain publicly needed functionality. */ /* Their portable part must be performed. So it is probably best */ /* to replace the non-portable part and to call these functions */ /* in your port, too. */ /* ----------------------------------------------------------------------- */ /** Wraps a detected drive into libburn structures and hands it over to libburn drive list. */ static void enumerate_common(char *fname, char *cdio_name, int bus_no, int host_no, int channel_no, int target_no, int lun_no) { int ret; struct burn_drive out; /* General libburn drive setup */ burn_setup_drive(&out, fname); /* This transport adapter uses SCSI-family commands and models (seems the adapter would know better than its boss, if ever) */ ret = burn_scsi_setup_drive(&out, bus_no, host_no, channel_no, target_no, lun_no, 0); if (ret <= 0) return; /* PORTING: ------------------- non portable part --------------- */ /* Transport adapter is libcdio */ /* Adapter specific handles and data */ out.p_cdio = NULL; strcpy(out.libcdio_name, fname); if (strlen(cdio_name) < sizeof(out.libcdio_name)) strcpy(out.libcdio_name, cdio_name); /* PORTING: ---------------- end of non portable part ------------ */ /* Adapter specific functions with standardized names */ out.grab = sg_grab; out.release = sg_release; out.drive_is_open = sg_drive_is_open; out.issue_command = sg_issue_command; /* Finally register drive and inquire drive information */ burn_drive_finish_enum(&out); } /* ------------------------------------------------------------------------ */ /* PORTING: Public functions. These MUST be ported. */ /* ------------------------------------------------------------------------ */ /** Returns the id string of the SCSI transport adapter and eventually needed operating system facilities. This call is usable even if sg_initialize() was not called yet. In that case a preliminary constant message might be issued if detailed info is not available yet. @param msg returns id string @param flag unused yet, submit 0 @return 1 = success, <=0 = failure */ int sg_id_string(char msg[1024], int flag) { char *version_text; sprintf(msg, "sg-libcdio h%d with libcdio ", LIBCDIO_VERSION_NUM); #if LIBCDIO_VERSION_NUM < 83 LIBBURN_MISCONFIGURATION = 0; INTENTIONAL_ABORT_OF_COMPILATION__HEADERFILE_cdio_version_dot_h_TOO_OLD__NEED_libcdio_VERSION_NUM_83 = 0; LIBBURN_MISCONFIGURATION_ = 0; #endif /* LIBCDIO_VERSION_NUM < 83 */ version_text = (char *) cdio_version_string; strncat(msg, version_text, 800); return 1; } /** Performs global initialization of the SCSI transport adapter and eventually needed operating system facilities. Checks for compatibility of supporting software components. @param msg returns ids and/or error messages of eventual helpers @param flag unused yet, submit 0 @return 1 = success, <=0 = failure */ int sg_initialize(char msg[1024], int flag) { int cdio_ver; char *msg_pt; cdio_loglevel_default = CDIO_LOG_ASSERT; msg[0] = 0; sg_id_string(msg, 0); cdio_ver = libcdio_version_num; libdax_msgs_submit(libdax_messenger, -1, 0x00000002, LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH, msg , 0, 0); if (cdio_ver < LIBCDIO_VERSION_NUM) { strcat(msg, " ---> "); msg_pt = msg + strlen(msg); sprintf(msg_pt, "libcdio TOO OLD: numeric version %d , need at least %d", cdio_ver, LIBCDIO_VERSION_NUM); libdax_msgs_submit(libdax_messenger, -1, 0x00000002, LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH, msg_pt, 0, 0); return 0; } return 1; } /** Performs global finalization of the SCSI transport adapter and eventually needed operating system facilities. Releases globally aquired resources. @param flag unused yet, submit 0 @return 1 = success, <=0 = failure */ int sg_shutdown(int flag) { return 1; } /** Finalizes BURN_OS_TRANSPORT_DRIVE_ELEMENTS, the components of struct burn_drive which are defined in os-*.h. The eventual initialization of those components was made underneath scsi_enumerate_drives(). This will be called when a burn_drive gets disposed. @param d the drive to be finalized @param flag unused yet, submit 0 @return 1 = success, <=0 = failure */ int sg_dispose_drive(struct burn_drive *d, int flag) { return 1; } /** Returns the next index number and the next enumerated drive address. The enumeration has to cover all available and accessible drives. It is allowed to return addresses of drives which are not available but under some (even exotic) circumstances could be available. It is on the other hand allowed, only to hand out addresses which can really be used right in the moment of this call. (This implementation chooses the latter.) @param idx An opaque handle. Make no own theories about it. @param adr Takes the reply @param adr_size Gives maximum size of reply including final 0 @param initialize 1 = start new, 0 = continue, use no other values for now -1 = finish @return 1 = reply is a valid address , 0 = no further address available -1 = severe error (e.g. adr_size too small) */ int sg_give_next_adr(burn_drive_enumerator_t *idx, char adr[], int adr_size, int initialize) { int ret, recursion_count = 0, path_size = 4096; char *path = NULL; #ifdef Libburn_is_on_solariS int l; #endif BURN_ALLOC_MEM(path, char, path_size); ret = sg_give_next_adr_raw(idx, adr, adr_size, initialize); if (ret <= 0) goto ex; if ((ssize_t) strlen(adr) >= path_size) goto ex; #ifdef Libburn_is_on_solariS /* >>> provisory : preserve Solaris /dev/rdsk/cXtYdZs2 addresses */ l = strlen(adr); if (l >= 18) if (strncmp(adr, "/dev/rdsk/c", 11) == 0 && adr[11] >= '0' && adr[11] <= '9' && strcmp(adr + (l - 2), "s2") == 0) {ret = 1; goto ex;} #endif /* Libburn_is_on_solariS */ ret = burn_drive_resolve_link(adr, path, &recursion_count, 2); if(ret > 0 && (ssize_t) strlen(path) < adr_size) strcpy(adr, path); ret = (ret >= 0); ex: BURN_FREE_MEM(path); return ret; } /** Brings all available, not-whitelist-banned, and accessible drives into libburn's list of drives. */ int scsi_enumerate_drives(void) { burn_drive_enumerator_t idx; int initialize = 1, ret, i_bus_no = -1, recursion_count = 0; int i_host_no = -1, i_channel_no = -1, i_target_no = -1, i_lun_no = -1; int buf_size = 4096; char *buf = NULL, *target = NULL; #ifdef Libburn_is_on_solariS int l; #endif BURN_ALLOC_MEM(buf, char, buf_size); BURN_ALLOC_MEM(target, char, buf_size); while(1) { ret = sg_give_next_adr_raw(&idx, buf, buf_size, initialize); initialize = 0; if (ret <= 0) break; ret = 1; #ifdef Libburn_is_on_solariS /* >>> provisory : preserve Solaris /dev/rdsk/cXtYdZs2 */ l = strlen(buf); if (l >= 18) if (strncmp(buf, "/dev/rdsk/c", 11) == 0 && buf[11] >= '0' && buf[11] <= '9' && strcmp(buf + (l - 2), "s2") == 0) ret = 0; #endif /* Libburn_is_on_solariS */ if (ret == 1) { ret = burn_drive_resolve_link(buf, target, &recursion_count,2); } if (ret <= 0) strcpy(target, buf); if (burn_drive_is_banned(target)) continue; sg_obtain_scsi_adr(buf, &i_bus_no, &i_host_no, &i_channel_no, &i_target_no, &i_lun_no); enumerate_common(target, buf, i_bus_no, i_host_no, i_channel_no, i_target_no, i_lun_no); } sg_give_next_adr(&idx, buf, buf_size, -1); ret = 1; ex:; BURN_FREE_MEM(buf); BURN_FREE_MEM(target); return ret; } /** Tells whether libburn has the given drive in use or exclusively reserved. If it is "open" then libburn will eventually call sg_release() on it when it is time to give up usage and reservation. */ /** Published as burn_drive.drive_is_open() */ int sg_drive_is_open(struct burn_drive * d) { return (d->p_cdio != NULL); } /** Opens the drive for SCSI commands and - if burn activities are prone to external interference on your system - obtains an exclusive access lock on the drive. (Note: this is not physical tray locking.) A drive that has been opened with sg_grab() will eventually be handed over to sg_release() for closing and unreserving. */ int sg_grab(struct burn_drive *d) { CdIo_t *p_cdio; char *am_eff, *msg = NULL, *am_wanted; int os_errno, second_try = 0, ret; if (d->p_cdio != NULL) { d->released = 0; {ret = 1; goto ex;} } if (d->libcdio_name[0] == 0) /* just to be sure it is initialized */ strcpy(d->libcdio_name, d->devname); am_wanted = (burn_sg_open_o_excl & 63) ? "MMC_RDWR_EXCL" : "MMC_RDWR"; try_to_open:; p_cdio = cdio_open_am(d->libcdio_name, DRIVER_DEVICE, am_wanted); if (p_cdio == NULL) { BURN_ALLOC_MEM(msg, char, 4096); os_errno = errno; sprintf(msg, "Could not grab drive '%s'", d->devname); libdax_msgs_submit(libdax_messenger, d->global_index, 0x00020003, LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH, msg, os_errno, 0); {ret = 0; goto ex;} } am_eff = (char *) cdio_get_arg(p_cdio, "access-mode"); if (strncmp(am_eff, "MMC_RDWR", 8) != 0) { cdio_destroy(p_cdio); if (!second_try) { am_wanted = (burn_sg_open_o_excl & 63) ? "MMC_RDWR" : "MMC_RDWR_EXCL"; second_try = 1; goto try_to_open; } libdax_msgs_submit(libdax_messenger, d->global_index, 0x00020003, LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH, "libcdio provides no MMC_RDWR access mode", 0, 0); {ret = 0; goto ex;} } d->p_cdio = p_cdio; d->released = 0; ret = 1; ex:; BURN_FREE_MEM(msg); return ret; } /** PORTING: Is mainly about the call to sg_close_drive() and whether it implements the demanded functionality. */ /** Gives up the drive for SCSI commands and releases eventual access locks. (Note: this is not physical tray locking.) */ int sg_release(struct burn_drive *d) { if (d->p_cdio == NULL) return 0; sg_close_drive(d); return 0; } /** Sends a SCSI command to the drive, receives reply and evaluates wether the command succeeded or shall be retried or finally failed. Returned SCSI errors shall not lead to a return value indicating failure. The callers get notified by c->error. An SCSI failure which leads not to a retry shall be notified via scsi_notify_error(). The Libburn_log_sg_commandS facility might be of help when problems with a drive have to be examined. It shall stay disabled for normal use. @return: 1 success , <=0 failure */ int sg_issue_command(struct burn_drive *d, struct command *c) { int sense_valid = 0, i, timeout_ms, sense_len; int key = 0, asc = 0, ascq = 0, done = 0; time_t start_time; driver_return_code_t i_status; unsigned int dxfer_len; static FILE *fp = NULL; mmc_cdb_t cdb = {{0, }}; cdio_mmc_direction_t e_direction; CdIo_t *p_cdio; cdio_mmc_request_sense_t *sense_pt = NULL; c->error = 0; memset(c->sense, 0, sizeof(c->sense)); if (d->p_cdio == NULL) { return 0; } p_cdio = (CdIo_t *) d->p_cdio; if (burn_sg_log_scsi & 1) { if (fp == NULL) { fp= fopen("/tmp/libburn_sg_command_log", "a"); fprintf(fp, "\n-----------------------------------------\n"); } } if (burn_sg_log_scsi & 3) scsi_log_cmd(c,fp,0); memcpy(cdb.field, c->opcode, c->oplen); if (c->dir == TO_DRIVE) { dxfer_len = c->page->bytes; e_direction = SCSI_MMC_DATA_WRITE; } else if (c->dir == FROM_DRIVE) { if (c->dxfer_len >= 0) dxfer_len = c->dxfer_len; else dxfer_len = BUFFER_SIZE; e_direction = SCSI_MMC_DATA_READ; /* touch page so we can use valgrind */ memset(c->page->data, 0, BUFFER_SIZE); } else { dxfer_len = 0; e_direction = SCSI_MMC_DATA_NONE; } /* retry-loop */ start_time = time(NULL); if (c->timeout > 0) timeout_ms = c->timeout; else timeout_ms = 200000; for(i = 0; !done; i++) { memset(c->sense, 0, sizeof(c->sense)); c->start_time = burn_get_time(0); i_status = mmc_run_cmd(p_cdio, timeout_ms, &cdb, e_direction, dxfer_len, c->page->data); c->end_time = burn_get_time(0); sense_valid = mmc_last_cmd_sense(p_cdio, &sense_pt); if (sense_valid >= 18) { memcpy(c->sense, (unsigned char *) sense_pt, (size_t) sense_valid >= sizeof(c->sense) ? sizeof(c->sense) : (size_t) sense_valid ); spc_decode_sense(c->sense, 0, &key, &asc, &ascq); } else key = asc = ascq = 0; if (sense_pt != NULL) free(sense_pt); /* Regrettably mmc_run_cmd() does not clearly distinguish between transport failure and SCSI error reply. This reaction here would be for transport failure: if (i_status != 0 && i_status != DRIVER_OP_ERROR) { libdax_msgs_submit(libdax_messenger, d->global_index, 0x0002010c, LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH, "Failed to transfer command to drive", errno, 0); sg_close_drive(d); d->released = 1; d->busy = BURN_DRIVE_IDLE; c->error = 1; return -1; } */ if ((!sense_valid) || (key == 0 && asc == 0 && ascq == 0)) { memset(c->sense, 0, sizeof(c->sense)); if (i_status != 0) { /* set dummy sense */ /*LOGICAL UNIT NOT READY, CAUSE NOT REPORTABLE*/ c->sense[0] = 0x70; /*Fixed format sense data*/ c->sense[2] = 0x02; c->sense[12] = 0x04; done = 1; } } if (key || asc || ascq) sense_len = 18; else sense_len = 0; done = scsi_eval_cmd_outcome(d, c, fp, c->sense, sense_len, start_time, timeout_ms, i, 0); if (d->cancel) done = 1; } /* end of retry-loop */ return 1; } /** Tries to obtain SCSI address parameters. @return 1 is success , 0 is failure */ int sg_obtain_scsi_adr(char *path, int *bus_no, int *host_no, int *channel_no, int *target_no, int *lun_no) { CdIo_t *p_cdio; char *tuple; *bus_no = *host_no = *channel_no = *target_no = *lun_no = -1; p_cdio = cdio_open(path, DRIVER_DEVICE); if (p_cdio == NULL) return 0; /* Try whether a bus,host,channel,target,lun address tuple is available */ tuple = (char *) cdio_get_arg(p_cdio, "scsi-tuple"); if (tuple != NULL) if (tuple[0]) { sscanf(tuple, "%d,%d,%d,%d,%d", bus_no, host_no, channel_no, target_no, lun_no); } cdio_destroy(p_cdio); return (*bus_no >= 0); } /** Tells wether a text is a persistent address as listed by the enumeration functions. */ int sg_is_enumerable_adr(char* adr) { burn_drive_enumerator_t idx; int initialize = 1, ret; char buf[64]; while(1) { ret = sg_give_next_adr(&idx, buf, sizeof(buf), initialize); initialize = 0; if (ret <= 0) break; if (strcmp(adr, buf) == 0) { sg_give_next_adr(&idx, buf, sizeof(buf), -1); return 1; } } sg_give_next_adr(&idx, buf, sizeof(buf), -1); return (0); } #ifdef __FreeBSD__ #define Libburn_guess_block_devicE 1 #endif #ifdef __FreeBSD_kernel__ #define Libburn_guess_block_devicE 1 #endif #ifdef Libburn_guess_block_devicE /* ts B00115 */ /* The FreeBSD implementation of burn_os_is_2k_seekrw(). On FreeBSD there are no block devices. */ static int freebsd_is_2k_seekrw(char *path, int flag) { struct stat stbuf; char *spt; int i, e; if (stat(path, &stbuf) == -1) return 0; if (S_ISREG(stbuf.st_mode)) return 1; if (!S_ISCHR(stbuf.st_mode)) return 0; spt = strrchr(path, '/'); if (spt == NULL) spt = path; else spt++; e = strlen(spt); for (i = strlen(spt) - 1; i > 0; i--) if (spt[i] >= '0' && spt[i] <= '9') e = i; if (strncmp(spt, "da", e) == 0) /* SCSI disk. E.g. USB stick. */ return 1; if (strncmp(spt, "cd", e) == 0) /* SCSI CD drive might be writeable. */ return 1; if (strncmp(spt, "ad", e) == 0) /* IDE hard drive */ return 1; if (strncmp(spt, "acd", e) == 0) /* IDE CD drive might be writeable */ return 1; if (strncmp(spt, "fd", e) == 0) /* Floppy disk */ return 1; if (strncmp(spt, "fla", e) == 0) /* Flash drive */ return 1; return 0; } #endif /* Libburn_guess_block_devicE */ /* Return 1 if the given path leads to a regular file or a device that can be seeked, read, and possibly written with 2 kB granularity. */ int burn_os_is_2k_seekrw(char *path, int flag) { #ifdef Libburn_guess_block_devicE return freebsd_is_2k_seekrw(path, flag); #else struct stat stbuf; if (stat(path, &stbuf) == -1) return 0; if (S_ISREG(stbuf.st_mode)) return 1; if (S_ISBLK(stbuf.st_mode)) return 1; return 0; #endif /* ! Libburn_guess_block_devicE */ } /** Estimate the potential payload capacity of a file address. @param path The address of the file to be examined. If it does not exist yet, then the directory will be inquired. @param bytes The pointed value gets modified, but only if an estimation is possible. @return -2 = cannot perform necessary operations on file object -1 = neither path nor dirname of path exist 0 = could not estimate size capacity of file object 1 = estimation has been made, bytes was set */ int burn_os_stdio_capacity(char *path, off_t write_start, off_t *bytes) { struct stat stbuf; #ifdef Libburn_os_has_statvfS struct statvfs vfsbuf; #endif char *testpath = NULL, *cpt; off_t add_size = 0; int ret; BURN_ALLOC_MEM(testpath, char, 4096); testpath[0] = 0; if (stat(path, &stbuf) == -1) { strcpy(testpath, path); cpt = strrchr(testpath, '/'); if(cpt == NULL) strcpy(testpath, "."); else if(cpt == testpath) testpath[1] = 0; else *cpt = 0; if (stat(testpath, &stbuf) == -1) {ret = -1; goto ex;} #ifdef __linux /* GNU/Linux specific determination of block device size */ } else if(S_ISBLK(stbuf.st_mode)) { int open_mode = O_RDONLY | O_BINARY, fd; long blocks; blocks = *bytes / 512; fd = open(path, open_mode); if (fd == -1) {ret = -2; goto ex;} ret = ioctl(fd, BLKGETSIZE, &blocks); close(fd); if (ret == -1) {ret = -2; goto ex;} *bytes = ((off_t) blocks) * (off_t) 512; #endif /* __linux */ #ifdef Libburn_is_on_freebsD } else if(S_ISCHR(stbuf.st_mode)) { int fd; fd = open(path, O_RDONLY | O_BINARY); if (fd == -1) {ret = -2; goto ex;} ret = ioctl(fd, DIOCGMEDIASIZE, &add_size); close(fd); if (ret == -1) {ret = -2; goto ex;} *bytes = add_size; #endif /* Libburn_is_on_freebsD */ #ifdef Libburn_is_on_solariS } else if(S_ISBLK(stbuf.st_mode)) { int open_mode = O_RDONLY | O_BINARY, fd; fd = open(path, open_mode); if (fd == -1) {ret = -2; goto ex;} *bytes = lseek(fd, 0, SEEK_END); close(fd); if (*bytes == -1) { *bytes = 0; {ret = 0; goto ex;} } #endif /* Libburn_is_on_solariS */ } else if(S_ISREG(stbuf.st_mode)) { add_size = burn_sparse_file_addsize(write_start, &stbuf); strcpy(testpath, path); } else {ret = 0; goto ex;} if (testpath[0]) { #ifdef Libburn_os_has_statvfS if (statvfs(testpath, &vfsbuf) == -1) {ret = -2; goto ex;} *bytes = add_size + ((off_t) vfsbuf.f_frsize) * (off_t) vfsbuf.f_bavail; #else /* Libburn_os_has_statvfS */ {ret = 0; goto ex;} #endif /* ! Libburn_os_has_stavtfS */ } ret = 1; ex:; BURN_FREE_MEM(testpath); return ret; } /* ts A91122 : an interface to open(O_DIRECT) or similar OS tricks. */ #ifdef Libburn_read_o_direcT /* No special O_DIRECT-like precautions are implemented here */ #endif /* Libburn_read_o_direcT */ int burn_os_open_track_src(char *path, int open_flags, int flag) { int fd; fd = open(path, open_flags | O_BINARY); return fd; } void *burn_os_alloc_buffer(size_t amount, int flag) { void *buf = NULL; buf = calloc(1, amount); return buf; } int burn_os_free_buffer(void *buffer, size_t amount, int flag) { if (buffer == NULL) return 0; free(buffer); return 1; } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������libburn-1.4.2/libburn/ecma130ab.c�������������������������������������������������������������������0000644�0001757�0001751�00000077665�12652644224�013375� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ /* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */ #ifdef HAVE_CONFIG_H #include "../config.h" #endif /* ts A91016 : libburn/ecma130ab.c is the replacement for old libburn/lec.c Copyright 2009, Thomas Schmitt <scdbackup@gmx.net>, libburnia-project.org Provided under GPL version 2 or later. This code module implements the production of RSPC parity bytes (P- and Q- parity) and the scrambling of raw CD-ROM sectors as specified in ECMA-130: http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-130.pdf The following statements about Galois Fields have been learned mostly from http://www.cs.utk.edu/~plank/plank/papers/CS-96-332.pdf by James S. Plank after an e-mail exchange with Norbert Preining. The output has been compared with the output of the old code of libburn which was labeled "borrowed HEAVILY from cdrdao" and claimed by Joerg Schilling to stem from code by Heiko Eissfeldt. ------------------------------------------------------------------------- Note: In this text, "^" denotes exponentiation and not the binary exor operation. Confusingly in the C code "^" is said exor. Note: This is not C1, C2 which is rather mentioned in ECMA-130 Annex C and always performed inside the drive. ------------------------------------------------------------------------- RSPC , P- and Q-Parity ECMA-130 Annex A prescribes to compute the parity bytes for P-columns and Q-diagonals by RSPC based on a Galois Field GF(2^8) with enumerating polynomials x^8+x^4+x^3+x^2+1 (i.e. 0x11d) and x^1 (i.e. 0x02). Bytes 12 to 2075 of a audio-sized sector get ordered in two byte words as 24 rows and 43 columns. Then this matrix is split into a LSB matrix and a MSB matrix of the same layout. Parity bytes are to be computed from these 8-bit values. 2 P-bytes cover each column of 24 bytes. They get appended to the matrix as rows 24 and 25. 2 Q-bytes cover each the 26 diagonals of the extended matrix. Both parity byte pairs have to be computed so that extended rows or diagonals match this linear equation: H x V = (0,0) H is a 2-row matrix of size n matching the length of the V ectors [ 1 1 ... 1 1 ] [ x^(n-1) x^(n-2) x^1 1 ] Vp represents a P-row. It is a byte vector consisting of row bytes at position 0 to 23 and the two parity bytes which shall be determined at position 24 and 25. So Hp has 26 columns. Vq represents a Q-diagonal. It is a byte vector consisting of diagonal bytes at position 0 to 42 and the two parity bytes at position 43 and 44. So Hq has 45 columns. The Q-diagonals cover P-parity bytes. By applying some high school algebra one gets the parity bytes b0, b1 of vector V = (n_payload_bytes, b0 , b1) as b0 = ( H[n] * SUM(n_payload_bytes) - H[0..(n-1)] x n_payload_bytes ) / (H[n+1] - H[n]) b1 = - SUM(n_payload_bytes) - b0 H[i] is the i-the element of the second row of matrix H. E.g. H[0] = x^(n-1) The result has to be computed by Galois field arithmetics. See below. The P-parity bytes of each column get reunited as LSB and MSB of two words. word1 gets written to positions 1032 to 1074, word0 to 1075 to 1117. The Q-parity bytes of each diagonal get reunited too. word1 goes to 1118 to 1143, word0 to 1144 to 1169. >>> I do not read this swap of word1 and word0 from ECMA-130 Annex A. >>> But the new output matches the old output only if it is done that way. >>> See correctness reservation below. Algebra on Galois fields is the same as on Rational Numbers. But arithmetics is defined by operations on polynomials rather than the usual integer arithmetics on binary numbers. Addition and subtraction are identical with the binary exor operator. Multiplication and division would demand polynomial division, e.g. by the euclidian algorithm. The computing path over logarithms and powers follows algebra and reduces the arithmetic task to table lookups, additions modulo 255, and exor operations. Note that the logarithms are natural numbers, not polynomials. They get added or subtracted by the usual addition (not by exor) and their polynomial power depends on their value modulo 255. Needed are a logarithm table and a power table (or inverse logarithm table) for Galois Field GF(2^8) which will serve to perform the peculiar multiplication and division operation of Galois fields. The power table is simply an enumeration of x^n accorting to GF-multiplication. It also serves as second line of matrix H for the parity equations: Hp[i] = gfpow[25-i] , i out of {0,..,25} Hq[i] = gfpow[44-i] , i out of {0,..,44} The logarithm table is the inverse permutation of the power table. Some simplifications apply to the implementation: In the world of Galois fields there is no difference between - and +. The term (H[n+1] - H[n]) is constant: 3. ------------------------------------------------------------------------- Scrambling ECMA-130 Annex B prescribes to exor the byte stream of an audio-sized sector with a sequence of pseudo random bytes. It mentions polynomial x^15+x+1 and a 15-bit register. It shows a diagram of a Feedback Shift Register with 16 bit boxes, though. Comparing this with explanations in http://www.newwaveinstruments.com/resources/articles/m_sequence_linear_feedback_shift_register_lfsr.htm one can recognize the diagram as a Fibonacci Implementation. But there seems really to be one bit box too many. The difference of both lengths is expressed in function next_bit() by the constants 0x3fff,0x4000 for 15 bit versus 0x7fff,0x8000 for 16 bits. Comparing the output of both alternatives with the old scrambler output lets 15 bit win for now. So the prescription is to start with 15 bit value 1, to use the lowest bit as output, to shift the bits down by one, to exor the output bit with the next lowest bit, and to put that exor result into bit 14 of the register. ------------------------------------------------------------------------- Correctness Reservation In both cases, parity and scrambling, the goal for now is to replicate the output of the dismissed old lec.c by output which is based on published specs and own implementation code. Whether they comply to ECMA-130 is a different question which can only be answered by real test cases for raw CD recording. Of course this implementation will be corrected so that it really complies to ECMA-130 as soon as evidence emerges that it does not yet. */ /* ------------------------------------------------------------------------- */ /* Power and logarithm tables for GF(2^8), parity matrices for ECMA-130. Generated by burn_rspc_setup_tables() and burn_rspc_print_tables(). The highest possible sum of gflog[] values is is 508. So the table gfpow[] with period 255 was manually unrolled to 509 elements to avoid one modulo 255 operation in burn_rspc_mult(). Proposed by D. Hugh Redelmeier. */ static unsigned char gfpow[509] = { 1, 2, 4, 8, 16, 32, 64, 128, 29, 58, 116, 232, 205, 135, 19, 38, 76, 152, 45, 90, 180, 117, 234, 201, 143, 3, 6, 12, 24, 48, 96, 192, 157, 39, 78, 156, 37, 74, 148, 53, 106, 212, 181, 119, 238, 193, 159, 35, 70, 140, 5, 10, 20, 40, 80, 160, 93, 186, 105, 210, 185, 111, 222, 161, 95, 190, 97, 194, 153, 47, 94, 188, 101, 202, 137, 15, 30, 60, 120, 240, 253, 231, 211, 187, 107, 214, 177, 127, 254, 225, 223, 163, 91, 182, 113, 226, 217, 175, 67, 134, 17, 34, 68, 136, 13, 26, 52, 104, 208, 189, 103, 206, 129, 31, 62, 124, 248, 237, 199, 147, 59, 118, 236, 197, 151, 51, 102, 204, 133, 23, 46, 92, 184, 109, 218, 169, 79, 158, 33, 66, 132, 21, 42, 84, 168, 77, 154, 41, 82, 164, 85, 170, 73, 146, 57, 114, 228, 213, 183, 115, 230, 209, 191, 99, 198, 145, 63, 126, 252, 229, 215, 179, 123, 246, 241, 255, 227, 219, 171, 75, 150, 49, 98, 196, 149, 55, 110, 220, 165, 87, 174, 65, 130, 25, 50, 100, 200, 141, 7, 14, 28, 56, 112, 224, 221, 167, 83, 166, 81, 162, 89, 178, 121, 242, 249, 239, 195, 155, 43, 86, 172, 69, 138, 9, 18, 36, 72, 144, 61, 122, 244, 245, 247, 243, 251, 235, 203, 139, 11, 22, 44, 88, 176, 125, 250, 233, 207, 131, 27, 54, 108, 216, 173, 71, 142, 1, 2, 4, 8, 16, 32, 64, 128, 29, 58, 116, 232, 205, 135, 19, 38, 76, 152, 45, 90, 180, 117, 234, 201, 143, 3, 6, 12, 24, 48, 96, 192, 157, 39, 78, 156, 37, 74, 148, 53, 106, 212, 181, 119, 238, 193, 159, 35, 70, 140, 5, 10, 20, 40, 80, 160, 93, 186, 105, 210, 185, 111, 222, 161, 95, 190, 97, 194, 153, 47, 94, 188, 101, 202, 137, 15, 30, 60, 120, 240, 253, 231, 211, 187, 107, 214, 177, 127, 254, 225, 223, 163, 91, 182, 113, 226, 217, 175, 67, 134, 17, 34, 68, 136, 13, 26, 52, 104, 208, 189, 103, 206, 129, 31, 62, 124, 248, 237, 199, 147, 59, 118, 236, 197, 151, 51, 102, 204, 133, 23, 46, 92, 184, 109, 218, 169, 79, 158, 33, 66, 132, 21, 42, 84, 168, 77, 154, 41, 82, 164, 85, 170, 73, 146, 57, 114, 228, 213, 183, 115, 230, 209, 191, 99, 198, 145, 63, 126, 252, 229, 215, 179, 123, 246, 241, 255, 227, 219, 171, 75, 150, 49, 98, 196, 149, 55, 110, 220, 165, 87, 174, 65, 130, 25, 50, 100, 200, 141, 7, 14, 28, 56, 112, 224, 221, 167, 83, 166, 81, 162, 89, 178, 121, 242, 249, 239, 195, 155, 43, 86, 172, 69, 138, 9, 18, 36, 72, 144, 61, 122, 244, 245, 247, 243, 251, 235, 203, 139, 11, 22, 44, 88, 176, 125, 250, 233, 207, 131, 27, 54, 108, 216, 173, 71, }; static unsigned char gflog[256] = { 0, 0, 1, 25, 2, 50, 26, 198, 3, 223, 51, 238, 27, 104, 199, 75, 4, 100, 224, 14, 52, 141, 239, 129, 28, 193, 105, 248, 200, 8, 76, 113, 5, 138, 101, 47, 225, 36, 15, 33, 53, 147, 142, 218, 240, 18, 130, 69, 29, 181, 194, 125, 106, 39, 249, 185, 201, 154, 9, 120, 77, 228, 114, 166, 6, 191, 139, 98, 102, 221, 48, 253, 226, 152, 37, 179, 16, 145, 34, 136, 54, 208, 148, 206, 143, 150, 219, 189, 241, 210, 19, 92, 131, 56, 70, 64, 30, 66, 182, 163, 195, 72, 126, 110, 107, 58, 40, 84, 250, 133, 186, 61, 202, 94, 155, 159, 10, 21, 121, 43, 78, 212, 229, 172, 115, 243, 167, 87, 7, 112, 192, 247, 140, 128, 99, 13, 103, 74, 222, 237, 49, 197, 254, 24, 227, 165, 153, 119, 38, 184, 180, 124, 17, 68, 146, 217, 35, 32, 137, 46, 55, 63, 209, 91, 149, 188, 207, 205, 144, 135, 151, 178, 220, 252, 190, 97, 242, 86, 211, 171, 20, 42, 93, 158, 132, 60, 57, 83, 71, 109, 65, 162, 31, 45, 67, 216, 183, 123, 164, 118, 196, 23, 73, 236, 127, 12, 111, 246, 108, 161, 59, 82, 41, 157, 85, 170, 251, 96, 134, 177, 187, 204, 62, 90, 203, 89, 95, 176, 156, 169, 160, 81, 11, 245, 22, 235, 122, 117, 44, 215, 79, 174, 213, 233, 230, 231, 173, 232, 116, 214, 244, 234, 168, 80, 88, 175 }; #define Libburn_use_h_matriceS 1 #ifdef Libburn_use_h_matriceS /* On my AMD 2x64 bit 3000 MHz processor h[i] costs about 7 % more time than using gfpow[25-i] and gfpow[44-1]. I blame this on the more condensed data representation which slightly increases the rate of cache hits. Nevertheless this effect is very likely depending on the exact cache size and architecture. In general, using h[] saves more than 8000 subtractions per sector. */ /* Parity matrices H as prescribed by ECMA-130 Annex A. Actually just reverted order start pieces of gfpow[]. */ static unsigned char h26[26] = { 3, 143, 201, 234, 117, 180, 90, 45, 152, 76, 38, 19, 135, 205, 232, 116, 58, 29, 128, 64, 32, 16, 8, 4, 2, 1, }; static unsigned char h45[45] = { 238, 119, 181, 212, 106, 53, 148, 74, 37, 156, 78, 39, 157, 192, 96, 48, 24, 12, 6, 3, 143, 201, 234, 117, 180, 90, 45, 152, 76, 38, 19, 135, 205, 232, 116, 58, 29, 128, 64, 32, 16, 8, 4, 2, 1, }; #endif /* Libburn_use_h_matriceS */ /* Pseudo-random bytes which of course are exactly the same as with the previously used code. Generated by function print_ecma_130_scrambler(). */ static unsigned char ecma_130_annex_b[2340] = { 1, 128, 0, 96, 0, 40, 0, 30, 128, 8, 96, 6, 168, 2, 254, 129, 128, 96, 96, 40, 40, 30, 158, 136, 104, 102, 174, 170, 252, 127, 1, 224, 0, 72, 0, 54, 128, 22, 224, 14, 200, 4, 86, 131, 126, 225, 224, 72, 72, 54, 182, 150, 246, 238, 198, 204, 82, 213, 253, 159, 1, 168, 0, 126, 128, 32, 96, 24, 40, 10, 158, 135, 40, 98, 158, 169, 168, 126, 254, 160, 64, 120, 48, 34, 148, 25, 175, 74, 252, 55, 1, 214, 128, 94, 224, 56, 72, 18, 182, 141, 182, 229, 182, 203, 54, 215, 86, 222, 190, 216, 112, 90, 164, 59, 59, 83, 83, 125, 253, 225, 129, 136, 96, 102, 168, 42, 254, 159, 0, 104, 0, 46, 128, 28, 96, 9, 232, 6, 206, 130, 212, 97, 159, 104, 104, 46, 174, 156, 124, 105, 225, 238, 200, 76, 86, 181, 254, 247, 0, 70, 128, 50, 224, 21, 136, 15, 38, 132, 26, 227, 75, 9, 247, 70, 198, 178, 210, 245, 157, 135, 41, 162, 158, 249, 168, 66, 254, 177, 128, 116, 96, 39, 104, 26, 174, 139, 60, 103, 81, 234, 188, 79, 49, 244, 20, 71, 79, 114, 180, 37, 183, 91, 54, 187, 86, 243, 126, 197, 224, 83, 8, 61, 198, 145, 146, 236, 109, 141, 237, 165, 141, 187, 37, 179, 91, 53, 251, 87, 3, 126, 129, 224, 96, 72, 40, 54, 158, 150, 232, 110, 206, 172, 84, 125, 255, 97, 128, 40, 96, 30, 168, 8, 126, 134, 160, 98, 248, 41, 130, 158, 225, 168, 72, 126, 182, 160, 118, 248, 38, 194, 154, 209, 171, 28, 127, 73, 224, 54, 200, 22, 214, 142, 222, 228, 88, 75, 122, 183, 99, 54, 169, 214, 254, 222, 192, 88, 80, 58, 188, 19, 49, 205, 212, 85, 159, 127, 40, 32, 30, 152, 8, 106, 134, 175, 34, 252, 25, 129, 202, 224, 87, 8, 62, 134, 144, 98, 236, 41, 141, 222, 229, 152, 75, 42, 183, 95, 54, 184, 22, 242, 142, 197, 164, 83, 59, 125, 211, 97, 157, 232, 105, 142, 174, 228, 124, 75, 97, 247, 104, 70, 174, 178, 252, 117, 129, 231, 32, 74, 152, 55, 42, 150, 159, 46, 232, 28, 78, 137, 244, 102, 199, 106, 210, 175, 29, 188, 9, 177, 198, 244, 82, 199, 125, 146, 161, 173, 184, 125, 178, 161, 181, 184, 119, 50, 166, 149, 186, 239, 51, 12, 21, 197, 207, 19, 20, 13, 207, 69, 148, 51, 47, 85, 220, 63, 25, 208, 10, 220, 7, 25, 194, 138, 209, 167, 28, 122, 137, 227, 38, 201, 218, 214, 219, 30, 219, 72, 91, 118, 187, 102, 243, 106, 197, 239, 19, 12, 13, 197, 197, 147, 19, 45, 205, 221, 149, 153, 175, 42, 252, 31, 1, 200, 0, 86, 128, 62, 224, 16, 72, 12, 54, 133, 214, 227, 30, 201, 200, 86, 214, 190, 222, 240, 88, 68, 58, 179, 83, 53, 253, 215, 1, 158, 128, 104, 96, 46, 168, 28, 126, 137, 224, 102, 200, 42, 214, 159, 30, 232, 8, 78, 134, 180, 98, 247, 105, 134, 174, 226, 252, 73, 129, 246, 224, 70, 200, 50, 214, 149, 158, 239, 40, 76, 30, 181, 200, 119, 22, 166, 142, 250, 228, 67, 11, 113, 199, 100, 82, 171, 125, 191, 97, 176, 40, 116, 30, 167, 72, 122, 182, 163, 54, 249, 214, 194, 222, 209, 152, 92, 106, 185, 239, 50, 204, 21, 149, 207, 47, 20, 28, 15, 73, 196, 54, 211, 86, 221, 254, 217, 128, 90, 224, 59, 8, 19, 70, 141, 242, 229, 133, 139, 35, 39, 89, 218, 186, 219, 51, 27, 85, 203, 127, 23, 96, 14, 168, 4, 126, 131, 96, 97, 232, 40, 78, 158, 180, 104, 119, 110, 166, 172, 122, 253, 227, 1, 137, 192, 102, 208, 42, 220, 31, 25, 200, 10, 214, 135, 30, 226, 136, 73, 166, 182, 250, 246, 195, 6, 209, 194, 220, 81, 153, 252, 106, 193, 239, 16, 76, 12, 53, 197, 215, 19, 30, 141, 200, 101, 150, 171, 46, 255, 92, 64, 57, 240, 18, 196, 13, 147, 69, 173, 243, 61, 133, 209, 163, 28, 121, 201, 226, 214, 201, 158, 214, 232, 94, 206, 184, 84, 114, 191, 101, 176, 43, 52, 31, 87, 72, 62, 182, 144, 118, 236, 38, 205, 218, 213, 155, 31, 43, 72, 31, 118, 136, 38, 230, 154, 202, 235, 23, 15, 78, 132, 52, 99, 87, 105, 254, 174, 192, 124, 80, 33, 252, 24, 65, 202, 176, 87, 52, 62, 151, 80, 110, 188, 44, 113, 221, 228, 89, 139, 122, 231, 99, 10, 169, 199, 62, 210, 144, 93, 172, 57, 189, 210, 241, 157, 132, 105, 163, 110, 249, 236, 66, 205, 241, 149, 132, 111, 35, 108, 25, 237, 202, 205, 151, 21, 174, 143, 60, 100, 17, 235, 76, 79, 117, 244, 39, 7, 90, 130, 187, 33, 179, 88, 117, 250, 167, 3, 58, 129, 211, 32, 93, 216, 57, 154, 146, 235, 45, 143, 93, 164, 57, 187, 82, 243, 125, 133, 225, 163, 8, 121, 198, 162, 210, 249, 157, 130, 233, 161, 142, 248, 100, 66, 171, 113, 191, 100, 112, 43, 100, 31, 107, 72, 47, 118, 156, 38, 233, 218, 206, 219, 20, 91, 79, 123, 116, 35, 103, 89, 234, 186, 207, 51, 20, 21, 207, 79, 20, 52, 15, 87, 68, 62, 179, 80, 117, 252, 39, 1, 218, 128, 91, 32, 59, 88, 19, 122, 141, 227, 37, 137, 219, 38, 219, 90, 219, 123, 27, 99, 75, 105, 247, 110, 198, 172, 82, 253, 253, 129, 129, 160, 96, 120, 40, 34, 158, 153, 168, 106, 254, 175, 0, 124, 0, 33, 192, 24, 80, 10, 188, 7, 49, 194, 148, 81, 175, 124, 124, 33, 225, 216, 72, 90, 182, 187, 54, 243, 86, 197, 254, 211, 0, 93, 192, 57, 144, 18, 236, 13, 141, 197, 165, 147, 59, 45, 211, 93, 157, 249, 169, 130, 254, 225, 128, 72, 96, 54, 168, 22, 254, 142, 192, 100, 80, 43, 124, 31, 97, 200, 40, 86, 158, 190, 232, 112, 78, 164, 52, 123, 87, 99, 126, 169, 224, 126, 200, 32, 86, 152, 62, 234, 144, 79, 44, 52, 29, 215, 73, 158, 182, 232, 118, 206, 166, 212, 122, 223, 99, 24, 41, 202, 158, 215, 40, 94, 158, 184, 104, 114, 174, 165, 188, 123, 49, 227, 84, 73, 255, 118, 192, 38, 208, 26, 220, 11, 25, 199, 74, 210, 183, 29, 182, 137, 182, 230, 246, 202, 198, 215, 18, 222, 141, 152, 101, 170, 171, 63, 63, 80, 16, 60, 12, 17, 197, 204, 83, 21, 253, 207, 1, 148, 0, 111, 64, 44, 48, 29, 212, 9, 159, 70, 232, 50, 206, 149, 148, 111, 47, 108, 28, 45, 201, 221, 150, 217, 174, 218, 252, 91, 1, 251, 64, 67, 112, 49, 228, 20, 75, 79, 119, 116, 38, 167, 90, 250, 187, 3, 51, 65, 213, 240, 95, 4, 56, 3, 82, 129, 253, 160, 65, 184, 48, 114, 148, 37, 175, 91, 60, 59, 81, 211, 124, 93, 225, 249, 136, 66, 230, 177, 138, 244, 103, 7, 106, 130, 175, 33, 188, 24, 113, 202, 164, 87, 59, 126, 147, 96, 109, 232, 45, 142, 157, 164, 105, 187, 110, 243, 108, 69, 237, 243, 13, 133, 197, 163, 19, 57, 205, 210, 213, 157, 159, 41, 168, 30, 254, 136, 64, 102, 176, 42, 244, 31, 7, 72, 2, 182, 129, 182, 224, 118, 200, 38, 214, 154, 222, 235, 24, 79, 74, 180, 55, 55, 86, 150, 190, 238, 240, 76, 68, 53, 243, 87, 5, 254, 131, 0, 97, 192, 40, 80, 30, 188, 8, 113, 198, 164, 82, 251, 125, 131, 97, 161, 232, 120, 78, 162, 180, 121, 183, 98, 246, 169, 134, 254, 226, 192, 73, 144, 54, 236, 22, 205, 206, 213, 148, 95, 47, 120, 28, 34, 137, 217, 166, 218, 250, 219, 3, 27, 65, 203, 112, 87, 100, 62, 171, 80, 127, 124, 32, 33, 216, 24, 90, 138, 187, 39, 51, 90, 149, 251, 47, 3, 92, 1, 249, 192, 66, 208, 49, 156, 20, 105, 207, 110, 212, 44, 95, 93, 248, 57, 130, 146, 225, 173, 136, 125, 166, 161, 186, 248, 115, 2, 165, 193, 187, 16, 115, 76, 37, 245, 219, 7, 27, 66, 139, 113, 167, 100, 122, 171, 99, 63, 105, 208, 46, 220, 28, 89, 201, 250, 214, 195, 30, 209, 200, 92, 86, 185, 254, 242, 192, 69, 144, 51, 44, 21, 221, 207, 25, 148, 10, 239, 71, 12, 50, 133, 213, 163, 31, 57, 200, 18, 214, 141, 158, 229, 168, 75, 62, 183, 80, 118, 188, 38, 241, 218, 196, 91, 19, 123, 77, 227, 117, 137, 231, 38, 202, 154, 215, 43, 30, 159, 72, 104, 54, 174, 150, 252, 110, 193, 236, 80, 77, 252, 53, 129, 215, 32, 94, 152, 56, 106, 146, 175, 45, 188, 29, 177, 201, 180, 86, 247, 126, 198, 160, 82, 248, 61, 130, 145, 161, 172, 120, 125, 226, 161, 137, 184, 102, 242, 170, 197, 191, 19, 48, 13, 212, 5, 159, 67, 40, 49, 222, 148, 88, 111, 122, 172, 35, 61, 217, 209, 154, 220, 107, 25, 239, 74, 204, 55, 21, 214, 143, 30, 228, 8, 75, 70, 183, 114, 246, 165, 134, 251, 34, 195, 89, 145, 250, 236, 67, 13, 241, 197, 132, 83, 35, 125, 217, 225, 154, 200, 107, 22, 175, 78, 252, 52, 65, 215, 112, 94, 164, 56, 123, 82, 163, 125, 185, 225, 178, 200, 117, 150, 167, 46, 250, 156, 67, 41, 241, 222, 196, 88, 83, 122, 189, 227, 49, 137, 212, 102, 223, 106, 216, 47, 26, 156, 11, 41, 199, 94, 210, 184, 93, 178, 185, 181, 178, 247, 53, 134, 151, 34, 238, 153, 140, 106, 229, 239, 11, 12, 7, 69, 194, 179, 17, 181, 204, 119, 21, 230, 143, 10, 228, 7, 11, 66, 135, 113, 162, 164, 121, 187, 98, 243, 105, 133, 238, 227, 12, 73, 197, 246, 211, 6, 221, 194, 217, 145, 154, 236, 107, 13, 239, 69, 140, 51, 37, 213, 219, 31, 27, 72, 11, 118, 135, 102, 226, 170, 201, 191, 22, 240, 14, 196, 4, 83, 67, 125, 241, 225, 132, 72, 99, 118, 169, 230, 254, 202, 192, 87, 16, 62, 140, 16, 101, 204, 43, 21, 223, 79, 24, 52, 10, 151, 71, 46, 178, 156, 117, 169, 231, 62, 202, 144, 87, 44, 62, 157, 208, 105, 156, 46, 233, 220, 78, 217, 244, 90, 199, 123, 18, 163, 77, 185, 245, 178, 199, 53, 146, 151, 45, 174, 157, 188, 105, 177, 238, 244, 76, 71, 117, 242, 167, 5, 186, 131, 51, 33, 213, 216, 95, 26, 184, 11, 50, 135, 85, 162, 191, 57, 176, 18, 244, 13, 135, 69, 162, 179, 57, 181, 210, 247, 29, 134, 137, 162, 230, 249, 138, 194, 231, 17, 138, 140, 103, 37, 234, 155, 15, 43, 68, 31, 115, 72, 37, 246, 155, 6, 235, 66, 207, 113, 148, 36, 111, 91, 108, 59, 109, 211, 109, 157, 237, 169, 141, 190, 229, 176, 75, 52, 55, 87, 86, 190, 190, 240, 112, 68, 36, 51, 91, 85, 251, 127, 3, 96, 1, 232, 0, 78, 128, 52, 96, 23, 104, 14, 174, 132, 124, 99, 97, 233, 232, 78, 206, 180, 84, 119, 127, 102, 160, 42, 248, 31, 2, 136, 1, 166, 128, 122, 224, 35, 8, 25, 198, 138, 210, 231, 29, 138, 137, 167, 38, 250, 154, 195, 43, 17, 223, 76, 88, 53, 250, 151, 3, 46, 129, 220, 96, 89, 232, 58, 206, 147, 20, 109, 207, 109, 148, 45, 175, 93, 188, 57, 177, 210, 244, 93, 135, 121, 162, 162, 249, 185, 130, 242, 225, 133, 136, 99, 38, 169, 218, 254, 219, 0, 91, 64, 59, 112, 19, 100, 13, 235, 69, 143, 115, 36, 37, 219, 91, 27, 123, 75, 99, 119, 105, 230, 174, 202, 252, 87, 1, 254, 128, 64, 96, 48, 40, 20, 30, 143, 72, 100, 54, 171, 86, 255, 126, 192, 32, 80, 24, 60, 10, 145, 199, 44, 82, 157, 253, 169, 129, 190, 224, 112, 72, 36, 54, 155, 86, 235, 126, 207, 96, 84, 40, 63, 94, 144, 56, 108, 18, 173, 205, 189, 149, 177, 175, 52, 124, 23, 97, 206, 168, 84, 126, 191, 96, 112, 40, 36, 30, 155, 72, 107, 118, 175, 102, 252, 42, 193, 223, 16, 88, 12, 58, 133, 211, 35, 29, 217, 201, 154, 214, 235, 30, 207, 72, 84, 54, 191, 86, 240, 62, 196, 16, 83, 76, 61, 245, 209, 135, 28, 98, 137, 233, 166, 206, 250, 212, 67, 31, 113, 200, 36, 86, 155, 126, 235, 96, 79, 104, 52, 46, 151, 92, 110, 185, 236, 114, 205, 229, 149, 139, 47, 39, 92, 26, 185, 203, 50, 215, 85, 158, 191, 40, 112, 30, 164, 8, 123, 70, 163, 114, 249, 229, 130, 203, 33, 151, 88, 110, 186, 172, 115, 61, 229, 209, 139, 28, 103, 73, 234, 182, 207, 54, 212, 22, 223, 78, 216, 52, 90, 151, 123, 46, 163, 92, 121, 249, 226, 194, 201, 145, 150, 236, 110, 205, 236, 85, 141, 255, 37, 128, 27, 32, 11, 88, 7, 122, 130, 163, 33, 185, 216, 114, 218, 165, 155, 59, 43, 83, 95, 125, 248, 33, 130, 152, 97, 170, 168, 127, 62, 160, 16, 120, 12, 34, 133, 217, 163, 26, 249, 203, 2, 215, 65, 158, 176, 104, 116, 46, 167, 92, 122, 185, 227, 50, 201, 213, 150, 223, 46, 216, 28, 90, 137, 251, 38, 195, 90, 209, 251, 28, 67, 73, 241, 246, 196, 70, 211, 114, 221, 229, 153 }; /* ------------------------------------------------------------------------- */ /* This is the new implementation of P- and Q-parity generation. It needs about the same computing time as the old implementation (both with gcc -O2 on AMD 64 bit). Measurements indicate that about 280 MIPS are needed for 48x CD speed (7.1 MB/s). */ static unsigned char burn_rspc_mult(unsigned char a, unsigned char b) { if (a == 0 || b == 0) return 0; /* Optimization of (a == 0 || b == 0) by D. Hugh Redelmeier if((((int)a - 1) | ((int)b - 1)) < 0) return 0; */ return gfpow[gflog[a] + gflog[b]]; /* % 255 not necessary because gfpow is unrolled up to index 510 */ } /* Divide by polynomial 0x03. Derived from burn_rspc_div() and using the unrolled size of the gfpow[] array. */ static unsigned char burn_rspc_div_3(unsigned char a) { if (a == 0) return 0; return gfpow[230 + gflog[a]]; } static void burn_rspc_p0p1(unsigned char *sector, int col, unsigned char *p0_lsb, unsigned char *p0_msb, unsigned char *p1_lsb, unsigned char *p1_msb) { unsigned char *start, b; unsigned int i, sum_v_lsb = 0, sum_v_msb = 0; unsigned int hxv_lsb = 0, hxv_msb = 0; start = sector + 12 + 2 * col; for(i = 0; i < 24; i++) { b = *start; sum_v_lsb ^= b; #ifdef Libburn_use_h_matriceS hxv_lsb ^= burn_rspc_mult(b, h26[i]); #else hxv_lsb ^= burn_rspc_mult(b, gfpow[25 - i]); #endif b = *(start + 1); sum_v_msb ^= b; #ifdef Libburn_use_h_matriceS hxv_msb ^= burn_rspc_mult(b, h26[i]); #else hxv_msb ^= burn_rspc_mult(b, gfpow[25 - i]); #endif start += 86; } /* 3 = gfpow[1] ^ gfpow[0] , 2 = gfpow[1] */ *p0_lsb = burn_rspc_div_3(burn_rspc_mult(2, sum_v_lsb) ^ hxv_lsb); *p0_msb = burn_rspc_div_3(burn_rspc_mult(2, sum_v_msb) ^ hxv_msb); *p1_lsb = sum_v_lsb ^ *p0_lsb; *p1_msb = sum_v_msb ^ *p0_msb; } void burn_rspc_parity_p(unsigned char *sector) { int i; unsigned char p0_lsb, p0_msb, p1_lsb, p1_msb; /* Loop over P columns */ for(i = 0; i < 43; i++) { burn_rspc_p0p1(sector, i, &p0_lsb, &p0_msb, &p1_lsb, &p1_msb); sector[2162 + 2 * i] = p0_lsb; sector[2162 + 2 * i + 1] = p0_msb; sector[2076 + 2 * i] = p1_lsb; sector[2076 + 2 * i + 1] = p1_msb; #ifdef Libburn_with_lec_generatoR if(verbous) { printf("p %2d : %2.2X %2.2X ", i, (unsigned int) p0_lsb, (unsigned int) p0_msb); printf("%2.2X %2.2X ", (unsigned int) p1_lsb, (unsigned int) p1_msb); printf("-> %d,%d\n", 2162 + 2 * i, 2076 + 2 * i); } #endif /* Libburn_with_lec_generatoR */ } } static void burn_rspc_q0q1(unsigned char *sector, int diag, unsigned char *q0_lsb, unsigned char *q0_msb, unsigned char *q1_lsb, unsigned char *q1_msb) { unsigned char *start, b; unsigned int i, idx, sum_v_lsb = 0, sum_v_msb = 0; unsigned int hxv_lsb = 0, hxv_msb = 0; start = sector + 12; idx = 2 * 43 * diag; for(i = 0; i < 43; i++) { if (idx >= 2236) idx -= 2236; b = start[idx]; sum_v_lsb ^= b; #ifdef Libburn_use_h_matriceS hxv_lsb ^= burn_rspc_mult(b, h45[i]); #else hxv_lsb ^= burn_rspc_mult(b, gfpow[44 - i]); #endif b = start[idx + 1]; sum_v_msb ^= b; #ifdef Libburn_use_h_matriceS hxv_msb ^= burn_rspc_mult(b, h45[i]); #else hxv_msb ^= burn_rspc_mult(b, gfpow[44 - i]); #endif idx += 88; } /* 3 = gfpow[1] ^ gfpow[0] , 2 = gfpow[1] */ *q0_lsb = burn_rspc_div_3(burn_rspc_mult(2, sum_v_lsb) ^ hxv_lsb); *q0_msb = burn_rspc_div_3(burn_rspc_mult(2, sum_v_msb) ^ hxv_msb); *q1_lsb = sum_v_lsb ^ *q0_lsb; *q1_msb = sum_v_msb ^ *q0_msb; } void burn_rspc_parity_q(unsigned char *sector) { int i; unsigned char q0_lsb, q0_msb, q1_lsb, q1_msb; /* Loop over Q diagonals */ for(i = 0; i < 26; i++) { burn_rspc_q0q1(sector, i, &q0_lsb, &q0_msb, &q1_lsb, &q1_msb); sector[2300 + 2 * i] = q0_lsb; sector[2300 + 2 * i + 1] = q0_msb; sector[2248 + 2 * i] = q1_lsb; sector[2248 + 2 * i + 1] = q1_msb; #ifdef Libburn_with_lec_generatoR if(verbous) { printf("q %2d : %2.2X %2.2X ", i, (unsigned int) q0_lsb, (unsigned int) q0_msb); printf("%2.2X %2.2X ", (unsigned int) q1_lsb, (unsigned int) q1_msb); printf("-> %d,%d\n", 2300 + 2 * i, 2248 + 2 * i); } #endif /* Libburn_with_lec_generatoR */ } } /* ------------------------------------------------------------------------- */ /* The new implementation of the ECMA-130 Annex B scrambler. It is totally unoptimized. One should make use of larger word operations. Measurements indicate that about 50 MIPS are needed for 48x CD speed. */ void burn_ecma130_scramble(unsigned char *sector) { int i; unsigned char *s; s = sector + 12; for (i = 0; i < 2340; i++) s[i] ^= ecma_130_annex_b[i]; } /* ------------------------------------------------------------------------- */ /* The following code is not needed for libburn but rather documents the origin of the tables above. In libburn it will not be compiled. */ #ifdef Libburn_with_lec_generatoR /* This function produced the content of gflog[] and gfpow[] */ static int burn_rspc_setup_tables(void) { unsigned int b, l; memset(gflog, 0, sizeof(gflog)); memset(gfpow, 0, sizeof(gfpow)); b = 1; for (l = 0; l < 255; l++) { gfpow[l] = (unsigned char) b; gflog[b] = (unsigned char) l; b = b << 1; if (b & 256) b = b ^ 0x11d; } return 0; } /* This function printed the content of gflog[] and gfpow[] as C code and compared the content with the tables of the old implementation. h26[] and h45[] are reverted order copies of gfpow[] */ static int burn_rspc_print_tables(void) { int i; printf("static unsigned char gfpow[255] = {"); printf("\n\t"); for(i= 0; i < 255; i++) { printf("%3u, ", gfpow[i]); #ifdef Libburn_with_old_lec_comparisoN if(gfpow[i] != gf8_ilog[i]) fprintf(stderr, "*** ILOG %d : %d != %d ***\n", i, gfpow[i], gf8_ilog[i]); #endif if((i % 10) == 9) printf("\n\t"); } printf("\n};\n\n"); printf("static unsigned char gflog[256] = {"); printf("\n\t"); for(i= 0; i < 256; i++) { printf(" %3u,", gflog[i]); #ifdef Libburn_with_old_lec_comparisoN if(gflog[i] != gf8_log[i]) fprintf(stderr, "*** LOG %d : %d != %d ***\n", i, gflog[i], gf8_log[i]); #endif if((i % 10) == 9) printf("\n\t"); } printf("\n};\n\n"); printf("static unsigned char h26[26] = {"); printf("\n\t"); for(i= 0; i < 26; i++) { printf(" %3u,", gfpow[25 - i]); if((i % 10) == 9) printf("\n\t"); } printf("\n};\n\n"); printf("static unsigned char h45[45] = {"); printf("\n\t"); for(i= 0; i < 45; i++) { printf(" %3u,",gfpow[44 - i]); if((i % 10) == 9) printf("\n\t"); } printf("\n};\n\n"); return 0; } /* This code was used to generate the content of array ecma_130_annex_b[]. */ static unsigned short ecma_130_fsr = 1; static int next_bit(void) { int ret; ret = ecma_130_fsr & 1; ecma_130_fsr = (ecma_130_fsr >> 1) & 0x3fff; if (ret ^ (ecma_130_fsr & 1)) ecma_130_fsr |= 0x4000; return ret; } static int print_ecma_130_scrambler(void) { int i, j, b; ecma_130_fsr = 1; printf("static unsigned char ecma_130_annex_b[2340] = {"); printf("\n\t"); for (i = 0; i < 2340; i++) { b = 0; for (j = 0; j < 8; j++) b |= next_bit() << j; printf("%3u, ", b); if ((i % 10) == 9) printf("\n\t"); } printf("\n};\n"); return 1; } #ifdef Libburn_with_general_rspc_diV /* This is a general polynomial division function. burn_rspc_div_3() has been derived from this by setting b to constant 3. */ static unsigned char burn_rspc_div(unsigned char a, unsigned char b) { int d; if (a == 0) return 0; if (b == 0) return -1; d = gflog[a] - gflog[b]; if (d < 0) d += 255; return gfpow[d]; } #endif /* Libburn_with_general_rspc_diV */ #endif /* Libburn_with_lec_generatoR */ ���������������������������������������������������������������������������libburn-1.4.2/libburn/sg-solaris.c������������������������������������������������������������������0000644�0001757�0001751�00000066246�12652644224�014015� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */ /* Copyright (c) 2010 - 2014 Thomas Schmitt <scdbackup@gmx.net> Provided under GPL version 2 or later. */ /* This is the main operating system dependent SCSI part of libburn. It implements the transport level aspects of SCSI control and command i/o. Present implementation: Solaris uscsi, e.g. for SunOS 5.11 PORTING: Porting libburn typically will consist of adding a new operating system case to the following switcher files: os.h Operating system specific libburn definitions and declarations. sg.c Operating system dependent transport level modules. and of deriving the following system specific files from existing examples: os-*.h Included by os.h. You will need some general system knowledge about signals and knowledge about the storage object needs of your transport level module sg-*.c. sg-*.c This source module. You will need special system knowledge about how to detect all potentially available drives, how to open them, eventually how to exclusively reserve them, how to perform SCSI transactions, how to inquire the (pseudo-)SCSI driver. You will not need to care about CD burning, MMC or other high-level SCSI aspects. Said sg-*.c operations are defined by a public function interface, which has to be implemented in a way that provides libburn with the desired services: sg_id_string() returns an id string of the SCSI transport adapter. It may be called before initialization but then may return only a preliminary id. sg_initialize() performs global initialization of the SCSI transport adapter and eventually needed operating system facilities. Checks for compatibility of supporting software components. sg_shutdown() performs global finalizations and releases golbally aquired resources. sg_give_next_adr() iterates over the set of potentially useful drive address strings. scsi_enumerate_drives() brings all available, not-whitelist-banned, and accessible drives into libburn's list of drives. sg_dispose_drive() finalizes adapter specifics of struct burn_drive on destruction. Releases resources which were aquired underneath scsi_enumerate_drives(). sg_drive_is_open() tells wether libburn has the given drive in use. sg_grab() opens the drive for SCSI commands and ensures undisturbed access. sg_release() closes a drive opened by sg_grab() sg_issue_command() sends a SCSI command to the drive, receives reply, and evaluates wether the command succeeded or shall be retried or finally failed. sg_obtain_scsi_adr() tries to obtain SCSI address parameters. burn_os_is_2k_seekrw() tells whether the given path leads to a file object that can be used in 2 kB granularity by lseek(2), read(2), and possibly write(2) if not read-only.. E.g. a USB stick or a hard disk. burn_os_stdio_capacity() estimates the emulated media space of stdio-drives. burn_os_open_track_src() opens a disk file in a way that offers best throughput with file reading and/or SCSI write command transmission. burn_os_alloc_buffer() allocates a memory area that is suitable for file descriptors issued by burn_os_open_track_src(). The buffer size may be rounded up for alignment reasons. burn_os_free_buffer() delete a buffer obtained by burn_os_alloc_buffer(). Porting hints are marked by the text "PORTING:". Send feedback to libburn-hackers@pykix.org . */ #ifdef HAVE_CONFIG_H #include "../config.h" #endif /** PORTING : ------- OS dependent headers and definitions ------ */ #include <unistd.h> #include <stropts.h> #include <stdio.h> #include <sys/types.h> #include <errno.h> #include <fcntl.h> #include <sys/stat.h> #include <string.h> #include <stdlib.h> #include <dirent.h> #ifdef Libburn_os_has_statvfS #include <sys/statvfs.h> #endif /* Libburn_os_has_stavtfS */ #include <volmgt.h> #include <sys/dkio.h> #include <sys/vtoc.h> #include <sys/scsi/impl/uscsi.h> /* The waiting time before eventually retrying a failed SCSI command. Before each retry wait Libburn_sg_linux_retry_incR longer than with the previous one. */ #define Libburn_sg_solaris_retry_usleeP 100000 #define Libburn_sg_solaris_retry_incR 100000 /** PORTING : ------ libburn portable headers and definitions ----- */ #include "transport.h" #include "drive.h" #include "sg.h" #include "spc.h" #include "sbc.h" #include "debug.h" #include "toc.h" #include "util.h" #include "init.h" #include "libdax_msgs.h" extern struct libdax_msgs *libdax_messenger; /* is in portable part of libburn */ int burn_drive_is_banned(char *device_address); int burn_drive_resolve_link(char *path, char adr[], int *recursion_count, int flag); /* drive.c */ /* Whether to log SCSI commands: bit0= log in /tmp/libburn_sg_command_log bit1= log to stderr bit2= flush every line */ extern int burn_sg_log_scsi; /* ------------------------------------------------------------------------ */ /* PORTING: Private definitions. Port only if needed by public functions. */ /* (Public functions are listed below) */ /* ------------------------------------------------------------------------ */ /* Storage object is in libburn/init.c whether to strive for exclusive access to the drive */ extern int burn_sg_open_o_excl; /* ------------------------------------------------------------------------ */ /* PORTING: Private functions. Port only if needed by public functions */ /* (Public functions are listed below) */ /* ------------------------------------------------------------------------ */ static int sg_close_drive(struct burn_drive * d) { if (d->fd != -1) { close(d->fd); d->fd = -1; return 1; } return 0; } static int decode_btl_number(char **cpt, int stopper, int *no) { *no = 0; for ((*cpt)++; **cpt != stopper; (*cpt)++) { if (**cpt < '0' || **cpt > '9') return 0; *no = *no * 10 + **cpt - '0'; } return 1; } /* Read bus, target, lun from name "cXtYdZs2" or "cXtYdZ/...". Return 0 if name is not of the desired form. */ static int decode_btl_solaris(char *name, int *busno, int *tgtno, int *lunno, int flag) { char *cpt, *cpt_mem; int ret; *busno = *tgtno = *lunno = -1; cpt = name; if (*cpt != 'c') return 0; ret = decode_btl_number(&cpt, 't', busno); if (ret <= 0) return ret; ret = decode_btl_number(&cpt, 'd', tgtno); if (ret <= 0) return ret; cpt_mem = cpt; ret = decode_btl_number(&cpt, 's', lunno); if (ret <= 0) { cpt = cpt_mem; ret = decode_btl_number(&cpt, '/', lunno); if (ret <= 0) return ret; return(1); } cpt++; if (*cpt != '2' || *(cpt + 1) != 0) return 0; return 1; } static int start_enum_cXtYdZs2(burn_drive_enumerator_t *idx, int flag) { DIR *dir; idx->dir = NULL; dir = opendir("/dev/rdsk"); if (dir == NULL) { libdax_msgs_submit(libdax_messenger, -1, 0x0002000c, LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH, "Cannot start device file enumeration. opendir(\"/dev/rdsk\") failed.", errno, 0); return 0; } idx->dir = dir; return 1; } static int sg_solaris_convert_devname(char *path, char **dev_to_open, int flag) { char *sym_name = NULL, *media_name = NULL, *curr_name, *msg = NULL; int ret; BURN_ALLOC_MEM(msg, char, 4096); BURN_FREE_MEM(*dev_to_open); *dev_to_open = NULL; curr_name = path; if (! volmgt_running()) goto set_name; sym_name = volmgt_symname(path); sprintf(msg, "Volume Management symbolic name: '%s' -> %s", path, sym_name == NULL ? "NULL" : sym_name); libdax_msgs_submit(libdax_messenger, -1, 0x00000002, LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH, msg, 0, 0); if (sym_name != NULL) media_name = media_findname(sym_name); else media_name = media_findname(path); if (media_name != NULL) curr_name = media_name; sprintf(msg, "Media name: %s -> %s", sym_name == NULL ? path : sym_name, media_name == NULL ? "NULL" : media_name); libdax_msgs_submit(libdax_messenger, -1, 0x00000002, LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH, msg, 0, 0); set_name: BURN_ALLOC_MEM(*dev_to_open, char, strlen(curr_name) + 1); strcpy(*dev_to_open, curr_name); ret = 1; ex: if (media_name != NULL) free(media_name); if (sym_name != NULL) free(sym_name); BURN_FREE_MEM(msg); return(ret); } static int next_enum_cXtYdZs2(burn_drive_enumerator_t *idx, char adr[], int adr_size, int flag) { int busno, tgtno, lunno, ret, fd = -1, volpath_size = 160, os_errno; char *volpath = NULL, *msg = NULL, *dev_to_open = NULL; struct dirent *entry; struct dk_cinfo cinfo; DIR *dir; BURN_ALLOC_MEM(volpath, char, volpath_size); BURN_ALLOC_MEM(msg, char, 4096); dir = idx->dir; while (1) { errno = 0; entry = readdir(dir); if (entry == NULL) { if (errno) { libdax_msgs_submit(libdax_messenger, -1, 0x0002000d, LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH, "Cannot enumerate next device. readdir() from \"/dev/rdsk\" failed.", errno, 0); {ret = -1; goto ex;} } break; } if (strlen(entry->d_name) > (size_t) (volpath_size - 11)) continue; ret = decode_btl_solaris(entry->d_name, &busno, &tgtno, &lunno, 0); if (ret <= 0) continue; /* not cXtYdZs2 */ sprintf(volpath, "/dev/rdsk/%s", entry->d_name); if (burn_drive_is_banned(volpath)) continue; ret = sg_solaris_convert_devname(volpath, &dev_to_open, 0); if (ret <= 0) continue; fd = open(dev_to_open, O_RDONLY | O_NDELAY); if (fd < 0) { os_errno = errno; sprintf(msg, "Could not open '%s' , errno = %d", dev_to_open, os_errno); libdax_msgs_submit(libdax_messenger, -1, 0x00000002, LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH, msg, os_errno, 0); continue; } /* See man dkio */ ret = ioctl(fd, DKIOCINFO, &cinfo); close(fd); if (ret < 0) { os_errno = errno; sprintf(msg, "ioctl(DKIOCINFO) failed on drive '%s', errno = %d", volpath, os_errno); libdax_msgs_submit(libdax_messenger, -1, 0x00000002, LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH, msg, os_errno, 0); continue; } if (cinfo.dki_ctype != DKC_CDROM) { sprintf(msg, "ioctl(DKIOCINFO) classifies drive '%s' as dki_ctype %ld, not as DKC_CDROM = %ld", volpath, (long int) cinfo.dki_ctype, (long int) DKC_CDROM); libdax_msgs_submit(libdax_messenger, -1, 0x00000002, LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH, msg, 0, 0); continue; } if (adr_size <= (int) strlen(volpath)) { sprintf(msg, "Device path '%s' too long. (Max. %d)", volpath, adr_size - 1); libdax_msgs_submit(libdax_messenger, -1, 0x00000002, LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH, msg, 0, 0); {ret = -1; goto ex;} } strcpy(adr, volpath); sprintf(msg, "Accepted as valid drive '%s'", volpath); libdax_msgs_submit(libdax_messenger, -1, 0x00000002, LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH, msg, 0, 0); {ret = 1; goto ex;} } ret = 0; ex:; BURN_FREE_MEM(dev_to_open); BURN_FREE_MEM(msg); BURN_FREE_MEM(volpath); return ret; } static int end_enum_cXtYdZs2(burn_drive_enumerator_t *idx, int flag) { DIR *dir; dir = idx->dir; if(dir != NULL) closedir(dir); idx->dir = NULL; return 1; } /* ----------------------------------------------------------------------- */ /* PORTING: Private functions which contain publicly needed functionality. */ /* Their portable part must be performed. So it is probably best */ /* to replace the non-portable part and to call these functions */ /* in your port, too. */ /* ----------------------------------------------------------------------- */ /** Wraps a detected drive into libburn structures and hands it over to libburn drive list. */ static void enumerate_common(char *fname, int bus_no, int host_no, int channel_no, int target_no, int lun_no) { int ret; struct burn_drive out; /* General libburn drive setup */ burn_setup_drive(&out, fname); /* This transport adapter uses SCSI-family commands and models (seems the adapter would know better than its boss, if ever) */ ret = burn_scsi_setup_drive(&out, bus_no, host_no, channel_no, target_no, lun_no, 0); if (ret <= 0) return; /* PORTING: ------------------- non portable part --------------- */ /* Transport adapter is Solaris uscsi */ /* Adapter specific handles and data */ out.fd = -1; /* PORTING: ---------------- end of non portable part ------------ */ /* Adapter specific functions with standardized names */ out.grab = sg_grab; out.release = sg_release; out.drive_is_open = sg_drive_is_open; out.issue_command = sg_issue_command; /* Finally register drive and inquire drive information */ burn_drive_finish_enum(&out); } /* ------------------------------------------------------------------------ */ /* PORTING: Public functions. These MUST be ported. */ /* ------------------------------------------------------------------------ */ /** Returns the id string of the SCSI transport adapter and eventually needed operating system facilities. This call is usable even if sg_initialize() was not called yet. In that case a preliminary constant message might be issued if detailed info is not available yet. @param msg returns id string @param flag unused yet, submit 0 @return 1 = success, <=0 = failure */ int sg_id_string(char msg[1024], int flag) { sprintf(msg, "internal Solaris uscsi adapter sg-solaris"); return 1; } /** Performs global initialization of the SCSI transport adapter and eventually needed operating system facilities. Checks for compatibility of supporting software components. @param msg returns ids and/or error messages of eventual helpers @param flag unused yet, submit 0 @return 1 = success, <=0 = failure */ int sg_initialize(char msg[1024], int flag) { return sg_id_string(msg, 0); } /** Performs global finalization of the SCSI transport adapter and eventually needed operating system facilities. Releases globally aquired resources. @param flag unused yet, submit 0 @return 1 = success, <=0 = failure */ int sg_shutdown(int flag) { return 1; } /** Finalizes BURN_OS_TRANSPORT_DRIVE_ELEMENTS, the components of struct burn_drive which are defined in os-*.h. The eventual initialization of those components was made underneath scsi_enumerate_drives(). This will be called when a burn_drive gets disposed. @param d the drive to be finalized @param flag unused yet, submit 0 @return 1 = success, <=0 = failure */ int sg_dispose_drive(struct burn_drive *d, int flag) { return 1; } /** Returns the next index number and the next enumerated drive address. The enumeration has to cover all available and accessible drives. It is allowed to return addresses of drives which are not available but under some (even exotic) circumstances could be available. It is on the other hand allowed, only to hand out addresses which can really be used right in the moment of this call. (This implementation chooses the latter.) @param idx An opaque handle. Make no own theories about it. @param adr Takes the reply @param adr_size Gives maximum size of reply including final 0 @param initialize 1 = start new, 0 = continue, use no other values for now -1 = finish @return 1 = reply is a valid address , 0 = no further address available -1 = severe error (e.g. adr_size too small) */ int sg_give_next_adr(burn_drive_enumerator_t *idx, char adr[], int adr_size, int initialize) { int ret; if (initialize == 1) { ret = start_enum_cXtYdZs2(idx, 0); if (ret <= 0) return ret; } else if (initialize == -1) { ret = end_enum_cXtYdZs2(idx, 0); return 0; } ret = next_enum_cXtYdZs2(idx, adr, adr_size, 0); return ret; } /** Brings all available, not-whitelist-banned, and accessible drives into libburn's list of drives. */ int scsi_enumerate_drives(void) { burn_drive_enumerator_t idx; int initialize = 1, ret, i_bus_no = -1, buf_size = 4096; int i_host_no = -1, i_channel_no = -1, i_target_no = -1, i_lun_no = -1; char *buf = NULL; BURN_ALLOC_MEM(buf, char, buf_size); while(1) { ret = sg_give_next_adr(&idx, buf, buf_size, initialize); initialize = 0; if (ret <= 0) break; if (burn_drive_is_banned(buf)) continue; sg_obtain_scsi_adr(buf, &i_bus_no, &i_host_no, &i_channel_no, &i_target_no, &i_lun_no); enumerate_common(buf, i_bus_no, i_host_no, i_channel_no, i_target_no, i_lun_no); } sg_give_next_adr(&idx, buf, buf_size, -1); ret = 1; ex:; BURN_FREE_MEM(buf); return ret; } /** Tells whether libburn has the given drive in use or exclusively reserved. If it is "open" then libburn will eventually call sg_release() on it when it is time to give up usage and reservation. */ /** Published as burn_drive.drive_is_open() */ int sg_drive_is_open(struct burn_drive * d) { return (d->fd != -1); } /** Opens the drive for SCSI commands and - if burn activities are prone to external interference on your system - obtains an exclusive access lock on the drive. (Note: this is not physical tray locking.) A drive that has been opened with sg_grab() will eventually be handed over to sg_release() for closing and unreserving. */ int sg_grab(struct burn_drive *d) { char *msg = NULL, *dev_to_open = NULL; int os_errno, ret; struct dk_cinfo cinfo; BURN_ALLOC_MEM(msg, char, 4096); if (d->fd != -1) { d->released = 0; {ret = 1; goto ex;} } ret = sg_solaris_convert_devname(d->devname, &dev_to_open, 0); if (ret <= 0) goto ex; d->fd = open(dev_to_open, O_RDONLY | O_NDELAY); if (d->fd == -1) { os_errno = errno; sprintf(msg, "Could not grab drive '%s'", d->devname); if (strcmp(d->devname, dev_to_open)) sprintf(msg + strlen(msg), " via '%s'", dev_to_open); libdax_msgs_submit(libdax_messenger, d->global_index, 0x00020003, LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH, msg, os_errno, 0); {ret = 0; goto ex;} } ret = ioctl(d->fd, DKIOCINFO, &cinfo); if (ret < 0) { os_errno = errno; sprintf(msg, "ioctl(DKIOCINFO) failed on drive '%s'", d->devname); libdax_msgs_submit(libdax_messenger, d->global_index, 0x00000002, LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH, msg, os_errno, 0); goto revoke; } if (cinfo.dki_ctype != DKC_CDROM) { sprintf(msg, "ioctl(DKIOCINFO) classifies drive '%s' as dki_ctype %ld, not as DKC_CDROM = %ld", d->devname, (long int) cinfo.dki_ctype, (long int) DKC_CDROM); libdax_msgs_submit(libdax_messenger, d->global_index, 0x00000002, LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH, msg, 0, 0); goto revoke; } /* >>> obtain eventual locks */; d->released = 0; {ret = 1; goto ex;} revoke:; sprintf(msg, "Could not grab drive '%s'. Not a CDROM device.", d->devname); libdax_msgs_submit(libdax_messenger, d->global_index, 0x00020003, LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH, msg, 0, 0); ret = 0; ex:; BURN_FREE_MEM(dev_to_open); BURN_FREE_MEM(msg); return ret; } /** PORTING: Is mainly about the call to sg_close_drive() and whether it implements the demanded functionality. */ /** Gives up the drive for SCSI commands and releases eventual access locks. (Note: this is not physical tray locking.) */ int sg_release(struct burn_drive *d) { if (d->fd < 0) return 0; sg_close_drive(d); return 0; } /** Sends a SCSI command to the drive, receives reply and evaluates wether the command succeeded or shall be retried or finally failed. Returned SCSI errors shall not lead to a return value indicating failure. The callers get notified by c->error. An SCSI failure which leads not to a retry shall be notified via scsi_notify_error(). The Libburn_log_sg_commandS facility might be of help when problems with a drive have to be examined. It shall stay disabled for normal use. @return: 1 success , <=0 failure */ int sg_issue_command(struct burn_drive *d, struct command *c) { int i, timeout_ms, ret, key, asc, ascq, done = 0, sense_len; time_t start_time; struct uscsi_cmd cgc; char msg[80]; static FILE *fp = NULL; c->error = 0; memset(c->sense, 0, sizeof(c->sense)); if (d->fd == -1) return 0; if (burn_sg_log_scsi & 1) { if (fp == NULL) { fp= fopen("/tmp/libburn_sg_command_log", "a"); fprintf(fp, "\n-----------------------------------------\n"); } } if (burn_sg_log_scsi & 3) scsi_log_cmd(c,fp,0); if (c->timeout > 0) timeout_ms = c->timeout; else timeout_ms = 200000; memset (&cgc, 0, sizeof (struct uscsi_cmd)); /* No error messages, no retries, do not execute with other commands, request sense data */ cgc.uscsi_flags = USCSI_SILENT | USCSI_DIAGNOSE | USCSI_ISOLATE | USCSI_RQENABLE; cgc.uscsi_timeout = timeout_ms / 1000; cgc.uscsi_cdb = (caddr_t) c->opcode; cgc.uscsi_bufaddr = (caddr_t) c->page->data; if (c->dir == TO_DRIVE) { cgc.uscsi_flags |= USCSI_WRITE; cgc.uscsi_buflen = c->page->bytes; } else if (c->dir == FROM_DRIVE) { cgc.uscsi_flags |= USCSI_READ; if (c->dxfer_len >= 0) cgc.uscsi_buflen = c->dxfer_len; else cgc.uscsi_buflen = BUFFER_SIZE; /* touch page so we can use valgrind */ memset(c->page->data, 0, BUFFER_SIZE); } else { cgc.uscsi_buflen = 0; } cgc.uscsi_cdblen = c->oplen; cgc.uscsi_rqlen = sizeof(c->sense); cgc.uscsi_rqbuf = (caddr_t) c->sense; /* retry-loop */ start_time = time(NULL); for(i = 0; !done; i++) { memset(c->sense, 0, sizeof(c->sense)); c->start_time = burn_get_time(0); ret = ioctl(d->fd, USCSICMD, &cgc); c->end_time = burn_get_time(0); /* For cgc.uscsi_status see SAM-3 5.3.1, Table 22 0 = GOOD , 2 = CHECK CONDITION : Sense Data are delivered 8 = BUSY */ if (ret != 0 && cgc.uscsi_status != 2) { sprintf(msg, "Failed to transfer command to drive. (uscsi_status = 0x%X)", (unsigned int) cgc.uscsi_status), libdax_msgs_submit(libdax_messenger, d->global_index, 0x0002010c, LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH, msg, errno, 0); sg_close_drive(d); d->released = 1; d->busy = BURN_DRIVE_IDLE; c->error = 1; return -1; } /* >>> Should replace "18" by realistic sense length. What's about following older remark ? */ /* >>> valid sense: cgc.uscsi_rqlen - cgc.uscsi_rqresid */; spc_decode_sense(c->sense, 0, &key, &asc, &ascq); if (key || asc || ascq) sense_len = 18; else sense_len = 0; done = scsi_eval_cmd_outcome(d, c, fp, c->sense, sense_len, start_time, timeout_ms, i, 0); if (d->cancel) done = 1; } /* end of retry-loop */ return 1; } /** Tries to obtain SCSI address parameters. @return 1 is success , 0 is failure */ int sg_obtain_scsi_adr(char *path, int *bus_no, int *host_no, int *channel_no, int *target_no, int *lun_no) { int ret; /* Try to guess from path */ if (strncmp("/dev/rdsk/", path, 10) == 0) { ret = decode_btl_solaris(path + 10, bus_no, target_no, lun_no, 0); if (ret > 0) { *host_no = *bus_no; *channel_no = 0; return 1; } } *bus_no = *host_no = *channel_no = *target_no = *lun_no = -1; /* >>> Could need a ioctl which gives SCSI numbers */; return (0); } /** Tells wether a text is a persistent address as listed by the enumeration functions. */ #ifndef NIX int sg_is_enumerable_adr(char* path) { int ret; int bus_no, target_no, lun_no; struct stat stbuf; if (strncmp("/dev/rdsk/", path, 10) != 0) return 0; ret = decode_btl_solaris(path + 10, &bus_no, &target_no, &lun_no, 0); if (ret <= 0) return 0; if (stat(path, &stbuf) == -1) return 0; return 1; } #else /* ! NIX */ int sg_is_enumerable_adr(char* adr) { burn_drive_enumerator_t idx; int initialize = 1, ret; char buf[64]; while(1) { ret = sg_give_next_adr(&idx, buf, sizeof(buf), initialize); initialize = 0; if (ret <= 0) break; if (strcmp(adr, buf) == 0) { sg_give_next_adr(&idx, buf, sizeof(buf), -1); return 1; } } sg_give_next_adr(&idx, buf, sizeof(buf), -1); return (0); } #endif /* NIX */ /* Return 1 if the given path leads to a regular file or a device that can be seeked, read, and possibly written with 2 kB granularity. */ int burn_os_is_2k_seekrw(char *path, int flag) { struct stat stbuf; if (stat(path, &stbuf) == -1) return 0; if (S_ISREG(stbuf.st_mode)) return 1; if (S_ISBLK(stbuf.st_mode)) return 1; return 0; } /** Estimate the potential payload capacity of a file address. @param path The address of the file to be examined. If it does not exist yet, then the directory will be inquired. @param bytes The pointed value gets modified, but only if an estimation is possible. @return -2 = cannot perform necessary operations on file object -1 = neither path nor dirname of path exist 0 = could not estimate size capacity of file object 1 = estimation has been made, bytes was set */ int burn_os_stdio_capacity(char *path, off_t write_start, off_t *bytes) { struct stat stbuf; int ret; #ifdef Libburn_os_has_statvfS struct statvfs vfsbuf; #endif char *testpath = NULL, *cpt; off_t add_size = 0; BURN_ALLOC_MEM(testpath, char, 4096); testpath[0] = 0; if (stat(path, &stbuf) == -1) { strcpy(testpath, path); cpt = strrchr(testpath, '/'); if(cpt == NULL) strcpy(testpath, "."); else if(cpt == testpath) testpath[1] = 0; else *cpt = 0; if (stat(testpath, &stbuf) == -1) {ret = -1; goto ex;} } else if(S_ISBLK(stbuf.st_mode)) { int open_mode = O_RDONLY, fd; fd = open(path, open_mode); if (fd == -1) {ret = -2; goto ex;} *bytes = lseek(fd, 0, SEEK_END); close(fd); if (*bytes == -1) { *bytes = 0; {ret = 0; goto ex;} } } else if(S_ISREG(stbuf.st_mode)) { add_size = burn_sparse_file_addsize(write_start, &stbuf); strcpy(testpath, path); } else {ret = 0; goto ex;} if (testpath[0]) { #ifdef Libburn_os_has_statvfS if (statvfs(testpath, &vfsbuf) == -1) {ret = -2; goto ex;} *bytes = add_size + ((off_t) vfsbuf.f_frsize) * (off_t) vfsbuf.f_bavail; #else /* Libburn_os_has_statvfS */ {ret = 0; goto ex;} #endif /* ! Libburn_os_has_stavtfS */ } ret = 1; ex:; BURN_FREE_MEM(testpath); return ret; } /* ts A91122 : an interface to open(O_DIRECT) or similar OS tricks. */ #ifdef Libburn_read_o_direcT /* No special O_DIRECT-like precautions are implemented here */ #endif /* Libburn_read_o_direcT */ int burn_os_open_track_src(char *path, int open_flags, int flag) { int fd; fd = open(path, open_flags); return fd; } void *burn_os_alloc_buffer(size_t amount, int flag) { void *buf = NULL; buf = calloc(1, amount); return buf; } int burn_os_free_buffer(void *buffer, size_t amount, int flag) { if (buffer == NULL) return 0; free(buffer); return 1; } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������libburn-1.4.2/libburn/ecma130ab.h�������������������������������������������������������������������0000644�0001757�0001751�00000001264�12652644224�013360� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ /* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */ /* ts A91016 : libburn/ecma130ab.h is the replacement for old libburn/lec.h Copyright 2009, Thomas Schmitt <scdbackup@gmx.net>, libburnia-project.org Provided under GPL version 2 or later. This code module implements the computations prescribed in ECMA-130 Annex A and B. For explanations of the underlying mathematics see ecma130ab.c . */ #ifndef Libburn_ecma130ab_includeD #define Libburn_ecma130ab_includeD 1 void burn_rspc_parity_p(unsigned char *sector); void burn_rspc_parity_q(unsigned char *sector); void burn_ecma130_scramble(unsigned char *sector); #endif /* ! Libburn_ecma130ab_includeD */ ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������libburn-1.4.2/libburn/back_hacks.h������������������������������������������������������������������0000644�0001757�0001751�00000003260�12652644224�013773� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/** Copyright (c) 2006 Thomas Schmitt <scdbackup@gmx.net> Provided under GPL version 2 or later. This file bundles variables which disable changes in libburn which are not yet completely accepted. The use of these variables is *strongly discouraged* unless you have sincere reason and are willing to share your gained knowledge with the libburn developers. Do *not silently rely* on these variables with your application. Tell us that you needed one or more of them. They are subject to removal as soon as consense has been found about correctness of the change they revoke. Value 0 means that the new behavior is enabled. Any other value enables the described old time behavior. If you doubt one of the changes here broke your application, then do *in your application*, *not here* : - #include "libburn/back_hacks.h" like you include "libburn/libburn.h" - Set the libburn_back_hack_* variable of your choice to 1. In your app. Not here. - Then start and use libburn as usual. Watch out for results. - If you believe to have detected a flaw in our change, come forward and report it to the libburn developers. Thanks in advance. :) */ /** Do not define this macro in your application. Only libburn/init.c is entitled to set it. */ #ifdef BURN_BACK_HACKS_INIT /** Corresponds to http://libburn.pykix.org/ticket/42 Reinstates the old ban not to blank appendable CD-RW. We see no reason for this ban yet. It appears unusual. But maybe it patches a bug. */ int libburn_back_hack_42= 0; #else /* BURN_BACK_HACKS_INIT */ /* Note: no application programmer info beyond this point */ extern int libburn_back_hack_42; #endif /* ! BURN_BACK_HACKS_INIT */ ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������libburn-1.4.2/libburn/spc.h�������������������������������������������������������������������������0000644�0001757�0001751�00000013550�12652644224�012512� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */ /* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens Copyright (c) 2006 - 2014 Thomas Schmitt <scdbackup@gmx.net> Provided under GPL version 2 or later. */ #ifndef __SPC #define __SPC #include "libburn.h" void spc_inquiry(struct burn_drive *); void spc_prevent(struct burn_drive *); void spc_allow(struct burn_drive *); void spc_sense_caps(struct burn_drive *); void spc_sense_error_params(struct burn_drive *); void spc_select_error_params(struct burn_drive *, const struct burn_read_opts *); void spc_getcaps(struct burn_drive *d); void spc_sense_write_params(struct burn_drive *); void spc_select_write_params(struct burn_drive *, struct burn_session *, int, const struct burn_write_opts *); #ifdef Libburn_enable_scsi_cmd_ABh int spc_read_media_serial_number(struct burn_drive *d); #endif void spc_probe_write_modes(struct burn_drive *); void spc_request_sense(struct burn_drive *d, struct buffer *buf); int spc_block_type(enum burn_block_types b); int spc_get_erase_progress(struct burn_drive *d); /* ts A70315 : test_unit_ready with result parameters */ int spc_test_unit_ready_r(struct burn_drive *d, int *key, int *asc, int *ascq, int *progress); int spc_test_unit_ready(struct burn_drive *d); /* ts A70315 */ /** Wait until the drive state becomes clear in or until max_sec elapsed */ int spc_wait_unit_attention(struct burn_drive *d, int max_sec, char *cmd_text, int flag); /* ts A61021 : the spc specific part of sg.c:enumerate_common() */ int spc_setup_drive(struct burn_drive *d); /* ts A61021 : the general SCSI specific part of sg.c:enumerate_common() @param flag Bitfield for control purposes bit0= do not setup spc/sbc/mmc */ int burn_scsi_setup_drive(struct burn_drive *d, int bus_no, int host_no, int channel_no, int target_no, int lun_no, int flag); /* ts A61115 moved from sg-*.h */ enum response { RETRY, FAIL, GO_ON }; enum response scsi_error(struct burn_drive *, unsigned char *, int); /* ts A61122 */ enum response scsi_error_msg(struct burn_drive *d, unsigned char *sense, int senselen, char msg[161], int *key, int *asc, int *ascq); /* ts A61030 */ /* @param flag bit0=do report conditions which are considered not an error */ int scsi_notify_error(struct burn_drive *, struct command *c, unsigned char *sense, int senselen, int flag); /* ts A70519 */ int scsi_init_command(struct command *c, unsigned char *opcode, int oplen); /* ts A91106 */ int scsi_show_cmd_text(struct command *c, void *fp, 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); /* ts B40731 */ /* Arbitrary SCSI log message */ int scsi_log_text(char *text, void *fp_in, int flag); /* ts A91218 (former sg_log_cmd ts A70518) */ /** Legacy frontend to scsi_log_command() */ 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, double duration, int flag); /* 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 burn_drive *d, struct command *c, void *fp, unsigned char sense[18], int sense_len, int flag); /* ts B31112 */ int scsi_log_message(struct burn_drive *d, void *fp, char * msg, int flag); /* ts B00728 */ int spc_decode_sense(unsigned char *sense, int senselen, int *key, int *asc, int *ascq); /* ts B00808 */ /** Evaluates outcome of a single SCSI command, eventually logs sense data, and issues DEBUG error message in case the command is evaluated as done. @param flag bit1 = do not print duration @return 0 = not yet done , 1 = done , -1 = error */ int scsi_eval_cmd_outcome(struct burn_drive *d, struct command *c, void *fp_in, unsigned char *sense, int sense_len, time_t start_time, int timeout_ms, int loop_count, int flag); /* ts B40204 */ /* Verify by INQUIRY that the drive is indeed a MMC device. */ int spc_confirm_cd_drive(struct burn_drive *d, int flag); /* The waiting time before eventually retrying a failed SCSI command. Before each retry wait Libburn_scsi_retry_incR longer than with the previous one. At most wait for Libburn_scsi_retry_umaX microseconds. */ #define Libburn_scsi_retry_usleeP 100000 #define Libburn_scsi_retry_incR 100000 #define Libburn_scsi_retry_umaX 500000 /* The retry waiting time for commands WRITE(10) and WRITE(12). */ #define Libburn_scsi_write_retry_usleeP 0 #define Libburn_scsi_write_retry_incR 2000 #define Libburn_scsi_write_retry_umaX 25000 /* ts B11124 */ /* Millisecond timeout for quickly responding SPC, SBC, and MMC commands */ #define Libburn_scsi_default_timeouT 30000 /* WRITE(10) and WRITE(12) */ #define Libburn_scsi_write_timeouT 200000 /* RESERVE TRACK */ #define Libburn_mmc_reserve_timeouT 200000 /* CLOSE TRACK/SESSION (with Immed bit) */ #define Libburn_mmc_close_timeouT 200000 /* BLANK , FORMAT UNIT (with Immed bit) */ #define Libburn_mmc_blank_timeouT 200000 /* SEND OPC INFORMATION */ #define Libburn_mmc_opc_timeouT 200000 /* MMC_SYNC_CACHE */ #define Libburn_mmc_sync_timeouT 200000 /* START STOP UNIT with Start bit and Load bit set */ #define Libburn_mmc_load_timeouT 300000 #endif /*__SPC*/ ��������������������������������������������������������������������������������������������������������������������������������������������������������libburn-1.4.2/libburn/crc.c�������������������������������������������������������������������������0000644�0001757�0001751�00000057434�12652644224�012500� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */ /* Copyright (c) 2012 Thomas Schmitt <scdbackup@gmx.net> Provided under GPL version 2 or later. Containing disabled code pieces from other GPL programs. They are just quotes for reference. The activated code uses plain polynomial division and other primitve algorithms to build tables of pre-computed CRC values. It then computes the CRCs by algorithms which are derived from mathematical considerations and from analysing the mathematical meaning of the disabled code pieces. The comments here are quite detailed in order to prove my own understanding of the topic. */ #ifdef HAVE_CONFIG_H #include "../config.h" #endif #include "crc.h" /* Exploration ts B00214 : ECMA-130, 22.3.6 "CRC field" "This field contains the inverted parity bits. The CRC code word must be divisible by the check polynomial. [...] The generating polynomial shall be G(x) = x^16 + x^12 + x^5 + 1 " Also known as CRC-16-CCITT, CRC-CCITT Used in libburn for raw write modes in sector.c. There is also disabled code in read.c which would use it. ts B11222: The same algorithm is prescribed for CD-TEXT in MMC-3 Annex J. "CRC Field consists of 2 bytes. Initiator system may use these bytes to check errors in the Pack. The polynomial is x^16 + x^12 + x^5 + 1. All bits shall be inverted." libburn/cdtext.c uses a simple bit shifting function : crc_11021() ts B20211: Discussion why both are equivalent in respect to their result: Both map the bits of the given bytes to a polynomial over the finite field of two elements "GF(2)". If bytes 0 .. M are given, then bit n of byte m is mapped to the coefficient of x exponent (n + ((M - m) * 8) + 16). I.e. they translate the bits into a polynomial with the highest bit becomming the coefficient of the highest power of x. Then this polynomial is multiplied by (x exp 16). The set of all such polynomials forms a commutative ring. Its addition corresponds to bitwise exclusive or. Addition and subtraction are identical. Multiplication with polynomials of only one single non-zero coefficient corresponds to leftward bit shifting by the exponent of that coefficient. The same rules apply as with elementary school arithmetics on integer numbers, but with surprising results due to the finite nature of the coefficient number space. Note that multiplication is _not_ an iteration of addition here. Function crc_11021() performs a division with residue by the euclidian algorithm. I.e. it splits polynomial d into quotient q(d) and residue r(d) in respect to the polynomial p = x exp 16 + x exp 12 + x exp 5 + x exp 0 d = p * q(d) + r(d) where r(d) is of a polynomial degree lower than p, i.e. only x exp 15 or lower have non-zero coefficients. The checksum crc(D) is derived by reverse mapping (r(d) * (x exp 16)). I.e. by mapping the coefficient of (x exp n) to bit n of the 16 bit word crc(D). The function result is the bit-wise complement of crc(D). Function crc_ccitt uses a table ccitt_table of r(d) values for the polynomials d which represent the single byte values 0x00 to 0xff. It computes r(d) by computing the residues of an iteratively expanded polynomial. The expansion of the processed byte string A by the next byte B from the input byte string happens by shifting the string 8 bits to the left, and by oring B onto bits 0 to 7. In the space of polynomials, the already processed polynomial "a" (image of byte string A) gets expanded by polynomial b (the image of byte B) like this a * X + b where X is (x exp 8), i.e. the single coefficient polynomial of degree 8. The following argumentation uses algebra with commutative, associative and distributive laws. Valid especially with polynomials is this rule: (1): r(a + b) = r(a) + r(b) because r(a) and r(b) are of degree lower than degree(p) and degree(a + b) <= max(degree(a), degree(b)) Further valid are: (2): r(a) = r(r(a)) (3): r(p * a) = 0 The residue of this expanded polynomial can be expressed by means of the residue r(a) which is known from the previous iteration step, and the residue r(b) which may be looked up in ccitt_table. r(a * X + b) = r(p * q(a) * X + r(a) * X + p * q(b) + r(b)) Applying rule (1): = r(p * q(a) * X) + r(r(a) * X) + r(p * q(b)) + r(r(b)) Rule (3) and rule (2): = r(r(a) * X) + r(b) Be h(a) and l(a) chosen so that: r(a) = h(a) * X + l(a), and l(a) has zero coefficients above (x exp 7), and h(a) * X has zero coefficients below (x exp 8). (They correspond to the high and low byte of the 16 bit word crc(A).) So the previous statement can be written as: = r(h(a) * X * X) + r(l(a) * X) + r(b) Since the degree of l(a) is lower than 8, the degree of l(a) * X is lower than 16. Thus it cannot be divisible by p which has degree 16. So: r(l(a) * X) = l(a) * X This yields = l(a) * X + r(h(a) * X * X + b) h(a) * X * X is the polynomial representation of the high byte of 16 bit word crc(A). So in the world of bit patterns the iteration step is: crc(byte string A expanded by byte B) = (low_byte(crc(A)) << 8) ^ crc(high_byte(crc(A)) ^ B) And this is what function crc_ccitt() does, modulo swapping the exor operants and the final bit inversion which is prescribed by ECMA-130 and MMC-3 Annex J. The start value of the table driven byte shifting algorithm may be different from the start value of an equivalent bit shifting algorithm. This is because the final flushing by zero bits is already pre-computed in the table. So the start value of the table driven algorithm must be the CRC of the 0-polynomial under the start value of the bit shifting algorithm. This fact is not of much importance here, because the start value of the bit shifter is 0x0000 which leads to CRC 0x0000 and thus to start value 0x0000 with the table driven byte shifter. */ /* Plain implementation of polynomial division on a Galois field, where addition and subtraction both are binary exor. Euclidian algorithm. Divisor is x^16 + x^12 + x^5 + 1 = 0x11021. This is about ten times slower than the table driven algorithm. */ static int crc_11021(unsigned char *data, int count, int flag) { int acc = 0, i; for (i = 0; i < count * 8 + 16; i++) { acc = (acc << 1); if (i < count * 8) acc |= ((data[i / 8] >> (7 - (i % 8))) & 1); if (acc & 0x10000) acc ^= 0x11021; } return acc; } /* This is my own table driven implementation for which i claim copyright. Copyright (c) 2012 Thomas Schmitt <scdbackup@gmx.net> */ unsigned short crc_ccitt(unsigned char *data, int count) { static unsigned short crc_tab[256], tab_initialized = 0; unsigned short acc = 0; unsigned char b[1]; int i; if (!tab_initialized) { /* Create table of byte residues */ for (i = 0; i < 256; i++) { b[0] = i; crc_tab[i] = crc_11021(b, 1, 0); } tab_initialized = 1; } /* There seems to be a speed advantage on amd64 if (acc << 8) is the second operant of exor, and *(data++) seems faster than data[i]. */ for (i = 0; i < count; i++) acc = crc_tab[(acc >> 8) ^ *(data++)] ^ (acc << 8); /* ECMA-130 22.3.6 and MMC-3 Annex J (CD-TEXT) want the result with inverted bits */ return ~acc; } /* This was the function inherited with libburn-0.2. static unsigned short ccitt_table[256] = { 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7, 0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF, 0x1231, 0x0210, 0x3273, 0x2252, 0x52B5, 0x4294, 0x72F7, 0x62D6, 0x9339, 0x8318, 0xB37B, 0xA35A, 0xD3BD, 0xC39C, 0xF3FF, 0xE3DE, 0x2462, 0x3443, 0x0420, 0x1401, 0x64E6, 0x74C7, 0x44A4, 0x5485, 0xA56A, 0xB54B, 0x8528, 0x9509, 0xE5EE, 0xF5CF, 0xC5AC, 0xD58D, 0x3653, 0x2672, 0x1611, 0x0630, 0x76D7, 0x66F6, 0x5695, 0x46B4, 0xB75B, 0xA77A, 0x9719, 0x8738, 0xF7DF, 0xE7FE, 0xD79D, 0xC7BC, 0x48C4, 0x58E5, 0x6886, 0x78A7, 0x0840, 0x1861, 0x2802, 0x3823, 0xC9CC, 0xD9ED, 0xE98E, 0xF9AF, 0x8948, 0x9969, 0xA90A, 0xB92B, 0x5AF5, 0x4AD4, 0x7AB7, 0x6A96, 0x1A71, 0x0A50, 0x3A33, 0x2A12, 0xDBFD, 0xCBDC, 0xFBBF, 0xEB9E, 0x9B79, 0x8B58, 0xBB3B, 0xAB1A, 0x6CA6, 0x7C87, 0x4CE4, 0x5CC5, 0x2C22, 0x3C03, 0x0C60, 0x1C41, 0xEDAE, 0xFD8F, 0xCDEC, 0xDDCD, 0xAD2A, 0xBD0B, 0x8D68, 0x9D49, 0x7E97, 0x6EB6, 0x5ED5, 0x4EF4, 0x3E13, 0x2E32, 0x1E51, 0x0E70, 0xFF9F, 0xEFBE, 0xDFDD, 0xCFFC, 0xBF1B, 0xAF3A, 0x9F59, 0x8F78, 0x9188, 0x81A9, 0xB1CA, 0xA1EB, 0xD10C, 0xC12D, 0xF14E, 0xE16F, 0x1080, 0x00A1, 0x30C2, 0x20E3, 0x5004, 0x4025, 0x7046, 0x6067, 0x83B9, 0x9398, 0xA3FB, 0xB3DA, 0xC33D, 0xD31C, 0xE37F, 0xF35E, 0x02B1, 0x1290, 0x22F3, 0x32D2, 0x4235, 0x5214, 0x6277, 0x7256, 0xB5EA, 0xA5CB, 0x95A8, 0x8589, 0xF56E, 0xE54F, 0xD52C, 0xC50D, 0x34E2, 0x24C3, 0x14A0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405, 0xA7DB, 0xB7FA, 0x8799, 0x97B8, 0xE75F, 0xF77E, 0xC71D, 0xD73C, 0x26D3, 0x36F2, 0x0691, 0x16B0, 0x6657, 0x7676, 0x4615, 0x5634, 0xD94C, 0xC96D, 0xF90E, 0xE92F, 0x99C8, 0x89E9, 0xB98A, 0xA9AB, 0x5844, 0x4865, 0x7806, 0x6827, 0x18C0, 0x08E1, 0x3882, 0x28A3, 0xCB7D, 0xDB5C, 0xEB3F, 0xFB1E, 0x8BF9, 0x9BD8, 0xABBB, 0xBB9A, 0x4A75, 0x5A54, 0x6A37, 0x7A16, 0x0AF1, 0x1AD0, 0x2AB3, 0x3A92, 0xFD2E, 0xED0F, 0xDD6C, 0xCD4D, 0xBDAA, 0xAD8B, 0x9DE8, 0x8DC9, 0x7C26, 0x6C07, 0x5C64, 0x4C45, 0x3CA2, 0x2C83, 0x1CE0, 0x0CC1, 0xEF1F, 0xFF3E, 0xCF5D, 0xDF7C, 0xAF9B, 0xBFBA, 0x8FD9, 0x9FF8, 0x6E17, 0x7E36, 0x4E55, 0x5E74, 0x2E93, 0x3EB2, 0x0ED1, 0x1EF0 }; unsigned short crc_ccitt(unsigned char *q, int len) { unsigned short crc = 0; while (len-- > 0) crc = ccitt_table[(crc >> 8 ^ *q++) & 0xff] ^ (crc << 8); return ~crc; } */ /* Exploration ts B00214 : ECMA-130, 14.3 "EDC field" "The EDC field shall consist of 4 bytes recorded in positions 2064 to 2067. The error detection code shall be a 32-bit CRC applied on bytes 0 to 2063. The least significant bit of a data byte is used first. The EDC codeword must be divisible by the check polynomial: P(x) = (x^16 + x^15 + x^2 + 1) . (x^16 + x^2 + x + 1) The least significant parity bit (x^0) is stored in the most significant bit position of byte 2067. " Used for raw writing in sector.c ts B20211: Discussion why function crc_32() implements above prescription of ECMA-130. See end of this file for the ofunction inherited with libburn-0.2. The mentioned polynomial product (x^16 + x^15 + x^2 + 1) . (x^16 + x^2 + x + 1) yields this sum of x exponents 32 31 18 16 18 17 4 2 17 16 3 1 16 15 2 0 ====================================== 32 31 16 15 4 3 1 0 (The number of x^18 and x^17 is divisible by two and thus 0 in GF(2).) This yields as 33 bit number: 0x18001801b If above prescription gets implemented straight forward by function crc_18001801b(), then its results match the ones of crc_32() with all test strings which i could invent. The function consists of a conventional polynomial division with reverse input order of bits per byte. Further it swaps the bits in the resulting 32 bit word. That is because sector.c:sector_headers writes the 4 bytes of crc_32() as little endian. The ECMA-130 prescription rather demands big endianness and bit swapping towards the normal bit order in bytes: "The EDC field shall consist of 4 bytes recorded in positions 2064 to 2067. [...] The least significant parity bit (x^0) is stored in the most significant bit position of byte 2067." ----------------------------------------------------------------------- */ /* Overall bit mirroring of a 32 bit word */ unsigned int rfl32(unsigned int acc) { unsigned int inv_acc; int i; inv_acc = 0; for (i = 0; i < 32; i++) if (acc & (1 << i)) inv_acc |= 1 << (31 - i); return inv_acc; } /* Plain implementation of polynomial division on a Galois field, where addition and subtraction both are binary exor. Euclidian algorithm. Divisor is (x^16 + x^15 + x^2 + 1) * (x^16 + x^2 + x + 1). This is about ten times slower than the table driven algorithm. @param flag bit0= do not mirror bits in input bytes and result word (Useful for building the byte indexed CRC table) */ static unsigned int crc_18001801b(unsigned char *data, int count, int flag) { unsigned int acc = 0, top; long int i; unsigned int inv_acc; for (i = 0; i < count * 8 + 32; i++) { top = acc & 0x80000000; acc = (acc << 1); if (i < count * 8) { if (flag & 1) /* Normal bit sequence of input bytes */ acc |= ((data[i / 8] >> (7 - (i % 8))) & 1); else /* Bit sequence of input bytes mirrored */ acc |= ((data[i / 8] >> (i % 8)) & 1); } if (top) acc ^= 0x8001801b; } if (flag & 1) return (unsigned int) (acc & 0xffffffff); /* The bits of the whole 32 bit result are mirrored for ECMA-130 output compliance and for sector.c habit to store CRC little endian although ECMA-130 prescribes it big endian. */ inv_acc = rfl32((unsigned int) acc); return inv_acc; } /* ----------------------------------------------------------------------- Above discussion why crc_ccitt() and crc_11021() yield identical results can be changed from 16 bit to 32 bit by chosing h(a) and l(a) so that: r(a) = h(a) * X * X * X + l(a) h(a) corresponds to the highest byte of crc(A), whereas l(a) corresponds to the lower three bytes of crc(A). This yields r(a * X + b) = l(a) * X + r(h(a) * X * X * X * X + b) h(a) * X * X * X * X is the polynomial representation of the high byte of 32 bit word crc(A). So in the world of bit patterns we have: crc(byte string A expanded by byte B) = (lowest_three_bytes(crc(A)) << 8) ^ crc(high_byte(crc(A)) ^ B) Regrettably this does not yet account for the byte-internal mirroring of bits during the conversion from bit pattern to polynomial, and during conversion from polynomial residue to bit pattern. Be rfl8(D) the result of byte-internal mirroring of bit pattern D, and mirr8(d) its corresponding polynom. Be now h(a) and l(a) chosen so that: r(mirr8(a)) = h(a) * X * X * X + l(a) This corresponds to highest byte and lower three bytes of crc(A). r(mirr8(a) * X + mirr8(b)) = r(h(a) * X * X * X * X) + r(l(a) * X) + r(mirr8(b)) = l(a)) * X + r(h(a) * X * X * X * X + mirr8(b)) The corresponding bit pattern operation is crc(mirrored byte string A expanded by mirrored byte B) = (lowest_three_bytes(crc(A)) << 8) ^ crc(high_byte(crc(A)) ^ rfl8(B)) This demands a final result mirroring to meet the ECMA-130 prescription. rfl8() can be implemented as lookup table. The start value of the bit shifting iteration is 0x00000000, which leads to the same start value for the table driven byte shifting. The following function crc32_by_tab() yields the same results as functions crc_18001801b() and crc_32(): ----------------------------------------------------------------------- */ /* Byte-internal bit mirroring function. */ unsigned int rfl8(unsigned int acc) { unsigned int inv_acc; int i, j; inv_acc = 0; for (j = 0; j < 4; j++) for (i = 0; i < 8; i++) if (acc & (1 << (i + 8 * j))) inv_acc |= 1 << ((7 - i) + 8 * j); return inv_acc; } #ifdef Libburn_with_crc_illustratioN /* Not needed for libburn. The new implementation of function crc_32() is the one that is used. */ unsigned int crc32_by_tab(unsigned char *data, int count, int flag) { static unsigned int crc_tab[256], tab_initialized = 0; static unsigned char mirr_tab[256]; unsigned int acc, inv_acc; unsigned char b[1]; int i; if (!tab_initialized) { for (i = 0; i < 256; i++) { b[0] = i; /* Create table of non-mirrored 0x18001801b residues */ crc_tab[i] = crc_18001801b(b, 1, 1); /* Create table of mirrored byte values */ mirr_tab[i] = rfl8(i); } tab_initialized = 1; } acc = 0; for (i = 0; i < count; i++) acc = (acc << 8) ^ crc_tab[(acc >> 24) ^ mirr_tab[data[i]]]; /* The bits of the whole 32 bit result are mirrored for ECMA-130 output compliance and for sector.c habit to store CRC little endian although ECMA-130 prescribes it big endian. */ inv_acc = rfl32((unsigned int) acc); return inv_acc; } #endif /* Libburn_with_crc_illustratioN */ /* ----------------------------------------------------------------------- Above function yields sufficient performance, nevertheless the old function crc_32() (see below) is faster by avoiding the additional mirror table lookup. A test with 10 times 650 MB on 3000 MHz amd64: crc_18001801b : 187 s crc32_by_tab : 27 s crc_32 : 16 s So how does crc_32() avoid the application of bit mirroring to B ?. Inherited crc_32() performs crc = crc32_table[(crc ^ *data++) & 0xffL] ^ (crc >> 8); Above function crc32_by_tab() would be crc = crc_tab[(crc >> 24) ^ mirr_tab[*data++]] ^ (crc << 8); The shortcut does not change the polynomial representation of the algorithm or the mapping from and to bit patterns. It only mirrors the bit direction in the bytes and in the 32-bit words which are involved in the bit pattern computation. This affects input (which is desired), intermediate state (which is as good as unmirrored), and final output (which would be slightly undesirable if libburn could not use the mirrored result anyway). Instead of the high byte (crc >> 24), the abbreviated algorithm uses the low byte of the mirrored intermediate checksum (crc & 0xffL). Instead of shifting the other three intermediate bytes to the left (crc << 8), the abbreviated algorithm shifts them to the right (crc >> 8). In both cases they overwrite the single byte that was used for computing the table index. The byte indexed table of CRC values needs to hold mirrored 32 bit values. The byte index [(crc ^ *data++) & 0xffL] would need to be mirrored, which would eat up the gain of not mirroring the input bytes. But this mirroring can be pre-computed into the table by exchanging each value with the value of its mirrored index. So this relation exists between the CRC table crc_tab[] of crc32_by_tab() and the table crc32_table[] of the abbreviated algorithm crc_32(): crc_tab[i] == rfl32(crc32_table[rfl8(i)]) for i={0..255}. I compared the generated table in crc32_by_tab() by this test for (i = 0; i < 256; i++) { if (rfl32(crc_tab[rfl8(i)]) != crc32_table[i] || crc_tab[i] != rfl32(crc32_table[rfl8(i)])) { printf("DEVIATION : i = %d\n", i); exit(1); } } No screaming abort happened. ----------------------------------------------------------------------- */ /* This is my own mirrored table implementation for which i claim copyright. With gcc -O2 it shows the same efficiency as the inherited implementation below. With -O3, -O1, or -O0 it is only slightly slower. Copyright (c) 2012 Thomas Schmitt <scdbackup@gmx.net> */ unsigned int crc_32(unsigned char *data, int count) { static unsigned int crc_tab[256], tab_initialized = 0; unsigned int acc = 0; unsigned char b[1]; int i; if (!tab_initialized) { /* Create table of mirrored 0x18001801b residues in bit-mirrored index positions. */ for (i = 0; i < 256; i++) { b[0] = i; crc_tab[rfl8(i)] = rfl32(crc_18001801b(b, 1, 1)); } tab_initialized = 1; } for (i = 0; i < count; i++) acc = (acc >> 8) ^ crc_tab[(acc & 0xff) ^ data[i]]; /* The bits of the whole 32 bit result stay mirrored for ECMA-130 output 8-bit mirroring and for sector.c habit to store the CRC little endian although ECMA-130 prescribes it big endian. */ return acc; } /* ----------------------------------------------------------------------- This was the function inherited with libburn-0.2 which implements the abbreviated algorithm. Its obscure existence led me to above insights. My compliments to the (unknown) people who invented this. unsigned long crc32_table[256] = { 0x00000000L, 0x90910101L, 0x91210201L, 0x01B00300L, 0x92410401L, 0x02D00500L, 0x03600600L, 0x93F10701L, 0x94810801L, 0x04100900L, 0x05A00A00L, 0x95310B01L, 0x06C00C00L, 0x96510D01L, 0x97E10E01L, 0x07700F00L, 0x99011001L, 0x09901100L, 0x08201200L, 0x98B11301L, 0x0B401400L, 0x9BD11501L, 0x9A611601L, 0x0AF01700L, 0x0D801800L, 0x9D111901L, 0x9CA11A01L, 0x0C301B00L, 0x9FC11C01L, 0x0F501D00L, 0x0EE01E00L, 0x9E711F01L, 0x82012001L, 0x12902100L, 0x13202200L, 0x83B12301L, 0x10402400L, 0x80D12501L, 0x81612601L, 0x11F02700L, 0x16802800L, 0x86112901L, 0x87A12A01L, 0x17302B00L, 0x84C12C01L, 0x14502D00L, 0x15E02E00L, 0x85712F01L, 0x1B003000L, 0x8B913101L, 0x8A213201L, 0x1AB03300L, 0x89413401L, 0x19D03500L, 0x18603600L, 0x88F13701L, 0x8F813801L, 0x1F103900L, 0x1EA03A00L, 0x8E313B01L, 0x1DC03C00L, 0x8D513D01L, 0x8CE13E01L, 0x1C703F00L, 0xB4014001L, 0x24904100L, 0x25204200L, 0xB5B14301L, 0x26404400L, 0xB6D14501L, 0xB7614601L, 0x27F04700L, 0x20804800L, 0xB0114901L, 0xB1A14A01L, 0x21304B00L, 0xB2C14C01L, 0x22504D00L, 0x23E04E00L, 0xB3714F01L, 0x2D005000L, 0xBD915101L, 0xBC215201L, 0x2CB05300L, 0xBF415401L, 0x2FD05500L, 0x2E605600L, 0xBEF15701L, 0xB9815801L, 0x29105900L, 0x28A05A00L, 0xB8315B01L, 0x2BC05C00L, 0xBB515D01L, 0xBAE15E01L, 0x2A705F00L, 0x36006000L, 0xA6916101L, 0xA7216201L, 0x37B06300L, 0xA4416401L, 0x34D06500L, 0x35606600L, 0xA5F16701L, 0xA2816801L, 0x32106900L, 0x33A06A00L, 0xA3316B01L, 0x30C06C00L, 0xA0516D01L, 0xA1E16E01L, 0x31706F00L, 0xAF017001L, 0x3F907100L, 0x3E207200L, 0xAEB17301L, 0x3D407400L, 0xADD17501L, 0xAC617601L, 0x3CF07700L, 0x3B807800L, 0xAB117901L, 0xAAA17A01L, 0x3A307B00L, 0xA9C17C01L, 0x39507D00L, 0x38E07E00L, 0xA8717F01L, 0xD8018001L, 0x48908100L, 0x49208200L, 0xD9B18301L, 0x4A408400L, 0xDAD18501L, 0xDB618601L, 0x4BF08700L, 0x4C808800L, 0xDC118901L, 0xDDA18A01L, 0x4D308B00L, 0xDEC18C01L, 0x4E508D00L, 0x4FE08E00L, 0xDF718F01L, 0x41009000L, 0xD1919101L, 0xD0219201L, 0x40B09300L, 0xD3419401L, 0x43D09500L, 0x42609600L, 0xD2F19701L, 0xD5819801L, 0x45109900L, 0x44A09A00L, 0xD4319B01L, 0x47C09C00L, 0xD7519D01L, 0xD6E19E01L, 0x46709F00L, 0x5A00A000L, 0xCA91A101L, 0xCB21A201L, 0x5BB0A300L, 0xC841A401L, 0x58D0A500L, 0x5960A600L, 0xC9F1A701L, 0xCE81A801L, 0x5E10A900L, 0x5FA0AA00L, 0xCF31AB01L, 0x5CC0AC00L, 0xCC51AD01L, 0xCDE1AE01L, 0x5D70AF00L, 0xC301B001L, 0x5390B100L, 0x5220B200L, 0xC2B1B301L, 0x5140B400L, 0xC1D1B501L, 0xC061B601L, 0x50F0B700L, 0x5780B800L, 0xC711B901L, 0xC6A1BA01L, 0x5630BB00L, 0xC5C1BC01L, 0x5550BD00L, 0x54E0BE00L, 0xC471BF01L, 0x6C00C000L, 0xFC91C101L, 0xFD21C201L, 0x6DB0C300L, 0xFE41C401L, 0x6ED0C500L, 0x6F60C600L, 0xFFF1C701L, 0xF881C801L, 0x6810C900L, 0x69A0CA00L, 0xF931CB01L, 0x6AC0CC00L, 0xFA51CD01L, 0xFBE1CE01L, 0x6B70CF00L, 0xF501D001L, 0x6590D100L, 0x6420D200L, 0xF4B1D301L, 0x6740D400L, 0xF7D1D501L, 0xF661D601L, 0x66F0D700L, 0x6180D800L, 0xF111D901L, 0xF0A1DA01L, 0x6030DB00L, 0xF3C1DC01L, 0x6350DD00L, 0x62E0DE00L, 0xF271DF01L, 0xEE01E001L, 0x7E90E100L, 0x7F20E200L, 0xEFB1E301L, 0x7C40E400L, 0xECD1E501L, 0xED61E601L, 0x7DF0E700L, 0x7A80E800L, 0xEA11E901L, 0xEBA1EA01L, 0x7B30EB00L, 0xE8C1EC01L, 0x7850ED00L, 0x79E0EE00L, 0xE971EF01L, 0x7700F000L, 0xE791F101L, 0xE621F201L, 0x76B0F300L, 0xE541F401L, 0x75D0F500L, 0x7460F600L, 0xE4F1F701L, 0xE381F801L, 0x7310F900L, 0x72A0FA00L, 0xE231FB01L, 0x71C0FC00L, 0xE151FD01L, 0xE0E1FE01L, 0x7070FF00L }; unsigned int crc_32(unsigned char *data, int len) { unsigned int crc = 0; while (len-- > 0) crc = crc32_table[(crc ^ *data++) & 0xffL] ^ (crc >> 8); return crc; } */ ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������libburn-1.4.2/libburn/mmc.c�������������������������������������������������������������������������0000644�0001757�0001751�00000454465�12652644224�012512� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */ /* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens Copyright (c) 2006 - 2015 Thomas Schmitt <scdbackup@gmx.net> Provided under GPL version 2 or later. */ #ifdef HAVE_CONFIG_H #include "../config.h" #endif /* ts A61009 */ /* #include <a ssert.h> */ #include <stdio.h> #include <string.h> #include <unistd.h> #include <stdlib.h> #include <sys/time.h> #include <pthread.h> #include <ctype.h> /* ts B41126 : O_BINARY is needed for Cygwin but undefined elsewhere */ #ifndef O_BINARY #define O_BINARY 0 #endif #include "error.h" #include "sector.h" #include "libburn.h" #include "transport.h" #include "mmc.h" #include "spc.h" #include "drive.h" #include "debug.h" #include "toc.h" #include "structure.h" #include "options.h" #include "util.h" #include "init.h" /* ts A70223 : in init.c */ extern int burn_support_untested_profiles; static int mmc_get_configuration_al(struct burn_drive *d, int *alloc_len); #ifdef Libburn_log_in_and_out_streaM /* <<< ts A61031 */ #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #endif /* Libburn_log_in_and_out_streaM */ /* ts A61005 */ #include "libdax_msgs.h" extern struct libdax_msgs *libdax_messenger; /* ts A61219 : Based on knowlege from dvd+rw-tools-7.0 and mmc5r03c.pdf */ #define Libburn_support_dvd_plus_rW 1 /* ts A61229 */ #define Libburn_support_dvd_minusrw_overW 1 /* ts A70112 */ /* ts A80410 : applies to BD-RE too */ #define Libburn_support_dvd_raM 1 /* ts A70129 */ #define Libburn_support_dvd_r_seQ 1 /* ts A70306 */ #define Libburn_support_dvd_plus_R 1 /* ts A70509 : handling 0x41 as read-only type */ #define Libburn_support_bd_r_readonlY 1 /* ts A81208 */ #define Libburn_support_bd_plus_r_srM 1 /* ts A80410 : <<< Dangerous experiment: Pretend that DVD-RAM is BD-RE # define Libburn_dvd_ram_as_bd_rE yes */ /* ts A80509 : <<< Experiment: pretend that DVD-ROM and CD-ROM are other media like BD-ROM (0x40), BD-R seq (0x41), BD-R random (0x42) # define Libburn_rom_as_profilE 0x40 */ /* ts A80425 : Prevents command FORMAT UNIT for DVD-RAM or BD-RE. Useful only to test the selection of format descriptors without actually formatting the media. # define Libburn_do_not_format_dvd_ram_or_bd_rE 1 */ /* ts A90603 : Simulate the command restrictions of an old MMC-1 drive # define Libisofs_simulate_old_mmc1_drivE 1 */ /* DVD/BD progress report: ts A61219 : It seems to work with a used (i.e. thoroughly formatted) DVD+RW. Error messages of class DEBUG appear because of inability to read TOC or track info. Nevertheless, the written images verify. ts A61220 : Burned to a virgin DVD+RW by help of new mmc_format_unit() (did not test wether it would work without). Burned to a not completely formatted DVD+RW. (Had worked before without mmc_format_unit() but i did not exceed the formatted range as reported by dvd+rw-mediainfo.) ts A61221 : Speed setting now works for both of my drives. The according functions in dvd+rw-tools are a bit intimidating to the reader. I hope it is possible to leave much of this to the drive. And if it fails ... well, it's only speed setting. :)) ts A61229 : Burned to several DVD-RW formatted to mode Restricted Overwrite by dvd+rw-format. Needs Libburn_support_dvd_minusrw_overW. ts A61230 : Other than growisofs, libburn does not send a mode page 5 for such DVD-RW (which the MMC-5 standard does deprecate) and it really seems to work without such a page. ts A70101 : Formatted DVD-RW media. Success is varying with media, but dvd+rw-format does not do better with the same media. ts A70112 : Support for writing to DVD-RAM. ts A70130 : Burned a first non-multi sequential DVD-RW. Feature 0021h Incremental Recording vanishes after that and media thus gets not recognized as suitable any more. After a run with -multi another disc still offers 0021h . dvd+rw-mediainfo shows two tracks. The second, an afio archive is readable by afio. Third and forth veryfy too. Suddenly dvd+rw-mediainfo sees lba 0 with track 2. But #2 still verifies if one knows its address. ts A70203 : DVD-RW need to get blanked fully. Then feature 0021h persists. Meanwhile Incremental streaming is supported like CD TAO: with unpredicted size, multi-track, multi-session. ts A70205 : Beginning to implement DVD-R[W] DAO : single track and session, size prediction mandatory. ts A70208 : Finally made tests with DVD-R. Worked exactly as new DVD-RW. ts A70306 : Implemented DVD+R (always -multi for now) ts A70330 : Allowed finalizing of DVD+R. ts A80228 : Made DVD+R/DL support official after nightmorph reported success in http://libburnia-project.org/ticket/13 ts A80416 : drive->do_stream_recording brings DVD-RAM to full nominal writing speed at cost of no defect management. ts A80416 : Giulio Orsero reports success with BD-RE writing. With drive->do_stream_recording it does full nominal speed. ts A80506 : Giulio Orsero reports success with BD-RE formatting. BD-RE is now an officially supported profile. ts A81209 : The first two sessions have been written to BD-R SRM (auto formatted without Defect Management). ts A90107 : BD-R is now supported media type */ /* ts A70519 : With MMC commands of data direction FROM_DRIVE: Made struct command.dxfer_len equal to Allocation Length of MMC commands. Made sure that not more bytes are allowed for transfer than there are available. */ /* ts A70711 Trying to keep writing from clogging the SCSI driver due to full buffer at burner drive: 0=waiting disabled, 1=enabled These are only defaults which can be overwritten by burn_drive_set_buffer_waiting() */ #define Libburn_wait_for_buffer_freE 0 #define Libburn_wait_for_buffer_min_useC 10000 #define Libburn_wait_for_buffer_max_useC 100000 #define Libburn_wait_for_buffer_tio_seC 120 #define Libburn_wait_for_buffer_min_perC 65 #define Libburn_wait_for_buffer_max_perC 95 /* ts B31107 The minimum values to be applied if maximum read speed is requested. Some drives tell only the currently set speed and thus cannot be made faster by using the highest told value. (The fractions get added or subtracted to yield an integer number on the safe side of the intended limit.) */ #define Libburn_cd_max_read_speeD (52 * 150) #define Libburn_dvd_max_read_speeD (24 * 1385) #define Libburn_bd_max_read_speeD (20 * 4495.625 + 0.5) /* ts B31114 The maximum values for minimum speed */ #define Libburn_cd_min_read_speeD ( 1 * 150) #define Libburn_dvd_min_read_speeD ( 1 * 1385) #define Libburn_bd_min_read_speeD ( 1 * 4495.625 - 0.625) static unsigned char MMC_GET_MSINFO[] = { 0x43, 0, 1, 0, 0, 0, 0, 16, 0, 0 }; static unsigned char MMC_GET_TOC[] = { 0x43, 2, 2, 0, 0, 0, 0, 16, 0, 0 }; static unsigned char MMC_GET_TOC_FMT0[] = { 0x43, 0, 0, 0, 0, 0, 0, 16, 0, 0 }; static unsigned char MMC_GET_ATIP[] = { 0x43, 2, 4, 0, 0, 0, 0, 16, 0, 0 }; static unsigned char MMC_GET_LEADTEXT[] = { 0x43, 2, 5, 0, 0, 0, 0, 4, 0, 0 }; static unsigned char MMC_GET_DISC_INFO[] = { 0x51, 0, 0, 0, 0, 0, 0, 16, 0, 0 }; static unsigned char MMC_READ_CD[] = { 0xBE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; static unsigned char MMC_BLANK[] = { 0xA1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; static unsigned char MMC_SEND_OPC[] = { 0x54, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; static unsigned char MMC_SET_SPEED[] = { 0xBB, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; static unsigned char MMC_WRITE_12[] = { 0xAA, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; static unsigned char MMC_WRITE_10[] = { 0x2A, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; /* ts A61201 : inserted 0, before 16, */ static unsigned char MMC_GET_CONFIGURATION[] = { 0x46, 0, 0, 0, 0, 0, 0, 16, 0, 0 }; static unsigned char MMC_SYNC_CACHE[] = { 0x35, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; static unsigned char MMC_GET_EVENT[] = { 0x4A, 1, 0, 0, 0x7e, 0, 0, 0, 8, 0 }; static unsigned char MMC_CLOSE[] = { 0x5B, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; static unsigned char MMC_TRACK_INFO[] = { 0x52, 0, 0, 0, 0, 0, 0, 16, 0, 0 }; static unsigned char MMC_SEND_CUE_SHEET[] = { 0x5D, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; /* ts A61023 : get size and free space of drive buffer */ static unsigned char MMC_READ_BUFFER_CAPACITY[] = { 0x5C, 0, 0, 0, 0, 0, 0, 16, 0, 0 }; /* ts A61219 : format DVD+RW (and various others) */ static unsigned char MMC_FORMAT_UNIT[] = { 0x04, 0x11, 0, 0, 0, 0 }; /* ts A61221 : To set speed for DVD media (0xBB is for CD but works on my LG GSA drive) */ static unsigned char MMC_SET_STREAMING[] = { 0xB6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* ts A61225 : To obtain write speed descriptors (command can do other things too) */ static unsigned char MMC_GET_PERFORMANCE[] = { 0xAC, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* ts A70108 : To obtain info about drive and media formatting opportunities */ static unsigned char MMC_READ_FORMAT_CAPACITIES[] = { 0x23, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* ts A70205 : To describe the layout of a DVD-R[W] DAO session */ static unsigned char MMC_RESERVE_TRACK[] = { 0x53, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* ts A70812 : Read data sectors (for types with 2048 bytes/sector only) */ static unsigned char MMC_READ_10[] = { 0x28, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* ts A81210 : Determine the upper limit of readable data size */ static unsigned char MMC_READ_CAPACITY[] = { 0x25, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* ts A90903 : Obtain media type specific information. E.g. manufacturer. */ static unsigned char MMC_READ_DISC_STRUCTURE[] = { 0xAD, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* ts B21125 : An alternative to BEh READ CD */ static unsigned char MMC_READ_CD_MSF[] = { 0xB9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; static int mmc_function_spy_do_tell = 0; int mmc_function_spy(struct burn_drive *d, char * text) { if (mmc_function_spy_do_tell) fprintf(stderr,"libburn: experimental: mmc_function_spy: %s\n", text); if (d == NULL) return 1; if (d->drive_role != 1) { char msg[4096]; sprintf(msg, "Emulated drive caught in SCSI adapter \"%s\"", text); libdax_msgs_submit(libdax_messenger, d->global_index, 0x0002014c, LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH, msg, 0, 0); d->cancel = 1; return 0; } return 1; } int mmc_function_spy_ctrl(int do_tell) { mmc_function_spy_do_tell= !!do_tell; return 1; } /* ts A70201 */ int mmc_four_char_to_int(unsigned char *data) { return (data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3]; } /* ts A70201 */ int mmc_int_to_four_char(unsigned char *data, int num) { data[0] = (num >> 24) & 0xff; data[1] = (num >> 16) & 0xff; data[2] = (num >> 8) & 0xff; data[3] = num & 0xff; return 1; } static int mmc_start_for_bit0 = 0; /* @param flag bit0= the calling function should need no START UNIT. (Handling depends on mmc_start_for_bit0) */ int mmc_start_if_needed(struct burn_drive *d, int flag) { if (!d->is_stopped) return 2; if ((flag & 1) && !mmc_start_for_bit0) return 2; d->start_unit(d); d->is_stopped = 0; return 1; } int mmc_send_cue_sheet(struct burn_drive *d, struct cue_sheet *s) { struct buffer *buf = NULL; struct command *c; c = &(d->casual_command); mmc_start_if_needed(d, 0); if (mmc_function_spy(d, "mmc_send_cue_sheet") <= 0) return 0; BURN_ALLOC_MEM_VOID(buf, struct buffer, 1); scsi_init_command(c, MMC_SEND_CUE_SHEET, sizeof(MMC_SEND_CUE_SHEET)); c->retry = 1; c->page = buf; c->page->bytes = s->count * 8; c->page->sectors = 0; c->opcode[6] = (c->page->bytes >> 16) & 0xFF; c->opcode[7] = (c->page->bytes >> 8) & 0xFF; c->opcode[8] = c->page->bytes & 0xFF; c->dir = TO_DRIVE; memcpy(c->page->data, s->data, c->page->bytes); d->issue_command(d, c); ex:; BURN_FREE_MEM(buf); if (c->error) { d->cancel = 1; scsi_notify_error(d, c, c->sense, 18, 2); } return !c->error; } /* ts A70205 : Announce size of a DVD-R[W] DAO session. @param size The size in bytes to be announced to the drive. It will get rounded up to align to 32 KiB. */ int mmc_reserve_track(struct burn_drive *d, off_t size) { struct command *c; int lba; char msg[80]; c = &(d->casual_command); mmc_start_if_needed(d, 0); if (mmc_function_spy(d, "mmc_reserve_track") <= 0) return 0; scsi_init_command(c, MMC_RESERVE_TRACK, sizeof(MMC_RESERVE_TRACK)); c->retry = 1; lba = size / 2048; if (size % 2048) lba++; mmc_int_to_four_char(c->opcode+5, lba); sprintf(msg, "reserving track of %d blocks", lba); libdax_msgs_submit(libdax_messenger, -1, 0x00000002, LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_ZERO, msg, 0, 0); c->page = NULL; c->dir = NO_TRANSFER; c->timeout = Libburn_mmc_reserve_timeouT; d->issue_command(d, c); if (c->error) { d->cancel = 1; scsi_notify_error(d, c, c->sense, 18, 2); } return !c->error; } /* ts A70201 : Common track info fetcher for mmc_get_nwa() and mmc_fake_toc() */ int mmc_read_track_info(struct burn_drive *d, int trackno, struct buffer *buf, int alloc_len) { struct command *c; c = &(d->casual_command); mmc_start_if_needed(d, 1); if (mmc_function_spy(d, "mmc_read_track_info") <= 0) return 0; scsi_init_command(c, MMC_TRACK_INFO, sizeof(MMC_TRACK_INFO)); c->dxfer_len = alloc_len; c->opcode[7] = (c->dxfer_len >> 8) & 0xff; c->opcode[8] = c->dxfer_len & 0xff; c->retry = 1; c->opcode[1] = 1; if(trackno<=0) { if (d->current_profile == 0x1a || d->current_profile == 0x13 || d->current_profile == 0x12 || d->current_profile == 0x42 || d->current_profile == 0x43) /* DVD+RW , DVD-RW restricted overwrite , DVD-RAM BD-R random recording, BD-RE */ trackno = 1; else if (d->current_profile == 0x10 || d->current_profile == 0x11 || d->current_profile == 0x14 || d->current_profile == 0x15 || d->current_profile == 0x40 || d->current_profile == 0x41) /* DVD-ROM , DVD-R[W] Sequential , BD-ROM , BD-R sequential */ trackno = d->last_track_no; else /* mmc5r03c.pdf: valid only for CD, DVD+R, DVD+R DL */ trackno = 0xFF; } mmc_int_to_four_char(c->opcode + 2, trackno); c->page = buf; memset(buf->data, 0, BUFFER_SIZE); c->dir = FROM_DRIVE; d->issue_command(d, c); if (c->error) return 0; return 1; } /* ts A61110 : added parameters trackno, lba, nwa. Redefined return value. @return 1=nwa is valid , 0=nwa is not valid , -1=error */ /* ts A70201 : outsourced 52h READ TRACK INFO command */ int mmc_get_nwa(struct burn_drive *d, int trackno, int *lba, int *nwa) { struct buffer *buf = NULL; int ret, num, alloc_len = 20, err; unsigned char *data; char *msg = NULL; if (trackno <= 0) d->next_track_damaged = 0; mmc_start_if_needed(d, 1); if (mmc_function_spy(d, "mmc_get_nwa") <= 0) {ret = -1; goto ex;} /* ts B00327 : Avoid to inquire unsuitable media states */ if (d->status != BURN_DISC_BLANK && d->status != BURN_DISC_APPENDABLE) {ret = 0; goto ex;} BURN_ALLOC_MEM(buf, struct buffer, 1); ret = mmc_read_track_info(d, trackno, buf, alloc_len); if (ret <= 0) goto ex; data = buf->data; *lba = mmc_four_char_to_int(data + 8); *nwa = mmc_four_char_to_int(data + 12); 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 /* >>> memorize track mode : data[6] & 0xf */; #endif { static int fake_damage = 0; /* bit0= damage on , bit1= NWA_V off */ if (fake_damage & 1) data[5] |= 32; /* Damage bit */ if (fake_damage & 2) data[7] &= ~1; } BURN_ALLOC_MEM(msg, char, 160); if (trackno > 0) sprintf(msg, "Track number %d: ", trackno); else sprintf(msg, "Upcomming track: "); if (d->current_profile == 0x1a || d->current_profile == 0x13 || d->current_profile == 0x12 || d->current_profile == 0x43) { /* overwriteable */ *lba = *nwa = num = 0; } else if (data[5] & 32) { /* ts B10534 : MMC-5 6.27.3.7 Damage Bit */ if (!(data[7] & 1)) { /* NWA_V is set to zero */ /* "not closed due to an incomplete write" */ strcat(msg, "Damaged, not closed and not writable"); err= 0x00020185; } else { /* "may be recorded further in an incremental manner"*/ strcat(msg, "Damaged and not closed"); err= 0x00020186; } libdax_msgs_submit(libdax_messenger, d->global_index, err, LIBDAX_MSGS_SEV_WARNING, LIBDAX_MSGS_PRIO_HIGH, msg, 0, 0); if (trackno <= 0) d->next_track_damaged |= ((!(data[7] & 1)) << 1) | 1; {ret = 0; goto ex;} } else if (!(data[7] & 1)) { /* ts A61106 : MMC-1 Table 142 : NWA_V = NWA Valid Flag */ strcat(msg, "No Next-Writable-Address"); libdax_msgs_submit(libdax_messenger, d->global_index, 0x00020184, LIBDAX_MSGS_SEV_WARNING, LIBDAX_MSGS_PRIO_HIGH, msg, 0, 0); if (trackno <= 0) d->next_track_damaged |= 2; {ret = 0; goto ex;} } if (num > 0) { burn_drive_set_media_capacity_remaining(d, ((off_t) num) * ((off_t) 2048)); d->media_lba_limit = *nwa + num; } else d->media_lba_limit = 0; /* fprintf(stderr, "LIBBURN_DEBUG: media_lba_limit= %d\n", d->media_lba_limit); */ ret = 1; ex: BURN_FREE_MEM(buf); BURN_FREE_MEM(msg); return ret; } /* ts A61009 : function is obviously unused. */ /* void mmc_close_disc(struct burn_drive *d, struct burn_write_opts *o) */ void mmc_close_disc(struct burn_write_opts *o) { struct burn_drive *d = o->drive; if (mmc_function_spy(d, "mmc_close_disc") <= 0) return; libdax_msgs_submit(libdax_messenger, -1, 0x00000002, LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_ZERO, "HOW THAT ? mmc_close_disc() was called", 0, 0); /* ts A61009 : made impossible by removing redundant parameter d */ /* a ssert(o->drive == d); */ o->multi = 0; spc_select_write_params(d, NULL, 0, o); mmc_close(d, 1, 0); } /* ts A61009 : function is obviously unused. */ /* void mmc_close_session(struct burn_drive *d, struct burn_write_opts *o) */ void mmc_close_session(struct burn_write_opts *o) { struct burn_drive *d = o->drive; if (mmc_function_spy(d, "mmc_close_session") <= 0) return; libdax_msgs_submit(libdax_messenger, -1, 0x00000002, LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_ZERO, "HOW THAT ? mmc_close_session() was called", 0, 0); /* ts A61009 : made impossible by removing redundant parameter d */ /* a ssert(o->drive == d); */ o->multi = 3; spc_select_write_params(d, NULL, 0, o); mmc_close(d, 1, 0); } /* ts A70227 : extended meaning of session to address all possible values of 5Bh CLOSE TRACK SESSION to address any Close Function. @param session contains the two high bits of Close Function @param track if not 0: sets the lowest bit of Close Function */ void mmc_close(struct burn_drive *d, int session, int track) { struct command *c; char msg[256]; int key, asc, ascq; c = &(d->casual_command); if (mmc_function_spy(d, "mmc_close") <= 0) return; scsi_init_command(c, MMC_CLOSE, sizeof(MMC_CLOSE)); c->retry = 1; c->opcode[1] |= 1; /* ts A70918 : Immed */ /* (ts A61030 : shifted !!session rather than or-ing plain session ) */ c->opcode[2] = ((session & 3) << 1) | !!track; c->opcode[4] = track >> 8; c->opcode[5] = track & 0xFF; c->page = NULL; c->dir = NO_TRANSFER; c->timeout = Libburn_mmc_close_timeouT; d->issue_command(d, c); /* ts A70918 : Immed : wait for drive to complete command */ if (c->error) { sprintf(msg, "Failed to close %s (%d)", session > 1 ? "disc" : session > 0 ? "session" : "track", ((session & 3) << 1) | !!track); sprintf(msg + strlen(msg), ". SCSI error : "); scsi_error_msg(d, c->sense, 14, msg + strlen(msg), &key, &asc, &ascq); libdax_msgs_submit(libdax_messenger, d->global_index, 0x0002017e, LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH, msg, 0, 0); d->cancel = 1; return; } if (spc_wait_unit_attention(d, 3600, "CLOSE TRACK SESSION", 0) <= 0) d->cancel = 1; } void mmc_get_event(struct burn_drive *d) { struct buffer *buf = NULL; struct command *c; int alloc_len = 8, len, evt_code, loops = 0; unsigned char *evt; c = &(d->casual_command); BURN_ALLOC_MEM_VOID(buf, struct buffer, 1); if (mmc_function_spy(d, "mmc_get_event") <= 0) goto ex; again:; scsi_init_command(c, MMC_GET_EVENT, sizeof(MMC_GET_EVENT)); c->dxfer_len = 8; /* >>> have a burn_drive element for Notification Class */; c->opcode[4] = 0x7e; c->opcode[7] = (c->dxfer_len >> 8) & 0xff; c->opcode[8] = c->dxfer_len & 0xff; c->retry = 1; c->page = buf; c->page->bytes = 0; c->page->sectors = 0; c->dir = FROM_DRIVE; d->issue_command(d, c); if (c->error) goto ex; evt = c->page->data; len = ((evt[0] << 8) | evt[1]) + 2; if (len < 8) goto ex; /* >>> memorize evt[3] in burn_drive element for Notification Class */; if (evt[3] == 0) /* No event */ goto ex; evt_code = evt[4] & 0xf; if (evt_code == 0) /* No change */ goto ex; switch (evt[2] & 7) { case 0: /* no events supported */ goto ex; case 1: /* Operational change */ if (((evt[6] << 8) | evt[7])) { alloc_len = 8; mmc_get_configuration_al(d, &alloc_len); } break; case 2: /* Power Management */ if (evt[5] >= 2) d->start_unit(d); break; case 3: /* External request */ /* >>> report about external request */; break; case 4: /* Media */ if (evt_code == 2) { d->start_unit(d); alloc_len = 8; mmc_get_configuration_al(d, &alloc_len); } break; case 5: /* Multiple Host Events */ /* >>> report about foreign host interference */; break; case 6: /* Device busy */ if (evt_code == 1 && evt[5]) { /* >>> wait the time announced in evt[6],[7] as 100ms units */; } break; default: /* reserved */ break; } loops++; if (loops < 100) goto again; ex:; BURN_FREE_MEM(buf); } /* ts A70711 This has become a little monster because of the creative buffer reports of my LG GSA-4082B : Belated, possibly statistically dampened. But only with DVD media. With CD it is ok. */ static int mmc_wait_for_buffer_free(struct burn_drive *d, struct buffer *buf) { int usec= 0, need, reported_3s = 0, first_wait = 1; struct timeval t0,tnow; struct timezone dummy_tz; double max_fac, min_fac, waiting; /* Enable to get reported waiting activities and total time. #define Libburn_mmc_wfb_debuG 1 */ #ifdef Libburn_mmc_wfb_debuG char sleeplist[32768]; static int buffer_still_invalid = 1; #endif max_fac = ((double) d->wfb_max_percent) / 100.0; /* Buffer info from the drive is valid only after writing has begun. Caring for buffer space makes sense mostly after max_percent of the buffer was transmitted. */ if (d->progress.buffered_bytes <= 0 || d->progress.buffer_capacity <= 0 || d->progress.buffered_bytes + buf->bytes <= d->progress.buffer_capacity * max_fac) return 2; #ifdef Libburn_mmc_wfb_debuG if (buffer_still_invalid) fprintf(stderr, "\nLIBBURN_DEBUG: Buffer considered valid now\n"); buffer_still_invalid = 0; #endif /* The pessimistic counter does not assume any buffer consumption */ if (d->pessimistic_buffer_free - buf->bytes >= ( 1.0 - max_fac) * d->progress.buffer_capacity) return 1; /* There is need to inquire the buffer fill */ d->pessimistic_writes++; min_fac = ((double) d->wfb_min_percent) / 100.0; gettimeofday(&t0, &dummy_tz); #ifdef Libburn_mmc_wfb_debuG sleeplist[0]= 0; sprintf(sleeplist,"(%d%s %d)", (int) (d->pessimistic_buffer_free - buf->bytes), (d->pbf_altered ? "? -" : " -"), (int) ((1.0 - max_fac) * d->progress.buffer_capacity)); #endif while (1) { if ((!first_wait) || d->pbf_altered) { d->pbf_altered = 1; mmc_read_buffer_capacity(d); } #ifdef Libburn_mmc_wfb_debuG if(strlen(sleeplist) < sizeof(sleeplist) - 80) sprintf(sleeplist+strlen(sleeplist)," (%d%s %d)", (int) (d->pessimistic_buffer_free - buf->bytes), (d->pbf_altered ? "? -" : " -"), (int) ((1.0 - min_fac) * d->progress.buffer_capacity)); #endif gettimeofday(&tnow,&dummy_tz); waiting = (tnow.tv_sec - t0.tv_sec) + ((double) (tnow.tv_usec - t0.tv_usec)) / 1.0e6; if (d->pessimistic_buffer_free - buf->bytes >= (1.0 - min_fac) * d->progress.buffer_capacity) { #ifdef Libburn_mmc_wfb_debuG if(strlen(sleeplist) >= sizeof(sleeplist) - 80) strcat(sleeplist," ..."); sprintf(sleeplist+strlen(sleeplist)," -> %d [%.6f]", (int) ( d->pessimistic_buffer_free - buf->bytes - (1.0 - min_fac) * d->progress.buffer_capacity ), waiting); fprintf(stderr, "\nLIBBURN_DEBUG: sleeplist= %s\n",sleeplist); #endif return 1; } /* Waiting is needed */ if (waiting >= 3 && !reported_3s) { libdax_msgs_submit(libdax_messenger, d->global_index, 0x0002013d, LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_LOW, "Waiting for free buffer takes more than 3 seconds", 0,0); reported_3s = 1; } else if (d->wfb_timeout_sec > 0 && waiting > d->wfb_timeout_sec) { d->wait_for_buffer_free = 0; libdax_msgs_submit(libdax_messenger, d->global_index, 0x0002013d, LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH, "Timeout with waiting for free buffer. Now disabled.", 0,0); break; } need = (1.0 - min_fac) * d->progress.buffer_capacity + buf->bytes - d->pessimistic_buffer_free; usec = 0; if (d->nominal_write_speed > 0) usec = ((double) need) / 1000.0 / ((double) d->nominal_write_speed) * 1.0e6; else usec = d->wfb_min_usec * 2; /* >>> learn about buffer progress and adjust usec */ if (usec < (int) d->wfb_min_usec) usec = d->wfb_min_usec; else if (usec > (int) d->wfb_max_usec) usec = d->wfb_max_usec; usleep(usec); if (d->waited_usec < 0xf0000000) d->waited_usec += usec; d->waited_tries++; if(first_wait) d->waited_writes++; #ifdef Libburn_mmc_wfb_debuG if(strlen(sleeplist) < sizeof(sleeplist) - 80) sprintf(sleeplist+strlen(sleeplist)," %d", usec); #endif first_wait = 0; } return 0; } void mmc_write_12(struct burn_drive *d, int start, struct buffer *buf) { struct command *c; int len; c = &(d->casual_command); mmc_start_if_needed(d, 0); if (mmc_function_spy(d, "mmc_write_12") <= 0) return; len = buf->sectors; scsi_init_command(c, MMC_WRITE_12, sizeof(MMC_WRITE_12)); c->retry = 1; mmc_int_to_four_char(c->opcode + 2, start); mmc_int_to_four_char(c->opcode + 6, len); c->page = buf; c->dir = TO_DRIVE; c->timeout = Libburn_scsi_write_timeouT; d->issue_command(d, c); /* ts A70711 */ d->pessimistic_buffer_free -= buf->bytes; d->pbf_altered = 1; } #ifdef Libburn_write_time_debuG static int print_time(int flag) { static struct timeval prev = {0, 0}; struct timeval now; struct timezone tz; int ret, diff; ret = gettimeofday(&now, &tz); if (ret == -1) return 0; if (now.tv_sec - prev.tv_sec < Libburn_scsi_write_timeouT) { diff = (now.tv_sec - prev.tv_sec) * 1000000 + ((int) (now.tv_usec) - (int) prev.tv_usec); fprintf(stderr, "\nlibburn_DEBUG: %d.%-6d : %d\n", (int) now.tv_sec, (int) now.tv_usec, diff); } memcpy(&prev, &now, sizeof(struct timeval)); return 1; } #endif /* Libburn_write_time_debuG */ int mmc_write(struct burn_drive *d, int start, struct buffer *buf) { int cancelled; struct command *c; int len, key, asc, ascq; char *msg = NULL; #ifdef Libburn_write_time_debuG extern int burn_sg_log_scsi; #endif /* fprintf(stderr, "libburn_DEBUG: buffer sectors= %d bytes= %d\n", buf->sectors, buf->bytes); */ c = &(d->casual_command); #ifdef Libburn_log_in_and_out_streaM /* <<< ts A61031 */ static int tee_fd= -1; if(tee_fd==-1) tee_fd= open("/tmp/libburn_sg_written", O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, S_IRUSR | S_IWUSR); #endif /* Libburn_log_in_and_out_streaM */ mmc_start_if_needed(d, 0); if (mmc_function_spy(d, "mmc_write") <= 0) return BE_CANCELLED; cancelled = d->cancel; if (cancelled) return BE_CANCELLED; /* ts A70215 */ if (d->media_lba_limit > 0 && start >= d->media_lba_limit) { msg = calloc(1, 160); if (msg != NULL) { sprintf(msg, "Exceeding range of permissible write addresses (%d >= %d)", start, d->media_lba_limit); libdax_msgs_submit(libdax_messenger, d->global_index, 0x0002012d, LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH, msg, 0, 0); free(msg); } d->cancel = 1; /* No need for mutexing because atomic */ return BE_CANCELLED; } len = buf->sectors; /* ts A61009 : buffer fill problems are to be handled by caller */ /* a ssert(buf->bytes >= buf->sectors);*/ /* can be == at 0... */ /* ts A70711 */ if(d->wait_for_buffer_free) mmc_wait_for_buffer_free(d, buf); #ifdef Libburn_write_time_debuG if (burn_sg_log_scsi & 3) print_time(0); #endif /* ts A80412 */ if(d->do_stream_recording > 0 && start >= d->stream_recording_start) { /* >>> ??? is WRITE12 available ? */ /* >>> ??? inquire feature 107h Stream Writing bit ? */ scsi_init_command(c, MMC_WRITE_12, sizeof(MMC_WRITE_12)); mmc_int_to_four_char(c->opcode + 2, start); mmc_int_to_four_char(c->opcode + 6, len); c->opcode[10] = 1<<7; /* Streaming bit */ } else { scsi_init_command(c, MMC_WRITE_10, sizeof(MMC_WRITE_10)); mmc_int_to_four_char(c->opcode + 2, start); c->opcode[6] = 0; c->opcode[7] = (len >> 8) & 0xFF; c->opcode[8] = len & 0xFF; } c->retry = 1; c->page = buf; c->dir = TO_DRIVE; c->timeout = Libburn_scsi_write_timeouT; #ifdef Libburn_log_in_and_out_streaM /* <<< ts A61031 */ if(tee_fd!=-1) { write(tee_fd, c->page->data, c->page->bytes); } #endif /* Libburn_log_in_and_out_streaM */ d->issue_command(d, c); /* ts A70711 */ d->pessimistic_buffer_free -= buf->bytes; d->pbf_altered = 1; /* ts A61112 : react on eventual error condition */ spc_decode_sense(c->sense, 0, &key, &asc, &ascq); if (c->error && key != 0) { int key, asc, ascq; int err_sev = LIBDAX_MSGS_SEV_FATAL; msg = calloc(1, 256); if (msg != NULL) { sprintf(msg, "SCSI error on write(%d,%d): ", start, len); scsi_error_msg(d, c->sense, 14, msg + strlen(msg), &key, &asc, &ascq); } /* ts B31023 */ /* Memorize if on DVD-RW write mode is TAO/Incremental and error [5 64 00] occurs within the first drive buffer fill. */ if (d->current_profile == 0x14 && d->write_opts != NULL && (d->progress.buffer_capacity == 0 || start < (int) d->progress.buffer_capacity / 2048) && key == 5 && asc == 0x64 && ascq == 0) { if (d->write_opts->write_type == BURN_WRITE_TAO) { d->was_feat21h_failure = 1 + (start == 0); if (d->write_opts->feat21h_fail_sev != 0) err_sev = d->write_opts->feat21h_fail_sev; } } if (msg != NULL) { libdax_msgs_submit(libdax_messenger, d->global_index, 0x0002011d, err_sev, LIBDAX_MSGS_PRIO_HIGH, msg, 0, 0); free(msg); } d->cancel = 1; return BE_CANCELLED; } return 0; } /* ts A70201 : Set up an entry for mmc_fake_toc() */ int mmc_fake_toc_entry(struct burn_toc_entry *entry, int session_number, int track_number, unsigned char *size_data, unsigned char *start_data, unsigned char *last_adr_data) { int min, sec, frames, num; /* mark DVD extensions and Track Info extension as valid */ entry->extensions_valid |= (1 | 2); /* defaults are as of mmc5r03.pdf 6.26.3.2.4 Fabricated TOC */ entry->session = session_number & 0xff; entry->session_msb = (session_number >> 8) & 0xff; entry->adr = 1; entry->control = 4; entry->tno = 0; entry->point = track_number & 0xff; entry->point_msb = (track_number >> 8) & 0xff; num = mmc_four_char_to_int(size_data); entry->track_blocks = num; burn_lba_to_msf(num, &min, &sec, &frames); if (min > 255) { min = 255; sec = 255; frames = 255; } entry->min = min; entry->sec = sec; entry->frame = frames; entry->zero = 0; num = mmc_four_char_to_int(start_data); entry->start_lba = num; burn_lba_to_msf(num, &min, &sec, &frames); if (min > 255) { min = 255; sec = 255; frames = 255; } entry->pmin = min; entry->psec = sec; entry->pframe = frames; entry->last_recorded_address = mmc_four_char_to_int(last_adr_data); return 1; } /* ts A71128 : for DVD-ROM drives which offer no reliable track information */ static int mmc_read_toc_fmt0_al(struct burn_drive *d, int *alloc_len) { struct burn_track *track; struct burn_session *session; struct burn_toc_entry *entry; struct buffer *buf = NULL; struct command *c = NULL; int dlen, i, old_alloc_len, session_number, prev_session = -1, ret; int lba, size; unsigned char *tdata, size_data[4], start_data[4], end_data[4]; if (*alloc_len < 4) {ret = 0; goto ex;} BURN_ALLOC_MEM(buf, struct buffer, 1); BURN_ALLOC_MEM(c, struct command, 1); scsi_init_command(c, MMC_GET_TOC_FMT0, sizeof(MMC_GET_TOC_FMT0)); c->dxfer_len = *alloc_len; c->opcode[7] = (c->dxfer_len >> 8) & 0xff; c->opcode[8] = c->dxfer_len & 0xff; c->retry = 1; c->page = buf; c->page->bytes = 0; c->page->sectors = 0; c->dir = FROM_DRIVE; d->issue_command(d, c); if (c->error) { err_ex:; libdax_msgs_submit(libdax_messenger, d->global_index, 0x0002010d, LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH, "Could not inquire TOC", 0,0); d->status = BURN_DISC_UNSUITABLE; d->toc_entries = 0; /* Prefering memory leaks over fandangos */ d->toc_entry = calloc(1, sizeof(struct burn_toc_entry)); {ret = 0; goto ex;} } dlen = c->page->data[0] * 256 + c->page->data[1]; old_alloc_len = *alloc_len; *alloc_len = dlen + 2; if (old_alloc_len < 12) {ret = 1; goto ex;} if (dlen + 2 > old_alloc_len) dlen = old_alloc_len - 2; d->complete_sessions = 1 + c->page->data[3] - c->page->data[2]; #ifdef Libburn_disc_with_incomplete_sessioN /* ts B30112 : number of open sessions */ d->incomplete_sessions = 0; #endif d->last_track_no = d->complete_sessions; if (dlen - 2 < (d->last_track_no + 1) * 8) { libdax_msgs_submit(libdax_messenger, d->global_index, 0x00020159, LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH, "TOC Format 0 returns inconsistent data", 0,0); goto err_ex; } d->toc_entries = d->last_track_no + d->complete_sessions; if (d->toc_entries < 1) {ret = 0; goto ex;} d->toc_entry = calloc(d->toc_entries, sizeof(struct burn_toc_entry)); if(d->toc_entry == NULL) {ret = 0; goto ex;} d->disc = burn_disc_create(); if (d->disc == NULL) {ret = 0; goto ex;} for (i = 0; i < d->complete_sessions; i++) { session = burn_session_create(); if (session == NULL) {ret = 0; goto ex;} burn_disc_add_session(d->disc, session, BURN_POS_END); burn_session_free(session); } for (i = 0; i < d->last_track_no; i++) { tdata = c->page->data + 4 + i * 8; session_number = i + 1; if (session_number != prev_session && prev_session > 0) { /* leadout entry previous session */ entry = &(d->toc_entry[(i - 1) + prev_session]); lba = mmc_four_char_to_int(start_data) + mmc_four_char_to_int(size_data); mmc_int_to_four_char(start_data, lba); mmc_int_to_four_char(size_data, 0); mmc_int_to_four_char(end_data, lba - 1); mmc_fake_toc_entry(entry, prev_session, 0xA2, size_data, start_data, end_data); entry->min= entry->sec= entry->frame= 0; d->disc->session[prev_session - 1]->leadout_entry = entry; } /* ??? >>> d->media_capacity_remaining , d->media_lba_limit as of mmc_fake_toc() */ entry = &(d->toc_entry[i + session_number - 1]); track = burn_track_create(); if (track == NULL) {ret = -1; goto ex;} burn_session_add_track( d->disc->session[session_number - 1], track, BURN_POS_END); track->entry = entry; burn_track_free(track); memcpy(start_data, tdata + 4, 4); /* size_data are estimated from next track start */ memcpy(size_data, tdata + 8 + 4, 4); mmc_int_to_four_char(end_data, mmc_four_char_to_int(size_data) - 1); size = mmc_four_char_to_int(size_data) - mmc_four_char_to_int(start_data); mmc_int_to_four_char(size_data, size); mmc_fake_toc_entry(entry, session_number, i + 1, size_data, start_data, end_data); if (prev_session != session_number) d->disc->session[session_number - 1]->firsttrack = i+1; d->disc->session[session_number - 1]->lasttrack = i+1; prev_session = session_number; } if (prev_session > 0 && prev_session <= d->disc->sessions) { /* leadout entry of last session of closed disc */ tdata = c->page->data + 4 + d->last_track_no * 8; entry = &(d->toc_entry[(d->last_track_no - 1) + prev_session]); memcpy(start_data, tdata + 4, 4); mmc_int_to_four_char(size_data, 0); mmc_int_to_four_char(end_data, mmc_four_char_to_int(start_data) - 1); mmc_fake_toc_entry(entry, prev_session, 0xA2, size_data, start_data, end_data); entry->min= entry->sec= entry->frame= 0; d->disc->session[prev_session - 1]->leadout_entry = entry; } ret = 1; ex:; BURN_FREE_MEM(buf); BURN_FREE_MEM(c); return ret; } /* ts A71128 : for DVD-ROM drives which offer no reliable track information */ static int mmc_read_toc_fmt0(struct burn_drive *d) { int alloc_len = 4, ret; mmc_start_if_needed(d, 1); if (mmc_function_spy(d, "mmc_read_toc_fmt0") <= 0) return -1; ret = mmc_read_toc_fmt0_al(d, &alloc_len); if (alloc_len >= 12) ret = mmc_read_toc_fmt0_al(d, &alloc_len); return ret; } /* ts A70131 : compose a disc TOC structure from d->complete_sessions and 52h READ TRACK INFORMATION */ int mmc_fake_toc(struct burn_drive *d) { struct burn_track *track; struct burn_session *session; struct burn_toc_entry *entry; struct buffer *buf = NULL; int i, session_number, prev_session = -1, ret, lba, alloc_len = 34; unsigned char *tdata, size_data[4], start_data[4], end_data[4]; char *msg = NULL; if (mmc_function_spy(d, "mmc_fake_toc") <= 0) {ret = -1; goto ex;} BURN_ALLOC_MEM(buf, struct buffer, 1); #ifdef Libburn_disc_with_incomplete_sessioN if (d->last_track_no <= 0 || d->complete_sessions + d->incomplete_sessions <= 0 || d->status == BURN_DISC_BLANK) {ret = 2; goto ex;} #else if (d->last_track_no <= 0 || d->complete_sessions <= 0 || d->status == BURN_DISC_BLANK) {ret = 2; goto ex;} #endif /* ! Libburn_disc_with_incomplete_sessioN */ if (d->last_track_no > BURN_MMC_FAKE_TOC_MAX_SIZE) { msg = calloc(1, 160); if (msg != NULL) { sprintf(msg, "Too many logical tracks recorded (%d , max. %d)\n", d->last_track_no, BURN_MMC_FAKE_TOC_MAX_SIZE); libdax_msgs_submit(libdax_messenger, d->global_index, 0x0002012c, LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH, msg, 0,0); free(msg); } {ret = 0; goto ex;} } /* ts A71128 : My DVD-ROM drive issues no reliable track info. One has to try 43h READ TOC/PMA/ATIP Form 0. */ if ((d->current_profile == 0x10) && d->last_track_no <= 1) { ret = mmc_read_toc_fmt0(d); goto ex; } d->disc = burn_disc_create(); if (d->disc == NULL) {ret = -1; goto ex;} d->toc_entries = d->last_track_no + d->complete_sessions + d->incomplete_sessions; d->toc_entry = calloc(d->toc_entries, sizeof(struct burn_toc_entry)); if (d->toc_entry == NULL) {ret = -1; goto ex;} memset(d->toc_entry, 0,d->toc_entries * sizeof(struct burn_toc_entry)); #ifdef Libburn_disc_with_incomplete_sessioN for (i = 0; i < d->complete_sessions + d->incomplete_sessions; i++) { #else for (i = 0; i < d->complete_sessions; i++) { #endif session = burn_session_create(); if (session == NULL) {ret = -1; goto ex;} burn_disc_add_session(d->disc, session, BURN_POS_END); burn_session_free(session); } #ifdef Libburn_disc_with_incomplete_sessioN d->disc->incomplete_sessions = d->incomplete_sessions; #endif memset(size_data, 0, 4); memset(start_data, 0, 4); /* Entry Layout : session 1 track 1 entry 0 ... session 1 track N entry N-1 leadout 1 entry N session 2 track N+1 entry N+1 ... session 2 track M+1 entry M+1 leadout 2 entry M+2 session X track K entry (K-1)+(X-1) ... session X track i+1 entry i+(X-1) leadout X entry i+X */ for (i = 0; i < d->last_track_no; i++) { ret = mmc_read_track_info(d, i+1, buf, alloc_len); if (ret <= 0) goto ex; tdata = buf->data; session_number = (tdata[33] << 8) | tdata[3]; if (session_number <= 0) continue; if (session_number != prev_session && prev_session > 0) { /* leadout entry previous session */ entry = &(d->toc_entry[(i - 1) + prev_session]); lba = mmc_four_char_to_int(start_data) + mmc_four_char_to_int(size_data); mmc_int_to_four_char(start_data, lba); mmc_int_to_four_char(size_data, 0); mmc_int_to_four_char(end_data, lba - 1); mmc_fake_toc_entry(entry, prev_session, 0xA2, size_data, start_data, end_data); entry->min= entry->sec= entry->frame= 0; d->disc->session[prev_session - 1]->leadout_entry = entry; } #ifdef Libburn_disc_with_incomplete_sessioN if (session_number > d->complete_sessions) { #else if (session_number > d->disc->sessions) { #endif if (i == d->last_track_no - 1) { /* ts A70212 : Last track field Free Blocks */ burn_drive_set_media_capacity_remaining(d, ((off_t) mmc_four_char_to_int(tdata + 16)) * ((off_t) 2048)); d->media_lba_limit = 0; } #ifdef Libburn_disc_with_incomplete_sessioN if (session_number > d->disc->sessions ) continue; #else continue; #endif } entry = &(d->toc_entry[i + session_number - 1]); track = burn_track_create(); if (track == NULL) {ret = -1; goto ex;} burn_session_add_track( d->disc->session[session_number - 1], track, BURN_POS_END); track->entry = entry; burn_track_free(track); memcpy(size_data, tdata + 24, 4); memcpy(start_data, tdata + 8, 4); memcpy(end_data, tdata + 28, 4); mmc_fake_toc_entry(entry, session_number, i + 1, size_data, start_data, end_data); entry->track_status_bits = tdata[5] | (tdata[6] << 8) | (tdata[7] << 16); entry->extensions_valid |= 4; if (prev_session != session_number) d->disc->session[session_number - 1]->firsttrack = i+1; d->disc->session[session_number - 1]->lasttrack = i+1; prev_session = session_number; } if (prev_session > 0 && prev_session <= d->disc->sessions) { /* leadout entry of last session of closed disc */ entry = &(d->toc_entry[(d->last_track_no - 1) + prev_session]); lba = mmc_four_char_to_int(start_data) + mmc_four_char_to_int(size_data); mmc_int_to_four_char(start_data, lba); mmc_int_to_four_char(size_data, 0); mmc_int_to_four_char(end_data, lba - 1); mmc_fake_toc_entry(entry, prev_session, 0xA2, size_data, start_data, end_data); entry->min= entry->sec= entry->frame= 0; d->disc->session[prev_session - 1]->leadout_entry = entry; } ret = 1; ex:; BURN_FREE_MEM(buf); return ret; } static int mmc_read_toc_al(struct burn_drive *d, int *alloc_len) { /* read full toc, all sessions, in m/s/f form, 4k buffer */ /* ts A70201 : or fake a toc from track information */ struct burn_track *track; struct burn_session *session; struct buffer *buf = NULL; struct command *c = NULL; int dlen; int i, old_alloc_len, t_idx, ret; unsigned char *tdata; char *msg = NULL; if (*alloc_len < 4) {ret = 0; goto ex;} BURN_ALLOC_MEM(buf, struct buffer, 1); BURN_ALLOC_MEM(c, struct command, 1); BURN_ALLOC_MEM(msg, char, 321); if (!(d->current_profile == -1 || d->current_is_cd_profile)) { /* ts A70131 : MMC_GET_TOC uses Response Format 2 For DVD this fails with 5,24,00 */ /* mmc_read_toc_fmt0() uses Response Format 0: mmc5r03.pdf 6.26.3.2 which does not yield the same result with the same disc on different drives. */ /* ts A70201 : This uses the session count from 51h READ DISC INFORMATION and the track records from 52h READ TRACK INFORMATION. mmc_read_toc_fmt0() is used as fallback for dull DVD-ROM. */ mmc_fake_toc(d); if (d->status == BURN_DISC_UNREADY) d->status = BURN_DISC_FULL; {ret = 1; goto ex;} } /* ts A90823: SanDisk Cruzer U3 memory stick stalls on format 2. Format 0 seems to be more conservative with read-only drives. */ if (!((d->mdata->p2a_valid > 0 && d->mdata->cdrw_write) || d->current_profile != 0x08)) { ret = mmc_read_toc_fmt0(d); goto ex; } scsi_init_command(c, MMC_GET_TOC, sizeof(MMC_GET_TOC)); c->dxfer_len = *alloc_len; c->opcode[7] = (c->dxfer_len >> 8) & 0xff; c->opcode[8] = c->dxfer_len & 0xff; c->retry = 1; c->page = buf; c->page->bytes = 0; c->page->sectors = 0; c->dir = FROM_DRIVE; d->issue_command(d, c); if (c->error) { /* ts A61020 : this snaps on non-blank DVD media */ /* ts A61106 : also snaps on CD with unclosed track/session */ /* Very unsure wether this old measure is ok. Obviously higher levels do not care about this. outdated info: DVD+RW burns go on after passing through here. d->busy = BURN_DRIVE_IDLE; */ libdax_msgs_submit(libdax_messenger, d->global_index, 0x0002010d, LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH, "Could not inquire TOC", 0,0); d->status = BURN_DISC_UNSUITABLE; d->toc_entries = 0; /* Prefering memory leaks over fandangos */ d->toc_entry = calloc(1, sizeof(struct burn_toc_entry)); {ret = 0; goto ex;} } dlen = c->page->data[0] * 256 + c->page->data[1]; old_alloc_len = *alloc_len; *alloc_len = dlen + 2; if (old_alloc_len < 15) {ret = 1; goto ex;} if (dlen + 2 > old_alloc_len) dlen = old_alloc_len - 2; d->toc_entries = (dlen - 2) / 11; if (d->toc_entries < 1) {ret = 0; goto ex;} /* some drives fail this check. ts A61007 : if re-enabled then not via Assert. a ssert(((dlen - 2) % 11) == 0); */ /* ts A81202: plus number of sessions as reserve for leadout default */ d->toc_entry = calloc(d->toc_entries + (unsigned char) c->page->data[3], sizeof(struct burn_toc_entry)); if(d->toc_entry == NULL) /* ts A70825 */ {ret = 0; goto ex;} tdata = c->page->data + 4; d->disc = burn_disc_create(); if (d->disc == NULL) /* ts A70825 */ {ret = 0; goto ex;} for (i = 0; i < c->page->data[3]; i++) { session = burn_session_create(); if (session == NULL) /* ts A70825 */ {ret = 0; goto ex;} burn_disc_add_session(d->disc, session, BURN_POS_END); burn_session_free(session); } /* ts A61022 */ for (i = 0; i < d->toc_entries; i++, tdata += 11) { /* fprintf(stderr, "libburn_experimental: toc entry #%d : %d %d %d\n",i,tdata[8], tdata[9], tdata[10]); */ #ifdef Libburn_allow_first_hiddeN /* ts B00430 : this causes problems because the track has no entry. One would have to coordinate this with other parts of libburn. */ if (tdata[3] == 1) { if (burn_msf_to_lba(tdata[8], tdata[9], tdata[10])) { d->disc->session[0]->hidefirst = 1; track = burn_track_create(); burn_session_add_track(d->disc-> session[tdata[0] - 1], track, BURN_POS_END); burn_track_free(track); } } #endif /* Libburn_allow_first_hiddeN */ if (tdata[0] <= 0 || tdata[0] > d->disc->sessions) tdata[0] = d->disc->sessions; if (tdata[3] < 100 && tdata[0] > 0) { track = burn_track_create(); burn_session_add_track(d->disc->session[tdata[0] - 1], track, BURN_POS_END); track->entry = &d->toc_entry[i]; burn_track_free(track); } d->toc_entry[i].session = tdata[0]; d->toc_entry[i].adr = tdata[1] >> 4; d->toc_entry[i].control = tdata[1] & 0xF; d->toc_entry[i].tno = tdata[2]; d->toc_entry[i].point = tdata[3]; d->toc_entry[i].min = tdata[4]; d->toc_entry[i].sec = tdata[5]; d->toc_entry[i].frame = tdata[6]; d->toc_entry[i].zero = tdata[7]; d->toc_entry[i].pmin = tdata[8]; d->toc_entry[i].psec = tdata[9]; d->toc_entry[i].pframe = tdata[10]; if (tdata[3] == 0xA0) d->disc->session[tdata[0] - 1]->firsttrack = tdata[8]; if (tdata[3] == 0xA1) d->disc->session[tdata[0] - 1]->lasttrack = tdata[8]; if (tdata[3] == 0xA2) d->disc->session[tdata[0] - 1]->leadout_entry = &d->toc_entry[i]; } /* ts A70131 : was (d->status != BURN_DISC_BLANK) */ if (d->status == BURN_DISC_UNREADY) d->status = BURN_DISC_FULL; toc_find_modes(d); /* ts A81202 ticket 146 : a drive reported a session with no leadout */ for (i = 0; i < d->disc->sessions; i++) { if (d->disc->session[i]->leadout_entry != NULL) continue; sprintf(msg, "Session %d of %d encountered without leadout", i + 1, d->disc->sessions); libdax_msgs_submit(libdax_messenger, d->global_index, 0x00020160, LIBDAX_MSGS_SEV_WARNING, LIBDAX_MSGS_PRIO_HIGH, msg, 0, 0); /* Produce default leadout entry from last track of session which will thus get its size set to 0 */; if (d->disc->session[i]->track != NULL && d->disc->session[i]->tracks > 0) { t_idx = d->toc_entries++; memcpy(d->toc_entry + t_idx, d->disc->session[i]->track[ d->disc->session[i]->tracks - 1]->entry, sizeof(struct burn_toc_entry)); d->toc_entry[t_idx].point = 0xA2; d->disc->session[i]->leadout_entry = d->toc_entry + t_idx; } else { burn_disc_remove_session(d->disc, d->disc->session[i]); sprintf(msg, "Empty session %d deleted. Now %d sessions.", i + 1, d->disc->sessions); libdax_msgs_submit(libdax_messenger, d->global_index, 0x00020161, LIBDAX_MSGS_SEV_WARNING, LIBDAX_MSGS_PRIO_HIGH, msg, 0, 0); i--; } } /* A80808 */ burn_disc_cd_toc_extensions(d, 0); ret = 1; ex:; BURN_FREE_MEM(msg); BURN_FREE_MEM(c); BURN_FREE_MEM(buf); return ret; } void mmc_read_toc(struct burn_drive *d) { int alloc_len = 4, ret; mmc_start_if_needed(d, 1); if (mmc_function_spy(d, "mmc_read_toc") <= 0) return; ret = mmc_read_toc_al(d, &alloc_len); /* fprintf(stderr, "LIBBURN_DEBUG: 43h READ TOC alloc_len = %d , ret = %d\n", alloc_len, ret); */ if (alloc_len >= 15) ret = mmc_read_toc_al(d, &alloc_len); if (ret <= 0) return; } /* ts A70131 : This tries to get the start of the last complete session */ /* man mkisofs , option -C : The first number is the sector number of the first sector in the last session of the disk that should be appended to. */ int mmc_read_multi_session_c1(struct burn_drive *d, int *trackno, int *start) { struct buffer *buf = NULL; struct command *c = NULL; unsigned char *tdata; int num_sessions, session_no, num_tracks, alloc_len = 12, ret; struct burn_disc *disc; struct burn_session **sessions; struct burn_track **tracks; struct burn_toc_entry toc_entry; BURN_ALLOC_MEM(buf, struct buffer, 1); BURN_ALLOC_MEM(c, struct command, 1); mmc_start_if_needed(d, 1); if (mmc_function_spy(d, "mmc_read_multi_session_c1") <= 0) {ret = 0; goto ex;} /* First try to evaluate the eventually loaded TOC before issueing a MMC command. This search obtains the first track of the last complete session which has a track. */ *trackno = 0; disc = burn_drive_get_disc(d); if (disc == NULL) goto inquire_drive; sessions = burn_disc_get_sessions(disc, &num_sessions); for (session_no = 0; session_no<num_sessions; session_no++) { tracks = burn_session_get_tracks(sessions[session_no], &num_tracks); if (tracks == NULL || num_tracks <= 0) continue; burn_track_get_entry(tracks[0], &toc_entry); if (toc_entry.extensions_valid & 1) { /* DVD extension valid */ *start = toc_entry.start_lba; *trackno = (toc_entry.point_msb << 8)| toc_entry.point; } else { *start = burn_msf_to_lba(toc_entry.pmin, toc_entry.psec, toc_entry.pframe); *trackno = toc_entry.point; } } burn_disc_free(disc); if(*trackno > 0) {ret = 1; goto ex;} inquire_drive:; /* mmc5r03.pdf 6.26.3.3.3 states that with non-CD this would be a useless fake always starting at track 1, lba 0. My drives return useful data, though. MMC-3 states that DVD had no tracks. So maybe this mandatory fake is a forgotten legacy ? */ scsi_init_command(c, MMC_GET_MSINFO, sizeof(MMC_GET_MSINFO)); c->dxfer_len = alloc_len; c->opcode[7]= (c->dxfer_len >> 8) & 0xff; c->opcode[8]= c->dxfer_len & 0xff; c->retry = 1; c->page = buf; c->page->bytes = 0; c->page->sectors = 0; c->dir = FROM_DRIVE; d->issue_command(d, c); if (c->error) {ret = 0; goto ex;} tdata = c->page->data + 4; *trackno = tdata[2]; *start = mmc_four_char_to_int(tdata + 4); ret = 1; ex:; BURN_FREE_MEM(buf); BURN_FREE_MEM(c); return ret; } /* ts A61201 */ char *mmc_obtain_profile_name(int profile_number) { static char *texts[0x53] = {NULL}; int i, max_pno = 0x53; if (texts[0] == NULL) { for (i = 0; i<max_pno; i++) texts[i] = ""; /* mmc5r03c.pdf , Table 89, Spelling: guessed cdrecord style */ texts[0x01] = "Non-removable disk"; texts[0x02] = "Removable disk"; texts[0x03] = "MO erasable"; texts[0x04] = "Optical write once"; texts[0x05] = "AS-MO"; texts[0x08] = "CD-ROM"; texts[0x09] = "CD-R"; texts[0x0a] = "CD-RW"; texts[0x10] = "DVD-ROM"; texts[0x11] = "DVD-R sequential recording"; texts[0x12] = "DVD-RAM"; texts[0x13] = "DVD-RW restricted overwrite"; texts[0x14] = "DVD-RW sequential recording"; texts[0x15] = "DVD-R/DL sequential recording"; texts[0x16] = "DVD-R/DL layer jump recording"; texts[0x1a] = "DVD+RW"; texts[0x1b] = "DVD+R"; texts[0x2a] = "DVD+RW/DL"; texts[0x2b] = "DVD+R/DL"; texts[0x40] = "BD-ROM"; texts[0x41] = "BD-R sequential recording"; texts[0x42] = "BD-R random recording"; texts[0x43] = "BD-RE"; texts[0x50] = "HD-DVD-ROM"; texts[0x51] = "HD-DVD-R"; texts[0x52] = "HD-DVD-RAM"; } if (profile_number<0 || profile_number>=max_pno) return ""; return texts[profile_number]; } /* ts A90603 : to be used if the drive knows no GET CONFIGURATION */ static int mmc_guess_profile(struct burn_drive *d, int flag) { int cp; cp = 0; if (d->status == BURN_DISC_BLANK || d->status == BURN_DISC_APPENDABLE) { cp = 0x09; } else if (d->status == BURN_DISC_FULL) { cp = 0x08; } if (cp) if (d->erasable) cp = 0x0a; d->current_profile = cp; if (cp == 0) return 0; d->current_is_cd_profile = 1; d->current_is_supported_profile = 1; strcpy(d->current_profile_text, mmc_obtain_profile_name(cp)); return 1; } static int mmc_read_disc_info_al(struct burn_drive *d, int *alloc_len) { struct buffer *buf = NULL; unsigned char *data; struct command *c = NULL; char *msg = NULL; /* ts A70131 : had to move mmc_read_toc() to end of function */ int do_read_toc = 0, disc_status, len, old_alloc_len; int ret, number_of_sessions = -1; int key, asc, ascq; BURN_ALLOC_MEM(buf, struct buffer, 1); BURN_ALLOC_MEM(c, struct command, 1); /* ts A61020 */ d->start_lba = d->end_lba = -2000000000; d->erasable = 0; d->last_track_no = 1; /* ts B10730 */ d->sent_default_page_05 = 0; /* ts A70212 - A70215 */ d->media_capacity_remaining = 0; d->media_lba_limit = 0; /* ts A81210 */ d->media_read_capacity = 0x7fffffff; /* ts A61202 */ d->toc_entries = 0; if (d->status == BURN_DISC_EMPTY) {ret = 1; goto ex;} mmc_get_configuration(d); scsi_init_command(c, MMC_GET_DISC_INFO, sizeof(MMC_GET_DISC_INFO)); c->dxfer_len = *alloc_len; c->opcode[7]= (c->dxfer_len >> 8) & 0xff; c->opcode[8]= c->dxfer_len & 0xff; c->retry = 1; c->page = buf; c->page->sectors = 0; c->page->bytes = 0; c->dir = FROM_DRIVE; d->issue_command(d, c); 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; {ret = 0; goto ex;} } data = c->page->data; len = (data[0] << 8) | data[1]; old_alloc_len = *alloc_len; *alloc_len = len + 2; if (old_alloc_len < 34) {ret = 1; goto ex;} if (*alloc_len < 24) /* data[23] is the last mandatory byte here */ {ret = 0; goto ex;} if (len + 2 > old_alloc_len) len = old_alloc_len - 2; d->erasable = !!(data[2] & 16); /* ts A90908 */ d->disc_type = data[8]; d->disc_info_valid = 1; d->disc_id = mmc_four_char_to_int(data + 12); d->disc_info_valid |= (!!(data[7] & 128)) << 1; if (len + 2 > 31 && (data[7] & 64)) { memcpy(d->disc_bar_code, data + 24, 8); d->disc_bar_code[8] = 0; d->disc_info_valid |= 4; } if (len + 2 > 32 && (data[7] & 16)) { d->disc_app_code = data[32]; d->disc_info_valid |= 8; } if (data[7] & 32) d->disc_info_valid |= 16; if (data[2] & 16) d->disc_info_valid |= 32; disc_status = data[2] & 3; d->state_of_last_session = (data[2] >> 2) & 3; number_of_sessions = (data[9] << 8) | data[4]; if (d->current_profile == 0x10 || d->current_profile == 0x40) { /* DVD-ROM , BD-ROM */ disc_status = 2; /* always full and finalized */ d->erasable = 0; /* never erasable */ } #ifdef Libburn_support_bd_r_readonlY /* <<< For now: declaring BD-R read-only */ #ifndef Libburn_support_bd_plus_r_srM if (d->current_profile == 0x41) { /* BD-R seq as readonly dummy */ disc_status = 2; /* always full and finalized */ d->erasable = 0; /* never erasable */ } #endif if (d->current_profile == 0x42) { /* BD-R rnd */ disc_status = 2; /* always full and finalized */ d->erasable = 0; /* never erasable */ } #endif /* Libburn_support_bd_r_readonlY */ /* MMC-5 6.22.3.1.16: Last Session Lead-in Start Address bytes 16 to 19 Last Possible Lead-out Start Address bytes 20 to 23 MSF for CD, LBA else */ if(d->current_profile == 0x08 || d->current_profile == 0x09 || d->current_profile == 0x0a) { d->last_lead_in = burn_msf_to_lba(data[17], data[18], data[19]); d->last_lead_out = burn_msf_to_lba(data[21], data[22], data[23]); } else { d->last_lead_in = mmc_four_char_to_int(data + 16); d->last_lead_out = mmc_four_char_to_int(data + 20); } switch (disc_status) { case 0: regard_as_blank:; d->toc_entries = 0; /* fprintf(stderr, "libburn_experimental: start_lba = %d (%d %d %d) , end_lba = %d (%d %d %d)\n", d->start_lba, data[17], data[18], data[19], d->end_lba, data[21], data[22], data[23]); */ d->status = BURN_DISC_BLANK; d->start_lba = d->last_lead_in; d->end_lba = d->last_lead_out; break; case 1: d->status = BURN_DISC_APPENDABLE; case 2: if (disc_status == 2) d->status = BURN_DISC_FULL; /* ts A81210 */ ret = mmc_read_capacity(d); /* Freshly formatted, unwritten BD-R pretend to be appendable but in our model they need to be regarded as blank. Criterion: BD-R seq, read capacity known and 0, declared appendable, single empty session */ if (d->current_profile == 0x41 && d->status == BURN_DISC_APPENDABLE && ret > 0 && d->media_read_capacity == 0 && d->state_of_last_session == 0 && number_of_sessions == 1) goto regard_as_blank; if (d->current_profile == 0x41 && d->status == BURN_DISC_APPENDABLE && d->state_of_last_session == 1) { /* ??? apply this test to other media types ? */ libdax_msgs_submit(libdax_messenger, d->global_index, 0x00020169, LIBDAX_MSGS_SEV_WARNING, LIBDAX_MSGS_PRIO_HIGH, "Last session on media is still open.", 0, 0); } do_read_toc = 1; break; case 3: /* ts A91009 : DVD-RAM has disc status "others" */ mmc_read_capacity(d); break; } /* ts A90603 : An MMC-1 drive might not know the media type yet */ if (d->current_is_guessed_profile && d->current_profile == 0) mmc_guess_profile(d, 0); if ((d->current_profile != 0 || d->status != BURN_DISC_UNREADY) && ! d->current_is_supported_profile) { if (!(d->silent_on_scsi_error == 1 || d->silent_on_scsi_error == 2)) { msg = calloc(1, 160); if (msg != NULL) { sprintf(msg, "Unsuitable media detected. Profile %4.4Xh %s", d->current_profile, d->current_profile_text); libdax_msgs_submit(libdax_messenger, d->global_index, 0x0002011e, d->silent_on_scsi_error == 3 ? LIBDAX_MSGS_SEV_DEBUG : LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH, msg, 0,0); free(msg); } } d->status = BURN_DISC_UNSUITABLE; {ret = 0; goto ex;} } /* ts A61217 : growisofs performs OPC if (data[0]<<8)|data[1]<=32 which indicates no OPC entries are attached to the reply from the drive. ts A91104 : Actually growisofs performs OPC only on DVD-R[W]. */ d->num_opc_tables = 0; if(((data[0] << 8) | data[1]) > 32) /* i.e. > 34 bytes are available */ d->num_opc_tables = data[33]; /* ts A61219 : mmc5r03c.pdf 6.22.3.1.13 BG Format Status 0=blank (not yet started) 1=started but neither running nor complete 2=in progress 3=completed */ d->bg_format_status = data[7] & 3; /* Preliminarily declare blank: ts A61219 : DVD+RW (is not bg_format_status==0 "blank") ts A61229 : same for DVD-RW Restricted overwrite ts A70112 : same for DVD-RAM */ if (d->current_profile == 0x1a || d->current_profile == 0x13 || d->current_profile == 0x12 || d->current_profile == 0x43) d->status = BURN_DISC_BLANK; #ifdef Libburn_disc_with_incomplete_sessioN /* ts B30112 : number of open sessions */ d->incomplete_sessions = 0; #endif if (d->status == BURN_DISC_BLANK) { d->last_track_no = 1; /* The "incomplete track" */ d->complete_sessions = 0; } else { /* ts A70131 : number of closed sessions */ d->complete_sessions = number_of_sessions; /* mmc5r03c.pdf 6.22.3.1.3 State of Last Session: 3=complete */ if (d->state_of_last_session != 3 && d->complete_sessions >= 1) { d->complete_sessions--; #ifdef Libburn_disc_with_incomplete_sessioN d->incomplete_sessions++; #endif } /* ts A70129 : mmc5r03c.pdf 6.22.3.1.7 This includes the "incomplete track" if the disk is appendable. I.e number of complete tracks + 1. */ d->last_track_no = (data[11] << 8) | data[6]; } if (d->current_profile != 0x0a && d->current_profile != 0x13 && d->current_profile != 0x14 && d->status != BURN_DISC_FULL) d->erasable = 0; /* stay in sync with burn_disc_erase() */ if (do_read_toc) mmc_read_toc(d); ret = 1; ex: BURN_FREE_MEM(buf); BURN_FREE_MEM(c); return ret; } void mmc_read_disc_info(struct burn_drive *d) { int alloc_len = 34, ret; mmc_start_if_needed(d, 1); if (mmc_function_spy(d, "mmc_read_disc_info") <= 0) return; ret = mmc_read_disc_info_al(d, &alloc_len); /* fprintf(stderr,"LIBBURN_DEBUG: 51h alloc_len = %d , ret = %d\n", alloc_len, ret); */ if (ret <= 0) return; /* for now there is no need to inquire the variable length part */ } /* @param flag bit= do not allocate text_packs */ static int mmc_get_leadin_text_al(struct burn_drive *d, unsigned char **text_packs, int *alloc_len, int flag) { struct buffer *buf = NULL; struct command *c = NULL; unsigned char *data; int ret, data_length; *text_packs = NULL; BURN_ALLOC_MEM(buf, struct buffer, 1); BURN_ALLOC_MEM(c, struct command, 1); scsi_init_command(c, MMC_GET_LEADTEXT, sizeof(MMC_GET_LEADTEXT)); c->dxfer_len = *alloc_len; c->opcode[7]= (c->dxfer_len >> 8) & 0xff; c->opcode[8]= c->dxfer_len & 0xff; c->retry = 1; c->page = buf; c->page->bytes = 0; c->page->sectors = 0; c->dir = FROM_DRIVE; d->issue_command(d, c); if (c->error) {ret = 0; goto ex;} data = c->page->data; data_length = (data[0] << 8) + data[1]; *alloc_len = data_length + 2; if (*alloc_len >= 22 && !(flag & 1)) { BURN_ALLOC_MEM(*text_packs, unsigned char, *alloc_len - 4); memcpy(*text_packs, data + 4, *alloc_len - 4); } ret = 1; ex:; BURN_FREE_MEM(c); BURN_FREE_MEM(buf); return ret; } /* ts B11201 */ /* Read the CD-TEXT data from the Lead-in of an Audio CD */ int mmc_get_leadin_text(struct burn_drive *d, unsigned char **text_packs, int *num_packs, int flag) { int alloc_len = 4, ret; *num_packs = 0; if (mmc_function_spy(d, "mmc_get_leadin_text") <= 0) return -1; ret = mmc_get_leadin_text_al(d, text_packs, &alloc_len, 1); if (ret <= 0 || alloc_len < 22) return (ret > 0 ? 0 : ret); ret = mmc_get_leadin_text_al(d, text_packs, &alloc_len, 0); if (ret <= 0 || alloc_len < 22) { if (*text_packs != NULL) free(*text_packs); *text_packs = NULL; return (ret > 0 ? 0 : ret); } *num_packs = (alloc_len - 4) / 18; return ret; } void mmc_read_atip(struct burn_drive *d) { struct buffer *buf = NULL; struct command *c = NULL; int alloc_len = 28; /* ts A61021 */ unsigned char *data; /* Speed values from A1: With 4 cdrecord tells "10" or "8" where MMC-1 says "8". cdrecord "8" appear on 4xCD-RW and thus seem to be quite invalid. My CD-R (>=24 speed) tell no A1. The higher non-MMC-1 values are hearsay. */ /* 0, 2, 4, 6, 10, -, 16, -, */ static int speed_value[16]= { 0, 353, 706, 1059, 1764, -5, 2824, -7, 4234, 5646, 7056, 8468, -12, -13, -14, -15}; /* 24, 32, 40, 48, -, -, -, - */ BURN_ALLOC_MEM_VOID(buf, struct buffer, 1); BURN_ALLOC_MEM_VOID(c, struct command, 1); mmc_start_if_needed(d, 1); if (mmc_function_spy(d, "mmc_read_atip") <= 0) goto ex; scsi_init_command(c, MMC_GET_ATIP, sizeof(MMC_GET_ATIP)); c->dxfer_len = alloc_len; c->opcode[7] = (c->dxfer_len >> 8) & 0xff; c->opcode[8] = c->dxfer_len & 0xff; c->retry = 1; c->page = buf; c->page->bytes = 0; c->page->sectors = 0; c->dir = FROM_DRIVE; d->issue_command(d, c); /* ts B00501 : now caring for error */ if (c->error) { d->erasable = 0; d->start_lba = 0; d->end_lba = 0; goto ex; } /* ts A61021 */ data = c->page->data; d->erasable = !!(data[6]&64); d->start_lba = burn_msf_to_lba(data[8],data[9],data[10]); d->end_lba = burn_msf_to_lba(data[12],data[13],data[14]); /* ts B21124 : LITE-ON LTR-48125S returns crap on pressed audio CD and CD-ROM */ if (d->start_lba >= d->end_lba) { d->start_lba = 0; d->end_lba = 0; } if (data[6]&4) { if (speed_value[(data[16]>>4)&7] > 0) { d->mdata->min_write_speed = speed_value[(data[16]>>4)&7]; if (speed_value[(data[16])&15] <= 0) d->mdata->max_write_speed = speed_value[(data[16]>>4)&7]; } if (speed_value[(data[16])&15] > 0) { d->mdata->max_write_speed = speed_value[(data[16])&15]; if (speed_value[(data[16]>>4)&7] <= 0) d->mdata->min_write_speed = speed_value[(data[16])&15]; } } #ifdef Burn_mmc_be_verbous_about_atiP { int i; fprintf(stderr,"libburn_experimental: Returned ATIP Data\n"); for(i= 0; i<28; i++) fprintf(stderr,"%3.3d (0x%2.2x)%s", data[i],data[i],(((i + 1) % 5) ? " " : "\n")); fprintf(stderr,"\n"); fprintf(stderr, "libburn_experimental: Indicative Target Writing Power= %d\n", (data[4]>>4)&7); fprintf(stderr, "libburn_experimental: Reference speed= %d ->%d\n", data[4]&7, speed_value[data[4]&7]); fprintf(stderr, "libburn_experimental: Is %sunrestricted\n", (data[5]&64?"":"not ")); fprintf(stderr, "libburn_experimental: Is %serasable, sub-type %d\n", (data[6]&64?"":"not "),(data[6]>>3)&3); fprintf(stderr, "libburn_experimental: lead in: %d (%-2.2d:%-2.2d/%-2.2d)\n", burn_msf_to_lba(data[8],data[9],data[10]), data[8],data[9],data[10]); fprintf(stderr, "libburn_experimental: lead out: %d (%-2.2d:%-2.2d/%-2.2d)\n", burn_msf_to_lba(data[12],data[13],data[14]), data[12],data[13],data[14]); if(data[6]&4) fprintf(stderr, "libburn_experimental: A1 speed low %d speed high %d\n", speed_value[(data[16]>>4)&7], speed_value[(data[16])&7]); if(data[6]&2) fprintf(stderr, "libburn_experimental: A2 speed low %d speed high %d\n", speed_value[(data[20]>>4)&7], speed_value[(data[20])&7]); if(data[6]&1) fprintf(stderr, "libburn_experimental: A3 speed low %d speed high %d\n", speed_value[(data[24]>>4)&7], speed_value[(data[24])&7]); } #endif /* Burn_mmc_be_verbous_about_atiP */ /* ts A61020 http://www.t10.org/ftp/t10/drafts/mmc/mmc-r10a.pdf , table 77 : 0 ATIP Data Length MSB 1 ATIP Data Length LSB 2 Reserved 3 Reserved 4 bit7=1, bit4-6="Indicative Target Writing Power", bit3=reserved , bit0-2="Reference speed" 5 bit7=0, bit6="URU" , bit0-5=reserved 6 bit7=1, bit6="Disc Type", bit3-4="Disc Sub-Type", bit2="A1", bit1="A2", bit0="A3" 7 reserved 8 ATIP Start Time of lead-in (Min) 9 ATIP Start Time of lead-in (Sec) 10 ATIP Start Time of lead-in (Frame) 11 reserved 12 ATIP Last Possible Start Time of lead-out (Min) 13 ATIP Last Possible Start Time of lead-out (Sec) 14 ATIP Last Possible Start Time of lead-out (Frame) 15 reserved 16 bit7=0, bit4-6="Lowest Usable CLV Recording speed" bit0-3="Highest Usable CLV Recording speed" 17 bit7=0, bit4-6="Power Multiplication Factor p", bit1-3="Target y value of the Modulation/Power function", bit0=reserved 18 bit7=1, bit4-6="Recommended Erase/Write Power Ratio (P(inf)/W(inf))" bit0-3=reserved 19 reserved 20-22 A2 Values 23 reserved 24-26 A3 Values 27 reserved Disc Type - zero indicates CD-R media; one indicates CD-RW media. Disc Sub-Type - shall be set to zero. A1 - when set to one, indicates that bytes 16-18 are valid. Lowest Usable CLV Recording Speed 000b Reserved 001b 2X 010b - 111b Reserved Highest CLV Recording Speeds 000b Reserved 001b 2X 010b 4X 011b 6X 100b 8X 101b - 111b Reserved MMC-3 seems to recommend MODE SENSE (5Ah) page 2Ah rather than A1, A2, A3. This page is loaded in libburn function spc_sense_caps() . Speed is given in kbytes/sec there. But i suspect this to be independent of media. So one would habe to associate the speed descriptor blocks with the ATIP media characteristics ? How ? */ ex:; BURN_FREE_MEM(buf); BURN_FREE_MEM(c); } int mmc_eval_read_error(struct burn_drive *d, struct command *c, char *what, int start_m, int start_s, int start_f, int end_m, int end_s, int end_f, int flag) { char *msg = NULL; int key, asc, ascq, silent; if (!c->error) return 0; msg = calloc(1, 256); if (msg != NULL) { if (start_s < 0 || start_f < 0 || end_s < 0 || end_f < 0) { sprintf(msg, "SCSI error on %s(%d,%d): ", what, start_m, end_m); } else { sprintf(msg, "SCSI error on %s(%dm%ds%df,%dm%ds%df): ", what, start_m, start_s, start_f, end_m, end_s, end_f); } scsi_error_msg(d, c->sense, 14, msg + strlen(msg), &key, &asc, &ascq); silent = (d->silent_on_scsi_error == 1); if (key == 5 && asc == 0x64 && ascq == 0x0) { d->had_particular_error |= 1; if (d->silent_on_scsi_error == 2) silent = 1; } if(!silent) libdax_msgs_submit(libdax_messenger, d->global_index, 0x00020144, d->silent_on_scsi_error == 3 ? LIBDAX_MSGS_SEV_DEBUG : LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH, msg, 0, 0); free(msg); } return BE_CANCELLED; } /* ts B21119 : Derived from older mmc_read_sectors() @param flag bit0= set DAP bit (also with o->dap_bit) */ int mmc_read_cd_msf(struct burn_drive *d, int start_m, int start_s, int start_f, int end_m, int end_s, int end_f, int sec_type, int main_ch, const struct burn_read_opts *o, struct buffer *buf, int flag) { int req, ret, dap_bit; int subcodes_audio = 0, subcodes_data = 0; struct command *c; #ifdef Libburn_mmc_report_recovereD int report_recovered_errors = 0; #endif c = &(d->casual_command); mmc_start_if_needed(d, 0); if (mmc_function_spy(d, "mmc_read_cd_msf") <= 0) return -1; dap_bit = flag & 1; if (o != NULL) { subcodes_audio = o->subcodes_audio; subcodes_data = o->subcodes_data; dap_bit |= o->dap_bit; #ifdef Libburn_mmc_report_recovereD report_recovered_errors = o->report_recovered_errors; #endif } scsi_init_command(c, MMC_READ_CD_MSF, sizeof(MMC_READ_CD_MSF)); c->retry = 1; c->opcode[1] = ((sec_type & 7) << 2) | ((!!dap_bit) << 1); c->opcode[3] = start_m; c->opcode[4] = start_s; c->opcode[5] = start_f; c->opcode[6] = end_m; c->opcode[7] = end_s; c->opcode[8] = end_f; req = main_ch & 0xf8; #ifdef Libburn_mmc_report_recovereD /* ts A61106 : LG GSA-4082B dislikes this. key=5h asc=24h ascq=00h */ if (d->busy == BURN_DRIVE_GRABBING || report_recovered_errors) req |= 2; #endif /* Libburn_mmc_report_recovereD */ c->opcode[9] = req; c->opcode[10] = 0; /* always read the subcode, throw it away later, since we don't know what we're really reading */ /* >>> ts B21125 : This is very obscure: MMC-3 has sub channel selection 001b as "RAW" MMC-5 does neither mention 001b nor "RAW". And why should a non-grabbed drive get here ? */ if (d->busy == BURN_DRIVE_GRABBING || subcodes_audio || subcodes_data) c->opcode[10] = 1; /* <<< ts B21125 : test with sub channel selection 100b no data, only sub channel c->opcode[9] = 0; c->opcode[10] = 4; Did not help either with reading before LBA -150 */ /* <<< ts B21125 : test with sub channel selection 001b and no user data c->opcode[9] = 0; c->opcode[10] = 1; */ c->page = buf; c->dir = FROM_DRIVE; d->issue_command(d, c); ret = mmc_eval_read_error(d, c, "read_cd_msf", start_m, start_s, start_f, end_m, end_s, end_f, 0); return ret; } /* ts B21119 : Derived from older mmc_read_sectors() @param flag bit0= set DAP bit (also with o->dap_bit) */ int mmc_read_cd(struct burn_drive *d, int start, int len, int sec_type, int main_ch, const struct burn_read_opts *o, struct buffer *buf, int flag) { int temp, req, ret, dap_bit; int subcodes_audio = 0, subcodes_data = 0; struct command *c; #ifdef Libburn_mmc_report_recovereD int report_recovered_errors = 0; #endif /* # define Libburn_read_cd_by_msF 1 */ #ifdef Libburn_read_cd_by_msF int start_m, start_s, start_f, end_m, end_s, end_f; burn_lba_to_msf(start, &start_m, &start_s, &start_f); burn_lba_to_msf(start + len, &end_m, &end_s, &end_f); ret = mmc_read_cd_msf(d, start_m, start_s, start_f, end_m, end_s, end_f, sec_type, main_ch, o, buf, flag); return ret; #endif /* Libburn_read_cd_by_msF */ c = &(d->casual_command); mmc_start_if_needed(d, 0); if (mmc_function_spy(d, "mmc_read_cd") <= 0) return -1; dap_bit = flag & 1; if (o != NULL) { subcodes_audio = o->subcodes_audio; subcodes_data = o->subcodes_data; dap_bit |= o->dap_bit; #ifdef Libburn_mmc_report_recovereD report_recovered_errors = o->report_recovered_errors; #endif } scsi_init_command(c, MMC_READ_CD, sizeof(MMC_READ_CD)); c->retry = 1; c->opcode[1] = ((sec_type & 7) << 2) | ((!!dap_bit) << 1); temp = start; c->opcode[5] = temp & 0xFF; temp >>= 8; c->opcode[4] = temp & 0xFF; temp >>= 8; c->opcode[3] = temp & 0xFF; temp >>= 8; c->opcode[2] = temp & 0xFF; c->opcode[8] = len & 0xFF; len >>= 8; c->opcode[7] = len & 0xFF; len >>= 8; c->opcode[6] = len & 0xFF; req = main_ch & 0xf8; #ifdef Libburn_mmc_report_recovereD /* ts A61106 : LG GSA-4082B dislikes this. key=5h asc=24h ascq=00h */ if (d->busy == BURN_DRIVE_GRABBING || report_recovered_errors) req |= 2; #endif /* Libburn_mmc_report_recovereD */ c->opcode[9] = req; c->opcode[10] = 0; /* always read the subcode, throw it away later, since we don't know what we're really reading */ /* >>> ts B21125 : This is very obscure: MMC-3 has sub channel selection 001b as "RAW" MMC-5 does neither mention 001b nor "RAW". And why should a non-grabbed drive get here ? */ if (d->busy == BURN_DRIVE_GRABBING || subcodes_audio || subcodes_data) c->opcode[10] = 1; /* <<< ts B21125 : test with sub channel selection 100b c->opcode[10] = 4; */ /* <<< ts B21125 : test with sub channel selection 001b and no user data c->opcode[9] = 0; c->opcode[10] = 1; */ c->page = buf; c->dir = FROM_DRIVE; d->issue_command(d, c); ret = mmc_eval_read_error(d, c, "read_cd", start, -1, -1, len, -1, -1, 0); return ret; } void mmc_erase(struct burn_drive *d, int fast) { struct command *c; c = &(d->casual_command); mmc_start_if_needed(d, 0); if (mmc_function_spy(d, "mmc_erase") <= 0) return; scsi_init_command(c, MMC_BLANK, sizeof(MMC_BLANK)); c->opcode[1] = 16; /* IMMED set to 1 */ c->opcode[1] |= !!fast; c->retry = 1; c->page = NULL; c->dir = NO_TRANSFER; c->timeout = Libburn_mmc_blank_timeouT; d->issue_command(d, c); if (c->error) { d->cancel = 1; scsi_notify_error(d, c, c->sense, 14, 2); } } void mmc_read_lead_in(struct burn_drive *d, struct buffer *buf) { struct command *c; c = &(d->casual_command); mmc_start_if_needed(d, 0); if (mmc_function_spy(d, "mmc_read_lead_in") <= 0) return; scsi_init_command(c, MMC_READ_CD, sizeof(MMC_READ_CD)); c->retry = 1; c->opcode[5] = 0; c->opcode[4] = 0; c->opcode[3] = 0; c->opcode[2] = 0xF0; c->opcode[8] = 1; c->opcode[7] = 0; c->opcode[6] = 0; c->opcode[9] = 0; c->opcode[10] = 2; c->page = buf; c->dir = FROM_DRIVE; d->issue_command(d, c); } void mmc_perform_opc(struct burn_drive *d) { struct command *c; c = &(d->casual_command); mmc_start_if_needed(d, 0); if (mmc_function_spy(d, "mmc_perform_opc") <= 0) return; scsi_init_command(c, MMC_SEND_OPC, sizeof(MMC_SEND_OPC)); c->retry = 1; c->opcode[1] = 1; c->page = NULL; c->dir = NO_TRANSFER; c->timeout = Libburn_mmc_opc_timeouT; d->issue_command(d, c); } /* ts A61221 : Learned much from dvd+rw-tools-7.0 set_speed_B6h() but then made own experiments on base of mmc5r03c.pdf 6.8.3 and 6.39 in the hope to achieve a leaner solution ts A70712 : That leaner solution does not suffice for my LG GSA-4082B. Meanwhile there is a speed descriptor list anyway. */ int mmc_set_streaming(struct burn_drive *d, int r_speed, int w_speed, int end_lba) { struct buffer *buf = NULL; struct command *c = NULL; int b, eff_end_lba, ret; char *msg = NULL; unsigned char *pd; int key, asc, ascq; BURN_ALLOC_MEM(buf, struct buffer, 1); BURN_ALLOC_MEM(c, struct command, 1); BURN_ALLOC_MEM(msg, char, 256); mmc_start_if_needed(d, 1); if (mmc_function_spy(d, "mmc_set_streaming") <= 0) {ret = 0; goto ex;} scsi_init_command(c, MMC_SET_STREAMING, sizeof(MMC_SET_STREAMING)); c->retry = 1; c->page = buf; c->page->bytes = 28; c->opcode[9] = (c->page->bytes >> 8) & 0xff; c->opcode[10] = c->page->bytes & 0xff; c->page->sectors = 0; c->dir = TO_DRIVE; memset(c->page->data, 0, c->page->bytes); pd = c->page->data; pd[0] = 0; /* WRC=0 (Default Rotation Control), RDD=Exact=RA=0 */ if (w_speed == 0) w_speed = 0x10000000; /* ~ 2 TB/s */ else if (w_speed < 0) w_speed = 177; /* 1x CD */ if (r_speed == 0) r_speed = 0x10000000; /* ~ 2 TB/s */ else if (r_speed < 0) r_speed = 177; /* 1x CD */ if (end_lba == 0) { /* Default computed from 4.7e9 */ eff_end_lba = 2294921 - 1; if (d->mdata->max_end_lba > 0) eff_end_lba = d->mdata->max_end_lba - 1; } else eff_end_lba = end_lba; sprintf(msg, "mmc_set_streaming: end_lba=%d , r=%d , w=%d", eff_end_lba, r_speed, w_speed); libdax_msgs_submit(libdax_messenger, d->global_index, 0x00000002, LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_ZERO, msg, 0, 0); /* start_lba is 0 , 1000 = 1 second as base time for data rate */ for (b = 0; b < 4 ; b++) { pd[8+b] = (eff_end_lba >> (24 - 8 * b)) & 0xff; pd[12+b] = (r_speed >> (24 - 8 * b)) & 0xff; pd[16+b] = (1000 >> (24 - 8 * b)) & 0xff; pd[20+b] = (w_speed >> (24 - 8 * b)) & 0xff; pd[24+b] = (1000 >> (24 - 8 * b)) & 0xff; } /* <<< fprintf(stderr,"LIBBURN_EXPERIMENTAL : B6h Performance descriptor:\n"); for (b = 0; b < 28 ; b++) fprintf(stderr, "%2.2X%c", pd[b], ((b+1)%4 ? ' ' : '\n')); */ d->issue_command(d, c); if (c->error) { spc_decode_sense(c->sense, 0, &key, &asc, &ascq); if (key != 0 && d->silent_on_scsi_error != 1 && d->silent_on_scsi_error != 2) { sprintf(msg, "SCSI error on set_streaming(%d): ", w_speed); scsi_error_msg(d, c->sense, 14, msg + strlen(msg), &key, &asc, &ascq); libdax_msgs_submit(libdax_messenger, d->global_index, 0x00020124, d->silent_on_scsi_error == 3 ? LIBDAX_MSGS_SEV_DEBUG : LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH, msg, 0, 0); } {ret = 0; goto ex;} } ret = 1; ex:; BURN_FREE_MEM(msg); BURN_FREE_MEM(c); BURN_FREE_MEM(buf); return ret; } void mmc_set_speed(struct burn_drive *d, int r, int w) { struct command *c; int ret, end_lba = 0, get_max, get_min; struct burn_speed_descriptor *best_sd = NULL; c = &(d->casual_command); mmc_start_if_needed(d, 1); if (mmc_function_spy(d, "mmc_set_speed") <= 0) return; if (r <= 0 || w <= 0) { /* ts A70712 : now searching for best speed descriptor */ /* ts B31030 : keeping max read speed from sinking too low */ if (r <= 0) { get_max = (r == 0); get_min = (r == -1); burn_drive_get_best_speed(d, r, &best_sd, 1 | 2); if (best_sd != NULL) { r = best_sd->read_speed; end_lba = best_sd->end_lba; } if (get_max) { if (d->current_is_cd_profile) { if (r < Libburn_cd_max_read_speeD) r = Libburn_cd_max_read_speeD; } else if (d->current_profile >= 0x10 && d->current_profile <= 0x2f) { if (r < Libburn_dvd_max_read_speeD) r = Libburn_dvd_max_read_speeD; } else if (d->current_profile >= 0x40 && d->current_profile <= 0x43) { if (r < Libburn_bd_max_read_speeD) r = Libburn_bd_max_read_speeD; } } else if(get_min) { if (d->current_is_cd_profile) { if (r > Libburn_cd_min_read_speeD) r = Libburn_cd_min_read_speeD; } else if (d->current_profile >= 0x10 && d->current_profile <= 0x2f) { if (r > Libburn_dvd_min_read_speeD) r = Libburn_dvd_min_read_speeD; } else if (d->current_profile >= 0x40 && d->current_profile <= 0x43) { if (r > Libburn_bd_min_read_speeD) r = Libburn_bd_min_read_speeD; } } } if (w <= 0) { burn_drive_get_best_speed(d, w, &best_sd, 2); if (best_sd != NULL) { w = best_sd->write_speed; d->nominal_write_speed = w; if (end_lba < best_sd->end_lba) end_lba = best_sd->end_lba; } } } /* A70711 */ d->nominal_write_speed = w; /* ts A61221 : try to set DVD speed via command B6h */ if (strstr(d->current_profile_text, "DVD") == d->current_profile_text || strstr(d->current_profile_text, "BD") == d->current_profile_text) { ret = mmc_set_streaming(d, r, w, end_lba); if (ret != 0) return; /* success or really fatal failure */ } /* ts A61112 : MMC standards prescribe FFFFh as max speed. But libburn.h prescribes 0. ts A70715 : <0 now means minimum speed */ if (r == 0 || r > 0xffff) r = 0xffff; else if (r < 0) r = 177; /* 1x CD */ if (w == 0 || w > 0xffff) w = 0xffff; else if (w < 0) w = 177; /* 1x CD */ scsi_init_command(c, MMC_SET_SPEED, sizeof(MMC_SET_SPEED)); c->retry = 1; c->opcode[2] = r >> 8; c->opcode[3] = r & 0xFF; c->opcode[4] = w >> 8; c->opcode[5] = w & 0xFF; c->page = NULL; c->dir = NO_TRANSFER; d->issue_command(d, c); } /* ts A61201 : found in unfunctional state */ static int mmc_get_configuration_al(struct burn_drive *d, int *alloc_len) { struct buffer *buf = NULL; int len, cp, descr_len = 0, feature_code, only_current = 1, i; int old_alloc_len, key, asc, ascq, ret; int feature_is_current; unsigned char *descr, *prf, *up_to, *prf_end; struct command *c = NULL; int phys_if_std = 0; char *phys_name = ""; struct burn_feature_descr *recent_feature = NULL, *new_feature; char *msg = NULL; /* Enable this to get loud and repeated reports about the feature set : # define Libburn_print_feature_descriptorS 1 */ #ifdef Libburn_print_feature_descriptorS int prf_number; only_current = 0; #endif if (*alloc_len < 8) {ret = 0; goto ex;} BURN_ALLOC_MEM(buf, struct buffer, 1); BURN_ALLOC_MEM(c, struct command, 1); d->current_profile = 0; d->current_profile_text[0] = 0; d->current_is_cd_profile = 0; d->current_is_supported_profile = 0; d->current_is_guessed_profile = 0; d->num_profiles = 0; if (d->features != NULL) burn_feature_descr_free(&(d->features), 0); d->current_has_feat21h = 0; d->current_feat21h_link_size = -1; d->current_feat23h_byte4 = 0; d->current_feat23h_byte8 = 0; d->current_feat2fh_byte4 = -1; scsi_init_command(c, MMC_GET_CONFIGURATION, sizeof(MMC_GET_CONFIGURATION)); c->dxfer_len= *alloc_len; c->retry = 1; c->opcode[7] = (c->dxfer_len >> 8) & 0xff; c->opcode[8] = c->dxfer_len & 0xff; c->page = buf; c->page->sectors = 0; c->page->bytes = 0; c->dir = FROM_DRIVE; d->issue_command(d, c); #ifdef Libisofs_simulate_old_mmc1_drivE c->error = 1; c->sense[0] = 0x70; /* Fixed format sense data */ c->sense[2] = 0x5; c->sense[12] = 0x20; c->sense[13] = 0x0; #endif /* Libisofs_simulate_old_mmc1_drivE */ if (c->error) { /* ts A90603 : MMC-1 drive do not know 46h GET CONFIGURATION */ spc_decode_sense(c->sense, 0, &key, &asc, &ascq); if (key == 0x5 && asc == 0x20 && ascq == 0x0) { d->current_is_guessed_profile = 1; /* Will yield a non-zero profile only after mmc_read_disc_info_al() was called */ mmc_guess_profile(d, 0); } {ret = 0; goto ex;} } old_alloc_len = *alloc_len; *alloc_len = len = mmc_four_char_to_int(c->page->data) + 4; if (len > old_alloc_len) len = old_alloc_len; if (len < 8) {ret = 0; goto ex;} if (len > 4096) { /* MMC-5 6.6.2.1, Note 11: The maximum is less than 1 KB */ BURN_ALLOC_MEM(msg, char, 256); sprintf(msg, "Implausible length announcement from SCSI command GET CONFIGURATION: %d", *alloc_len); libdax_msgs_submit(libdax_messenger, d->global_index, 0x000201a9, LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_ZERO, msg, 0, 0); ret = 0; goto ex; } cp = (c->page->data[6]<<8) | c->page->data[7]; #ifdef Libburn_rom_as_profilE if (cp == 0x08 || cp == 0x10 || cp==0x40) cp = Libburn_rom_as_profilE; #endif /* Libburn_rom_as_profilE */ d->current_profile = cp; strcpy(d->current_profile_text, mmc_obtain_profile_name(cp)); /* Read-only supported media */ if (cp == 0x08) /* CD-ROM */ d->current_is_supported_profile = d->current_is_cd_profile = 1; if (cp == 0x10) /* DVD-ROM */ d->current_is_supported_profile = 1; if (cp == 0x40) /* BD-ROM */ d->current_is_supported_profile = 1; #ifdef Libburn_support_bd_r_readonlY #ifndef Libburn_support_bd_plus_r_srM if (cp == 0x41) /* BD-R sequential (here as read-only dummy) */ d->current_is_supported_profile = 1; #endif if (cp == 0x42) /* BD-R random recording */ d->current_is_supported_profile = 1; #endif /* Write supported media (they get declared suitable in burn_disc_get_multi_caps) */ if (cp == 0x09 || cp == 0x0a) d->current_is_supported_profile = d->current_is_cd_profile = 1; #ifdef Libburn_support_dvd_plus_rW if (cp == 0x1a) d->current_is_supported_profile = 1; #endif #ifdef Libburn_support_dvd_minusrw_overW if (cp == 0x13) d->current_is_supported_profile = 1; #endif #ifdef Libburn_support_dvd_raM if (cp == 0x12 || cp == 0x43) { /* DVD-RAM , BD-RE */ d->current_is_supported_profile = 1; #ifdef Libburn_dvd_ram_as_bd_rE cp = d->current_profile = 0x43; strcpy(d->current_profile_text, mmc_obtain_profile_name(cp)); #endif } #endif #ifdef Libburn_support_dvd_r_seQ if (cp == 0x11 || cp == 0x14) /* DVD-R, DVD-RW */ d->current_is_supported_profile = 1; if (cp == 0x15) /* DVD-R/DL */ d->current_is_supported_profile = 1; #endif #ifdef Libburn_support_dvd_plus_R if (cp == 0x1b || cp == 0x2b) /* DVD+R , DVD+R/DL */ d->current_is_supported_profile = 1; #endif #ifdef Libburn_support_bd_plus_r_srM if (cp == 0x41) /* BD-R SRM */ d->current_is_supported_profile = 1; #endif /* ts A70127 : Interpret list of profile and feature descriptors. see mmc5r03c.pdf 5.2 */ up_to = c->page->data + len; #ifdef Libburn_print_feature_descriptorS fprintf(stderr, "-----------------------------------------------------------------\n"); fprintf(stderr, "LIBBURN_EXPERIMENTAL : feature list length = %d , shown = %d\n", len, (int) (up_to - c->page->data)); #endif /* Libburn_print_feature_descriptorS */ for (descr = c->page->data + 8; descr + 3 < up_to; descr += descr_len){ descr_len = 4 + descr[3]; feature_code = (descr[0] << 8) | descr[1]; feature_is_current = descr[2] & 1; ret = burn_feature_descr_new(&new_feature, descr, up_to - descr, 0); if (ret > 0) { if (d->features == NULL) d->features = new_feature; else recent_feature->next = new_feature; recent_feature = new_feature; } if (only_current && !feature_is_current) continue; #ifdef Libburn_print_feature_descriptorS fprintf(stderr, "LIBBURN_EXPERIMENTAL : %s feature %4.4Xh :", (descr[2] & 1) ? "+" : "-", feature_code); if (feature_code != 0x00) for (i = 2; i < descr_len; i++) fprintf(stderr, " %2.2X", descr[i]); fprintf(stderr, "\n"); #endif /* Libburn_print_feature_descriptorS */ if (feature_code == 0x0) { prf_end = descr + 4 + descr[3]; d->num_profiles = descr[3] / 4; if (d->num_profiles > 64) d->num_profiles = 64; if (d->num_profiles > 0) memcpy(d->all_profiles, descr + 4, d->num_profiles * 4); for (prf = descr + 4; prf + 2 < prf_end; prf += 4) { #ifdef Libburn_print_feature_descriptorS prf_number = (prf[0] << 8) | prf[1]; fprintf(stderr, "LIBBURN_EXPERIMENTAL : %s profile %4.4Xh \"%s\"\n", prf[2] & 1 ? "+" : "-", prf_number, mmc_obtain_profile_name(prf_number)); #endif /* Libburn_print_feature_descriptorS */ } } else if (feature_code == 0x21) { d->current_has_feat21h = feature_is_current; for (i = 0; i < descr[7]; i++) { if (i == 0 || descr[8 + i] == 16) d->current_feat21h_link_size = descr[8 + i]; #ifdef Libburn_print_feature_descriptorS fprintf(stderr, "LIBBURN_EXPERIMENTAL : + Link Size = %d\n", descr[8 + i]); #endif /* Libburn_print_feature_descriptorS */ } } else if (feature_code == 0x23) { if (feature_is_current) { d->current_feat23h_byte4 = descr[4]; d->current_feat23h_byte8 = descr[8]; } #ifdef Libburn_print_feature_descriptorS if (cp >= 0x41 && cp <= 0x43) fprintf(stderr, "LIBBURN_EXPERIMENTAL : BD formats: %s%s%s%s%s\n", descr[4] & 1 ? " Cert" : "", descr[4] & 2 ? " QCert" : "", descr[4] & 4 ? " Expand" : "", descr[4] & 8 ? " RENoSA" : "", descr[8] & 1 ? " RRM" : ""); #endif /* Libburn_print_feature_descriptorS */ } else if (feature_code == 0x2F) { if (feature_is_current) d->current_feat2fh_byte4 = descr[4]; #ifdef Libburn_print_feature_descriptorS fprintf(stderr, "LIBBURN_EXPERIMENTAL : BUF = %d , Test Write = %d , DVD-RW = %d\n", !!(descr[4] & 64), !!(descr[4] & 4), !!(descr[4] & 2)); #endif /* Libburn_print_feature_descriptorS */ } else if (feature_code == 0x01) { phys_if_std = (descr[4] << 24) | (descr[5] << 16) | (descr[6] << 8) | descr[7]; if (phys_if_std == 1) phys_name = "SCSI Family"; else if(phys_if_std == 2) phys_name = "ATAPI"; else if(phys_if_std == 3 || phys_if_std == 4 || phys_if_std == 6) phys_name = "IEEE 1394 FireWire"; else if(phys_if_std == 7) phys_name = "Serial ATAPI"; else if(phys_if_std == 8) phys_name = "USB"; d->phys_if_std = phys_if_std; strcpy(d->phys_if_name, phys_name); #ifdef Libburn_print_feature_descriptorS fprintf(stderr, "LIBBURN_EXPERIMENTAL : Phys. Interface Standard %Xh \"%s\"\n", phys_if_std, phys_name); } else if (feature_code == 0x107) { fprintf(stderr, "LIBBURN_EXPERIMENTAL : CD SPEED = %d , page 2Ah = %d , SET STREAMING = %d\n", !!(descr[4] & 8), !!(descr[4] & 4), !!(descr[4] & 2)); #endif /* Libburn_print_feature_descriptorS */ } else if (feature_code == 0x108 || feature_code == 0x10c) { int c_limit; #ifdef Libburn_print_feature_descriptorS int i; fprintf(stderr, "LIBBURN_EXPERIMENTAL : %s = ", feature_code == 0x108 ? "Drive Serial Number" : "Drive Firmware Date"); #endif /* Libburn_print_feature_descriptorS */ c_limit = descr[3] - 2 * (feature_code == 0x10c); if (feature_code == 0x108) { if (d->drive_serial_number != NULL) BURN_FREE_MEM(d->drive_serial_number); BURN_ALLOC_MEM(d->drive_serial_number, char, c_limit + 1); memcpy(d->drive_serial_number, descr + 4, c_limit); d->drive_serial_number[c_limit] = 0; d->drive_serial_number_len = c_limit; } #ifdef Libburn_print_feature_descriptorS for (i = 0; i < c_limit; i++) if (descr[4 + i] < 0x20 || descr[4 + i] > 0x7e || descr[4 + i] == '\\') fprintf(stderr,"\\%2.2X",descr[4 + i]); else fprintf(stderr, "%c", descr[4 + i]); fprintf(stderr, "\n"); #endif /* Libburn_print_feature_descriptorS */ } } ret = 1; ex: BURN_FREE_MEM(msg); BURN_FREE_MEM(buf); BURN_FREE_MEM(c); return ret; } void mmc_get_configuration(struct burn_drive *d) { int alloc_len = 8, ret; if (d->current_profile > 0 && d->current_profile < 0xffff) return; mmc_start_if_needed(d, 1); if (mmc_function_spy(d, "mmc_get_configuration") <= 0) return; /* first command execution to learn Allocation Length */ ret = mmc_get_configuration_al(d, &alloc_len); /* fprintf(stderr,"LIBBURN_DEBUG: 46h alloc_len = %d , ret = %d\n", alloc_len, ret); */ if (alloc_len > 8 && ret > 0) { /* second execution with announced length */ mmc_get_configuration_al(d, &alloc_len); } } /* ts A70108 */ /* mmc5r03c.pdf 6.24 */ static int mmc_read_format_capacities_al(struct burn_drive *d, int *alloc_len, int top_wanted) { struct buffer *buf = NULL; int len, type, score, num_descr, max_score = -2000000000, i, sign = 1; int old_alloc_len, ret; off_t size, num_blocks; struct command *c = NULL; unsigned char *dpt; BURN_ALLOC_MEM(buf, struct buffer, 1); BURN_ALLOC_MEM(c, struct command, 1); if (*alloc_len < 4) {ret = 0; goto ex;} d->format_descr_type = 3; d->format_curr_max_size = 0; d->format_curr_blsas = 0; d->best_format_type = -1; d->best_format_size = 0; scsi_init_command(c, MMC_READ_FORMAT_CAPACITIES, sizeof(MMC_READ_FORMAT_CAPACITIES)); c->dxfer_len = *alloc_len; c->retry = 1; c->opcode[7]= (c->dxfer_len >> 8) & 0xff; c->opcode[8]= c->dxfer_len & 0xff; c->page = buf; c->page->sectors = 0; c->page->bytes = 0; c->dir = FROM_DRIVE; d->issue_command(d, c); if (c->error) {ret = 0; goto ex;} len = c->page->data[3]; old_alloc_len = *alloc_len; *alloc_len = len + 4; if (old_alloc_len < 12) {ret = 1; goto ex;} if (len + 4 > old_alloc_len) len = old_alloc_len - 4; if (len < 8) {ret = 0; goto ex;} dpt = c->page->data + 4; /* decode 6.24.3.2 Current/Maximum Capacity Descriptor */ d->format_descr_type = dpt[4] & 3; d->format_curr_max_size = (((off_t) dpt[0]) << 24) + (dpt[1] << 16) + (dpt[2] << 8) + dpt[3]; if (d->format_descr_type == BURN_FORMAT_IS_UNKNOWN) d->format_curr_max_size = 0; d->format_curr_blsas = (dpt[5] << 16) + (dpt[6] << 8) + dpt[7]; d->format_curr_max_size *= (off_t) 2048; if((d->current_profile == 0x12 || d->current_profile == 0x43) && d->media_capacity_remaining == 0) { burn_drive_set_media_capacity_remaining(d, d->format_curr_max_size); d->media_lba_limit = d->format_curr_max_size / 2048; } #ifdef Libburn_dvd_ram_as_bd_rE /* <<< dummy format descriptor list as obtained from dvd+rw-mediainfo by Giulio Orsero in April 2008 */ d->num_format_descr = 5; d->format_descriptors[0].type = 0x00; d->format_descriptors[0].size = (off_t) 11826176 * (off_t) 2048; d->format_descriptors[0].tdp = 0x3000; d->format_descriptors[1].type = 0x30; d->format_descriptors[1].size = (off_t) 11826176 * (off_t) 2048; d->format_descriptors[1].tdp = 0x3000; d->format_descriptors[2].type = 0x30; d->format_descriptors[2].size = (off_t) 11564032 * (off_t) 2048; d->format_descriptors[2].tdp = 0x5000; d->format_descriptors[3].type = 0x30; d->format_descriptors[3].size = (off_t) 12088320 * (off_t) 2048; d->format_descriptors[3].tdp = 0x1000; d->format_descriptors[4].type = 0x31; d->format_descriptors[4].size = (off_t) 12219392 * (off_t) 2048; d->format_descriptors[4].tdp = 0x800; d->best_format_type = 0x00; d->best_format_size = (off_t) 11826176 * (off_t) 2048; /* silencing compiler warnings about unused variables */ num_blocks = size = sign = i = max_score = num_descr = score = type = 0; if (d->current_profile == 0x12 || d->current_profile == 0x43) {ret = 1; goto ex;} d->num_format_descr = 0; #endif /* Libburn_dvd_ram_as_bd_rE */ if (top_wanted == 0x00 || top_wanted == 0x10) sign = -1; /* the caller clearly desires full format */ /* 6.24.3.3 Formattable Capacity Descriptors */ num_descr = (len - 8) / 8; for (i = 0; i < num_descr; i++) { dpt = c->page->data + 12 + 8 * i; num_blocks = mmc_four_char_to_int(dpt); size = num_blocks * (off_t) 2048; type = dpt[4] >> 2; if (i < 32) { d->format_descriptors[i].type = type; d->format_descriptors[i].size = size; d->format_descriptors[i].tdp = (dpt[5] << 16) + (dpt[6] << 8) + dpt[7]; d->num_format_descr = i + 1; } /* Criterion is proximity to quick intermediate state */ if (type == 0x00) { /* full format (with lead out) */ score = 1 * sign; } else if (type == 0x10) { /* DVD-RW full format */ score = 10 * sign; } else if(type == 0x13) { /* DVD-RW quick grow last session */ score = 100 * sign; } else if(type == 0x15) { /* DVD-RW Quick */ score = 50 * sign; if(d->current_profile == 0x13) { burn_drive_set_media_capacity_remaining(d, size); d->media_lba_limit = num_blocks; } } else if(type == 0x26) { /* DVD+RW */ score = 1 * sign; burn_drive_set_media_capacity_remaining(d, size); d->media_lba_limit = num_blocks; } else { continue; } if (type == top_wanted) score += 1000000000; if (score > max_score) { d->best_format_type = type; d->best_format_size = size; max_score = score; } } ret = 1; ex: BURN_FREE_MEM(buf); BURN_FREE_MEM(c); return ret; } int mmc_read_format_capacities(struct burn_drive *d, int top_wanted) { int alloc_len = 4, ret; mmc_start_if_needed(d, 1); if (mmc_function_spy(d, "mmc_read_format_capacities") <= 0) return 0; ret = mmc_read_format_capacities_al(d, &alloc_len, top_wanted); /* fprintf(stderr,"LIBBURN_DEBUG: 23h alloc_len = %d , ret = %d\n", alloc_len, ret); */ if (alloc_len >= 12 && ret > 0) ret = mmc_read_format_capacities_al(d, &alloc_len, top_wanted); return ret; } void mmc_sync_cache(struct burn_drive *d) { struct command *c = NULL; char *msg = NULL; int key, asc, ascq; if (mmc_function_spy(d, "mmc_sync_cache") <= 0) goto ex; BURN_ALLOC_MEM_VOID(c, struct command, 1); BURN_ALLOC_MEM_VOID(msg, char, 256); scsi_init_command(c, MMC_SYNC_CACHE, sizeof(MMC_SYNC_CACHE)); c->retry = 1; c->opcode[1] |= 2; /* ts A70918 : Immed */ c->page = NULL; c->dir = NO_TRANSFER; c->timeout = Libburn_mmc_sync_timeouT; libdax_msgs_submit(libdax_messenger, -1, 0x00000002, LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_ZERO, "syncing cache", 0, 0); if(d->wait_for_buffer_free) { sprintf(msg, "Checked buffer %u times. Waited %u+%u times = %.3f s", d->pessimistic_writes, d->waited_writes, d->waited_tries - d->waited_writes, ((double) d->waited_usec) / 1.0e6); libdax_msgs_submit(libdax_messenger, d->global_index, 0x0002013f, LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_LOW, msg, 0,0); } d->issue_command(d, c); /* ts A70918 */ if (c->error) { sprintf(msg, "Failed to synchronize drive cache"); sprintf(msg + strlen(msg), ". SCSI error : "); scsi_error_msg(d, c->sense, 14, msg + strlen(msg), &key, &asc, &ascq); libdax_msgs_submit(libdax_messenger, d->global_index, 0x0002017f, LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH, msg, 0, 0); d->cancel = 1; goto ex; } if (spc_wait_unit_attention(d, 3600, "SYNCHRONIZE CACHE", 0) <= 0) d->cancel = 1; else d->needs_sync_cache = 0; ex: BURN_FREE_MEM(msg); BURN_FREE_MEM(c); } /* ts A61023 : http://libburn.pykix.org/ticket/14 get size and free space of drive buffer */ int mmc_read_buffer_capacity(struct burn_drive *d) { struct buffer *buf = NULL; struct command *c = NULL; unsigned char *data; int alloc_len = 12, ret; BURN_ALLOC_MEM(buf, struct buffer, 1); BURN_ALLOC_MEM(c, struct command, 1); if (mmc_function_spy(d, "mmc_read_buffer_capacity") <= 0) {ret = 0; goto ex;} scsi_init_command(c, MMC_READ_BUFFER_CAPACITY, sizeof(MMC_READ_BUFFER_CAPACITY)); c->dxfer_len = alloc_len; c->opcode[7] = (c->dxfer_len >> 8) & 0xff; c->opcode[8] = c->dxfer_len & 0xff; c->retry = 1; c->page = buf; memset(c->page->data, 0, alloc_len); c->page->bytes = 0; c->page->sectors = 0; c->dir = FROM_DRIVE; d->issue_command(d, c); /* >>> ??? error diagnostics */ if (c->error) {ret = 0; goto ex;} data = c->page->data; d->progress.buffer_capacity = (data[4]<<24)|(data[5]<<16)|(data[6]<<8)|data[7]; d->progress.buffer_available = (data[8]<<24)|(data[9]<<16)|(data[10]<<8)|data[11]; if (d->progress.buffer_capacity < d->progress.buffer_available) { /* Default mad buffer usage to 50 percent */ d->progress.buffer_available = d->progress.buffer_capacity / 2; } d->pessimistic_buffer_free = d->progress.buffer_available; d->pbf_altered = 0; if (d->progress.buffered_bytes >= d->progress.buffer_capacity){ double fill; fill = d->progress.buffer_capacity - d->progress.buffer_available; if (fill < d->progress.buffer_min_fill && fill>=0) d->progress.buffer_min_fill = fill; } ret = 1; ex:; BURN_FREE_MEM(c); BURN_FREE_MEM(buf); return ret; } /* ts A61219 : learned much from dvd+rw-tools-7.0: plus_rw_format() and mmc5r03c.pdf, 6.5 FORMAT UNIT */ /* @param size The size (in bytes) to be sent with the FORMAT comand @param flag bit1+2: size mode 0 = use parameter size as far as it makes sense 1 = insist in size 0 even if there is a better default known 2 = without bit7: format to maximum available size with bit7 : take size from indexed format descriptor 3 = format to default size bit3= expand format up to at least size bit4= enforce re-format of (partly) formatted media bit5= try to disable eventual defect management bit6= try to avoid lengthy media certification bit7= bit8 to bit15 contain the index of the format to use bit8-bit15 = see bit7 bit16= enable POW on blank BD-R */ int mmc_format_unit(struct burn_drive *d, off_t size, int flag) { struct buffer *buf = NULL; struct command *c = NULL; int ret, tolerate_failure = 0, return_immediately = 0, i, format_type; int index, format_sub_type = 0, format_00_index, size_mode; int accept_count = 0; off_t num_of_blocks = 0, diff, format_size, i_size, format_00_max_size; off_t min_size = -1, max_size = -1; char *msg = NULL, descr[80]; int key, asc, ascq; int full_format_type = 0x00; /* Full Format (or 0x10 for DVD-RW ?) */ BURN_ALLOC_MEM(buf, struct buffer, 1); BURN_ALLOC_MEM(c, struct command, 1); BURN_ALLOC_MEM(msg, char, 256); mmc_start_if_needed(d, 0); if (mmc_function_spy(d, "mmc_format_unit") <= 0) {ret = 0; goto ex;} size_mode = (flag >> 1) & 3; scsi_init_command(c, MMC_FORMAT_UNIT, sizeof(MMC_FORMAT_UNIT)); c->retry = 1; c->page = buf; c->page->bytes = 12; c->page->sectors = 0; c->dir = TO_DRIVE; c->timeout = Libburn_mmc_blank_timeouT; memset(c->page->data, 0, c->page->bytes); descr[0] = 0; c->page->data[1] = 0x02; /* Immed */ c->page->data[3] = 8; /* Format descriptor length */ num_of_blocks = size / 2048; mmc_int_to_four_char(c->page->data + 4, num_of_blocks); if (flag & 128) { /* explicitely chosen format descriptor */ /* use case: the app knows what to do */ ret = mmc_read_format_capacities(d, -1); if (ret <= 0) goto selected_not_suitable; index = (flag >> 8) & 0xff; if(index < 0 || index >= d->num_format_descr) { selected_not_suitable:; libdax_msgs_submit(libdax_messenger, d->global_index, 0x00020132, LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH, "Selected format is not suitable for libburn", 0, 0); {ret = 0; goto ex;} } if (!(d->current_profile == 0x13 || d->current_profile == 0x14 || d->current_profile == 0x1a || d->current_profile == 0x12 || d->current_profile == 0x41 || d->current_profile == 0x43)) goto unsuitable_media; format_type = d->format_descriptors[index].type; if (!(format_type == 0x00 || format_type == 0x01 || format_type == 0x10 || format_type == 0x11 || format_type == 0x13 || format_type == 0x15 || format_type == 0x26 || format_type == 0x30 || format_type == 0x31 || format_type == 0x32)) goto selected_not_suitable; if (flag & 4) { num_of_blocks = d->format_descriptors[index].size / 2048; mmc_int_to_four_char(c->page->data + 4, num_of_blocks); } if (format_type != 0x26) for (i = 0; i < 3; i++) c->page->data[9 + i] = ( d->format_descriptors[index].tdp >> (16 - 8 * i)) & 0xff; if (format_type == 0x30 || format_type == 0x31) { format_sub_type = 0; if (flag & 64) { if (d->current_feat23h_byte4 & 2) /* Quick certification */ format_sub_type = 3; } else { if (d->current_feat23h_byte4 & 1) /* Full certification */ format_sub_type = 2; } } else if (format_type == 0x32 || (format_type == 0x00 && d->current_profile == 0x41)) { if (flag & (1 << 16)) format_sub_type = 0; /* SRM + POW */ else format_sub_type = 1; /* SRM (- POW) */ } if (d->current_profile == 0x12 && format_type !=0x01 && (flag & 64)) { /* DCRT and CmpList, see below */ c->page->data[1] |= 0x20; c->opcode[1] |= 0x08; } c->page->data[1] |= 0x80; /* FOV = this flag vector is valid */ sprintf(descr, "%s (descr %d)", d->current_profile_text,index); return_immediately = 1; /* caller must do the waiting */ } else if (d->current_profile == 0x1a) { /* DVD+RW */ /* use case: background formatting during write !(flag&4) de-icing as explicit formatting action (flag&4) */ /* mmc5r03c.pdf , 6.5.4.2.14, DVD+RW Basic Format */ format_type = 0x26; /* >>> ??? is this "| 8" a bug ? */ if ((size <= 0 && !(flag & 2)) || (flag & (4 | 8))) { /* maximum capacity */ memset(c->page->data + 4, 0xff, 4); num_of_blocks = 0xffffffff; } if(d->bg_format_status == 2 || (d->bg_format_status == 3 && !(flag & 16))) { sprintf(msg,"FORMAT UNIT ignored. Already %s.", (d->bg_format_status == 2 ? "in progress" : "completed")); libdax_msgs_submit(libdax_messenger, d->global_index, 0x00020120, LIBDAX_MSGS_SEV_NOTE, LIBDAX_MSGS_PRIO_HIGH, msg, 0,0); {ret = 2; goto ex;} } if (!(flag & 16)) /* if not re-format is desired */ if (d->bg_format_status == 1) /* is partly formatted */ c->page->data[11] = 1; /* Restart bit */ sprintf(descr, "DVD+RW (fs=%d,rs=%d)", d->bg_format_status, (c->page->data[11] == 1)); if (flag & 4) return_immediately = 1;/* caller must do the waiting */ } else if (d->current_profile == 0x13 && !(flag & 16)) { /*DVD-RW restricted overwrite*/ /* use case: quick grow formatting during write */ ret = mmc_read_format_capacities(d, 0x13); if (ret > 0) { if (d->best_format_type == 0x13) { if (d->best_format_size <= 0) {ret = 1; goto ex;} } else { if (d->format_descr_type == 2) /* formatted */ {ret = 1; goto ex;} if (d->format_descr_type == 3){/*intermediate*/ d->needs_close_session = 1; {ret = 1; goto ex;} } /* does trying make sense at all ? */ tolerate_failure = 1; } } if (d->best_format_type == 0x13 && (flag & (4 | 8))) { num_of_blocks = d->best_format_size / 2048; if (flag & 8) { /* num_of_blocks needed to reach size */ diff = (size - d->format_curr_max_size) /32768; if ((size - d->format_curr_max_size) % 32768) diff++; diff *= 16; if (diff < num_of_blocks) num_of_blocks = diff; } if (num_of_blocks > 0) mmc_int_to_four_char(c->page->data + 4, num_of_blocks); } /* 6.5.4.2.8 , DVD-RW Quick Grow Last Border */ format_type = 0x13; c->page->data[11] = 16; /* block size * 2k */ sprintf(descr, "DVD-RW quick grow"); } else if (d->current_profile == 0x14 || (d->current_profile == 0x13 && (flag & 16))) { /* DVD-RW sequential recording (or Overwrite for re-format) */ /* use case : transition from Sequential to Overwrite re-formatting of Overwrite media */ /* To Restricted Overwrite */ /* 6.5.4.2.10 Format Type = 15h (DVD-RW Quick) */ /* or 6.5.4.2.1 Format Type = 00h (Full Format) */ /* or 6.5.4.2.5 Format Type = 10h (DVD-RW Full Format) */ mmc_read_format_capacities(d, (flag & 4) ? full_format_type : 0x15); if (d->best_format_type == 0x15 || d->best_format_type == full_format_type) { if ((flag & 4) || d->best_format_type == full_format_type) { num_of_blocks = d->best_format_size / 2048; mmc_int_to_four_char(c->page->data + 4, num_of_blocks); } } else { no_suitable_formatting_type:; libdax_msgs_submit(libdax_messenger, d->global_index, 0x00020131, LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH, "No suitable formatting type offered by drive", 0, 0); {ret = 0; goto ex;} } format_type = d->best_format_type; sprintf(descr, "DVD-RW %s", format_type == 0x15 ? "quick" : "full"); return_immediately = 1; /* caller must do the waiting */ } else if (d->current_profile == 0x12) { /* ts A80417 : DVD-RAM */ /* 6.5.4.2.1 Format Type = 00h (Full Format) 6.5.4.2.2 Format Type = 01h (Spare Area Expansion) */ index = format_00_index = -1; format_size = format_00_max_size = -1; for (i = 0; i < d->num_format_descr; i++) { format_type = d->format_descriptors[i].type; i_size = d->format_descriptors[i].size; if (format_type != 0x00 && format_type != 0x01) continue; if (flag & 32) { /* No defect mgt */ /* Search for largest 0x00 format descriptor */ if (format_type != 0x00) continue; if (i_size < format_size) continue; format_size = i_size; index = i; continue; } else if (flag & 4) { /*Max or default size with mgt*/ /* Search for second largest 0x00 format descriptor. For max size allow format type 0x01. */ if (format_type == 0x00) { if (i_size < format_size) continue; if (i_size < format_00_max_size) { format_size = i_size; index = i; continue; } format_size = format_00_max_size; index = format_00_index; format_00_max_size = i_size; format_00_index = i; continue; } if (size_mode==3) continue; if (i_size > format_size) { format_size = i_size; index = i; } continue; } /* Search for smallest 0x0 or 0x01 descriptor >= size */; if (d->format_descriptors[i].size >= size && (format_size < 0 || i_size < format_size) ) { format_size = i_size; index = i; } } if(index < 0 && (flag & 4) && !(flag & 32)) { format_size = format_00_max_size; index = format_00_index; } if(index < 0) goto no_suitable_formatting_type; format_type = d->format_descriptors[index].type; num_of_blocks = d->format_descriptors[index].size / 2048; mmc_int_to_four_char(c->page->data + 4, num_of_blocks); for (i = 0; i < 3; i++) c->page->data[9 + i] = ( d->format_descriptors[index].tdp >> (16 - 8 * i)) & 0xff; sprintf(descr, "%s", d->current_profile_text); return_immediately = 1; /* caller must do the waiting */ c->page->data[1] |= 0x80; /* FOV = this flag vector is valid */ if ((flag & 64) && format_type != 0x01) { /* MMC-5 6.5.3.2 , 6.5.4.2.1.2 DCRT: Disable Certification and maintain number of blocks CmpList: Override maintaining of number of blocks with DCRT */ /* ts A80426 : prevents change of formatted size with PHILIPS SPD3300L and Verbatim 3x DVD-RAM and format_type 0x00. Works on TSSTcorp SH-S203B */ c->page->data[1] |= 0x20; c->opcode[1] |= 0x08; } } else if (d->current_profile == 0x41) { /* BD-R SRM */ index = -1; format_size = -1; if (d->num_format_descr <= 0) goto no_suitable_formatting_type; if (d->format_descriptors[0].type != 0) goto no_suitable_formatting_type; for (i = 0; i < d->num_format_descr; i++) { format_type = d->format_descriptors[i].type; i_size = d->format_descriptors[i].size; if (format_type != 0x00 && format_type != 0x32) continue; if (flag & 32) { /* No defect mgt */ /* ts A81211 : MMC-5 6.5.4.2.17.1 When formatted with Format Type 32h, the BD-R disc is required to allocate a non-zero number of spares. */ goto no_suitable_formatting_type; } else if(size_mode == 2) { /* max payload size */ /* search largest 0x32 format descriptor */ if(format_type != 0x32) continue; } else if(size_mode == 3) { /* default payload size */ if (format_type == 0x00) { index = i; break; } continue; } else { /* defect managed format with size wish */ #ifdef Libburn_bd_r_format_olD /* search for smallest 0x32 >= size */ if(format_type != 0x32) continue; if (i_size < size) continue; if (format_size >= 0 && i_size >= format_size) continue; index = i; format_size = i_size; continue; #else /* Libburn_bd_r_format_olD */ /* search largest and smallest 0x32 */ if(format_type != 0x32) continue; if (i_size < min_size || min_size < 0) min_size = i_size; if (i_size > max_size) max_size = i_size; #endif /* ! Libburn_bd_r_format_olD */ } /* common for all cases which search largest descriptors */ if (i_size > format_size) { format_size = i_size; index = i; } } if (size_mode == 2 && index < 0 && !(flag & 32)) index = 0; if (index < 0) goto no_suitable_formatting_type; format_type = d->format_descriptors[index].type; if (flag & (1 << 16)) format_sub_type = 0; /* SRM + POW */ else format_sub_type = 1; /* SRM (- POW) */ #ifdef Libburn_bd_r_format_olD if (0) { #else if (size_mode == 0 || size_mode == 1) { #endif /* ! Libburn_bd_r_format_olD */ if (min_size < 0 || max_size < 0) goto no_suitable_formatting_type; if (size <= 0) size = min_size; if (size % 0x10000) size += 0x10000 - (size % 0x10000); if (size < min_size) goto no_suitable_formatting_type; else if(size > max_size) goto no_suitable_formatting_type; num_of_blocks = size / 2048; mmc_int_to_four_char(c->page->data + 4, num_of_blocks); for (i = 0; i < 3; i++) c->page->data[9 + i] = 0; } else { num_of_blocks = d->format_descriptors[index].size / 2048; mmc_int_to_four_char(c->page->data + 4, num_of_blocks); for (i = 0; i < 3; i++) c->page->data[9 + i] = ( d->format_descriptors[index].tdp >> (16 - 8 * i)) & 0xff; } sprintf(descr, "%s", d->current_profile_text); return_immediately = 1; /* caller must do the waiting */ c->page->data[1] |= 0x80; /* FOV = this flag vector is valid */ } else if (d->current_profile == 0x43) { /* BD-RE */ index = -1; format_size = -1; if (d->num_format_descr <= 0) goto no_suitable_formatting_type; if (d->format_descriptors[0].type != 0) goto no_suitable_formatting_type; for (i = 0; i < d->num_format_descr; i++) { format_type = d->format_descriptors[i].type; i_size = d->format_descriptors[i].size; if (format_type != 0x00 && format_type != 0x30 && format_type != 0x31) continue; if (flag & 32) { /* No defect mgt */ /* search largest format 0x31 */ if(format_type != 0x31) continue; } else if(size_mode == 2) { /* max payload size */ /* search largest 0x30 format descriptor */ if(format_type != 0x30) continue; } else if(size_mode == 3) { /* default payload size */ if (accept_count < 1) index = 0; /* this cannot certify */ /* ts A81129 LG GGW-H20L YL03 refuses on 0x30 with "Quick certification". dvd+rw-format does 0x00 by default and succeeds quickly. */ if ((flag & 64) && format_type == 0x00) { index = i; break; } if(format_type != 0x30) continue; accept_count++; if (accept_count == 1) index = i; continue; } else { /* defect managed format with size wish */ #ifdef Libburn_bd_re_format_olD /* search for smallest 0x30 >= size */ if(format_type != 0x30) continue; if (i_size < size) continue; if (format_size >= 0 && i_size >= format_size) continue; index = i; format_size = i_size; continue; #else /* Libburn_bd_re_format_olD */ /* search largest and smallest 0x30 */ if(format_type != 0x30) continue; if (i_size < min_size || min_size < 0) min_size = i_size; if (i_size > max_size) max_size = i_size; #endif /* ! Libburn_bd_re_format_olD */ } /* common for all cases which search largest descriptors */ if (i_size > format_size) { format_size = i_size; index = i; } } if (size_mode == 2 && index < 0 && !(flag & 32)) index = 0; if (index < 0) goto no_suitable_formatting_type; format_type = d->format_descriptors[index].type; if (format_type == 0x30 || format_type == 0x31) { if ((flag & 64) || !(d->current_feat23h_byte4 & 3)) { format_sub_type = 0; if (!(flag & 64)) libdax_msgs_submit(libdax_messenger, d->global_index, 0x0002019e, LIBDAX_MSGS_SEV_NOTE, LIBDAX_MSGS_PRIO_HIGH, "Drive does not support media certification", 0, 0); } else { /* With Certification */ if (d->current_feat23h_byte4 & 1) format_sub_type = 2; /* Full */ else format_sub_type = 3; /* Quick */ } } #ifdef Libburn_bd_re_format_olD if (0) { #else if (size_mode == 0 || size_mode == 1) { #endif /* ! Libburn_bd_re_format_olD */ if (min_size < 0 || max_size < 0) goto no_suitable_formatting_type; if (size <= 0) size = min_size; if (size % 0x10000) size += 0x10000 - (size % 0x10000); if (size < min_size) goto no_suitable_formatting_type; else if(size > max_size) goto no_suitable_formatting_type; num_of_blocks = size / 2048; mmc_int_to_four_char(c->page->data + 4, num_of_blocks); for (i = 0; i < 3; i++) c->page->data[9 + i] = 0; } else { num_of_blocks = d->format_descriptors[index].size / 2048; mmc_int_to_four_char(c->page->data + 4, num_of_blocks); for (i = 0; i < 3; i++) c->page->data[9 + i] = ( d->format_descriptors[index].tdp >> (16 - 8 * i)) & 0xff; } sprintf(descr, "%s", d->current_profile_text); return_immediately = 1; /* caller must do the waiting */ c->page->data[1] |= 0x80; /* FOV = this flag vector is valid */ } else { /* >>> other formattable types to come */ unsuitable_media:; sprintf(msg, "Unsuitable media detected. Profile %4.4Xh %s", d->current_profile, d->current_profile_text); libdax_msgs_submit(libdax_messenger, d->global_index, 0x0002011e, LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH, msg, 0, 0); {ret = 0; goto ex;} } c->page->data[8] = (format_type << 2) | (format_sub_type & 3); /* MMC-5 Table 253 , column Type Dependent Parameter */ if (format_type == 0x00 || format_type == 0x01 || format_type == 0x31) { /* Block Length 0x0800 = 2k */ c->page->data[ 9] = 0x00; c->page->data[10] = 0x08; c->page->data[11] = 0x00; } else if (format_type >= 0x10 && format_type <= 0x15) { /* ECC block size = 16 * 2k */ c->page->data[ 9] = 0; c->page->data[10] = 0; c->page->data[11] = 16; } sprintf(msg, "Format type %2.2Xh \"%s\", blocks = %.f", format_type, descr, (double) num_of_blocks); libdax_msgs_submit(libdax_messenger, d->global_index, 0x00000002, LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_ZERO, msg, 0, 0); sprintf(msg, "CDB: "); for (i = 0; i < 6; i++) sprintf(msg + strlen(msg), "%2.2X ", c->opcode[i]); libdax_msgs_submit(libdax_messenger, d->global_index, 0x00000002, LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_ZERO, msg, 0, 0); sprintf(msg, "Format list: "); for (i = 0; i < 12; i++) sprintf(msg + strlen(msg), "%2.2X ", c->page->data[i]); strcat(msg, "\n"); libdax_msgs_submit(libdax_messenger, d->global_index, 0x00000002, LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_ZERO, msg, 0, 0); #ifdef Libburn_do_not_format_dvd_ram_or_bd_rE if(d->current_profile == 0x43 || d->current_profile == 0x12) { sprintf(msg, "Formatting of %s not implemented yet - This is a dummy", d->current_profile_text); libdax_msgs_submit(libdax_messenger, d->global_index, 0x00000002, LIBDAX_MSGS_SEV_WARNING, LIBDAX_MSGS_PRIO_ZERO, msg, 0, 0); {ret = 1; goto ex;} } #endif /* Libburn_do_not_format_dvd_ram_or_bd_rE */ /* <<< fprintf(stderr, "\nlibburn_DEBUG: FORMAT UNIT temporarily disabled.\n"); ret = 1; goto ex; */ d->issue_command(d, c); if (c->error && !tolerate_failure) { spc_decode_sense(c->sense, 0, &key, &asc, &ascq); if (key != 0) { sprintf(msg, "SCSI error on format_unit(%s): ", descr); scsi_error_msg(d, c->sense, 14, msg + strlen(msg), &key, &asc, &ascq); libdax_msgs_submit(libdax_messenger, d->global_index, 0x00020122, LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH, msg, 0, 0); } {ret = 0; goto ex;} } else if ((!c->error) && (format_type == 0x13 || format_type == 0x15)) d->needs_close_session = 1; if (return_immediately) {ret = 1; goto ex;} usleep(1000000); /* there seems to be a little race condition */ for (ret = 0; ret <= 0 ;) { usleep(50000); ret = spc_test_unit_ready(d); } mmc_sync_cache(d); ret = 1; ex:; BURN_FREE_MEM(msg); BURN_FREE_MEM(c); BURN_FREE_MEM(buf); return ret; } /* ts B40107 : Outsourced from mmc_get_performance_al() */ static int new_burn_speed_descr(struct burn_drive *d, int sd_source, struct burn_speed_descriptor **sd, int flag) { int ret; ret = burn_speed_descriptor_new(&(d->mdata->speed_descriptors), NULL, d->mdata->speed_descriptors, 0); if (ret <= 0) return ret; *sd = d->mdata->speed_descriptors; (*sd)->source = sd_source; if (d->current_profile > 0) { (*sd)->profile_loaded = d->current_profile; strcpy((*sd)->profile_name, d->current_profile_text); } return 1; } /* ts B40107 : Outsourced from mmc_get_performance_al() and extended for descr_type 0x00 @param flag bit0= register speed descriptors */ static int interpret_performance(struct burn_drive *d, struct command *c, int descr_type, int *alloc_len, int *max_descr, int *num_descr, int flag) { int len, i, b, ret, old_alloc_len; int exact_bit, read_speed, write_speed, start_speed; int min_write_speed = 0x7fffffff, max_write_speed = 0; int min_read_speed = 0x7fffffff, max_read_speed = 0; unsigned long end_lba; unsigned char *pd; struct burn_speed_descriptor *sd; /* ts A61225 : 1 = report about speed descriptors */ static int speed_debug = 0; len = mmc_four_char_to_int(c->page->data); old_alloc_len = *alloc_len; *alloc_len = len + 4; if (len + 4 > old_alloc_len) len = old_alloc_len - 4; *num_descr = ( *alloc_len - 8 ) / 16; if (*max_descr == 0) { *max_descr = *num_descr; {ret = 1; goto ex;} } if (old_alloc_len < 16) {ret = 1; goto ex;} if (len < 12) {ret = 0; goto ex;} min_write_speed = d->mdata->min_write_speed; max_write_speed = d->mdata->max_write_speed; pd = c->page->data; if (*num_descr > *max_descr) *num_descr = *max_descr; for (i = 0; i < *num_descr && (flag & 1); i++) { end_lba = read_speed = write_speed = start_speed = 0; if (descr_type == 0x03) { exact_bit = !!(pd[8 + i*16] & 2); for (b = 0; b < 4 ; b++) { end_lba += ((unsigned long int) pd[8 + i*16 + 4 + b]) << (24 - 8 * b); read_speed += pd[8 + i*16 + 8 + b] << (24 - 8 * b); write_speed += pd[8 + i*16 + 12 + b] << (24 - 8 * b); } if (end_lba > 0x7ffffffe) end_lba = 0x7ffffffe; if (speed_debug) fprintf(stderr, "LIBBURN_DEBUG: kB/s: write=%d read=%d end=%lu exact=%d\n", write_speed, read_speed, end_lba, exact_bit); ret = new_burn_speed_descr(d, 2, &sd, 0); if (ret > 0) { sd->wrc = (pd[8 + i*16] >> 3 ) & 3; sd->exact = exact_bit; sd->mrw = pd[8 + i*16] & 1; sd->end_lba = end_lba; sd->write_speed = write_speed; sd->read_speed = read_speed; } } else { /* descr_type == 0 */ for (b = 0; b < 4 ; b++) { start_speed += pd[8 + i*16 + 4 + b] << (24 - 8 * b); end_lba += ((unsigned long int) pd[8 + i*16 + 8 + b]) << (24 - 8 * b); read_speed += pd[8 + i*16 + 12 + b] << (24 - 8 * b); } if (speed_debug) fprintf(stderr, "LIBBURN_DEBUG: start=%d end=%d lba=%lu\n", start_speed, read_speed, end_lba); if (end_lba > 0x7ffffffe) end_lba = 0x7ffffffe; ret = new_burn_speed_descr(d, 3, &sd, 0); if (ret > 0) { sd->end_lba = end_lba; sd->read_speed = start_speed; } if (start_speed > 0 && start_speed < min_read_speed) min_read_speed = start_speed; if (start_speed > max_read_speed) max_read_speed = start_speed; ret = new_burn_speed_descr(d, 3, &sd, 0); if (ret > 0) { sd->end_lba = end_lba; sd->read_speed = read_speed; } } if ((int) end_lba > d->mdata->max_end_lba) d->mdata->max_end_lba = end_lba; if ((int) end_lba < d->mdata->min_end_lba) d->mdata->min_end_lba = end_lba; if (write_speed > 0 && write_speed < min_write_speed) min_write_speed = write_speed; if (write_speed > max_write_speed) max_write_speed = write_speed; if (read_speed > 0 && read_speed < min_read_speed) min_read_speed = read_speed; if (read_speed > max_read_speed) max_read_speed = read_speed; } if (min_write_speed < 0x7fffffff) d->mdata->min_write_speed = min_write_speed; if (max_write_speed > 0) d->mdata->max_write_speed = max_write_speed; /* there is no mdata->min_read_speed yet if (min_read_speed < 0x7fffffff) d->mdata->min_read_speed = min_read_speed; */ if (max_read_speed > 0) d->mdata->max_read_speed = max_read_speed; ret = 1; ex:; return ret; } /* ts A61225 */ /* @param flag bit0= register speed descriptors */ static int mmc_get_performance_al(struct burn_drive *d, int descr_type, int *alloc_len, int *max_descr, int flag) { int num_descr, ret; struct buffer *buf = NULL; struct command *c = NULL; BURN_ALLOC_MEM(buf, struct buffer, 1); BURN_ALLOC_MEM(c, struct command, 1); if (d->current_profile < 0) mmc_get_configuration(d); if (*alloc_len < 8) {ret = 0; goto ex;} if (descr_type != 0x00 && descr_type != 0x03) {ret = 0; goto ex;} scsi_init_command(c, MMC_GET_PERFORMANCE, sizeof(MMC_GET_PERFORMANCE)); /* >>> future: maintain a list of write descriptors if (max_descr > d->max_write_descr - d->num_write_descr) max_descr = d->max_write_descr; */ c->dxfer_len = *alloc_len; if (descr_type == 0x00) c->opcode[1] = 0x10; /* Data Type: nominal read performance */ c->opcode[8] = ( *max_descr >> 8 ) & 0xff; c->opcode[9] = ( *max_descr >> 0 ) & 0xff; c->opcode[10] = descr_type; c->retry = 1; c->page = buf; c->page->sectors = 0; c->page->bytes = 0; c->dir = FROM_DRIVE; d->issue_command(d, c); #ifdef Libisofs_simulate_old_mmc1_drivE c->error = 1; c->sense[0] = 0x70; /* Fixed format sense data */ c->sense[2] = 0x5; c->sense[12] = 0x20; c->sense[13] = 0x0; #endif /* Libisofs_simulate_old_mmc1_drivE */ if (c->error) {ret = 0; goto ex;} ret = interpret_performance(d, c, descr_type, alloc_len, max_descr, &num_descr, flag); if (ret <= 0) goto ex; ret = num_descr; ex:; BURN_FREE_MEM(buf); BURN_FREE_MEM(c); return ret; } int mmc_get_performance(struct burn_drive *d, int descr_type, int flag) { int alloc_len = 8, max_descr = 0, ret; mmc_start_if_needed(d, 1); if (mmc_function_spy(d, "mmc_get_write_performance") <= 0) return 0; /* first command execution to learn number of descriptors and dxfer_len */ ret = mmc_get_performance_al(d, descr_type, &alloc_len, &max_descr, 0); if (max_descr > 0 && ret > 0) { /* Some drives announce only 1 descriptor if asked for 0. So ask twice for non-0 descriptors. */ ret = mmc_get_performance_al(d, descr_type, &alloc_len, &max_descr, 0); } /* fprintf(stderr,"LIBBURN_DEBUG: ACh alloc_len = %d , ret = %d\n", alloc_len, ret); */ if (max_descr > 0 && ret > 0) { /* final execution with announced length */ max_descr = (alloc_len - 8) / 16; ret = mmc_get_performance_al(d, descr_type, &alloc_len, &max_descr, 1); } return ret; } int mmc_get_write_performance(struct burn_drive *d) { int ret; ret = mmc_get_performance(d, 0x03, 0); return ret; } /* ts A61229 : outsourced from spc_select_write_params() */ /* Note: Page data is not zeroed here in order not to overwrite preset defaults. Thus memset(pd, 0, 2 + d->mdata->write_page_length); is the eventual duty of the caller. */ int mmc_compose_mode_page_5(struct burn_drive *d, struct burn_session *s, int tnum, const struct burn_write_opts *o, unsigned char *pd) { unsigned char *catalog = NULL; char isrc_text[13]; struct isrc *isrc; pd[0] = 5; pd[1] = d->mdata->write_page_length; if (d->current_profile == 0x13) { /* A61229 : DVD-RW restricted overwrite */ /* learned from transport.hxx : page05_setup() and mmc3r10g.pdf table 347 */ /* BUFE (burnproof), no LS_V (i.e. default Link Size, i hope), no simulate, write type 0 = packet */ pd[2] = (1 << 6); /* no multi, fixed packet, track mode 5 */ pd[3] = (1 << 5) | 5; /* Data Block Type */ pd[4] = 8; /* Link size dummy */ pd[5] = 0; } else if ((d->current_profile == 0x14 || d->current_profile == 0x11 || d->current_profile == 0x15) && o->write_type == BURN_WRITE_SAO) { /* ts A70205 : DVD-R[W][/DL] : Disc-at-once, DAO */ /* Learned from dvd+rw-tools and mmc5r03c.pdf . See doc/cookbook.txt for more detailed references. */ /* BUFE , LS_V = 0, Test Write, Write Type = 2 SAO (DAO) */ pd[2] = ((!!o->underrun_proof) << 6) | ((!!o->simulate) << 4) | 2; /* No multi-session , FP = 0 , Copy = 0, Track Mode = 5 */ pd[3] = 5; #ifdef Libburn_pioneer_dvr_216d_load_mode5 /* >>> use track mode from mmc_get_nwa() */ /* >>> pd[3] = (pd[3] & ~0xf) | (d->track_inf[5] & 0xf); */ #endif /* Data Block Type = 8 */ pd[4] = 8; } else if (d->current_profile == 0x14 || d->current_profile == 0x11 || d->current_profile == 0x15) { /* ts A70128 : DVD-R[W][/DL] Incremental Streaming */ /* Learned from transport.hxx : page05_setup() and mmc5r03c.pdf 7.5, 4.2.3.4 Table 17 and spc3r23.pdf 6.8, 7.4.3 */ /* BUFE , LS_V = 1, Test Write, Write Type = 0 Packet/Incremental */ pd[2] = ((!!o->underrun_proof) << 6) | (1 << 5) | ((!!o->simulate) << 4); /* Multi-session , FP = 1 , Track Mode = 5 */ pd[3] = ((3 * !!o->multi) << 6) | (1 << 5) | 5; /* Data Block Type = 8 */ pd[4] = 8; /* Link Size */ if (d->current_feat21h_link_size >= 0) pd[5] = d->current_feat21h_link_size; else pd[5] = 16; if (d->current_feat21h_link_size != 16) { char msg[80]; sprintf(msg, "Feature 21h Link Size = %d (expected 16)\n", d->current_feat21h_link_size); libdax_msgs_submit(libdax_messenger, -1, 0x00000002, LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_ZERO, msg, 0, 0); } /* Packet Size */ pd[13] = 16; } else if (d->current_profile == 0x1a || d->current_profile == 0x1b || d->current_profile == 0x2b || d->current_profile == 0x12 || d->current_profile == 0x41 || d->current_profile == 0x42 || d->current_profile == 0x43) { /* not with DVD+R[W][/DL] or DVD-RAM or BD-R[E] */; return 0; } else { /* Traditional setup for CD */ pd[2] = ((!!o->underrun_proof) << 6) | ((!!o->simulate) << 4) | (o->write_type & 0x0f); /* ts A61106 : MMC-1 table 110 : multi==0 or multi==3 */ pd[3] = ((3 * !!o->multi) << 6) | (o->control & 0x0f); pd[4] = spc_block_type(o->block_type); /* fprintf(stderr, "libburn_EXPERIMENTAL: block_type = %d, pd[4]= %u\n", o->block_type, (unsigned int) pd[4]); */ /* ts A61104 */ if(!(o->control&4)) /* audio (MMC-1 table 61) */ if(o->write_type == BURN_WRITE_TAO) pd[4] = 0; /* Data Block Type: Raw Data */ pd[14] = 0; /* audio pause length MSB */ pd[15] = 150; /* audio pause length LSB */ /*XXX need session format! */ /* ts A61229 : but session format (pd[8]) = 0 seems ok */ /* Media Catalog Number at byte 16 to 31, MMC-5, 7.5, Tables 664, 670 */ if (o->has_mediacatalog) catalog = (unsigned char *) o->mediacatalog; else if (s != NULL) { if (s->mediacatalog[0]) catalog = s->mediacatalog; } if (catalog != NULL && d->mdata->write_page_length >= 30) { pd[16] = 0x80; /* MCVAL */ memcpy(pd + 17, catalog, 13); } /* ISRC at bytes 32 to 47. Tables 664, 671 */ /* SCMS at byte 3 bit 4 */ isrc_text[0] = 0; if (s != NULL && o->write_type == BURN_WRITE_TAO) { if (tnum >= 0 && tnum < s->tracks) { if (s->track[tnum]->isrc.has_isrc) { isrc = &(s->track[tnum]->isrc); isrc_text[0] = isrc->country[0]; isrc_text[1] = isrc->country[1]; isrc_text[2] = isrc->owner[0]; isrc_text[3] = isrc->owner[1]; isrc_text[4] = isrc->owner[2]; sprintf(isrc_text + 5, "%-2.2u%-5.5u", (unsigned int) isrc->year, isrc->serial); } if ((s->track[tnum]->mode & BURN_SCMS) && !(s->track[tnum]->mode & BURN_COPY)) pd[3] |= 0x10; } } if (isrc_text[0] != 0 && d->mdata->write_page_length >= 46) { pd[32] = 0x80; /* TCVAL */ memcpy(pd + 33, isrc_text, 12); } } return 1; } /* A70812 ts */ int mmc_read_10(struct burn_drive *d, int start,int amount, struct buffer *buf) { struct command *c; char *msg = NULL; int key, asc, ascq, silent; c = &(d->casual_command); mmc_start_if_needed(d, 0); if (mmc_function_spy(d, "mmc_read_10") <= 0) return -1; if (amount > BUFFER_SIZE / 2048) return -1; scsi_init_command(c, MMC_READ_10, sizeof(MMC_READ_10)); c->dxfer_len = amount * 2048; c->retry = 1; mmc_int_to_four_char(c->opcode + 2, start); c->opcode[7] = (amount >> 8) & 0xFF; c->opcode[8] = amount & 0xFF; c->page = buf; c->page->bytes = 0; c->page->sectors = 0; c->dir = FROM_DRIVE; d->issue_command(d, c); /* <<< replace by mmc_eval_read_error */; if (c->error) { msg = calloc(1, 256); if (msg != NULL) { sprintf(msg, "SCSI error on read_10(%d,%d): ", start, amount); scsi_error_msg(d, c->sense, 14, msg + strlen(msg), &key, &asc, &ascq); silent = (d->silent_on_scsi_error == 1); if (key == 5 && asc == 0x64 && ascq == 0x0) { d->had_particular_error |= 1; if (d->silent_on_scsi_error == 2) silent = 1; } if(!silent) libdax_msgs_submit(libdax_messenger, d->global_index, 0x00020144, (d->silent_on_scsi_error == 3) ? LIBDAX_MSGS_SEV_DEBUG : LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH, msg, 0, 0); free(msg); } return BE_CANCELLED; } buf->sectors = amount; buf->bytes = amount * 2048; return 0; } #ifdef Libburn_develop_quality_scaN /* B21108 ts : Vendor specific command REPORT ERROR RATE, see http://liggydee.cdfreaks.com/ddl/errorcheck.pdf */ int mmc_nec_optiarc_f3(struct burn_drive *d, int sub_op, int start_lba, int rate_period, int *ret_lba, int *error_rate1, int *error_rate2) { struct buffer *buf = NULL; struct command *c; char *msg = NULL; int key, asc, ascq, ret; static unsigned char MMC_NEC_OPTIARC_F3[] = { 0xF3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; BURN_ALLOC_MEM(buf, struct buffer, 1); BURN_ALLOC_MEM(c, struct command, 1); mmc_start_if_needed(d, 0); if (mmc_function_spy(d, "mmc_nec_optiarc_f3") <= 0) return -1; scsi_init_command(c, MMC_NEC_OPTIARC_F3, sizeof(MMC_NEC_OPTIARC_F3)); if (sub_op == 3) { c->dxfer_len = 8; c->dir = FROM_DRIVE; } else { c->dxfer_len = 0; c->dir = NO_TRANSFER; } c->retry = 0; c->opcode[1] = sub_op; mmc_int_to_four_char(c->opcode + 2, start_lba); c->opcode[8] = rate_period; c->page = buf; c->page->bytes = 0; c->page->sectors = 0; d->issue_command(d, c); if (c->error) { msg = calloc(1, 256); if (msg != NULL) { sprintf(msg, "SCSI error on nec_optiarc_f3(%d, %d, %d): ", sub_op, start_lba, rate_period); scsi_error_msg(d, c->sense, 14, msg + strlen(msg), &key, &asc, &ascq); libdax_msgs_submit(libdax_messenger, d->global_index, 0x00020144, LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH, msg, 0, 0); free(msg); } return BE_CANCELLED; } if (sub_op == 3) { *ret_lba = mmc_four_char_to_int(c->page->data); *error_rate1 = c->page->data[4] * 256 + c->page->data[5]; *error_rate2 = c->page->data[6] * 256 + c->page->data[7]; } ret = 1; ex:; BURN_FREE_MEM(c); BURN_FREE_MEM(buf); return ret; } #endif /* Libburn_develop_quality_scaN */ /* ts A81210 : Determine the upper limit of readable data size */ int mmc_read_capacity(struct burn_drive *d) { struct buffer *buf = NULL; struct command *c = NULL; int alloc_len= 8, ret; BURN_ALLOC_MEM(buf, struct buffer, 1); BURN_ALLOC_MEM(c, struct command, 1); d->media_read_capacity = 0x7fffffff; mmc_start_if_needed(d, 1); if (mmc_function_spy(d, "mmc_read_capacity") <= 0) {ret = 0; goto ex;} scsi_init_command(c, MMC_READ_CAPACITY, sizeof(MMC_READ_CAPACITY)); c->dxfer_len = alloc_len; c->retry = 1; c->page = buf; c->page->bytes = 0; c->page->sectors = 0; c->dir = FROM_DRIVE; d->issue_command(d, c); d->media_read_capacity = mmc_four_char_to_int(c->page->data); if (d->media_read_capacity < 0) { d->media_read_capacity = 0x7fffffff; {ret = 0; goto ex;} } ret = 1; ex:; BURN_FREE_MEM(c); BURN_FREE_MEM(buf); return ret; } /* ts A90903 */ /* mmc5r03c.pdf 6.23 ADh READ DISC STRUCTURE obtains media specific information */ static int mmc_read_disc_structure_al(struct burn_drive *d, int *alloc_len, int media_type, int layer_number, int format, int min_len, char **reply, int *reply_len, int flag) { struct buffer *buf = NULL; int old_alloc_len, len, ret; struct command *c = NULL; unsigned char *dpt; BURN_ALLOC_MEM(buf, struct buffer, 1); BURN_ALLOC_MEM(c, struct command, 1); *reply = NULL; *reply_len = 0; if (*alloc_len < 4) {ret = 0; goto ex;} scsi_init_command(c, MMC_READ_DISC_STRUCTURE, sizeof(MMC_READ_DISC_STRUCTURE)); c->dxfer_len = *alloc_len; c->retry = 1; c->opcode[1]= media_type; c->opcode[7]= format; c->opcode[8]= (c->dxfer_len >> 8) & 0xff; c->opcode[9]= c->dxfer_len & 0xff; c->page = buf; c->page->sectors = 0; c->page->bytes = 0; c->dir = FROM_DRIVE; d->issue_command(d, c); if (c->error) {ret = 0; goto ex;} len = (c->page->data[0] << 8) | (c->page->data[1]); old_alloc_len = *alloc_len; *alloc_len = len + 2; if (old_alloc_len <= 4) {ret = 1; goto ex;} if (len + 2 > old_alloc_len) len = old_alloc_len - 2; if (len < 4) {ret = 0; goto ex;} dpt = c->page->data + 4; if (len - 2 < min_len) {ret = 0; goto ex;} *reply = calloc(len - 2, 1); if (*reply == NULL) {ret = 0; goto ex;} *reply_len = len - 2; memcpy(*reply, dpt, len - 2); ret = 1; ex:; BURN_FREE_MEM(c); BURN_FREE_MEM(buf); return ret; } int mmc_read_disc_structure(struct burn_drive *d, int media_type, int layer_number, int format, int min_len, char **reply, int *reply_len, int flag) { int alloc_len = 4, ret; char msg[80]; mmc_start_if_needed(d, 1); if (mmc_function_spy(d, "mmc_read_disc_structure") <= 0) return 0; ret = mmc_read_disc_structure_al(d, &alloc_len, media_type, layer_number, format, min_len, reply, reply_len, 0); /* fprintf(stderr,"LIBBURN_DEBUG: ADh alloc_len = %d , ret = %d\n", alloc_len, ret); */ if (ret <= 0) return ret; if (alloc_len < 12) { sprintf(msg, "READ DISC STRUCTURE announces only %d bytes of reply\n", alloc_len); libdax_msgs_submit(libdax_messenger, -1, 0x00000002, LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_ZERO, msg, 0, 0); ret = 0; /* ts A91205 LG GH22LS30 revision 1.00 returns for DVD-R format code 0x0E an allocation length of 4 (= 0 payload). A MS-Windows tool can inquire media code "RITEKF1", though. This macro causes a try to unconditionally read the desired payload bytes. The drive then returns 35 bytes as requested and the media id is "RITEKF1". Nevertheless this is not a generally usable gesture because older GNU/Linux USB dislikes requests to fetch more bytes than the drive will deliver. # define Libburn_enforce_structure_code_0x0E 1 */ #ifdef Libburn_enforce_structure_code_0x0E if (format == 0x0E) { alloc_len = min_len + 4; ret = mmc_read_disc_structure_al(d, &alloc_len, media_type, layer_number, format, min_len, reply, reply_len, 0); if (*reply_len < min_len || *reply == NULL) ret = 0; sprintf(msg, "READ DISC STRUCTURE returns %d bytes of required %d\n", *reply_len + 4, min_len + 4); libdax_msgs_submit(libdax_messenger, -1, 0x00000002, LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_ZERO, msg, 0, 0); } #endif } else ret = mmc_read_disc_structure_al(d, &alloc_len, media_type, layer_number, format, min_len, reply, reply_len, 0); return ret; } /* ts A90903 */ /* @param flag bit0= set bit1 in flag for burn_util_make_printable_word and do not append media revision bit1= truncate media_code1 to 6 characters (else 8) */ static int mmc_set_product_id(char *reply, int manuf_idx, int type_idx, int rev_idx, char **product_id, char **media_code1, char **media_code2, int flag) { int ret; *product_id = calloc(17, 1); *media_code1 = calloc(9, 1); *media_code2 = calloc(8, 1); if (*product_id == NULL || *media_code1 == NULL || *media_code2 == NULL) return -1; if (flag & 2) sprintf(*media_code1, "%.6s", reply + manuf_idx); else sprintf(*media_code1, "%.8s", reply + manuf_idx); ret = burn_util_make_printable_word(media_code1, 1 | ((flag & 1) << 1)); if (ret <= 0) return -1; sprintf(*media_code2, "%.3s%s", reply + type_idx, (flag & 1) ? "" : "xxxx"); ret = burn_util_make_printable_word(media_code2, 1 | ((flag & 1) << 1)); if (ret <= 0) return -1; if (!(flag & 1)) { sprintf(*media_code2 + strlen(*media_code2) - 4, "/%d", (int) ((unsigned char *) reply)[rev_idx]); } sprintf(*product_id, "%s/%s", *media_code1, *media_code2); return 1; } /* ts A90903 */ /* MMC backend of API call burn_disc_get_media_id() See also doc/mediainfo.txt @param flag Bitfield for control purposes bit0= do not escape " _/" (not suitable for burn_guess_manufacturer()) */ int mmc_get_media_product_id(struct burn_drive *d, char **product_id, char **media_code1, char **media_code2, char **book_type, int flag) { int prf, ret, reply_len, i, has_11h = -1, bt, start_lba, end_lba; int min, sec, fr, media_type = 0; char *reply = NULL, *wpt; static char *books[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", "DVD+RW DL" "DVD+R DL", "unknown"}; *product_id = *media_code1 = *media_code2 = *book_type = NULL; prf = d->current_profile; if (prf == 0x09 || prf == 0x0A) { *product_id = calloc(20, 1); *media_code1 = calloc(10, 1); *media_code2 = calloc(10, 1); if (*product_id == NULL || *media_code1 == NULL || *media_code2 == NULL) { ret = -1; goto ex; } ret = burn_disc_read_atip(d); if (ret <= 0) goto ex; ret = burn_drive_get_start_end_lba(d, &start_lba, &end_lba, 0); if (ret <= 0) goto ex; burn_lba_to_msf(start_lba, &min, &sec, &fr); sprintf(*media_code1, "%2.2dm%2.2ds%2.2df", min, sec, fr); burn_lba_to_msf(end_lba, &min, &sec, &fr); sprintf(*media_code2, "%2.2dm%2.2ds%2.2df", min, sec, fr); sprintf(*product_id, "%s/%s", *media_code1, *media_code2); ret = 1; goto ex; /* No booktype with CD media */ } else if (prf == 0x11 || prf == 0x13 || prf == 0x14 || prf == 0x15) { /* DVD-R */ ret = mmc_read_disc_structure(d, 0, 0, 0x0E, 31, &reply, &reply_len, 0); if (ret <= 0) goto ex; /* ECMA-279 for DVD-R promises a third sixpack in field 5, but ECMA-338 for DVD-RW defines a different meaning. DVD-R and DVD-RW bear unprintable characters in there. */ if (reply[16] != 3 || reply[24] != 4) { ret = 0; goto ex; } *media_code1 = calloc(19, 1); *media_code2 = strdup(""); if (*media_code1 == NULL || *media_code2 == NULL) { ret = -1; goto ex; } memcpy(*media_code1, reply + 17, 6); memcpy(*media_code1 + 6, reply + 25, 6); /* Clean out 0 bytes */ wpt = *media_code1; for (i = 0; i < 18; i++) if ((*media_code1)[i]) *(wpt++) = (*media_code1)[i]; *wpt = 0; ret = burn_util_make_printable_word(media_code1, 1 | ((flag & 1) << 1)); if (ret <= 0) goto ex; *product_id = strdup(*media_code1); if (*product_id == NULL) { ret = -1; goto ex; } } else if (prf == 0x1a || prf == 0x1b || prf == 0x2b) { /* DVD+R[W] */ /* Check whether the drive supports format 11h */ has_11h = 0; ret = mmc_read_disc_structure(d, 0, 0, 0xff, 4, &reply, &reply_len, 0); if (ret > 0) { for (i = 0; i < reply_len; i += 4) { if (reply[i] == 0x11 && (reply[i + 1] & 64)) has_11h = 1; } } if (reply != NULL) free(reply); reply = NULL; ret = mmc_read_disc_structure(d, 0, 0, 0x11, 29, &reply, &reply_len, 0); if (ret <= 0) { /* Hope for format 00h */ has_11h = 0; } else { /* Dig out manufacturer, media type and revision */ ret = mmc_set_product_id(reply, 19, 27, 28, product_id, media_code1, media_code2, flag & 1); if (ret <= 0) goto ex; } } else if (prf == 0x41 || prf == 0x43 || prf == 0x40 || prf == 0x42) { /* BD */ media_type = 1; ret = mmc_read_disc_structure(d, 1, 0, 0x00, 112, &reply, &reply_len, 0); if (ret <= 0) goto ex; if (reply[0] != 'D' || reply[1] != 'I') { ret = 0; goto ex; } /* Dig out manufacturer, media type and revision */ ret = mmc_set_product_id(reply, 100, 106, 111, product_id, media_code1, media_code2, 2 | (flag & 1)); if (ret <= 0) goto ex; } else { /* Source of DVD-RAM manufacturer and media id not found yet */ ret = 0; goto ex; } if (reply != NULL) free(reply); reply = NULL; ret = mmc_read_disc_structure(d, media_type, 0, 0x00, 1, &reply, &reply_len, 0); if (ret <= 0) goto ex; bt = (reply[0] >> 4) & 0xf; *book_type = calloc(80 + strlen(books[bt]), 1); if (*book_type == NULL) { ret = -1; goto ex; } sprintf(*book_type, "%2.2Xh, %s book [revision %d]", bt, books[bt], reply[0] & 0xf); if (has_11h == 0 && *product_id == NULL && reply_len > 28) { /* DVD+ with no format 11h */ /* Get manufacturer and media type from bytes 19 and 27 */ ret = mmc_set_product_id(reply, 19, 27, 28, product_id, media_code1, media_code2, flag & 1); if (*product_id == NULL) { ret = 0; goto ex; } } ret = 1; ex:; if (reply != NULL) free(reply); if (ret <= 0) { if (*product_id != NULL) free(*product_id); if (*media_code1 != NULL) free(*media_code1); if (*media_code2 != NULL) free(*media_code2); if (*book_type != NULL) free(*book_type); *product_id = *media_code1 = *media_code2 = *book_type = NULL; } return ret; } /* ts B00924 MMC-5, 6.23.3.3.4 Format Code 0Ah: Spare Area Information */ int mmc_get_bd_spare_info(struct burn_drive *d, int *alloc_blocks, int *free_blocks, int flag) { int ret, reply_len, prf; char *reply = NULL; prf = d->current_profile; if (!(prf == 0x41 || prf == 0x43 || prf == 0x42)) return 0; /* Not a BD loaded */ ret = mmc_read_disc_structure(d, 1, 0, 0x0a, 12, &reply, &reply_len, 0); if (ret <= 0) goto ex; *alloc_blocks = mmc_four_char_to_int((unsigned char *) reply + 8); *free_blocks = mmc_four_char_to_int((unsigned char *) reply + 4); ret = 1; ex:; if (reply != NULL) free(reply); return ret; } /* 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() */ int mmc_setup_drive(struct burn_drive *d) { d->read_atip = mmc_read_atip; d->read_toc = mmc_read_toc; d->write = mmc_write; d->erase = mmc_erase; d->read_cd = mmc_read_cd; d->perform_opc = mmc_perform_opc; d->set_speed = mmc_set_speed; d->send_cue_sheet = mmc_send_cue_sheet; d->reserve_track = mmc_reserve_track; d->sync_cache = mmc_sync_cache; d->get_nwa = mmc_get_nwa; d->read_multi_session_c1 = mmc_read_multi_session_c1; d->close_disc = mmc_close_disc; d->close_session = mmc_close_session; d->close_track_session = mmc_close; d->read_buffer_capacity = mmc_read_buffer_capacity; d->format_unit = mmc_format_unit; d->read_format_capacities = mmc_read_format_capacities; d->read_10 = mmc_read_10; /* ts A70302 */ d->phys_if_std = -1; d->phys_if_name[0] = 0; /* ts A61020 */ d->start_lba = -2000000000; d->end_lba = -2000000000; /* ts A61201 - A90815*/ d->erasable = 0; d->current_profile = -1; d->current_profile_text[0] = 0; d->current_is_cd_profile = 0; d->current_is_supported_profile = 0; d->current_is_guessed_profile = 0; memset(d->all_profiles, 0, 256); d->num_profiles = 0; d->current_has_feat21h = 0; d->current_feat21h_link_size = -1; d->current_feat23h_byte4 = 0; d->current_feat23h_byte8 = 0; d->current_feat2fh_byte4 = -1; d->next_track_damaged = 0; d->needs_close_session = 0; d->needs_sync_cache = 0; d->bg_format_status = -1; d->num_opc_tables = -1; d->last_lead_in = -2000000000; d->last_lead_out = -2000000000; d->disc_type = 0xff; d->disc_id = 0; memset(d->disc_bar_code, 0, 9); d->disc_app_code = 0; d->disc_info_valid = 0; d->num_format_descr = 0; d->complete_sessions = 0; #ifdef Libburn_disc_with_incomplete_sessioN d->incomplete_sessions = 0; #endif d->state_of_last_session = -1; d->last_track_no = 1; d->media_capacity_remaining = 0; d->media_lba_limit = 0; d->media_read_capacity = 0x7fffffff; d->pessimistic_buffer_free = 0; d->pbf_altered = 0; d->wait_for_buffer_free = Libburn_wait_for_buffer_freE; d->nominal_write_speed = 0; d->pessimistic_writes = 0; d->waited_writes = 0; d->waited_tries = 0; d->waited_usec = 0; d->wfb_min_usec = Libburn_wait_for_buffer_min_useC; d->wfb_max_usec = Libburn_wait_for_buffer_max_useC; d->wfb_timeout_sec = Libburn_wait_for_buffer_tio_seC; d->wfb_min_percent = Libburn_wait_for_buffer_min_perC; d->wfb_max_percent = Libburn_wait_for_buffer_max_perC; d->sent_default_page_05 = 0; return 1; } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������libburn-1.4.2/libburn/options.h���������������������������������������������������������������������0000644�0001757�0001751�00000011250�12652644224�013413� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ /* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens Copyright (c) 2006 - 2013 Thomas Schmitt <scdbackup@gmx.net> Provided under GPL version 2 or later. */ #ifndef BURN__OPTIONS_H #define BURN__OPTIONS_H #include "libburn.h" /** Options for disc writing operations. This should be created with burn_write_opts_new() and freed with burn_write_opts_free(). */ struct burn_write_opts { /** Drive the write opts are good for */ struct burn_drive *drive; /** For internal use. */ int refcount; /** The method/style of writing to use. */ enum burn_write_types write_type; /** format of the data to send to the drive */ enum burn_block_types block_type; /** Number of toc entries. if this is 0, they will be auto generated*/ int toc_entries; /** Toc entries for the disc */ struct burn_toc_entry *toc_entry; /** Simulate the write so that the disc is not actually written */ unsigned int simulate:1; /** If available, enable a drive feature which prevents buffer underruns if not enough data is available to keep up with the drive. */ unsigned int underrun_proof:1; /** Perform calibration of the drive's laser before beginning the write. */ unsigned int perform_opc:1; /* ts A61219 : Output block size to trigger buffer flush if hit. -1 with CD, 32 kB with DVD */ int obs; int obs_pad; /* >0 pad up last block to obs, 0 do not 2 indicates burn_write_opts_set_obs_pad(,1) */ /* ts A61222 : Start address for media which offer a choice */ off_t start_byte; /* ts A70213 : Wether to fill up the available space on media */ int fill_up_media; /* ts A70303 : Wether to override conformance checks: - the check wether CD write+block type is supported by the drive */ int force_is_set; /* ts A80412 : whether to use WRITE12 with Streaming bit set rather than WRITE10. Speeds up DVD-RAM. Might help with BD-RE. This gets transferred to burn_drive.do_stream_recording */ int do_stream_recording; /* ts A91115 : override value for .obs on DVD media. Only values 0, 32K and 64K are allowed for now. */ int dvd_obs_override; /* ts A91115 : size of the fsync() interval for stdio writing. Values 0 or >= 32 counted in 2 KB blocks. */ int stdio_fsync_size; /* ts B11203 : CD-TEXT */ unsigned char *text_packs; int num_text_packs; int no_text_pack_crc_check; /** A disc can have a media catalog number */ int has_mediacatalog; unsigned char mediacatalog[13]; /** Session format */ int format; /* internal use only */ unsigned char control; /* Whether to keep medium appendable */ unsigned char multi; /* ts B31024 */ /* The severity to be attributed to error messages about failed write attempt with blank DVD-RW, possibly due to falsely reported feature 21h Incremental Streaming Writable */ int feat21h_fail_sev; }; /* Default value for burn_write_opts.stdio_flush_size */ #define Libburn_stdio_fsync_limiT 8192 /* Maximum number of Lead-in text packs. READ TOC/PMA/ATIP can at most return 3640.7 packs. The sequence counters of the packs have 8 bits. There are 8 blocks at most. Thus max 2048 packs. */ #define Libburn_leadin_cdtext_packs_maX 2048 /** Options for disc reading operations. This should be created with burn_read_opts_new() and freed with burn_read_opts_free(). */ struct burn_read_opts { /** Drive the read opts are good for */ struct burn_drive *drive; /** For internal use. */ int refcount; /** Read in raw mode, so that everything in the data tracks on the disc is read, including headers. Not needed if just reading a filesystem off a disc, but it should usually be used when making a disc image or copying a disc. */ unsigned int raw:1; /** Report c2 errors. Useful for statistics reporting */ unsigned int c2errors:1; /** Read subcodes from audio tracks on the disc */ unsigned int subcodes_audio:1; /** Read subcodes from data tracks on the disc */ unsigned int subcodes_data:1; /** Have the drive recover errors if possible */ unsigned int hardware_error_recovery:1; /** Report errors even when they were recovered from */ unsigned int report_recovered_errors:1; /** Read blocks even when there are unrecoverable errors in them */ unsigned int transfer_damaged_blocks:1; /** The number of retries the hardware should make to correct errors. */ unsigned char hardware_error_retries; /* ts B21119 */ /* >>> Needs API access */ /** Whether to set DAP bit which allows the drive to apply "flaw obscuring mechanisms like audio data mute and interpolate" */ unsigned int dap_bit; }; int burn_write_opts_clone(struct burn_write_opts *from, struct burn_write_opts **to, int flag); #endif /* BURN__OPTIONS_H */ ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������libburn-1.4.2/libburn/sector.h����������������������������������������������������������������������0000644�0001757�0001751�00000002470�12652644224�013223� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */ /* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens Copyright (c) 2006 - 2010 Thomas Schmitt <scdbackup@gmx.net> Provided under GPL version 2 or later. */ #ifndef __SECTOR #define __SECTOR #include "libburn.h" #include "transport.h" struct burn_drive; struct isrc; int dec_to_bcd(int); int sector_toc(struct burn_write_opts *, int mode); int sector_pregap(struct burn_write_opts *, unsigned char tno, unsigned char control, int mode); int sector_postgap(struct burn_write_opts *, unsigned char tno, unsigned char control, int mode); int sector_lout(struct burn_write_opts *, unsigned char control, int mode); int sector_data(struct burn_write_opts *, struct burn_track *t, int psub); /* ts B20113 */ int sector_write_buffer(struct burn_drive *d, struct burn_track *track, int flag); /* ts A61009 */ int sector_headers_is_ok(struct burn_write_opts *o, int mode); int sector_headers(struct burn_write_opts *, unsigned char *, int mode, int leadin); void subcode_user(struct burn_write_opts *, unsigned char *s, unsigned char tno, unsigned char control, unsigned char index, struct isrc *isrc, int psub); int sector_identify(unsigned char *); void process_q(struct burn_drive *d, unsigned char *q); #endif /* __SECTOR */ ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������libburn-1.4.2/libburn/os-freebsd.h������������������������������������������������������������������0000644�0001757�0001751�00000004313�12652644224�013753� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ /* os-freebsd.h Operating system specific libburn definitions and declarations. Included by os.h in case of compilation for FreeBSD with CAM Copyright (C) 2006 - 2013 Thomas Schmitt <scdbackup@gmx.net>, Provided under GPLv2+ */ /** List of all signals which shall be caught by signal handlers and trigger a graceful abort of libburn. (See man 7 signal.) */ /* Once as system defined macros */ #define BURN_OS_SIGNAL_MACRO_LIST \ SIGHUP, SIGINT, SIGQUIT, SIGILL, SIGABRT, \ SIGFPE, SIGSEGV, SIGPIPE, SIGALRM, SIGTERM, \ SIGUSR1, SIGUSR2, SIGXCPU, SIGBUS, SIGPROF, \ SIGSYS, SIGTRAP, SIGVTALRM, SIGXCPU, SIGXFSZ /* Once as text 1:1 list of strings for messages and interpreters */ #define BURN_OS_SIGNAL_NAME_LIST \ "SIGHUP", "SIGINT", "SIGQUIT", "SIGILL", "SIGABRT", \ "SIGFPE", "SIGSEGV", "SIGPIPE", "SIGALRM", "SIGTERM", \ "SIGUSR1", "SIGUSR2", "SIGXCPU", "SIGBUS", "SIGPROF", \ "SIGSYS", "SIGTRAP", "SIGVTALRM", "SIGXCPU", "SIGXFSZ" /* The number of above list items */ #define BURN_OS_SIGNAL_COUNT 20 /** To list all signals which shall surely not be caught */ #define BURN_OS_NON_SIGNAL_MACRO_LIST \ SIGKILL, SIGCHLD, SIGSTOP, SIGTSTP, SIGCONT, SIGTTIN, SIGTTOU, SIGURG, SIGWINCH /* The number of above list items */ #define BURN_OS_NON_SIGNAL_COUNT 9 /* The maximum size for a (SCSI) i/o transaction */ /* Important : MUST be at least 32768 ! */ /* Older BSD info says that 32 kB is maximum. But 64 kB seems to work well on 8-STABLE. It is by default only used with BD in streaming mode. So older systems should still be quite safe with this buffer max size. */ #define BURN_OS_TRANSPORT_BUFFER_SIZE 65536 /** To hold all state information of BSD device enumeration which are now local in sg_enumerate() . So that sg_give_next_adr() can work in BSD and sg_enumerate() can use it. */ #define BURN_OS_DEFINE_DRIVE_ENUMERATOR_T \ struct burn_drive_enumeration_state; \ typedef struct burn_drive_enumeration_state *burn_drive_enumerator_t; /* The list of operating system dependent elements in struct burn_drive. To be initialized and used within sg-*.c . */ #define BURN_OS_TRANSPORT_DRIVE_ELEMENTS \ struct cam_device* cam; \ int lock_fd; \ int is_ahci; \ ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������libburn-1.4.2/libburn/libdax_msgs.c�����������������������������������������������������������������0000644�0001757�0001751�00000024661�12652644224�014221� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ /* libdax_msgs Message handling facility of libdax. Copyright (C) 2006 - 2010 Thomas Schmitt <scdbackup@gmx.net>, provided under GPL version 2 or later. */ #ifdef HAVE_CONFIG_H #include "../config.h" #endif #include <stdio.h> #include <sys/types.h> #include <unistd.h> #include <string.h> #include <stdlib.h> #include <errno.h> #include <sys/time.h> #include <pthread.h> /* Only this single source module is entitled to do this */ #define LIBDAX_MSGS_H_INTERNAL 1 /* All participants in the messaging system must do this */ #include "libdax_msgs.h" /* ----------------------------- libdax_msgs_item ------------------------- */ static int libdax_msgs_item_new(struct libdax_msgs_item **item, struct libdax_msgs_item *link, int flag) { int ret; struct libdax_msgs_item *o; struct timeval tv; struct timezone tz; (*item)= o= (struct libdax_msgs_item *) calloc(1, sizeof(struct libdax_msgs_item)); if(o==NULL) return(-1); o->timestamp= 0.0; ret= gettimeofday(&tv,&tz); if(ret==0) o->timestamp= tv.tv_sec+0.000001*tv.tv_usec; o->process_id= getpid(); o->origin= -1; o->severity= LIBDAX_MSGS_SEV_ALL; o->priority= LIBDAX_MSGS_PRIO_ZERO; o->error_code= 0; o->msg_text= NULL; o->os_errno= 0; o->prev= link; o->next= NULL; if(link!=NULL) { if(link->next!=NULL) { link->next->prev= o; o->next= link->next; } link->next= o; } return(1); } /** Detaches item from its queue and eventually readjusts start, end pointers of the queue */ int libdax_msgs_item_unlink(struct libdax_msgs_item *o, struct libdax_msgs_item **chain_start, struct libdax_msgs_item **chain_end, int flag) { if(o->prev!=NULL) o->prev->next= o->next; if(o->next!=NULL) o->next->prev= o->prev; if(chain_start!=NULL) if(*chain_start == o) *chain_start= o->next; if(chain_end!=NULL) if(*chain_end == o) *chain_end= o->prev; o->next= o->prev= NULL; return(1); } int libdax_msgs_item_destroy(struct libdax_msgs_item **item, int flag) { struct libdax_msgs_item *o; o= *item; if(o==NULL) return(0); libdax_msgs_item_unlink(o,NULL,NULL,0); if(o->msg_text!=NULL) free((char *) o->msg_text); free((char *) o); *item= NULL; return(1); } int libdax_msgs_item_get_msg(struct libdax_msgs_item *item, int *error_code, char **msg_text, int *os_errno, int flag) { *error_code= item->error_code; *msg_text= item->msg_text; *os_errno= item->os_errno; return(1); } int libdax_msgs_item_get_origin(struct libdax_msgs_item *item, double *timestamp, pid_t *process_id, int *origin, int flag) { *timestamp= item->timestamp; *process_id= item->process_id; *origin= item->origin; return(1); } int libdax_msgs_item_get_rank(struct libdax_msgs_item *item, int *severity, int *priority, int flag) { *severity= item->severity; *priority= item->priority; return(1); } /* ------------------------------- libdax_msgs ---------------------------- */ int libdax_msgs_new(struct libdax_msgs **m, int flag) { struct libdax_msgs *o; (*m)= o= (struct libdax_msgs *) calloc(1, sizeof(struct libdax_msgs)); if(o==NULL) return(-1); o->refcount= 1; o->oldest= NULL; o->youngest= NULL; o->count= 0; o->queue_severity= LIBDAX_MSGS_SEV_ALL; o->print_severity= LIBDAX_MSGS_SEV_NEVER; strcpy(o->print_id,"libdax: "); #ifndef LIBDAX_MSGS_SINGLE_THREADED pthread_mutex_init(&(o->lock_mutex),NULL); #endif return(1); } static int libdax_msgs_lock(struct libdax_msgs *m, int flag) { #ifndef LIBDAX_MSGS_SINGLE_THREADED int ret; ret= pthread_mutex_lock(&(m->lock_mutex)); if(ret!=0) return(0); #endif return(1); } static int libdax_msgs_unlock(struct libdax_msgs *m, int flag) { #ifndef LIBDAX_MSGS_SINGLE_THREADED int ret; ret= pthread_mutex_unlock(&(m->lock_mutex)); if(ret!=0) return(0); #endif return(1); } int libdax_msgs_destroy(struct libdax_msgs **m, int flag) { struct libdax_msgs *o; struct libdax_msgs_item *item, *next_item; o= *m; if(o==NULL) return(0); if(o->refcount > 1) { if(libdax_msgs_lock(*m,0)<=0) return(-1); o->refcount--; libdax_msgs_unlock(*m,0); *m= NULL; return(1); } #ifndef LIBDAX_MSGS_SINGLE_THREADED if(pthread_mutex_destroy(&(o->lock_mutex))!=0) { pthread_mutex_unlock(&(o->lock_mutex)); pthread_mutex_destroy(&(o->lock_mutex)); } #endif for(item= o->oldest; item!=NULL; item= next_item) { next_item= item->next; libdax_msgs_item_destroy(&item,0); } free((char *) o); *m= NULL; return(1); } int libdax_msgs_refer(struct libdax_msgs **pt, struct libdax_msgs *m, int flag) { if(libdax_msgs_lock(m,0)<=0) return(0); m->refcount++; *pt= m; libdax_msgs_unlock(m,0); return(1); } int libdax_msgs_set_severities(struct libdax_msgs *m, int queue_severity, int print_severity, char *print_id, int flag) { if(libdax_msgs_lock(m,0)<=0) return(0); m->queue_severity= queue_severity; m->print_severity= print_severity; strncpy(m->print_id,print_id,80); m->print_id[80]= 0; libdax_msgs_unlock(m,0); return(1); } int libdax_msgs__text_to_sev(char *severity_name, int *severity, int flag) { if(strncmp(severity_name,"NEVER",5)==0) *severity= LIBDAX_MSGS_SEV_NEVER; else if(strncmp(severity_name,"ABORT",5)==0) *severity= LIBDAX_MSGS_SEV_ABORT; else if(strncmp(severity_name,"FATAL",5)==0) *severity= LIBDAX_MSGS_SEV_FATAL; else if(strncmp(severity_name,"FAILURE",7)==0) *severity= LIBDAX_MSGS_SEV_FAILURE; else if(strncmp(severity_name,"MISHAP",6)==0) *severity= LIBDAX_MSGS_SEV_MISHAP; else if(strncmp(severity_name,"SORRY",5)==0) *severity= LIBDAX_MSGS_SEV_SORRY; else if(strncmp(severity_name,"WARNING",7)==0) *severity= LIBDAX_MSGS_SEV_WARNING; else if(strncmp(severity_name,"HINT",4)==0) *severity= LIBDAX_MSGS_SEV_HINT; else if(strncmp(severity_name,"NOTE",4)==0) *severity= LIBDAX_MSGS_SEV_NOTE; else if(strncmp(severity_name,"UPDATE",6)==0) *severity= LIBDAX_MSGS_SEV_UPDATE; else if(strncmp(severity_name,"DEBUG",5)==0) *severity= LIBDAX_MSGS_SEV_DEBUG; else if(strncmp(severity_name,"ERRFILE",7)==0) *severity= LIBDAX_MSGS_SEV_ERRFILE; else if(strncmp(severity_name,"ALL",3)==0) *severity= LIBDAX_MSGS_SEV_ALL; else { *severity= LIBDAX_MSGS_SEV_ALL; return(0); } return(1); } int libdax_msgs__sev_to_text(int severity, char **severity_name, int flag) { if(flag&1) { *severity_name= "ALL ERRFILE DEBUG UPDATE NOTE HINT WARNING SORRY MISHAP FAILURE FATAL ABORT NEVER"; return(1); } *severity_name= ""; if(severity>=LIBDAX_MSGS_SEV_NEVER) *severity_name= "NEVER"; else if(severity>=LIBDAX_MSGS_SEV_ABORT) *severity_name= "ABORT"; else if(severity>=LIBDAX_MSGS_SEV_FATAL) *severity_name= "FATAL"; else if(severity>=LIBDAX_MSGS_SEV_FAILURE) *severity_name= "FAILURE"; else if(severity>=LIBDAX_MSGS_SEV_MISHAP) *severity_name= "MISHAP"; else if(severity>=LIBDAX_MSGS_SEV_SORRY) *severity_name= "SORRY"; else if(severity>=LIBDAX_MSGS_SEV_WARNING) *severity_name= "WARNING"; else if(severity>=LIBDAX_MSGS_SEV_HINT) *severity_name= "HINT"; else if(severity>=LIBDAX_MSGS_SEV_NOTE) *severity_name= "NOTE"; else if(severity>=LIBDAX_MSGS_SEV_UPDATE) *severity_name= "UPDATE"; else if(severity>=LIBDAX_MSGS_SEV_DEBUG) *severity_name= "DEBUG"; else if(severity>=LIBDAX_MSGS_SEV_ERRFILE) *severity_name= "ERRFILE"; else if(severity>=LIBDAX_MSGS_SEV_ALL) *severity_name= "ALL"; else { *severity_name= ""; return(0); } return(1); } /* @param flag Bitfield for control purposes bit0= If direct output to stderr: CarriageReturn rather than LineFeed */ int libdax_msgs_submit(struct libdax_msgs *m, int origin, int error_code, int severity, int priority, char *msg_text, int os_errno, int flag) { int ret; char *textpt,*sev_name,sev_text[81]; struct libdax_msgs_item *item= NULL; if(severity >= m->print_severity) { if(msg_text==NULL) textpt= ""; else textpt= msg_text; sev_text[0]= 0; ret= libdax_msgs__sev_to_text(severity,&sev_name,0); if(ret>0) sprintf(sev_text,"%s : ",sev_name); fprintf(stderr, "%s%s%s%c", m->print_id, sev_text, textpt, (flag & 1) ? '\r' : '\n'); if(os_errno!=0) { ret= libdax_msgs_lock(m,0); if(ret<=0) return(-1); fprintf(stderr,"%s( Most recent system error: %d '%s' )\n", m->print_id,os_errno,strerror(os_errno)); libdax_msgs_unlock(m,0); } } if(severity < m->queue_severity) return(0); ret= libdax_msgs_lock(m,0); if(ret<=0) return(-1); ret= libdax_msgs_item_new(&item,m->youngest,0); if(ret<=0) goto failed; item->origin= origin; item->error_code= error_code; item->severity= severity; item->priority= priority; if(msg_text!=NULL) { item->msg_text= calloc(1, strlen(msg_text)+1); if(item->msg_text==NULL) goto failed; strcpy(item->msg_text,msg_text); } item->os_errno= os_errno; if(m->oldest==NULL) m->oldest= item; m->youngest= item; m->count++; libdax_msgs_unlock(m,0); /* fprintf(stderr,"libdax_experimental: message submitted to queue (now %d)\n", m->count); */ return(1); failed:; libdax_msgs_item_destroy(&item,0); libdax_msgs_unlock(m,0); return(-1); } int libdax_msgs_obtain(struct libdax_msgs *m, struct libdax_msgs_item **item, int severity, int priority, int flag) { int ret; struct libdax_msgs_item *im, *next_im= NULL; *item= NULL; ret= libdax_msgs_lock(m,0); if(ret<=0) return(-1); for(im= m->oldest; im!=NULL; im= next_im) { for(; im!=NULL; im= next_im) { next_im= im->next; if(im->severity>=severity) break; libdax_msgs_item_unlink(im,&(m->oldest),&(m->youngest),0); libdax_msgs_item_destroy(&im,0); /* severity too low: delete */ } if(im==NULL) break; if(im->priority>=priority) break; } if(im==NULL) {ret= 0; goto ex;} libdax_msgs_item_unlink(im,&(m->oldest),&(m->youngest),0); *item= im; ret= 1; ex:; libdax_msgs_unlock(m,0); return(ret); } int libdax_msgs_destroy_item(struct libdax_msgs *m, struct libdax_msgs_item **item, int flag) { int ret; ret= libdax_msgs_lock(m,0); if(ret<=0) return(-1); ret= libdax_msgs_item_destroy(item,0); libdax_msgs_unlock(m,0); return(ret); } �������������������������������������������������������������������������������libburn-1.4.2/libburn/sg.c��������������������������������������������������������������������������0000644�0001757�0001751�00000003610�12652644224�012325� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ /* sg.c Switcher for operating system dependent transport level modules of libburn. Copyright (C) 2009 - 2014 Thomas Schmitt <scdbackup@gmx.net>, provided under GPLv2+ */ #ifdef HAVE_CONFIG_H #include "../config.h" #undef HAVE_CONFIG_H #endif /* <<< Until it is known whether this adapter would work on OpenBSD too */ #ifdef __NetBSD__ #define Libburn_use_sg_netbsD #endif #ifdef Libburn_use_sg_dummY #include "sg-dummy.c" #else #ifdef Libburn_use_libcdiO #include "sg-libcdio.c" #else #ifdef Libburn_use_sg_netbsD /* To become: # ifdef __NetBSD__ */ #include "sg-netbsd.c" #else #ifdef __FreeBSD__ #ifdef Libburn_use_sg_freebsd_porT #include "sg-freebsd-port.c" #else #include "sg-freebsd.c" #endif #else #ifdef __FreeBSD_kernel__ #ifdef Libburn_use_sg_freebsd_porT #include "sg-freebsd-port.c" #else #include "sg-freebsd.c" #endif #else #ifdef __linux #include "sg-linux.c" #else #ifdef __sun #include "sg-solaris.c" #else /* The dummy adapter formally fulfills the expectations of libburn towards its SCSI command transport. It will show no drives and perform no SCSI commands. libburn will then be restricted to using its stdio pseudo drives. */ static int intentional_compiler_warning(void) { int INTENTIONAL_COMPILER_WARNING_; int Cannot_recognize_supported_operating_system_; int Like_GNU_Linux_or_FreeBSD_or_Solaris_or_NetBSD_; int Have_to_use_dummy_MMC_transport_adapter_; int This_libburn_will_not_be_able_to_operate_on_real_CD_drives; int Have_to_use_dummy_MMC_transport_adapter; int Like_GNU_Linux_or_FreeBSD_or_Solaris_or_NetBSD; int Cannot_recognize_supported_operating_system; int INTENTIONAL_COMPILER_WARNING; return(0); } #include "sg-dummy.c" #endif /* ! __sun */ #endif /* ! __linux */ #endif /* ! __FreeBSD_kernel__ */ #endif /* ! __FreeBSD__ */ #endif /* ! Libburn_use_sg_netbsD */ #endif /* ! Libburn_use_libcdiO */ #endif /* ! Libburn_use_sg_dummY */ ������������������������������������������������������������������������������������������������������������������������libburn-1.4.2/libburn/async.h�����������������������������������������������������������������������0000644�0001757�0001751�00000000747�12652644224�013046� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */ #ifndef BURN__ASYNC_H #define BURN__ASYNC_H void burn_async_join_all(void); struct burn_write_opts; /* ts A70930 */ /* To be called when the first read() call comes to a fifo */ int burn_fifo_start(struct burn_source *source, int flag); /* ts A81108 */ /* To abort a running fifo thread before the fifo object gets deleted */ int burn_fifo_abort(struct burn_source_fifo *fs, int flag); #endif /* BURN__ASYNC_H */ �������������������������libburn-1.4.2/libburn/debug.c�����������������������������������������������������������������������0000644�0001757�0001751�00000000664�12652644224�013010� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */ /* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens Provided under GPL version 2 or later. */ #ifdef HAVE_CONFIG_H #include "../config.h" #endif #ifdef WIN32 #include <windows.h> #endif #include <stdarg.h> #include <stdio.h> #include "libburn.h" #include "debug.h" static int burn_verbosity = 0; void burn_set_verbosity(int v) { burn_verbosity = v; } ����������������������������������������������������������������������������libburn-1.4.2/libburn/util.h������������������������������������������������������������������������0000644�0001757�0001751�00000000771�12652644224�012703� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������#ifndef __UTIL #define __UTIL /* for struct stat */ #include <sys/types.h> #include <sys/stat.h> #include <unistd.h> /* ts A90905 */ int burn_util_make_printable_word(char **text, int flag); /* ts B11216 */ char *burn_sfile_fgets(char *line, int maxl, FILE *fp); char *burn_printify(char *msg); /* ts B30521 */ void burn_int_to_lsb(int val, char *target); /* ts B30609 */ double burn_get_time(int flag); /* ts B40609 */ off_t burn_sparse_file_addsize(off_t write_start, struct stat *stbuf); #endif �������libburn-1.4.2/libburn/libburn.h���������������������������������������������������������������������0000644�0001757�0001751�00000570071�12652644224�013370� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */ /* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens Copyright (c) 2006 - 2015 Thomas Schmitt <scdbackup@gmx.net> Provided under GPL version 2 or later. This is the official API definition of libburn. */ /* Important: If you add a public API function then add its name to file libburn/libburn.ver */ #ifndef LIBBURN_H #define LIBBURN_H /* Applications must use 64 bit off_t. E.g. by defining #define _LARGEFILE_SOURCE #define _FILE_OFFSET_BITS 64 or take special precautions to interface with the library by 64 bit integers where this .h files prescribe off_t. To prevent 64 bit file i/o in the library would keep the application from processing tracks of more than 2 GB size. */ #include <sys/types.h> #ifndef DOXYGEN #if defined(__cplusplus) #define BURN_BEGIN_DECLS \ namespace burn { \ extern "C" { #define BURN_END_DECLS \ } \ } #else #define BURN_BEGIN_DECLS #define BURN_END_DECLS #endif BURN_BEGIN_DECLS #endif /** References a physical drive in the system */ struct burn_drive; /** References a whole disc */ struct burn_disc; /** References a single session on a disc */ struct burn_session; /** References a single track on a disc */ struct burn_track; /* ts A61111 */ /** References a set of write parameters */ struct burn_write_opts; /** Session format for normal audio or data discs */ #define BURN_CDROM 0 /** Session format for obsolete CD-I discs */ #define BURN_CDI 0x10 /** Session format for CDROM-XA discs */ #define BURN_CDXA 0x20 #define BURN_POS_END 100 /** Mask for mode bits */ #define BURN_MODE_BITS 127 /** Track mode - mode 0 data 0 bytes of user data. it's all 0s. mode 0. get it? HAH */ #define BURN_MODE0 (1 << 0) /** Track mode - mode "raw" - all 2352 bytes supplied by app FOR DATA TRACKS ONLY! */ #define BURN_MODE_RAW (1 << 1) /** Track mode - mode 1 data 2048 bytes user data, and all the LEC money can buy */ #define BURN_MODE1 (1 << 2) /** Track mode - mode 2 data defaults to formless, 2336 bytes of user data, unprotected | with a data form if required. */ #define BURN_MODE2 (1 << 3) /** Track mode modifier - Form 1, | with MODE2 for reasonable results 2048 bytes of user data, 4 bytes of subheader */ #define BURN_FORM1 (1 << 4) /** Track mode modifier - Form 2, | with MODE2 for reasonable results lots of user data. not much LEC. */ #define BURN_FORM2 (1 << 5) /** Track mode - audio 2352 bytes per sector. may be | with 4ch or preemphasis. NOT TO BE CONFUSED WITH BURN_MODE_RAW Audio data must be 44100Hz 16bit stereo with no riff or other header at beginning. Extra header data will cause pops or clicks. Audio data should also be in little-endian byte order. Big-endian audio data causes static. */ #define BURN_AUDIO (1 << 6) /** Track mode modifier - 4 channel audio. */ #define BURN_4CH (1 << 7) /** Track mode modifier - Digital copy permitted, can be set on any track.*/ #define BURN_COPY (1 << 8) /** Track mode modifier - 50/15uS pre-emphasis */ #define BURN_PREEMPHASIS (1 << 9) /** Input mode modifier - subcodes present packed 16 */ #define BURN_SUBCODE_P16 (1 << 10) /** Input mode modifier - subcodes present packed 96 */ #define BURN_SUBCODE_P96 (1 << 11) /** Input mode modifier - subcodes present raw 96 */ #define BURN_SUBCODE_R96 (1 << 12) /* ts B11230 */ /** Track mode modifier - Serial Copy Management System, SAO only If this is set and BURN_COPY is not set, then copying the emerging track will be forbidden. @since 1.2.0 */ #define BURN_SCMS (1 << 13) /** Possible disc writing style/modes */ enum burn_write_types { /** Packet writing. currently unsupported, (for DVD Incremental Streaming use TAO) */ BURN_WRITE_PACKET, /** With CD: Track At Once recording 2s gaps between tracks, no fonky lead-ins With sequential DVD-R[W]: Incremental Streaming With DVD+R and BD-R: Track of open size With DVD-RAM, DVD+RW, BD-RE: Random Writeable (used sequentially) With overwriteable DVD-RW: Rigid Restricted Overwrite */ BURN_WRITE_TAO, /** With CD: Session At Once Block type MUST be BURN_BLOCK_SAO ts A70122: Currently not capable of mixing data and audio tracks. With sequential DVD-R[W]: Disc-at-once, DAO Single session, single track, fixed size mandatory, (-dvd-compat) With other DVD or BD media: same as BURN_WRITE_TAO but may demand that track size is known in advance. */ BURN_WRITE_SAO, /** With CD: Raw disc at once recording. all subcodes must be provided by lib or user only raw block types are supported With DVD and BD media: not supported. ts A90901: This had been disabled because its implementation relied on code from cdrdao which is not understood currently. A burn run will abort with "FATAL" error message if this mode is attempted. @since 0.7.2 ts A91016: Re-implemented according to ECMA-130 Annex A and B. Now understood, explained and not stemming from cdrdao. @since 0.7.4 */ BURN_WRITE_RAW, /** In replies this indicates that not any writing will work. As parameter for inquiries it indicates that no particular write mode shall is specified. Do not use for setting a write mode for burning. It will not work. */ BURN_WRITE_NONE }; /** Data format to send to the drive */ enum burn_block_types { /** sync, headers, edc/ecc provided by lib/user */ BURN_BLOCK_RAW0 = 1, /** sync, headers, edc/ecc and p/q subs provided by lib/user */ BURN_BLOCK_RAW16 = 2, /** sync, headers, edc/ecc and packed p-w subs provided by lib/user */ BURN_BLOCK_RAW96P = 4, /** sync, headers, edc/ecc and raw p-w subs provided by lib/user */ BURN_BLOCK_RAW96R = 8, /** only 2048 bytes of user data provided by lib/user */ BURN_BLOCK_MODE1 = 256, /** 2336 bytes of user data provided by lib/user */ BURN_BLOCK_MODE2R = 512, /** 2048 bytes of user data provided by lib/user subheader provided in write parameters are we ever going to support this shit? I vote no. (supposed to be supported on all drives...) */ BURN_BLOCK_MODE2_PATHETIC = 1024, /** 2048 bytes of data + 8 byte subheader provided by lib/user hey, this is also dumb */ BURN_BLOCK_MODE2_LAME = 2048, /** 2324 bytes of data provided by lib/user subheader provided in write parameters no sir, I don't like it. */ BURN_BLOCK_MODE2_OBSCURE = 4096, /** 2332 bytes of data supplied by lib/user 8 bytes sub header provided in write parameters this is the second least suck mode2, and is mandatory for all drives to support. */ BURN_BLOCK_MODE2_OK = 8192, /** SAO block sizes are based on cue sheet, so use this. */ BURN_BLOCK_SAO = 16384 }; /** Possible status of the drive in regard to the disc in it. */ enum burn_disc_status { /** The current status is not yet known */ BURN_DISC_UNREADY, /** The drive holds a blank disc. It is ready for writing from scratch. Unused multi-session media: CD-R, CD-RW, DVD-R, DVD-RW, DVD+R, BD-R Blanked multi-session media (i.e. treated by burn_disc_erase()) CD-RW, DVD-RW Overwriteable media with or without valid data DVD-RAM, DVD+RW, formatted DVD-RW, BD-RE */ BURN_DISC_BLANK, /** There is no disc at all in the drive */ BURN_DISC_EMPTY, /** There is an incomplete disc in the drive. It is ready for appending another session. Written but not yet closed multi-session media CD-R, CD-RW, DVD-R, DVD-RW, DVD+R, BD-R */ BURN_DISC_APPENDABLE, /** There is a disc with data on it in the drive. It is usable only for reading. Written and closed multi-session media CD-R, CD-RW, DVD-R, DVD-RW, DVD+R, BD-R Read-Only media CD-ROM, DVD-ROM, BD-ROM Note that many DVD-ROM drives report any written media as Read-Only media and not by their real media types. */ BURN_DISC_FULL, /* ts A61007 */ /* @since 0.2.4 */ /** The drive was not grabbed when the status was inquired */ BURN_DISC_UNGRABBED, /* ts A61020 */ /* @since 0.2.6 */ /** The media seems to be unsuitable for reading and for writing */ BURN_DISC_UNSUITABLE }; /** Possible data source return values */ enum burn_source_status { /** The source is ok */ BURN_SOURCE_OK, /** The source is at end of file */ BURN_SOURCE_EOF, /** The source is unusable */ BURN_SOURCE_FAILED }; /** Possible busy states for a drive */ enum burn_drive_status { /** The drive is not in an operation */ BURN_DRIVE_IDLE, /** The library is spawning the processes to handle a pending operation (A read/write/etc is about to start but hasn't quite yet) */ BURN_DRIVE_SPAWNING, /** The drive is reading data from a disc */ BURN_DRIVE_READING, /** The drive is writing data to a disc */ BURN_DRIVE_WRITING, /** The drive is writing Lead-In */ BURN_DRIVE_WRITING_LEADIN, /** The drive is writing Lead-Out */ BURN_DRIVE_WRITING_LEADOUT, /** The drive is erasing a disc */ BURN_DRIVE_ERASING, /** The drive is being grabbed */ BURN_DRIVE_GRABBING, /* ts A61102 */ /* @since 0.2.6 */ /** The drive gets written zeroes before the track payload data */ BURN_DRIVE_WRITING_PREGAP, /** The drive is told to close a track (TAO only) */ BURN_DRIVE_CLOSING_TRACK, /** The drive is told to close a session (TAO only) */ BURN_DRIVE_CLOSING_SESSION, /* ts A61223 */ /* @since 0.3.0 */ /** The drive is formatting media */ BURN_DRIVE_FORMATTING, /* ts A70822 */ /* @since 0.4.0 */ /** The drive is busy in synchronous read (if you see this then it has been interrupted) */ BURN_DRIVE_READING_SYNC, /** The drive is busy in synchronous write (if you see this then it has been interrupted) */ BURN_DRIVE_WRITING_SYNC }; /** Information about a track on a disc - this is from the q sub channel of the lead-in area of a disc. The documentation here is very terse. See a document such as mmc3 for proper information. CAUTION : This structure is prone to future extension ! Do not restrict your application to unsigned char with any counter like "session", "point", "pmin", ... Do not rely on the current size of a burn_toc_entry. */ struct burn_toc_entry { /** Session the track is in */ unsigned char session; /** Type of data. for this struct to be valid, it must be 1 */ unsigned char adr; /** Type of data in the track */ unsigned char control; /** Zero. Always. Really. */ unsigned char tno; /** Track number or special information */ unsigned char point; unsigned char min; unsigned char sec; unsigned char frame; unsigned char zero; /** Track start time minutes for normal tracks */ unsigned char pmin; /** Track start time seconds for normal tracks */ unsigned char psec; /** Track start time frames for normal tracks */ unsigned char pframe; /* Indicates whether extension data are valid and eventually override older elements in this structure: bit0= DVD extension is valid @since 0.3.2 @since 0.5.2 : DVD extensions are made valid for CD too bit1= LRA extension is valid @since 0.7.2 bit2= Track status bits extension is valid @since 1.2.8 */ unsigned char extensions_valid; /* ts A70201 : DVD extension. extensions_valid:bit0 If invalid the members are guaranteed to be 0. */ /* @since 0.3.2 */ /* Tracks and session numbers are 16 bit. Here are the high bytes. */ unsigned char session_msb; unsigned char point_msb; /* pmin, psec, and pframe may be too small if DVD extension is valid */ int start_lba; /* min, sec, and frame may be too small if DVD extension is valid */ int track_blocks; /* ts A90909 : LRA extension. extensions_valid:bit1 */ /* @since 0.7.2 */ /* MMC-5 6.27.3.18 : The Last Recorded Address is valid for DVD-R, DVD-R DL when LJRS = 00b, DVD-RW, HD DVD-R, and BD-R. This would mean profiles: 0x11, 0x15, 0x13, 0x14, 0x51, 0x41, 0x42 */ int last_recorded_address; /* ts B30112 : Track status bits extension. extensions_valid:bit2 */ /* @since 1.2.8 */ /* Names as of READ TRACK INFORMATION, MMC-5 6.27.3 : bit0 - bit3 = Track Mode bit4 = Copy bit5 = Damage bit6 - bit7 = LJRS bit8 - bit11 = Data Mode bit12 = FP bit13 = Packet/Inc bit14 = Blank bit15 = RT bit16 = NWA_V bit17 = LRA_V */ int track_status_bits; }; /** Data source interface for tracks. This allows you to use arbitrary program code as provider of track input data. Objects compliant to this interface are either provided by the application or by API calls of libburn: burn_fd_source_new() , burn_file_source_new(), and burn_fifo_source_new(). The API calls may use any file object as data source. Consider to feed an eventual custom data stream asynchronously into a pipe(2) and to let libburn handle the rest. In this case the following rule applies: Call burn_source_free() exactly once for every source obtained from libburn API. You MUST NOT otherwise use or manipulate its components. In general, burn_source objects can be freed as soon as they are attached to track objects. The track objects will keep them alive and dispose them when they are no longer needed. With a fifo burn_source it makes sense to keep the own reference for inquiring its state while burning is in progress. --- The following description of burn_source applies only to application implemented burn_source objects. You need not to know it for API provided ones. If you really implement an own passive data producer by this interface, then beware: it can do anything and it can spoil everything. In this case the functions (*read), (*get_size), (*set_size), (*free_data) MUST be implemented by the application and attached to the object at creation time. Function (*read_sub) is allowed to be NULL or it MUST be implemented and attached. burn_source.refcount MUST be handled properly: If not exactly as many references are freed as have been obtained, then either memory leaks or corrupted memory are the consequence. All objects which are referred to by *data must be kept existent until (*free_data) is called via burn_source_free() by the last referer. */ struct burn_source { /** Reference count for the data source. MUST be 1 when a new source is created and thus the first reference is handed out. Increment it to take more references for yourself. Use burn_source_free() to destroy your references to it. */ int refcount; /** Read data from the source. Semantics like with read(2), but MUST either deliver the full buffer as defined by size or MUST deliver EOF (return 0) or failure (return -1) at this call or at the next following call. I.e. the only incomplete buffer may be the last one from that source. libburn will read a single sector by each call to (*read). The size of a sector depends on BURN_MODE_*. The known range is 2048 to 2352. If this call is reading from a pipe then it will learn about the end of data only when that pipe gets closed on the feeder side. So if the track size is not fixed or if the pipe delivers less than the predicted amount or if the size is not block aligned, then burning will halt until the input process closes the pipe. IMPORTANT: If this function pointer is NULL, then the struct burn_source is of version >= 1 and the job of .(*read)() is done by .(*read_xt)(). See below, member .version. */ int (*read)(struct burn_source *, unsigned char *buffer, int size); /** Read subchannel data from the source (NULL if lib generated) WARNING: This is an obscure feature with CD raw write modes. Unless you checked the libburn code for correctness in that aspect you should not rely on raw writing with own subchannels. ADVICE: Set this pointer to NULL. */ int (*read_sub)(struct burn_source *, unsigned char *buffer, int size); /** Get the size of the source's data. Return 0 means unpredictable size. If application provided (*get_size) might return 0, then the application MUST provide a fully functional (*set_size). */ off_t (*get_size)(struct burn_source *); /* ts A70125 : BROKE BINARY BACKWARD COMPATIBILITY AT libburn-0.3.1. */ /* @since 0.3.2 */ /** Program the reply of (*get_size) to a fixed value. It is advised to implement this by a attribute off_t fixed_size; in *data . The read() function does not have to take into respect this fake setting. It is rather a note of libburn to itself. Eventually necessary truncation or padding is done in libburn. Truncation is usually considered a misburn. Padding is considered ok. libburn is supposed to work even if (*get_size) ignores the setting by (*set_size). But your application will not be able to enforce fixed track sizes by burn_track_set_size() and possibly even padding might be left out. */ int (*set_size)(struct burn_source *source, off_t size); /** Clean up the source specific data. This function will be called once by burn_source_free() when the last referer disposes the source. */ void (*free_data)(struct burn_source *); /** Next source, for when a source runs dry and padding is disabled WARNING: This is an obscure feature. Set to NULL at creation and from then on leave untouched and uninterpreted. */ struct burn_source *next; /** Source specific data. Here the various source classes express their specific properties and the instance objects store their individual management data. E.g. data could point to a struct like this: struct app_burn_source { struct my_app *app_handle; ... other individual source parameters ... off_t fixed_size; }; Function (*free_data) has to be prepared to clean up and free the struct. */ void *data; /* ts A71222 : Supposed to be binary backwards compatible extension. */ /* @since 0.4.2 */ /** Valid only if above member .(*read)() is NULL. This indicates a version of struct burn_source younger than 0. From then on, member .version tells which further members exist in the memory layout of struct burn_source. libburn will only touch those announced extensions. Versions: 0 has .(*read)() != NULL, not even .version is present. 1 has .version, .(*read_xt)(), .(*cancel)() */ int version; /** This substitutes for (*read)() in versions above 0. */ int (*read_xt)(struct burn_source *, unsigned char *buffer, int size); /** Informs the burn_source that the consumer of data prematurely ended reading. This call may or may not be issued by libburn before (*free_data)() is called. */ int (*cancel)(struct burn_source *source); }; /** Information on a drive in the system */ struct burn_drive_info { /** Name of the vendor of the drive */ char vendor[9]; /** Name of the drive */ char product[17]; /** Revision of the drive */ char revision[5]; /** Invalid: Was: "Location of the drive in the filesystem." */ /** This string has no meaning any more. Once it stored the drive device file address. Now always use function burn_drive_d_get_adr() to inquire a device file address. ^^^^^ ALWAYS ^^^^^^^*/ char location[17]; /* NOTE: The capability to write particular media types is also announced by their profile number being in the list returned by burn_drive_get_all_profile(). This is the only way to inquire types DVD-RW, DVD+R, DVD+R DL, DVD+RW, BD-R, BD-RE. */ /** Can the drive read DVD-RAM discs */ unsigned int read_dvdram:1; /** Can the drive read DVD-R discs */ unsigned int read_dvdr:1; /** Can the drive read DVD-ROM discs */ unsigned int read_dvdrom:1; /** Can the drive read CD-R discs */ unsigned int read_cdr:1; /** Can the drive read CD-RW discs */ unsigned int read_cdrw:1; /** Can the drive write DVD-RAM discs */ unsigned int write_dvdram:1; /** Can the drive write DVD-R discs */ unsigned int write_dvdr:1; /** Can the drive write CD-R discs */ unsigned int write_cdr:1; /** Can the drive write CD-RW discs */ unsigned int write_cdrw:1; /** Can the drive simulate a write */ unsigned int write_simulate:1; /** DEPRECATED: Can the drive report C2 errors */ unsigned int c2_errors:1; /** DEPRECATED: The size of the drive's buffer (in kilobytes) */ int buffer_size; /** * The supported block types in tao mode. * They should be tested with the desired block type. * See also burn_block_types. */ int tao_block_types; /** * The supported block types in sao mode. * They should be tested with the desired block type. * See also burn_block_types. */ int sao_block_types; /** * The supported block types in raw mode. * They should be tested with the desired block type. * See also burn_block_types. */ int raw_block_types; /** * The supported block types in packet mode. * They should be tested with the desired block type. * See also burn_block_types. */ int packet_block_types; /** The value by which this drive can be indexed when using functions in the library. This is the value to pass to all libbburn functions that operate on a drive. */ struct burn_drive *drive; }; /** Operation progress report. All values are 0 based indices. * */ struct burn_progress { /** The total number of sessions */ int sessions; /** Current session.*/ int session; /** The total number of tracks */ int tracks; /** Current track. */ int track; /** The total number of indices */ int indices; /** Curent index. */ int index; /** The starting logical block address */ int start_sector; /** On write: The number of sectors. On blank: 0x10000 as upper limit for relative progress steps */ int sectors; /** On write: The current sector being processed. On blank: Relative progress steps 0 to 0x10000 */ int sector; /* ts A61023 */ /* @since 0.2.6 */ /** The capacity of the drive buffer */ unsigned buffer_capacity; /** The free space in the drive buffer (might be slightly outdated) */ unsigned buffer_available; /* ts A61119 */ /* @since 0.2.6 */ /** The number of bytes sent to the drive buffer */ off_t buffered_bytes; /** The minimum number of bytes stored in buffer during write. (Caution: Before surely one buffer size of bytes was processed, this value is 0xffffffff.) */ unsigned buffer_min_fill; }; /* ts A61226 */ /* @since 0.3.0 */ /** Description of a speed capability as reported by the drive in conjunction with eventually loaded media. There can be more than one such object per drive. So they are chained via .next and .prev , where NULL marks the end of the chain. This list is set up by burn_drive_scan() and gets updated by burn_drive_grab(). A copy may be obtained by burn_drive_get_speedlist() and disposed by burn_drive_free_speedlist(). For technical background info see SCSI specs MMC and SPC: mode page 2Ah (from SPC 5Ah MODE SENSE) , mmc3r10g.pdf , 6.3.11 Table 364 ACh GET PERFORMANCE, Type 03h , mmc5r03c.pdf , 6.8.5.3 Table 312 */ struct burn_speed_descriptor { /** Where this info comes from : 0 = misc 1 = mode page 2Ah 2 = ACh GET PERFORMANCE Type 03h 3 = ACh GET PERFORMANCE Type 00h Data Type 10h (read speed) */ int source; /** The media type that was current at the time of report -2 = state unknown, -1 = no media was loaded , else see burn_disc_get_profile() */ int profile_loaded; char profile_name[80]; /** The attributed capacity of appropriate media in logical block units i.e. 2352 raw bytes or 2048 data bytes. -1 = capacity unknown. */ int end_lba; /** Speed is given in 1000 bytes/s , 0 = invalid. The numbers are supposed to be usable with burn_drive_set_speed() */ int write_speed; int read_speed; /** Expert info from ACh GET PERFORMANCE and/or mode page 2Ah. Expect values other than 0 or 1 to get a meaning in future.*/ /* Rotational control: 0 = CLV/default , 1 = CAV */ int wrc; /* 1 = drive promises reported performance over full media */ int exact; /* 1 = suitable for mixture of read and write */ int mrw; /** List chaining. Use .next until NULL to iterate over the list */ struct burn_speed_descriptor *prev; struct burn_speed_descriptor *next; }; /** Initialize the library. This must be called before using any other functions in the library. It may be called more than once with no effect. It is possible to 'restart' the library by shutting it down and re-initializing it. Once this was necessary if you follow the older and more general way of accessing a drive via burn_drive_scan() and burn_drive_grab(). See burn_drive_scan_and_grab() with its strong urges and its explanations. @return Nonzero if the library was able to initialize; zero if initialization failed. */ int burn_initialize(void); /** Shutdown the library. This should be called before exiting your application. Make sure that all drives you have grabbed are released <i>before</i> calling this. */ void burn_finish(void); /* ts A61002 */ /** Abort any running drive operation and eventually call burn_finish(). You MUST shut down the busy drives if an aborting event occurs during a burn run. For that you may call this function either from your own signal handling code or indirectly by activating the built-in signal handling: burn_set_signal_handling("my_app_name : ", NULL, 0); Else you may eventually call burn_drive_cancel() on the active drives and wait for them to assume state BURN_DRIVE_IDLE. @param patience Maximum number of seconds to wait for drives to finish. @since 0.7.8 : If this is -1, then only the cancel operations will be performed and no burn_finish() will happen. @param pacifier_func If not NULL: a function to produce appeasing messages. See burn_abort_pacifier() for an example. @param handle Opaque handle to be used with pacifier_func @return 1 ok, all went well 0 had to leave a drive in unclean state <0 severe error, do no use libburn again @since 0.2.6 */ int burn_abort(int patience, int (*pacifier_func)(void *handle, int patience, int elapsed), void *handle); /** A pacifier function suitable for burn_abort. @param handle If not NULL, a pointer to a text suitable for printf("%s") @param patience Maximum number of seconds to wait @param elapsed Elapsed number of seconds */ int burn_abort_pacifier(void *handle, int patience, int elapsed); /** ts A61006 : This is for development only. Not suitable for applications. Set the verbosity level of the library. The default value is 0, which means that nothing is output on stderr. The more you increase this, the more debug output should be displayed on stderr for you. @param level The verbosity level desired. 0 for nothing, higher positive values for more information output. */ void burn_set_verbosity(int level); /* ts A91111 */ /** Enable or disable logging of SCSI commands. 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 safe for multiple drives. @param flag Bitfield for control purposes. The default is 0. bit0= log to file /tmp/libburn_sg_command_log bit1= log to stderr bit2= flush output after each line @since 0.7.4 */ void burn_set_scsi_logging(int flag); /* ts A60813 */ /** Set parameters for behavior on opening device files. To be called early after burn_initialize() and before any bus scan. But not mandatory at all. Parameter value 1 enables a feature, 0 disables. Default is (1,0,0). Have a good reason before you change it. @param exclusive 0 = no attempt to make drive access exclusive. 1 = Try to open only devices which are not marked as busy and try to mark them busy if opened sucessfully. (O_EXCL on GNU/Linux , flock(LOCK_EX) on FreeBSD.) 2 = in case of a SCSI device, also try to open exclusively the matching /dev/sr, /dev/scd and /dev/st . One may select a device SCSI file family by adding 0 = default family 4 = /dev/sr%d 8 = /dev/scd%d 16 = /dev/sg%d Do not use other values ! Add 32 to demand on GNU/Linux an exclusive lock by fcntl(,F_SETLK,) after open() has succeeded. @param blocking Try to wait for drives which do not open immediately but also do not return an error as well. (O_NONBLOCK) This might stall indefinitely with /dev/hdX hard disks. @param abort_on_busy Unconditionally abort process when a non blocking exclusive opening attempt indicates a busy drive. Use this only after thorough tests with your app. @since 0.2.2 */ void burn_preset_device_open(int exclusive, int blocking, int abort_on_busy); /* ts A70223 */ /** Allows the use of media types which are implemented in libburn but not yet tested. The list of those untested profiles is subject to change. - Currently no media types are under test reservation - If you really test such media, then please report the outcome on libburn-hackers@pykix.org If ever then this call should be done soon after burn_initialize() before any drive scanning. @param yes 1=allow all implemented profiles, 0=only tested media (default) @since 0.3.4 */ void burn_allow_untested_profiles(int yes); /* ts A60823 */ /** Aquire a drive with known device file address. This is the sysadmin friendly way to open one drive and to leave all others untouched. It bundles the following API calls to form a non-obtrusive way to use libburn: burn_drive_add_whitelist() , burn_drive_scan() , burn_drive_grab() You are *strongly urged* to use this call whenever you know the drive address in advance. If not, then you have to use directly above calls. In that case, you are *strongly urged* to drop any unintended drive which will be exclusively occupied and not closed by burn_drive_scan(). This can be done by shutting down the library including a call to burn_finish(). You may later start a new libburn session and should then use the function described here with an address obtained after burn_drive_scan() via burn_drive_d_get_adr(drive_infos[driveno].drive,adr). Another way is to drop the unwanted drives by burn_drive_info_forget(). Operating on multiple drives: Different than with burn_drive_scan() it is allowed to call burn_drive_scan_and_grab() without giving up any other scanned drives. So this call can be used to get a collection of more than one aquired drives. The attempt to aquire the same drive twice will fail, though. Pseudo-drives: burn_drive_scan_and_grab() is able to aquire virtual drives which will accept options much like a MMC burner drive. Many of those options will not cause any effect, though. The address of a pseudo-drive begins with prefix "stdio:" followed by a path. Examples: "stdio:/tmp/pseudo_drive" , "stdio:/dev/null" , "stdio:-" If the path is empty, the result is a null-drive = drive role 0. It pretends to have loaded no media and supports no reading or writing. If the path leads to an existing regular file, or to a not yet existing file, or to an existing block device, then the result is a random access stdio-drive capable of reading and writing = drive role 2. If the path leads to an existing file of any type other than directory, then the result is a sequential write-only stdio-drive = drive role 3. The special address form "stdio:/dev/fd/{number}" is interpreted literally as reference to open file descriptor {number}. This address form coincides with real files on some systems, but it is in fact hardcoded in libburn. Special address "stdio:-" means stdout = "stdio:/dev/fd/1". The role of such a drive is determined by the file type obtained via fstat({number}). Roles 2 and 3 perform all their eventual data transfer activities on a file via standard i/o functions open(2), lseek(2), read(2), write(2), close(2). The media profile is reported as 0xffff. Write space information from those media is not necessarily realistic. The capabilities of role 2 resemble DVD-RAM but it can simulate writing. If the path does not exist in the filesystem yet, it is attempted to create it as a regular file as soon as write operations are started. The capabilities of role 3 resemble a blank DVD-R. Nevertheless each burn_disc_write() run may only write a single track. One may distinguish pseudo-drives from MMC drives by call burn_drive_get_drive_role(). @param drive_infos On success returns a one element array with the drive (cdrom/burner). Thus use with driveno 0 only. On failure the array has no valid elements at all. The returned array should be freed via burn_drive_info_free() when it is no longer needed. This is a result from call burn_drive_scan(). See there. Use with driveno 0 only. @param adr The device file address of the desired drive. Either once obtained by burn_drive_d_get_adr() or composed skillfully by application or its user. E.g. "/dev/sr0". Consider to preprocess it by burn_drive_convert_fs_adr(). @param load Nonzero to make the drive attempt to load a disc (close its tray door, etc). @return 1 = success , 0 = drive not found , -1 = other error @since 0.2.2 */ int burn_drive_scan_and_grab(struct burn_drive_info *drive_infos[], char* adr, int load); /* ts A51221 */ /* @since 0.2.2 */ /** Maximum number of particularly permissible drive addresses */ #define BURN_DRIVE_WHITELIST_LEN 255 /** Add a device to the list of permissible drives. As soon as some entry is in the whitelist all non-listed drives are banned from scanning. @return 1 success, <=0 failure @since 0.2.2 */ int burn_drive_add_whitelist(char *device_address); /** Remove all drives from whitelist. This enables all possible drives. */ void burn_drive_clear_whitelist(void); /** Scan for drives. This function MUST be called until it returns nonzero. In case of re-scanning: All pointers to struct burn_drive and all struct burn_drive_info arrays are invalidated by using this function. Do NOT store drive pointers across calls to this function ! To avoid invalid pointers one MUST free all burn_drive_info arrays by burn_drive_info_free() before calling burn_drive_scan() a second time. If there are drives left, then burn_drive_scan() will refuse to work. After this call all drives depicted by the returned array are subject to eventual (O_EXCL) locking. See burn_preset_device_open(). This state ends either with burn_drive_info_forget() or with burn_drive_release(). It is unfriendly to other processes on the system to hold drives locked which one does not definitely plan to use soon. @param drive_infos Returns an array of drive info items (cdroms/burners). The returned array must be freed by burn_drive_info_free() before burn_finish(), and also before calling this function burn_drive_scan() again. @param n_drives Returns the number of drive items in drive_infos. @return 0 while scanning is not complete >0 when it is finished sucessfully, <0 when finished but failed. */ int burn_drive_scan(struct burn_drive_info *drive_infos[], unsigned int *n_drives); /* ts A60904 : ticket 62, contribution by elmom */ /** Release memory about a single drive and any exclusive lock on it. Become unable to inquire or grab it. Expect FATAL consequences if you try. @param drive_info pointer to a single element out of the array obtained from burn_drive_scan() : &(drive_infos[driveno]) @param force controls degree of permissible drive usage at the moment this function is called, and the amount of automatically provided drive shutdown : 0= drive must be ungrabbed and BURN_DRIVE_IDLE 1= try to release drive even if in state BURN_DRIVE_GRABBING Use these two only. Further values are to be defined. @return 1 on success, 2 if drive was already forgotten, 0 if not permissible, <0 on other failures, @since 0.2.2 */ int burn_drive_info_forget(struct burn_drive_info *drive_info, int force); /** When no longer needed, free a whole burn_drive_info array which was returned by burn_drive_scan(). For freeing single drive array elements use burn_drive_info_forget(). */ void burn_drive_info_free(struct burn_drive_info drive_infos[]); /* ts A60823 */ /* @since 0.2.2 */ /** Maximum length+1 to expect with a drive device file address string */ #define BURN_DRIVE_ADR_LEN 1024 /* ts A70906 */ /** Inquire the device file address of the given drive. @param drive The drive to inquire. @param adr An application provided array of at least BURN_DRIVE_ADR_LEN characters size. The device file address gets copied to it. @return >0 success , <=0 error (due to libburn internal problem) @since 0.4.0 */ int burn_drive_d_get_adr(struct burn_drive *drive, char adr[]); /* A60823 */ /** Inquire the device file address of a drive via a given drive_info object. (Note: This is a legacy call.) @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 characters size. The device file address gets copied to it. @return >0 success , <=0 error (due to libburn internal problem) @since 0.2.6 */ int burn_drive_get_adr(struct burn_drive_info *drive_info, char adr[]); /* ts A60922 ticket 33 */ /** Evaluate whether the given address would be a drive device file address 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 @since 0.2.6 */ int burn_drive_is_enumerable_adr(char *adr); /* ts A60922 ticket 33 */ /** 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 system address can be read from the filesystem object and a matching drive is found. @param path The address of an existing file system object @param adr An application provided array of at least BURN_DRIVE_ADR_LEN characters size. The device file address gets copied to it. @return 1 = success , 0 = failure , -1 = severe error @since 0.2.6 */ int burn_drive_convert_fs_adr(char *path, char adr[]); /* ts A60923 */ /** Try to convert a given SCSI address of bus,host,channel,target,lun into 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 the >= 0 parameters is taken as result. Note: bus and (host,channel) are supposed to be redundant. @param bus_no "Bus Number" (something like a virtual controller) @param host_no "Host Number" (something like half a virtual controller) @param channel_no "Channel Number" (other half of "Host Number") @param target_no "Target Number" or "SCSI Id" (a device) @param lun_no "Logical Unit Number" (a sub device) @param adr An application provided array of at least BURN_DRIVE_ADR_LEN characters size. The device file address gets copied to it. @return 1 = success , 0 = failure , -1 = severe error @since 0.2.6 */ int burn_drive_convert_scsi_adr(int bus_no, int host_no, int channel_no, 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 */ /** 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 drive device file address obtained via burn_drive_d_get_adr(). It is also supposed to succeed with any device file of a (possibly emulated) SCSI device. @return 1 = success , 0 = failure , -1 = severe error @since 0.2.6 */ int burn_drive_obtain_scsi_adr(char *path, int *bus_no, int *host_no, int *channel_no, int *target_no, int *lun_no); /** Grab a drive. This must be done before the drive can be used (for reading, writing, etc). @param drive The drive to grab. This is found in a returned burn_drive_info struct. @param load Nonzero to make the drive attempt to load a disc (close its tray door, etc). @return 1 if it was possible to grab the drive, else 0 */ int burn_drive_grab(struct burn_drive *drive, int load); /* ts B00114 */ /* Probe available CD write modes and block types. In earlier versions this was done unconditionally on drive examination or aquiration. But it is lengthy and obtrusive, up to spoiling burn runs on the examined drives. So now this probing is omitted by default. All drives which announce to be capable of CD or DVD writing, get blindly attributed the capability for SAO and TAO. Applications which are interested in RAW modes or want to rely on the traditional write mode information, may use this call. @param drive_info drive object to be inquired @return >0 indicates success, <=0 means failure @since 0.7.6 */ int burn_drive_probe_cd_write_modes(struct burn_drive_info *drive_info); /* ts A90824 */ /** Calm down or alert a drive. Some drives stay alert after reading for quite some time. This saves time with the startup for the next read operation but also causes noise and consumes extra energy. It makes sense to calm down the drive if no read operation is expected for the next few seconds. The drive will get alert automatically if operations are required. @param d The drive to influence. @param flag Bitfield for control purposes bit0= become alert (else start snoozing) This is not mandatory for further drive operations @return 1= success , 0= drive role not suitable for calming @since 0.7.0 */ 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 d 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 busy (see burn_drive_get_status). @param drive The drive to release. @param eject Nonzero to make the drive eject the disc in it. */ void burn_drive_release(struct burn_drive *drive, int eject); /* ts A70918 */ /** Like burn_drive_release() but keeping the drive tray closed and its eject button disabled. This physically locked drive state will last until the drive is grabbed again and released via burn_drive_release(). Programs like eject, cdrecord, growisofs will break that ban too. @param d The drive to release and leave locked. @param flag Bitfield for control purposes (unused yet, submit 0) @return 1 means success, <=0 means failure @since 0.4.0 */ int burn_drive_leave_locked(struct burn_drive *d, int flag); /** Returns what kind of disc a drive is holding. This function may need to be called more than once to get a proper status from it. See burn_disc_status for details. @param drive The drive to query for a disc. @return The status of the drive, or what kind of disc is in it. Note: BURN_DISC_UNGRABBED indicates wrong API usage */ enum burn_disc_status burn_disc_get_status(struct burn_drive *drive); /* ts A61020 */ /** WARNING: This revives an old bug-like behavior that might be dangerous. Sets the drive status to BURN_DISC_BLANK if it is BURN_DISC_UNREADY or BURN_DISC_UNSUITABLE. Thus marking media as writable which actually failed to declare themselves either blank or (partially) filled. @return 1 drive status has been set , 0 = unsuitable drive status @since 0.2.6 */ int burn_disc_pretend_blank(struct burn_drive *drive); /* ts A61106 */ /** WARNING: This overrides the safety measures against unsuitable media. Sets the drive status to BURN_DISC_FULL if it is BURN_DISC_UNREADY or BURN_DISC_UNSUITABLE. Thus marking media as blankable which actually failed to declare themselves either blank or (partially) filled. @since 0.2.6 */ int burn_disc_pretend_full(struct burn_drive *drive); /* ts B31110 */ /** WARNING: This overrides the safety measures against unsuitable media. Sets the drive status to BURN_DISC_FULL unconditionally. @since 1.3.4 */ int burn_disc_pretend_full_uncond(struct burn_drive *drive); /* ts B51016 */ /** Returns the Drive Serial Number as of MMC feature 108h. @param d The drive to inquire. @param sno Returns the bytes of the serial number. A trailing 0-byte is appended for convenience. MMC specifies ASCII 0x20 to 0x7h as possible byte values. But given drive firmware habits there is no warranty that *sno contains no other byte values. Submit *sno as NULL or pointing to free()-able memory. Apply free() to *sno when no longer needed. @param sno_len Returns the number of valid bytes in returned *sno, not counting the appended trailing 0. @return 1= success (but maybe *sno_len is 0), <= 0 severe failure @since 1.4.2 */ int burn_drive_get_serial_no(struct burn_drive *d, char **sno, int *sno_len); /* ts B51016 */ /** Returns the Media Serial Number as of MMC feature 109h and command ABh READ MEDIA SERIAL NUMBER. Note: This call will return an empty result unless the macro Libburn_enable_scsi_cmd_ABh is defined at compile time. This is because the command READ MEDIA SERIAL NUMBER demands superuser authority on Linux, because no medium with serial number could be tested yet, and because this command made one of the test drives unusable until power cycle when it was executed despite feature 109h was not announced as "current". @param d The drive to inquire. @param sno Returns the bytes of the serial number. A trailing 0-byte is appended for convenience. There is no warranty that *sno contains only non-zero printable bytes. Submit *sno as NULL or pointing to free()-able memory. Apply free() to *sno when no longer needed. @param sno_len Returns the number of valid bytes in returned *sno, not counting the appended trailing 0. @return 1= success (but maybe *sno_len is 0), <= 0 severe failure @since 1.4.2 */ int burn_drive_get_media_sno(struct burn_drive *d, char **sno, int *sno_len); /* ts A61021 */ /** Reads ATIP information from inserted media. To be obtained via burn_drive_get_write_speed(), burn_drive_get_min_write_speed(), burn_drive_get_start_end_lba(). The drive must be grabbed for this call. @param drive The drive to query. @return 1=sucess, 0=no valid ATIP info read, -1 severe error @since 0.2.6 */ int burn_disc_read_atip(struct burn_drive *drive); /* ts A61020 */ /** Returns start and end lba of the media which is currently inserted in the given drive. The drive has to be grabbed to have hope for reply. Shortcomming (not a feature): unless burn_disc_read_atip() was called only blank media will return valid info. @param drive The drive to query. @param start_lba Returns the start lba value @param end_lba Returns the end lba value @param flag Bitfield for control purposes (unused yet, submit 0) @return 1 if lba values are valid , 0 if invalid @since 0.2.6 */ int burn_drive_get_start_end_lba(struct burn_drive *drive, int *start_lba, int *end_lba, int flag); /* ts A90902 */ /** Guess the manufacturer name of CD media from the ATIP addresses of lead-in and lead-out. (Currently only lead-in is interpreted. Lead-out may in future be used to identify the media type in more detail.) The parameters of this call should be obtained by burn_disc_read_atip(d), burn_drive_get_start_end_lba(d, &start_lba, &end_lba, 0), burn_lba_to_msf(start_lba, &m_li, &s_li, &f_li) and burn_lba_to_msf(end_lba, &m_lo, &s_lo, &f_lo). @param m_li "minute" part of ATIP lead-in or start_lba @param s_li "second" of lead-in or start_lba @param f_li "frame" of lead-in @param m_lo "minute" part of ATIP lead-out @param s_lo "second" of lead-out @param f_lo "frame" of lead-out @param flag Bitfield for control purposes, bit0= append a text "(aka ...)" to reply if other brands or vendor names are known. @return Printable text or NULL on memory shortage. Dispose by free() when no longer needed. @since 0.7.2 */ 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); /* ts A90909 */ /** Retrieve some media information which is mainly specific to CD. For other media only the bits in reply parameter valid are supposed to be meaningful. @param d The drive to query. @param disc_type A string saying either "CD-DA or CD-ROM", or "CD-I", or ""CD-ROM XA", or "undefined". @param disc_id A 32 bit number read from the media. (Meaning unclear yet) @param bar_code 8 hex digits from a barcode on media read by the drive (if the drive has a bar code reader built in). @param app_code The Host Application Code which must be set in the Write Parameters Page if the media is not unrestricted (URU==0). @param valid Replies bits which indicate the validity of other reply parameters or the state of certain CD info bits: bit0= disc_type is valid bit1= disc_id is valid bit2= bar_code is valid bit3= disc_app_code is valid bit4= Disc is unrestricted (URU bit, 51h READ DISC INFO) This seems to be broken with my drives. The bit is 0 and the validity bit for disc_app_code is 0 too. bit5= Disc is nominally erasable (Erasable bit) This will be set with overwriteable media which libburn normally considers to be unerasable blank. @return 1 success, <= 0 an error occured @since 0.7.2 */ int burn_disc_get_cd_info(struct burn_drive *d, char disc_type[80], unsigned int *disc_id, char bar_code[9], int *app_code, int *valid); /* ts B11201 */ /** Read the array of CD-TEXT packs from the Lead-in of an audio CD. Each pack consists of 18 bytes, of which 4 are header. 12 bytes are pieces of 0-terminated texts or binary data. 2 bytes hold a CRC. For a description of the format of the array, see file doc/cdtext.txt. @param d The drive to query. @param text_packs Will point to an allocated memory buffer with CD-TEXT. It will only contain text packs, and not be prepended by the TOC header of four bytes, which gets stored with file cdtext.dat by cdrecord -vv -toc. (The first two of these bytes are supposed to hold the number of CD-TEXT bytes + 2. The other two bytes are supposed to be 0.) Dispose this buffer by free(), when no longer needed. @param num_packs Will tell the number of text packs, i.e. the number of bytes in text_packs divided by 18. @param flag Bitfield for control purposes, Unused yet. Submit 0. @return 1 success, 0= no CD-TEXT found, < 0 an error occured @since 1.2.0 */ int burn_disc_get_leadin_text(struct burn_drive *d, unsigned char **text_packs, int *num_packs, int flag); /* ts B00924 */ /** Read the current usage of the eventual BD Spare Area. This area gets reserved on BD media during formatting. During writing it is used to host replacements of blocks which failed the checkread immediately after writing. This call applies only to recordable BD media. I.e. profiles 0x41 to 0x43. @param d The drive to query. @param alloc_blocks Returns the number of blocks reserved as Spare Area @param free_blocks Returns the number of yet unused blocks in that area @param flag Bitfield for control purposes (unused yet, submit 0) @return 1 = reply prarameters are valid, <=0 = reply is invalid (e.g. because no BD profile) @since 0.8.8 */ int burn_disc_get_bd_spare_info(struct burn_drive *d, 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 */ /** 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(). This call retrieves an updated lba, eventual nwa, and can address the invisible track to come. The drive must be grabbed for this call. One may not issue this call during ongoing burn_disc_write() or burn_disc_erase(). @param d The drive to query. @param o If not NULL: write parameters to be set on drive before query @param trackno 0=next track to come, >0 number of existing track The first existing track on a CD may have a number higher than 1. Use burn_session_get_start_tno() to inquire this start number. @param lba return value: start lba @param nwa return value: Next Writeable Address @return 1=nwa is valid , 0=nwa is not valid , -1=error @since 0.2.6 */ int burn_disc_track_lba_nwa(struct burn_drive *d, struct burn_write_opts *o, int trackno, int *lba, int *nwa); /* ts B10525 */ /** Tells whether a previous attempt to determine the Next Writeable Address of the upcomming track reveiled that the READ TRACK INFORMATION Damage Bit is set for this track and that no valid writable address is available. See MMC-5 6.27.3.7 Damage Bit, 6.27.3.11 NWA_V (NWA valid) @param d The drive to query. @param flag Bitfield for control purposes (unused yet, submit 0) @return 0= Looks ok: Damage Bit is not set, NWA_V is set 1= Damaged and theoretically writable (NWA_V is set) 2= Not writable: NWA_V is not set 3= Damaged and not writable (NWA_V is not set), @since 1.1.0 */ 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 */ /** Read start lba of the first track in the last complete session. This is the first parameter of mkisofs option -C. The second parameter is nwa as obtained by burn_disc_track_lba_nwa() with trackno 0. @param d The drive to query. @param start_lba returns the start address of that track @return <= 0 : failure, 1 = ok @since 0.3.2 */ int burn_disc_get_msc1(struct burn_drive *d, int *start_lba); /* ts A70213 */ /** Return the best possible estimation of the currently available capacity of the media. This might depend on particular write option settings. For inquiring the space with such a set of options, the drive has to be grabbed and BURN_DRIVE_IDLE. If not, then one will only get a canned value from the most recent automatic inquiry (e.g. during last drive grabbing). An eventual start address from burn_write_opts_set_start_byte() will be taken into respect with the capacity estimation. Negative results get 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 o If not NULL: write parameters to be set on drive before query @return number of most probably available free bytes @since 0.3.4 */ off_t burn_disc_available_space(struct burn_drive *d, struct burn_write_opts *o); /* ts A61202 */ /** Tells the MMC Profile identifier of the loaded media. The drive must be grabbed in order to get a non-zero result. libburn currently writes only to profiles 0x09 "CD-R" 0x0a "CD-RW" 0x11 "DVD-R sequential recording" 0x12 "DVD-RAM" 0x13 "DVD-RW restricted overwrite" 0x14 "DVD-RW sequential recording", 0x15 "DVD-R/DL sequential recording", 0x1a "DVD+RW" 0x1b "DVD+R", 0x2b "DVD+R/DL", 0x41 "BD-R sequential recording", 0x43 "BD-RE", 0xffff "stdio file" Note: 0xffff is not a MMC profile but a libburn invention. Read-only are the profiles 0x08 "CD-ROM", 0x10 "DVD-ROM", 0x40 "BD-ROM", Read-only for now is this BD-R profile (testers wanted) 0x42 "BD-R random recording" Empty drives are supposed to report 0x00 "" @param d The drive where the media is inserted. @param pno Profile Number. See also mmc5r03c.pdf, table 89 @param name Profile Name (see above list, unknown profiles have empty name) @return 1 profile is valid, 0 no profile info available @since 0.3.0 */ int burn_disc_get_profile(struct burn_drive *d, int *pno, char name[80]); /* ts A90903 : API */ /** Obtain product id and standards defined media codes. The product id is a printable string which is supposed to be the same for identical media but should vary with non-identical media. Some media cannot provide such an id at all. The pair (profile_number, product_id) should be the best id to identify media with identical product specifications. The reply parameters media_code1 and media_code2 can be used with burn_guess_manufacturer() The reply parameters have to be disposed by free() when no longer needed. @param d The drive where the media is inserted. @param product_id Reply: Printable text depicting manufacturer and eventually media id. @param media_code1 Reply: The eventual manufacturer identification as read from DVD/BD media or a text "XXmYYsZZf" from CD media ATIP lead-in. @param media_code2 The eventual media id as read from DVD+/BD media or a text "XXmYYsZZf" from CD ATIP lead-out. @param book_type Book type text for DVD and BD. Caution: is NULL with CD, even if return value says ok. @param flag Bitfield for control purposes bit0= do not escape " _/" (not suitable for burn_guess_manufacturer()) @return 1= ok, product_id and media codes are valid, 0= no product id_available, reply parameters are NULL <0= error @since 0.7.2 */ int burn_disc_get_media_id(struct burn_drive *d, char **product_id, char **media_code1, char **media_code2, char **book_type, int flag); /* ts A90904 */ /** Guess the name of a manufacturer by profile number, manufacturer code and media code. The profile number can be obtained by burn_disc_get_profile(), the other two parameters can be obtained as media_code1 and media_code2 by burn_disc_get_media_id(). @param profile_no Profile number (submit -1 if not known) @param manuf_code Manufacturer code from media (e.g. "RICOHJPN") @param media_code Media ID code from media (e.g. "W11") @param flag Bitfield for control purposes, submit 0 @return Printable text or NULL on memory shortage. If the text begins with "Unknown " then no item of the manufacturer list matched the codes. Dispose by free() when no longer needed. @since 0.7.2 */ char *burn_guess_manufacturer(int profile_no, char *manuf_code, char *media_code, int flag); /** Tells whether a disc can be erased or not @param d The drive to inquire. @return Non-zero means erasable */ int burn_disc_erasable(struct burn_drive *d); /** Returns the progress and status of a drive. @param drive The drive to query busy state for. @param p Returns the progress of the operation, NULL if you don't care @return the current status of the drive. See also burn_drive_status. */ enum burn_drive_status burn_drive_get_status(struct burn_drive *drive, struct burn_progress *p); /** Creates a write_opts struct for burning to the specified drive. The returned object must later be freed with burn_write_opts_free(). @param drive The drive to write with @return The write_opts, NULL on error */ struct burn_write_opts *burn_write_opts_new(struct burn_drive *drive); /* ts A70901 */ /** Inquires the drive associated with a burn_write_opts object. @param opts object to inquire @return pointer to drive @since 0.4.0 */ struct burn_drive *burn_write_opts_get_drive(struct burn_write_opts *opts); /** Frees a write_opts struct created with burn_write_opts_new @param opts write_opts to free */ void burn_write_opts_free(struct burn_write_opts *opts); /** Creates a read_opts struct for reading from the specified drive must be freed with burn_read_opts_free @param drive The drive to read from @return The read_opts */ struct burn_read_opts *burn_read_opts_new(struct burn_drive *drive); /** Frees a read_opts struct created with burn_read_opts_new @param opts write_opts to free */ void burn_read_opts_free(struct burn_read_opts *opts); /** Erase a disc in the drive. The drive must be grabbed successfully BEFORE calling this functions. Always ensure that the drive reports a status of BURN_DISC_FULL before calling this function. An erase operation is not cancellable, as control of the operation is passed wholly to the drive and there is no way to interrupt it safely. @param drive The drive with which to erase a disc. Only drive roles 1 (MMC) and 5 (stdio random write-only) support erasing. @param fast Nonzero to do a fast erase, where only the disc's headers are erased; zero to erase the entire disc. With DVD-RW, fast blanking yields media capable only of DAO. */ void burn_disc_erase(struct burn_drive *drive, int fast); /* ts A70101 - A70417 */ /** Format media for use with libburn. This currently applies to DVD-RW in state "Sequential Recording" (profile 0014h) which get formatted to state "Restricted Overwrite" (profile 0013h). DVD+RW can be "de-iced" by setting bit4 of flag. DVD-RAM and BD-RE may get formatted initially or re-formatted to adjust their Defect Managment. This function usually returns while the drive is still in the process of formatting. The formatting is done, when burn_drive_get_status() returns BURN_DRIVE_IDLE. This may be immediately after return or may need several thousand seconds to occur. @param drive The drive with the disc to format. @param size The size in bytes to be used with the format command. It should be divisible by 32*1024. The effect of this parameter may depend on the media profile and on parameter flag. @param flag Bitfield for control purposes: bit0= after formatting, write the given number of zero-bytes to the media and eventually perform preliminary closing. bit1+2: size mode 0 = use parameter size as far as it makes sense 1 = insist in size 0 even if there is a better default known (on DVD-RAM or BD-R identical to size mode 0, i.e. they never get formatted with payload size 0) 2 = without bit7: format to maximum available size with bit7 : take size from indexed format descriptor 3 = without bit7: format to default size with bit7 : take size from indexed format descriptor bit3= -reserved- bit4= enforce re-format of (partly) formatted media bit5= try to disable eventual defect management bit6= try to avoid lengthy media certification bit7, bit8 to bit15 = bit7 enables MMC expert application mode (else libburn tries to choose a suitable format type): If it is set then bit8 to bit15 contain the index of the format to use. See burn_disc_get_formats(), burn_disc_get_format_descr(). Acceptable types are: 0x00, 0x01, 0x10, 0x11, 0x13, 0x15, 0x26, 0x30, 0x31, 0x32. If bit7 is set, then bit4 is set automatically. bit16= enable POW on blank BD-R @since 0.3.0 */ void burn_disc_format(struct burn_drive *drive, off_t size, int flag); /* ts A70112 */ /* @since 0.3.0 */ /** Possible formatting status values */ #define BURN_FORMAT_IS_UNFORMATTED 1 #define BURN_FORMAT_IS_FORMATTED 2 #define BURN_FORMAT_IS_UNKNOWN 3 /* ts A70112 */ /** Inquire the formatting status, the associated sizes and the number of available formats. The info is media specific and stems from MMC command 23h READ FORMAT CAPACITY. See mmc5r03c.pdf 6.24 for background details. Media type can be determined via burn_disc_get_profile(). @param drive The drive with the disc to format. @param status The current formatting status of the inserted media. See BURN_FORMAT_IS_* macros. Note: "unknown" is the legal status for quick formatted, yet unwritten DVD-RW. @param size The size in bytes associated with status. unformatted: the maximum achievable size of the media formatted: the currently formatted capacity unknown: maximum capacity of drive or of media @param bl_sas Additional info "Block Length/Spare Area Size". Expected to be constantly 2048 for non-BD media. @param num_formats The number of available formats. To be used with burn_disc_get_format_descr() to obtain such a format and eventually with burn_disc_format() to select one. @return 1 reply is valid , <=0 failure @since 0.3.0 */ int burn_disc_get_formats(struct burn_drive *drive, int *status, off_t *size, unsigned *bl_sas, int *num_formats); /* ts A70112 */ /** Inquire parameters of an available media format. @param drive The drive with the disc to format. @param index The index of the format item. Beginning with 0 up to reply parameter from burn_disc_get_formats() : num_formats - 1 @param type The format type. See mmc5r03c.pdf, 6.5, 04h FORMAT UNIT. 0x00=full, 0x10=CD-RW/DVD-RW full, 0x11=CD-RW/DVD-RW grow, 0x15=DVD-RW quick, 0x13=DVD-RW quick grow, 0x26=DVD+RW background, 0x30=BD-RE with spare areas, 0x31=BD-RE without spare areas @param size The maximum size in bytes achievable with this format. @param tdp Type Dependent Parameter. See mmc5r03c.pdf. @return 1 reply is valid , <=0 failure @since 0.3.0 */ int burn_disc_get_format_descr(struct burn_drive *drive, int index, int *type, off_t *size, unsigned *tdp); /* ts A61109 : this was and is defunct */ /** Read a disc from the drive and write it to an fd pair. The drive must be grabbed successfully BEFORE calling this function. Always ensure that the drive reports a status of BURN_DISC_FULL before calling this function. @param drive The drive from which to read a disc. @param o The options for the read operation. */ void burn_disc_read(struct burn_drive *drive, const struct burn_read_opts *o); /* ts A70222 */ /* @since 0.3.4 */ /** The length of a rejection reasons string for burn_precheck_write() and burn_write_opts_auto_write_type() . */ #define BURN_REASONS_LEN 4096 /* ts A70219 */ /** Examines a completed setup for burn_disc_write() whether it is permissible with drive and media. This function is called by burn_disc_write() but an application might be interested in this check in advance. @param o The options for the writing operation. @param disc The descrition of the disc to be created @param reasons Eventually returns a list of rejection reason statements @param silent 1= do not issue error messages , 0= report problems @return 1 ok, -1= no recordable media detected, 0= other failure @since 0.3.4 */ int burn_precheck_write(struct burn_write_opts *o, struct burn_disc *disc, char reasons[BURN_REASONS_LEN], int silent); /** Write a disc in the drive. The drive must be grabbed successfully before calling this function. Always ensure that the drive reports a status of BURN_DISC_BLANK ot BURN_DISC_APPENDABLE before calling this function. Note: write_type BURN_WRITE_SAO is currently not capable of writing a mix of data and audio tracks. You must use BURN_WRITE_TAO for such sessions. To be set by burn_write_opts_set_write_type(). 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. 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 disc The struct burn_disc * that described the disc to be created */ void burn_disc_write(struct burn_write_opts *o, struct burn_disc *disc); /* ts A90227 */ /** Control stream recording during the write run and eventually set the start LBA for stream recording. Stream recording is set from struct burn_write_opts when the write run gets started. See burn_write_opts_set_stream_recording(). The call described here can be used later to override this setting and to program automatic switching at a given LBA. It also affects subsequent calls to burn_random_access_write(). @param drive The drive which performs the write operation. @param recmode -1= disable stream recording 0= leave setting as is 1= enable stream recording @param start The LBA where actual stream recording shall start. (0 means unconditional stream recording) @param flag Bitfield for control purposes (unused yet, submit 0). @return 1=success , <=0 failure @since 0.6.4 */ int burn_drive_set_stream_recording(struct burn_drive *drive, int recmode, int start, int flag); /** Cancel an operation on a drive. This will only work when the drive's busy state is BURN_DRIVE_READING or BURN_DRIVE_WRITING. @param drive The drive on which to cancel the current operation. */ void burn_drive_cancel(struct burn_drive *drive); /* ts A61223 */ /** Inquire whether the most recent asynchronous media job was successful. This applies to burn_disc_erase(), burn_disc_format(), burn_disc_write(). Reasons for non-success may be: rejection of burn parameters, abort due to fatal errors during write, blank or format, a call to burn_drive_cancel() by the application thread. @param d The drive to inquire. @return 1=burn seems to have went well, 0=burn failed @since 0.2.6 */ int burn_drive_wrote_well(struct burn_drive *d); /* ts B31023 */ /** Inquire whether a write error occured which is suspected to have happened due to a false report about DVD-RW capability to be written in write type BURN_WRITE_TAO. @param d The drive to inquire. @return 1= it seems that BURN_WRITE_TAO on DVD-RW caused error, 0= it does not seem so @since 1.3.4 */ int burn_drive_was_feat21_failure(struct burn_drive *d); /** Convert a minute-second-frame (MSF) value to sector count @param m Minute component @param s Second component @param f Frame component @return The sector count */ int burn_msf_to_sectors(int m, int s, int f); /** Convert a sector count to minute-second-frame (MSF) @param sectors The sector count @param m Returns the minute component @param s Returns the second component @param f Returns the frame component */ void burn_sectors_to_msf(int sectors, int *m, int *s, int *f); /** Convert a minute-second-frame (MSF) value to an lba @param m Minute component @param s Second component @param f Frame component @return The lba */ int burn_msf_to_lba(int m, int s, int f); /** Convert an lba to minute-second-frame (MSF) @param lba The lba @param m Returns the minute component @param s Returns the second component @param f Returns the frame component */ void burn_lba_to_msf(int lba, int *m, int *s, int *f); /** Create a new disc @return Pointer to a burn_disc object or NULL on failure. */ struct burn_disc *burn_disc_create(void); /** Delete disc and decrease the reference count on all its sessions @param d The disc to be freed */ void burn_disc_free(struct burn_disc *d); /** Create a new session @return Pointer to a burn_session object or NULL on failure. */ struct burn_session *burn_session_create(void); /** Free a session (and decrease reference count on all tracks inside) @param s Session to be freed */ void burn_session_free(struct burn_session *s); /** Add a session to a disc at a specific position, increasing the sessions's reference count. @param d Disc to add the session to @param s Session to add to the disc @param pos position to add at (BURN_POS_END is "at the end") @return 0 for failure, 1 for success */ int burn_disc_add_session(struct burn_disc *d, struct burn_session *s, unsigned int pos); /** Remove a session from a disc @param d Disc to remove session from @param s Session pointer to find and remove */ int burn_disc_remove_session(struct burn_disc *d, struct burn_session *s); /* ts B11219 */ /** Read a CDRWIN cue sheet file and equip the session object by tracks and CD-TEXT according to the content of the file. For a description of CDRWIN file format see http://digitalx.org/cue-sheet/syntax/ Fully supported commands are: CATALOG , CDTEXTFILE , FLAGS , INDEX , ISRC , PERFORMER , POSTGAP , PREGAP , REM , SONGWRITER , TITLE Further supported commands introduced by cdrecord (usage like PERFORMER): ARRANGER , COMPOSER , MESSAGE Partly supported commands are: FILE which supports only types BINARY , MOTOROLA , WAVE TRACK which supports only datatypes AUDIO , MODE1/2048 Unsupported types of FILE or TRACK lead to failure of the call. libburn does not yet support mixing of AUDIO and MODE1/2048. So this call will fail if such a mix is found. CD-TEXT information is allowed only if all tracks are of datatype AUDIO. Empty lines and lines which start by '#' are ignored. @param session Session where to attach tracks. It must not yet have tracks or else this call will fail. @param path Filesystem address of the CDRWIN cue sheet file. Normally with suffix .cue @param fifo_size Number of bytes in fifo. This will be rounded up by the block size of the track mode. <= 0 means no fifo. @param fifo Returns a reference to the burn_source object that was installed as fifo between FILE and the track burn sources. One may use this to inquire the fifo state. Dispose it by burn_source_free() when no longer needed. It is permissible to pass this parameter to libburn as NULL, in order to immediately drop ownership on the fifo. @param text_packs Returns pre-formatted CD-TEXT packs resulting from cue sheet command CDTEXTFILE. To be used with call burn_write_opts_set_leadin_text(). It is permissible to pass this parameter to libburn as NULL, in order to disable CDTEXTFILE. @param num_packs Returns the number of 18 byte records in text_packs. @param flag Bitfield for control purposes. bit0= Do not attach CD-TEXT information to session and tracks. Do not load text_packs. bit1= Do not use media catalog string of session or ISRC strings of tracks for writing to Q sub-channel. @return > 0 indicates success, <= 0 indicates failure @since 1.2.0 */ int burn_session_by_cue_file(struct burn_session *session, char *path, int fifo_size, struct burn_source **fifo, unsigned char **text_packs, int *num_packs, int flag); /** Create a track */ struct burn_track *burn_track_create(void); /** Free a track @param t Track to free */ void burn_track_free(struct burn_track *t); /** Add a track to a session at specified position @param s Session to add to @param t Track to insert in session @param pos position to add at (BURN_POS_END is "at the end") @return 0 for failure, 1 for success */ int burn_session_add_track(struct burn_session *s, struct burn_track *t, unsigned int pos); /** Remove a track from a session @param s Session to remove track from @param t Track pointer to find and remove @return 0 for failure, 1 for success */ int burn_session_remove_track(struct burn_session *s, struct burn_track *t); /* ts B20107 */ /** Set the number which shall be written as CD track number with the first track of the session. The following tracks will then get written with consecutive CD track numbers. The resulting number of the last track must not exceed 99. The lowest possible start number is 1, which is also the default. This setting applies only to CD SAO writing. @param session The session to be manipulated @param tno A number between 1 and 99 @param flag Bitfield for control purposes. Unused yet. Submit 0. @return > 0 indicates success, <= 0 indicates failure @since 1.2.0 */ int burn_session_set_start_tno(struct burn_session *session, int tno, int flag); /* ts B20108 */ /** Inquire the CD track start number, as set by default or by burn_session_set_start_tno(). @param session The session to be inquired @param flag Bitfield for control purposes. Unused yet. Submit 0. @return > 0 is the currently set CD track start number <= 0 indicates failure @since 1.2.0 */ int burn_session_get_start_tno(struct burn_session *session, int flag); /* ts B11206 */ /** Set the Character Codes, the Copyright bytes, and the Language Codes for CD-TEXT blocks 0 to 7. They will be used in the block summaries of text packs which get generated from text or binary data submitted by burn_session_set_cdtext() and burn_track_set_cdtext(). Character Code value can be 0x00 = ISO-8859-1 0x01 = 7 bit ASCII 0x80 = MS-JIS (japanesei Kanji, double byte characters) Copyright byte value can be 0x00 = not copyrighted 0x03 = copyrighted Language Code value will typically be 0x09 = English or 0x69 = Japanese. See below macros BURN_CDTEXT_LANGUAGES_0X00 and BURN_CDTEXT_LANGUAGES_0X45, but be aware that many of these codes have never been seen on CD, and that many of them do not have a character representation among the above Character Codes. Default is 0x09 = English for block 0 and 0x00 = Unknown for block 1 to 7. Copyright and Character Code are 0x00 for all blocks by default. See also file doc/cdtext.txt, "Format of a CD-TEXT packs array", "Pack type 0x8f". Parameter value -1 leaves the current setting of the session parameter unchanged. @param s Session where to change settings @param char_codes Character Codes for block 0 to 7 @param copyrights Copyright bytes for block 0 to 7 @param languages Language Codes for block 0 to 7 @param flag Bitfiled for control purposes. Unused yet. Submit 0. @return <=0 failure, > 0 success @since 1.2.0 */ int burn_session_set_cdtext_par(struct burn_session *s, int char_codes[8], int copyrights[8], int languages[8], int flag); /** This is the first list of languages sorted by their Language codes, which start at 0x00. They stem from from EBU Tech 3264, appendix 3. E.g. language 0x00 is "Unknown", 0x08 is "German", 0x10 is "Frisian", 0x18 is "Latvian", 0x20 is "Polish", 0x28 is "Swedish", 0x2b is "Wallon". See also file doc/cdtext.txt. @since 1.2.0 */ #define BURN_CDTEXT_LANGUAGES_0X00 \ "Unknown", "Albanian", "Breton", "Catalan", \ "Croatian", "Welsh", "Czech", "Danish", \ "German", "English", "Spanish", "Esperanto", \ "Estonian", "Basque", "Faroese", "French", \ "Frisian", "Irish", "Gaelic", "Galician", \ "Icelandic", "Italian", "Lappish", "Latin", \ "Latvian", "Luxembourgian", "Lithuanian", "Hungarian", \ "Maltese", "Dutch", "Norwegian", "Occitan", \ "Polish", "Portuguese", "Romanian", "Romansh", \ "Serbian", "Slovak", "Slovenian", "Finnish", \ "Swedish", "Turkish", "Flemish", "Wallon" /** This is the second list of languages sorted by their Language codes, which start at 0x45. They stem from from EBU Tech 3264, appendix 3. E.g. language 0x45 is "Zulu", 0x50 is "Sranan Tongo", 0x58 is "Pushtu", 0x60 is "Moldavian", 0x68 is "Kannada", 0x70 is "Greek", 0x78 is "Bengali", 0x7f is "Amharic". See also file doc/cdtext.txt. @since 1.2.0 */ #define BURN_CDTEXT_LANGUAGES_0X45 \ "Zulu", "Vietnamese", "Uzbek", \ "Urdu", "Ukrainian", "Thai", "Telugu", \ "Tatar", "Tamil", "Tadzhik", "Swahili", \ "Sranan Tongo", "Somali", "Sinhalese", "Shona", \ "Serbo-croat", "Ruthenian", "Russian", "Quechua", \ "Pushtu", "Punjabi", "Persian", "Papamiento", \ "Oriya", "Nepali", "Ndebele", "Marathi", \ "Moldavian", "Malaysian", "Malagasay", "Macedonian", \ "Laotian", "Korean", "Khmer", "Kazakh", \ "Kannada", "Japanese", "Indonesian", "Hindi", \ "Hebrew", "Hausa", "Gurani", "Gujurati", \ "Greek", "Georgian", "Fulani", "Dari", \ "Churash", "Chinese", "Burmese", "Bulgarian", \ "Bengali", "Bielorussian", "Bambora", "Azerbaijani", \ "Assamese", "Armenian", "Arabic", "Amharic" /* This is the list of empty languages names between 0x30 and 0x44. Together the three macros fill an array of 128 char pointers. static char *languages[] = { BURN_CDTEXT_LANGUAGES_0X00, BURN_CDTEXT_FILLER, BURN_CDTEXT_LANGUAGES_0X45 }; */ #define BURN_CDTEXT_FILLER \ "", "", "", "", \ "", "", "", "", \ "", "", "", "", \ "", "", "", "", \ "", "", "", "", \ "", "", "", "", \ "" /* ts B11206 */ /** Obtain the current settings as of burn_session_set_cdtext_par() @param s Session which to inquire @param char_codes Will return Character Codes for block 0 to 7 @param copyrights Will return Copyright bytes for block 0 to 7 @param block_languages Will return Language Codes for block 0 to 7 @param flag Bitfiled for control purposes. Unused yet. Submit 0. @return <=0 failure, reply invalid, > 0 success, reply valid @since 1.2.0 */ int burn_session_get_cdtext_par(struct burn_session *s, int char_codes[8], int copyrights[8], int block_languages[8], int flag); /* ts B11206 */ /** Attach text or binary data as CD-TEXT attributes to a session. They can be used to generate CD-TEXT packs by burn_cdtext_from_session() or to write CD-TEXT packs into the lead-in of a CD SAO session. The latter happens only if no array of CD-TEXT packs is attached to the write options by burn_write_opts_set_leadin_text(). For details of the CD-TEXT format and of the payload content, see file doc/cdtext.txt . @param s Session where to attach CD-TEXT attribute @param block Number of the language block in which the attribute shall appear. Possible values: 0 to 7. @param pack_type Pack type number. 0x80 to 0x8e. Used if pack_type_name is NULL or empty text. Else submit 0 and a name. Pack type 0x8f is generated automatically and may not be set by applications. @param pack_type_name The pack type by name. Defined names are: 0x80 = "TITLE" 0x81 = "PERFORMER" 0x82 = "SONGWRITER" 0x83 = "COMPOSER" 0x84 = "ARRANGER" 0x85 = "MESSAGE" 0x86 = "DISCID" 0x87 = "GENRE" 0x88 = "TOC" 0x89 = "TOC2" 0x8d = "CLOSED" 0x8e = "UPC_ISRC" Names are recognized uppercase and lowercase. @param payload Text or binary bytes. The data will be copied to session-internal memory. Pack types 0x80 to 0x85 contain 0-terminated cleartext encoded according to the block's Character Code. If double byte characters are used, then two 0-bytes terminate the cleartext. Pack type 0x86 is 0-terminated ASCII cleartext. Pack type 0x87 consists of two byte big-endian Genre code (see below BURN_CDTEXT_GENRE_LIST), and 0-terminated ASCII cleartext of genre description. Pack type 0x88 mirrors the session table-of-content. Pack type 0x89 is not understood yet. Pack types 0x8a to 0x8c are reserved. Pack type 0x8d contains ISO-8859-1 cleartext which is not to be shown by commercial audio CD players. Pack type 0x8e is ASCII cleartext with UPC/EAN code. @param length Number of bytes in payload. Including terminating 0-bytes. @param flag Bitfield for control purposes. bit0= payload contains double byte characters (with character code 0x80 MS-JIS japanese Kanji) @return > 0 indicates success , <= 0 is failure @since 1.2.0 */ int burn_session_set_cdtext(struct burn_session *s, int block, int pack_type, char *pack_type_name, unsigned char *payload, int length, int flag); /** This is the list of Genres sorted by their Genre codes. E.g. genre code 0x0000 is "No Used", 0x0008 is "Dance, 0x0010 is "Musical", 0x0018 is "Rhythm & Blues", 0x001b is "World Music". See also file doc/cdtext.txt. @since 1.2.0 */ #define BURN_CDTEXT_GENRE_LIST \ "Not Used", "Not Defined", "Adult Contemporary", "Alternative Rock", \ "Childrens Music", "Classical", "Contemporary Christian", "Country", \ "Dance", "Easy Listening", "Erotic", "Folk", \ "Gospel", "Hip Hop", "Jazz", "Latin", \ "Musical", "New Age", "Opera", "Operetta", \ "Pop Music", "Rap", "Reggae", "Rock Music", \ "Rhythm & Blues", "Sound Effects", "Spoken Word", "World Music" /* The number of genre names in BURN_CDTEXT_GENRE_LIST. */ #define BURN_CDTEXT_NUM_GENRES 28 /* ts B11206 */ /** Obtain a CD-TEXT attribute that was set by burn_session_set_cdtext() @param s Session to inquire @param block Number of the language block to inquire. @param pack_type Pack type number to inquire. Used if pack_type_name is NULL or empty text. Else submit 0 and a name. Pack type 0x8f is generated automatically and may not be inquire in advance. Use burn_cdtext_from_session() to generate all packs including type 0x8f packs. @param pack_type_name The pack type by name. See above burn_session_set_cdtext(). @param payload Will return a pointer to text or binary bytes. Not a copy of data. Do not free() this address. If no text attribute is attached for pack type and block, then payload is returned as NULL. The return value will not indicate error in this case. @param length Will return the number of bytes pointed to by payload. Including terminating 0-bytes. @param flag Bitfield for control purposes. Unused yet. Submit 0. @return 1 single byte char, 2 double byte char, <=0 error @since 1.2.0 */ int burn_session_get_cdtext(struct burn_session *s, int block, int pack_type, char *pack_type_name, unsigned char **payload, int *length, int flag); /* ts B11215 */ /** Read a Sony CD-TEXT Input Sheet Version 0.7T file and attach its text attributes to the given session and its tracks for the given CD-TEXT block number. This overrides previous settings made by burn_session_set_cdtext(), burn_track_set_cdtext(), burn_track_set_isrc(), burn_session_set_start_tno(). It can later be overridden by said function calls. The media catalog number from purpose specifier "UPC / EAN" gets into effect only if burn_write_opts_set_has_mediacatalog() is set to 0. The format of a v07t sheet file is documented in doc/cdtext.txt. @param session Session where to attach CD-TEXT attributes @param path Local filesystem address of the sheet file which shall be read and interpreted. @param block Number of the language block in which the attributes shall appear. Possible values: 0 to 7. @param flag Bitfield for control purposes. bit0= Permission to read multiple blocks from the given sheet file. Each block is supposed to begin by a line "Input Sheet Version = 0.7T". Therefore this permission is only valid if the input file begins by such a line. @since 1.3.2 bit1= Do not use media catalog string of session or ISRC strings of tracks for writing to Q sub-channel. @since 1.2.0 @return > 0 indicates success and the number of interpreted blocks (1 if not flag bit0 is set). <= 0 indicates failure @since 1.2.0 */ int burn_session_input_sheet_v07t(struct burn_session *session, char *path, int block, int flag); /* ts B11210 */ /** Produce an array of CD-TEXT packs that could be submitted to burn_write_opts_set_leadin_text(), or stored as *.cdt file, or submitted to burn_make_input_sheet_v07t(). For a description of the format of the array, see file doc/cdtext.txt. The input data stem from burn_session_set_cdtext_par(), burn_session_set_cdtext(), and burn_track_set_cdtext(). @param s Session from which to produce CD-TEXT packs. @param text_packs Will return the buffer with the CD-TEXT packs. Dispose by free() when no longer needed. @param num_packs Will return the number of 18 byte text packs. @param flag Bitfield for control purposes. bit0= do not return generated CD-TEXT packs, but check whether production would work and indicate the number of packs by the call return value. This happens also if (text_packs == NULL || num_packs == NULL). @return Without flag bit0: > 0 is success, <= 0 failure With flag bit0: > 0 is number of packs, 0 means no packs will be generated, < 0 means failure @since 1.2.0 */ int burn_cdtext_from_session(struct burn_session *s, unsigned char **text_packs, int *num_packs, int flag); /* ts B30519 */ /** Convert an array of CD-TEXT packs into the text format of Sony CD-TEXT Input Sheet Version 0.7T . @param text_packs Array of bytes which form CD-TEXT packs of 18 bytes each. For a description of the format of the array, see file doc/cdtext.txt. No header of 4 bytes must be prepended which would tell the number of pack bytes + 2. This parameter may be NULL if the currently attached array of packs shall be removed. @param num_packs The number of 18 byte packs in text_packs. @param start_tno The start number of track counting, if known from CD table-of-content or other sources. Submit 0 to enable the attempt to read it and the track_count from pack type 0x8f. @param track_count The number of tracks, if known from CD table-of-content or orther sources. @param result Will return the buffer with Sheet text. Dispose by free() when no longer needed. It will be filled by the text for the v07t sheet file plus a trailing 0-byte. (Be aware that double-byte characters might contain 0-bytes, too.) Each CD-TEXT language block starts by the line "Input Sheet Version = 0.7T" and a "Remarks" line that tells the block number. @param char_code Returns the character code of the pack array: 0x00 = ISO-8859-1 0x01 = 7 bit ASCII 0x80 = MS-JIS (japanese Kanji, double byte characters) The presence of a code value that is not in this list will cause this function to fail. @param flag Bitfield for control purposes. Unused yet. Submit 0. @return > 0 tells the number of valid text bytes in result. This does not include the trailing 0-byte. <= 0 indicates failure. @since 1.3.2 */ int burn_make_input_sheet_v07t(unsigned char *text_packs, int num_packs, int start_tno, int track_count, char **result, int *char_code, int flag); /* ts B11206 */ /** Remove all CD-TEXT attributes of the given block from the session. They were attached by burn_session_set_cdtext(). @param s Session where to remove the CD-TEXT attribute @param block Number of the language block in which the attribute shall appear. Possible values: 0 to 7. -1 causes text packs of all blocks to be removed. @return > 0 is success, <= 0 failure @since 1.2.0 */ int burn_session_dispose_cdtext(struct burn_session *s, int block); /* ts B11221*/ /** Read an array of CD-TEXT packs from a file. This array should be suitable for burn_write_opts_set_leadin_text(). The function tolerates and removes 4-byte headers as produced by cdrecord -vv -toc, if this header tells the correct number of bytes which matches the file size. If no 4-byte header is present, then the function tolerates and removes a trailing 0-byte as of Sony specs. @param path Filesystem address of the CD-TEXT pack file. Normally with suffix .cdt or .dat @param text_packs Will return the buffer with the CD-TEXT packs. Dispose by free() when no longer needed. @param num_packs Will return the number of 18 byte text packs. @param flag Bitfield for control purposes. Unused yet.Submit 0. @return 0 is success, <= 0 failure @since 1.2.0 */ int burn_cdtext_from_packfile(char *path, unsigned char **text_packs, int *num_packs, int flag); /** Define the data in a track @param t the track to define @param offset The lib will write this many 0s before start of data @param tail The number of extra 0s to write after data @param pad 1 means the lib should pad the last sector with 0s if the track isn't exactly sector sized. (otherwise the lib will begin reading from the next track) @param mode data format (bitfield) */ void burn_track_define_data(struct burn_track *t, int offset, int tail, int pad, int mode); /* ts B11206 */ /** Attach text or binary data as CD-TEXT attributes to a track. The payload will be used to generate CD-TEXT packs by burn_cdtext_from_session() or to write CD-TEXT packs into the lead-in of a CD SAO session. This happens if the CD-TEXT attribute of the session gets generated, which has the same block number and pack type. In this case, each track should have such a CD-TEXT attribute, too. See burn_session_set_cdtext(). Be cautious not to exceed the maximum number of 253 payload packs per language block. Use burn_cdtext_from_session() to learn whether a valid array of CD-TEXT packs can be generated from your attributes. @param t Track where to attach CD-TEXT attribute. @param block Number of the language block in which the attribute shall appear. Possible values: 0 to 7. @param pack_type Pack type number. 0x80 to 0x85 or 0x8e. Used if pack_type_name is NULL or empty text. Else submit 0 and a name. @param pack_type_name The pack type by name. Applicable names are: 0x80 = "TITLE" 0x81 = "PERFORMER" 0x82 = "SONGWRITER" 0x83 = "COMPOSER" 0x84 = "ARRANGER" 0x85 = "MESSAGE" 0x8e = "UPC_ISRC" @param payload 0-terminated cleartext. If double byte characters are used, then two 0-bytes terminate the cleartext. @param length Number of bytes in payload. Including terminating 0-bytes. @param flag Bitfield for control purposes. bit0= payload contains double byte characters (with character code 0x80 MS-JIS japanese Kanji) @return > 0 indicates success , <= 0 is failure @since 1.2.0 */ int burn_track_set_cdtext(struct burn_track *t, int block, int pack_type, char *pack_type_name, unsigned char *payload, int length, int flag); /* ts B11206 */ /** Obtain a CD-TEXT attribute that was set by burn_track_set_cdtext(). @param t Track to inquire @param block Number of the language block to inquire. @param pack_type Pack type number to inquire. Used if pack_type_name is NULL or empty text. Else submit 0 and a name. @param pack_type_name The pack type by name. See above burn_track_set_cdtext(). @param payload Will return a pointer to text bytes. Not a copy of data. Do not free() this address. If no text attribute is attached for pack type and block, then payload is returned as NULL. The return value will not indicate error in this case. @param length Will return the number of bytes pointed to by payload. Including terminating 0-bytes. @param flag Bitfield for control purposes. Unused yet. Submit 0. @return 1=single byte char , 2= double byte char , <=0 error @since 1.2.0 */ int burn_track_get_cdtext(struct burn_track *t, int block, int pack_type, char *pack_type_name, unsigned char **payload, int *length, int flag); /* ts B11206 */ /** Remove all CD-TEXT attributes of the given block from the track. They were attached by burn_track_set_cdtext(). @param t Track where to remove the CD-TEXT attribute. @param block Number of the language block in which the attribute shall appear. Possible values: 0 to 7. -1 causes text packs of all blocks to be removed. @return > 0 is success, <= 0 failure @since 1.2.0 */ int burn_track_dispose_cdtext(struct burn_track *t, int block); /* ts A90910 */ /** Activates CD XA compatibility modes. libburn currently writes data only in CD mode 1. Some programs insist in sending data with additional management bytes. These bytes have to be stripped in order to make the input suitable for BURN_MODE1. @param t The track to manipulate @param value 0= no conversion 1= strip 8 byte sector headers of CD-ROM XA mode 2 form 1 see MMC-5 4.2.3.8.5.3 Block Format for Mode 2 form 1 Data all other values are reserved @return 1=success , 0=unacceptable value @since 0.7.2 */ int burn_track_set_cdxa_conv(struct burn_track *t, int value); /** Set the ISRC details for a track. When writing to CD media, ISRC will get written into the Q sub-channel. @param t The track to change @param country the 2 char country code. Each character must be only numbers or letters. @param owner 3 char owner code. Each character must be only numbers or letters. @param year 2 digit year. A number in 0-99 (Yep, not Y2K friendly). @param serial 5 digit serial number. A number in 0-99999. */ void burn_track_set_isrc(struct burn_track *t, char *country, char *owner, unsigned char year, unsigned int serial); /* ts B11226 */ /** Set the composed ISRC string for a track. This is an alternative to burn_track_set_isrc(). @param t The track to be manipulated @param isrc 12 characters which are composed from ISRC details. Format is CCOOOYYSSSSS, terminated by a 0-byte: Country, Owner, Year(decimal digits), Serial(decimal digits). @param flag Bitfield for control purposes. Unused yet. Submit 0. @return > 0 indicates success, <= 0 means failure @since 1.2.0 */ int burn_track_set_isrc_string(struct burn_track *t, char isrc[13], int flag); /** Disable ISRC parameters for a track @param t The track to change */ void burn_track_clear_isrc(struct burn_track *t); /* ts B20103 */ /** Define an index start address within a track. The index numbers inside a track have to form sequence starting at 0 or 1 with no gaps up to the highest number used. They affect only writing of CD SAO sessions. The first index start address of a track must be 0. Blocks between index 0 and index 1 are considered to be located before the track start as of the table-of-content. @param t The track to be manipulated @param index_number A number between 0 and 99 @param relative_lba The start address relative to the start of the burn_source of the track. It will get mapped to the appropriate absolute block address. @param flag Bitfield for control purposes. Unused yet. Submit 0. @return > 0 indicates success, <= 0 means failure @since 1.2.0 */ int burn_track_set_index(struct burn_track *t, int index_number, unsigned int relative_lba, int flag); /* ts B20103 */ /** Remove all index start addresses and reset to the default indexing of CD SAO sessions. This means index 0 of track 1 reaches from LBA -150 to LBA -1. Index 1 of track 1 reaches from LBA 0 to track end. Index 1 of track 2 follows immediately. The same happens for all further tracks after the end of their predecessor. @param t The track to be manipulated @param flag Bitfield for control purposes. Unused yet. Submit 0. @return > 0 indicates success, <= 0 means failure @since 1.2.0 */ int burn_track_clear_indice(struct burn_track *t, int flag); /* ts B20110 */ /** Define whether a pre-gap shall be written before the track and how many sectors this pre-gap shall have. A pre-gap is written in the range of track index 0 and contains zeros (audio silence). No bytes from the track source will be read for writing the pre-gap. This setting affects only CD SAO write runs. The first track automatically gets a pre-gap of at least 150 sectors. Its size may be enlarged by this call. Further pre-gaps are demanded by MMC for tracks which follow tracks of a different mode. (But Mode mixing in CD SAO sessions is currently not supported by libburn.) @param t The track to change @param size Number of sectors in the pre-gap. -1 disables pre-gap, except for the first track. libburn allows 0, but MMC does not propose this. @param flag Bitfield for control purposes. Unused yet. Submit 0. @return > 0 indicates success, <= 0 means failure @since 1.2.0 */ int burn_track_set_pregap_size(struct burn_track *t, int size, int flag); /* ts B20111 */ /** Define whether a post-gap shall be written at the end of the track and how many sectors this gap shall have. A post-gap occupies the range of an additional index of the track. It contains zeros. No bytes from the track source will be read for writing the post-gap. This setting affects only CD SAO write runs. MMC prescribes to add a post-gap to a data track which is followed by a non-data track. (But libburn does not yet support mixed mode CD SAO sessions.) @param t The track to change @param size Number of sectors in the post-gap. -1 disables post-gap. libburn allows 0, but MMC does not propose this. @param flag Bitfield for control purposes. Unused yet. Submit 0. @return > 0 indicates success, <= 0 means failure @since 1.2.0 */ int burn_track_set_postgap_size(struct burn_track *t, int size, int flag); /* ts A61024 */ /** Define whether a track shall swap bytes of its input stream. @param t The track to change @param swap_source_bytes 0=do not swap, 1=swap byte pairs @return 1=success , 0=unacceptable value @since 0.2.6 */ int burn_track_set_byte_swap(struct burn_track *t, int swap_source_bytes); /** Hide the first track in the "pre gap" of the disc @param s session to change @param onoff 1 to enable hiding, 0 to disable */ void burn_session_hide_first_track(struct burn_session *s, int onoff); /** Get the drive's disc struct - free when done @param d drive to query @return the disc struct or NULL on failure */ struct burn_disc *burn_drive_get_disc(struct burn_drive *d); /** Set the track's data source @param t The track to set the data source for @param s The data source to use for the contents of the track @return An error code stating if the source is ready for use for writing the track, or if an error occured */ enum burn_source_status burn_track_set_source(struct burn_track *t, struct burn_source *s); /* ts A70218 */ /** Set a default track size to be used only if the track turns out to be of unpredictable length and if the effective write type demands a fixed size. This can be useful to enable write types CD SAO or DVD DAO together with a track source like stdin. If the track source delivers fewer bytes than announced then the track will be padded up with zeros. @param t The track to change @param size The size to set @return 0=failure 1=sucess @since 0.3.4 */ int burn_track_set_default_size(struct burn_track *t, off_t size); /** Free a burn_source (decrease its refcount and maybe free it) @param s Source to free */ void burn_source_free(struct burn_source *s); /** Creates a data source for an image file (and maybe subcode file) @param path The file address for the main channel payload. @param subpath Eventual address for subchannel data. Only used in exotic raw write modes. Submit NULL for normal tasks. @return Pointer to a burn_source object, NULL indicates failure */ struct burn_source *burn_file_source_new(const char *path, const char *subpath); /* ts A91122 : An interface to open(O_DIRECT) or similar OS tricks. */ /** Opens a file with eventual acceleration preparations which may depend on the operating system and on compile time options of libburn. You may use this call instead of open(2) for opening file descriptors which shall be handed to burn_fd_source_new(). This should only be done for tracks with BURN_BLOCK_MODE1 (2048 bytes per block). If you use this call then you MUST allocate the buffers which you use with read(2) by call burn_os_alloc_buffer(). Read sizes MUST be a multiple of a safe buffer amount. Else you risk that track data get altered during transmission. burn_disk_write() will allocate a suitable read/write buffer for its own operations. A fifo created by burn_fifo_source_new() will allocate suitable memory for its buffer if called with flag bit0 and a multiple of a safe buffer amount. @param path The file address to open @param open_flags The flags as of man 2 open. Normally just O_RDONLY. @param flag Bitfield for control purposes (unused yet, submit 0). @return A file descriptor as of open(2). Finally to be disposed by close(2). -1 indicates failure. @since 0.7.4 */ int burn_os_open_track_src(char *path, int open_flags, int flag); /** Allocate a memory area that is suitable for reading with a file descriptor opened by burn_os_open_track_src(). @param amount Number of bytes to allocate. This should be a multiple of the operating system's i/o block size. 32 KB is guaranteed by libburn to be safe. @param flag Bitfield for control purposes (unused yet, submit 0). @return The address of the allocated memory, or NULL on failure. A non-NULL return value has finally to be disposed via burn_os_free_buffer(). @since 0.7.4 */ void *burn_os_alloc_buffer(size_t amount, int flag); /** Dispose a memory area which was obtained by burn_os_alloc_buffer(), @param buffer Memory address to be freed. @param amount The number of bytes which was allocated at that address. @param flag Bitfield for control purposes (unused yet, submit 0). @return 1 success , <=0 failure @since 0.7.4 */ int burn_os_free_buffer(void *buffer, size_t amount, int flag); /** Creates a data source for an image file (a track) from an open readable filedescriptor, an eventually open readable subcodes file descriptor and eventually a fixed size in bytes. @param datafd The source of data. @param subfd The eventual source of subchannel data. Only used in exotic raw write modes. Submit -1 for normal tasks. @param size The eventual fixed size of eventually both fds. If this value is 0, the size will be determined from datafd. @return Pointer to a burn_source object, NULL indicates failure */ struct burn_source *burn_fd_source_new(int datafd, int subfd, off_t size); /* ts B00922 */ /** Creates an offset source which shall provide a byte interval of a stream to its consumer. It is supposed to be chain-linked with other offset sources which serve neighboring consumers. The chronological sequence of consumers and the sequence of offset sources must match. The intervals of the sources must not overlap. A chain of these burn_source objects may be used to feed multiple tracks from one single stream of input bytes. Each of the offset sources will skip the bytes up to its start address and provide the prescribed number of bytes to the track. Skipping takes into respect the bytes which have been processed by eventual predecessors in the chain. Important: It is not allowed to free an offset source before its successor has ended its work. Best is to keep them all until all tracks are done. @param inp The burn_source object from which to read stream data. E.g. created by burn_file_source_new(). @param prev The eventual offset source object which shall read data from inp before the new offset source will begin its own work. This must either be a result of burn_offst_source_new() or it must be NULL. @param start The byte address where to start reading bytes for the consumer. inp bytes may get skipped to reach this address. @param size The number of bytes to be delivered to the consumer. If size is <= 0 then it may be set later by a call of method set_size(). If it is >= 0, then it can only be changed if flag bit0 was set with burn_offst_source_new(). @param flag Bitfield for control purposes bit0 = Prevent set_size() from overriding interval sizes > 0. If such a size is already set, then the new one will only affect the reply of get_size(). See also above struct burn_source. @since 1.2.0 @return Pointer to a burn_source object, later to be freed by burn_source_free(). NULL indicates failure. @since 0.8.8 */ struct burn_source *burn_offst_source_new( struct burn_source *inp, struct burn_source *prev, off_t start, off_t size, int flag); /* ts A70930 */ /** Creates a fifo which acts as proxy for an already existing data source. The fifo provides a ring buffer which shall smoothen the data stream between burn_source and writer thread. Each fifo serves only for one data source. It may be attached to one track as its only data source by burn_track_set_source(), or it may be used as input for other burn sources. A fifo starts its life in "standby" mode with no buffer space allocated. As soon as its consumer requires bytes, the fifo establishes a worker thread and allocates its buffer. After input has ended and all buffer content is consumed, the buffer space gets freed and the worker thread ends. This happens asynchronously. So expect two buffers and worker threads to exist for a short time between tracks. Be modest in your size demands if multiple tracks are to be expected. @param inp The burn_source for which the fifo shall act as proxy. It can be disposed by burn_source_free() immediately after this call. @param chunksize The size in bytes of a chunk. Use 2048 for sources suitable for BURN_BLOCK_MODE1, 2352 for sources which deliver for BURN_BLOCK_AUDIO, 2056 for sources which shall get treated by burn_track_set_cdxa_conv(track, 1). Some variations of burn_source might work only with a particular chunksize. E.g. libisofs demands 2048. @param chunks The number of chunks to be allocated in ring buffer. This value must be >= 2. @param flag Bitfield for control purposes: bit0= The read method of inp is capable of delivering arbitrary amounts of data per call. Not only one sector. Suitable for inp from burn_file_source_new() and burn_fd_source_new() if not the fd has exotic limitations on read size. You MUST use this on inp which uses an fd opened with burn_os_open_track_src(). Better do not use with other inp types. @since 0.7.4 @return A pointer to the newly created burn_source. Later both burn_sources, inp and the returned fifo, have to be disposed by calling burn_source_free() for each. inp can be freed immediately, the returned fifo may be kept as handle for burn_fifo_inquire_status(). @since 0.4.0 */ struct burn_source *burn_fifo_source_new(struct burn_source *inp, int chunksize, int chunks, int flag); /* ts A71003 */ /** Inquires state and fill parameters of a fifo burn_source which was created by burn_fifo_source_new() . Do not use with other burn_source variants. @param fifo The fifo object to inquire @param size The total size of the fifo @param free_bytes The current free capacity of the fifo @param status_text Returns a pointer to a constant text, see below @return <0 reply invalid, >=0 fifo status code: bit0+1=input status, bit2=consumption status, i.e: 0="standby" : data processing not started yet 1="active" : input and consumption are active 2="ending" : input has ended without error 3="failing" : input had error and ended, 4="unused" : ( consumption has ended before processing start ) 5="abandoned" : consumption has ended prematurely 6="ended" : consumption has ended without input error 7="aborted" : consumption has ended after input error @since 0.4.0 */ int burn_fifo_inquire_status(struct burn_source *fifo, int *size, int *free_bytes, char **status_text); /* ts A91125 */ /** Inquire various counters which reflect the fifo operation. @param fifo The fifo object to inquire @param total_min_fill The minimum number of bytes in the fifo. Beginning from the moment when fifo consumption is enabled. @param interval_min_fill The minimum byte number beginning from the moment when fifo consumption is enabled or from the most recent moment when burn_fifo_next_interval() was called. @param put_counter The number of data transactions into the fifo. @param get_counter The number of data transactions out of the fifo. @param empty_counter The number of times the fifo was empty. @param full_counter The number of times the fifo was full. @since 0.7.4 */ void burn_fifo_get_statistics(struct burn_source *fifo, int *total_min_fill, int *interval_min_fill, int *put_counter, int *get_counter, int *empty_counter, int *full_counter); /* ts A91125 */ /** Inquire the fifo minimum fill counter for intervals and reset that counter. @param fifo The fifo object to inquire @param interval_min_fill The minimum number of bytes in the fifo. Beginning from the moment when fifo consumption is enabled or from the most recent moment when burn_fifo_next_interval() was called. @since 0.7.4 */ void burn_fifo_next_interval(struct burn_source *fifo, int *interval_min_fill); /* ts A80713 */ /** Obtain a preview of the first input data of a fifo which was created by burn_fifo_source_new(). The data will later be delivered normally to the consumer track of the fifo. bufsize may not be larger than the fifo size (chunk_size * chunks) - 32k. This call will succeed only if data consumption by the track has not started yet, i.e. best before the call to burn_disc_write(). It will start the worker thread of the fifo with the expectable side effects on the external data source. Then it waits either until enough data have arrived or until it becomes clear that this will not happen. The call may be repeated with increased bufsize. It will always yield the bytes beginning from the first one in the fifo. @param fifo The fifo object to start and to inquire @param buf Pointer to memory of at least bufsize bytes where to deliver the peeked data. @param bufsize Number of bytes to peek from the start of the fifo data @param flag Bitfield for control purposes (unused yet, submit 0). @return <0 on severe error, 0 if not enough data, 1 if bufsize bytes read @since 0.5.0 */ int burn_fifo_peek_data(struct burn_source *fifo, char *buf, int bufsize, int flag); /* ts A91125 */ /** Start the fifo worker thread and wait either until the requested number of bytes have arrived or until it becomes clear that this will not happen. Filling will go on asynchronously after burn_fifo_fill() returned. This call and burn_fifo_peek_data() do not disturb each other. @param fifo The fifo object to start @param fill Number of bytes desired. Expect to get return 1 if at least fifo size - 32k were read. @param flag Bitfield for control purposes. bit0= fill fifo to maximum size @return <0 on severe error, 0 if not enough data, 1 if desired amount or fifo full @since 0.7.4 */ int burn_fifo_fill(struct burn_source *fifo, int fill, int flag); /* ts A70328 */ /** Sets a fixed track size after the data source object has already been created. @param t The track to operate on @param size the number of bytes to use as track size @return <=0 indicates failure , >0 success @since 0.3.6 */ int burn_track_set_size(struct burn_track *t, off_t size); /** Tells how many sectors a track will have on disc, or already has on disc. This includes offset, payload, tail, and post-gap, but not pre-gap. The result is NOT RELIABLE with tracks of undefined length */ int burn_track_get_sectors(struct burn_track *); /* ts A61101 */ /** Tells how many source bytes have been read and how many data bytes have been written by the track during burn. @param t The track to inquire @param read_bytes Number of bytes read from the track source @param written_bytes Number of bytes written to track @since 0.2.6 */ int burn_track_get_counters(struct burn_track *t, off_t *read_bytes, off_t *written_bytes); /** Sets drive read and write speed Note: "k" is 1000, not 1024. 1xCD = 176.4 k/s, 1xDVD = 1385 k/s, 1xBD = 4496 k/s. Fractional speeds should be rounded up. Like 4xCD = 706. @param d The drive to set speed for @param read Read speed in k/s (0 is max, -1 is min). @param write Write speed in k/s (0 is max, -1 is min). */ void burn_drive_set_speed(struct burn_drive *d, int read, int write); /* ts A70711 */ /** Controls the behavior with writing when the drive buffer is suspected to be full. To check and wait for enough free buffer space before writing will move the task of waiting from the operating system's device driver to libburn. While writing is going on and waiting is enabled, any write operation will be checked whether it will fill the drive buffer up to more than max_percent. If so, then waiting will happen until the buffer fill is predicted with at most min_percent. Thus: if min_percent < max_percent then transfer rate will oscillate. This may allow the driver to operate on other devices, e.g. a disk from which to read the input for writing. On the other hand, this checking might reduce maximum throughput to the drive or even get misled by faulty buffer fill replies from the drive. If a setting parameter is < 0, then this setting will stay unchanged by the call. Known burner or media specific pitfalls: To have max_percent larger than the burner's best reported buffer fill has the same effect as min_percent==max_percent. Some burners do not report their full buffer with all media types. Some are not suitable because they report their buffer fill with delay. Some do not go to full speed unless their buffer is full. @param d The drive to control @param enable 0= disable , 1= enable waiting , (-1 = do not change setting) @param min_usec Shortest possible sleeping period (given in micro seconds) @param max_usec Longest possible sleeping period (given in micro seconds) @param timeout_sec If a single write has to wait longer than this number of seconds, then waiting gets disabled and mindless writing starts. A value of 0 disables this timeout. @param min_percent Minimum of desired buffer oscillation: 25 to 100 @param max_percent Maximum of desired buffer oscillation: 25 to 100 @return 1=success , 0=failure @since 0.3.8 */ int burn_drive_set_buffer_waiting(struct burn_drive *d, int enable, int min_usec, int max_usec, int timeout_sec, int min_percent, int max_percent); /* 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_session(struct burn_session *s); void burn_structure_print_track(struct burn_track *t); /** Sets the write type for the write_opts struct. Note: write_type BURN_WRITE_SAO is currently not capable of writing a mix of data and audio tracks. You must use BURN_WRITE_TAO for such sessions. @param opts The write opts to change @param write_type The write type to use @param block_type The block type to use @return Returns 1 on success and 0 on failure. */ int burn_write_opts_set_write_type(struct burn_write_opts *opts, enum burn_write_types write_type, int block_type); /* ts A70207 */ /** As an alternative to burn_write_opts_set_write_type() this function tries to find a suitable write type and block type for a given write job described by opts and disc. To be used after all other setups have been made, i.e. immediately before burn_disc_write(). @param opts The nearly complete write opts to change @param disc The already composed session and track model @param reasons This text string collects reasons for decision or failure @param flag Bitfield for control purposes: bit0= do not choose type but check the one that is already set bit1= do not issue error messages via burn_msgs queue (is automatically set with bit0) @return Chosen write type. BURN_WRITE_NONE on failure. @since 0.3.2 */ enum burn_write_types burn_write_opts_auto_write_type( struct burn_write_opts *opts, struct burn_disc *disc, char reasons[BURN_REASONS_LEN], int flag); /** Supplies toc entries for writing - not normally required for cd mastering @param opts The write opts to change @param count The number of entries @param toc_entries */ void burn_write_opts_set_toc_entries(struct burn_write_opts *opts, int count, struct burn_toc_entry *toc_entries); /** Sets the session format for a disc @param opts The write opts to change @param format The session format to set */ void burn_write_opts_set_format(struct burn_write_opts *opts, int format); /** Sets the simulate value for the write_opts struct . 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 actual availability of this feature. If the media is suitable, the drive will perform burn_disc_write() as a simulation instead of effective write operations. This means that the media content and burn_disc_get_status() stay unchanged. Note: With stdio-drives, the target file gets eventually created, opened, lseeked, and closed, but not written. So there are effects on it. Warning: Call burn_random_access_write() will never do simulation because it does not get any burn_write_opts. @param opts The write opts to change @param sim Non-zero enables simulation, 0 enables real writing @return Returns 1 on success and 0 on failure. */ int burn_write_opts_set_simulate(struct burn_write_opts *opts, int sim); /** Controls buffer underrun prevention. This is only needed with CD media and possibly with old DVD-R drives. All other media types are not vulnerable to burn failure due to buffer underrun. @param opts The write opts to change @param underrun_proof if non-zero, buffer underrun protection is enabled @return Returns 1 if the drive announces to be capable of underrun prevention, Returns 0 if not. */ int burn_write_opts_set_underrun_proof(struct burn_write_opts *opts, int underrun_proof); /** Sets whether to use opc or not with the write_opts struct @param opts The write opts to change @param opc If non-zero, optical power calibration will be performed at start of burn */ void burn_write_opts_set_perform_opc(struct burn_write_opts *opts, int opc); /** The Q sub-channel of a CD may contain a Media Catalog Number of 13 decimal digits. This call sets the string of digits, but does not yet activate it for writing. @param opts The write opts to change @param mediacatalog The 13 decimal digits as ASCII bytes. I.e. '0' = 0x30. */ void burn_write_opts_set_mediacatalog(struct burn_write_opts *opts, unsigned char mediacatalog[13]); /** This call activates the Media Catalog Number for writing. The digits of that number have to be set by call burn_write_opts_set_mediacatalog(). @param opts The write opts to change @param has_mediacatalog 1= activate writing of catalog to Q sub-channel 0= deactivate it */ void burn_write_opts_set_has_mediacatalog(struct burn_write_opts *opts, int has_mediacatalog); /* ts A61106 */ /** Sets the multi flag which eventually marks the emerging session as not being the last one and thus creating a BURN_DISC_APPENDABLE media. Note: DVD-R[W] in write mode BURN_WRITE_SAO are not capable of this. DVD-R DL are not capable of this at all. libburn will refuse to write if burn_write_opts_set_multi() is enabled under such conditions. @param opts The option object to be manipulated @param multi 1=media will be appendable, 0=media will be closed (default) @since 0.2.6 */ void burn_write_opts_set_multi(struct burn_write_opts *opts, int multi); /* ts B31024 */ /** Set the severity to be used with write error messages which are potentially caused by not using write type BURN_WRITE_SAO on fast blanked DVD-RW. Normally the call burn_write_opts_auto_write_type() can prevent such errors by looking for MMC feature 21h "Incremental Streaming Writable" which anounnces the capability for BURN_WRITE_TAO and multi session. Regrettable many drives announce feature 21h even if they only can do BURN_WRITE_SAO. This mistake becomes obvious by an early write error. If you plan to call burn_drive_was_feat21_failure() and to repeat the burn attempt with BURN_WRITE_SAO, then set the severity of the error message low enough, so that the application does not see reason to abort. @param opts The option object to be manipulated @param severity Severity as with burn_msgs_set_severities(). "ALL" or empty text means the default severity that is attributed to other kinds of write errors. */ void burn_write_opts_set_fail21h_sev(struct burn_write_opts *opts, char *severity); /* ts B11204 */ /** Submit an array of CD-TEXT packs which shall be written to the Lead-in of a SAO write run on CD. @param opts The option object to be manipulated @param text_packs Array of bytes which form CD-TEXT packs of 18 bytes each. For a description of the format of the array, see file doc/cdtext.txt. No header of 4 bytes must be prepended which would tell the number of pack bytes + 2. This parameter may be NULL if the currently attached array of packs shall be removed. @param num_packs The number of 18 byte packs in text_packs. This parameter may be 0 if the currently attached array of packs shall be removed. @param flag Bitfield for control purposes. bit0= do not verify checksums bit1= repair mismatching checksums bit2= repair checksums if they are 00 00 with each pack @return 1 on success, <= 0 on failure @since 1.2.0 */ int burn_write_opts_set_leadin_text(struct burn_write_opts *opts, unsigned char *text_packs, int num_packs, int flag); /* ts A61222 */ /** Sets a start address for writing to media and write modes which are able to choose this address at all (for now: DVD+RW, DVD-RAM, formatted DVD-RW). now). The address is given in bytes. If it is not -1 then a write run will fail if choice of start address is not supported or if the block alignment of the address is not suitable for media and write mode. Alignment to 32 kB blocks is supposed to be safe with DVD media. Call burn_disc_get_multi_caps() can obtain the necessary media info. See resulting struct burn_multi_caps elements .start_adr , .start_alignment , .start_range_low , .start_range_high . @param opts The write opts to change @param value The address in bytes (-1 = start at default address) @since 0.3.0 */ void burn_write_opts_set_start_byte(struct burn_write_opts *opts, off_t value); /* ts A70213 */ /** Caution: still immature and likely to change. Problems arose with sequential DVD-RW on one drive. Controls whether the whole available space of the media shall be filled up by the last track of the last session. @param opts The write opts to change @param fill_up_media If 1 : fill up by last track, if 0 = do not fill up @since 0.3.4 */ void burn_write_opts_set_fillup(struct burn_write_opts *opts, int fill_up_media); /* ts A70303 */ /** Eventually makes libburn ignore the failure of some conformance checks: - the check whether CD write+block type is supported by the drive - the check whether the media profile supports simulated burning @param opts The write opts to change @param use_force 1=ignore above checks, 0=refuse work on failed check @since 0.3.4 */ void burn_write_opts_set_force(struct burn_write_opts *opts, int use_force); /* ts A80412 */ /** Eventually makes use of the more modern write command AAh WRITE12 and sets the Streaming bit. With DVD-RAM and BD this can override the traditional slowdown to half nominal speed. But if it speeds up writing then it also disables error management and correction. Weigh your priorities. This affects the write operations of burn_disc_write() and subsequent calls of burn_random_access_write(). @param opts The write opts to change @param value 0=use 2Ah WRITE10, 1=use AAh WRITE12 with Streaming bit @since 0.6.4: >=16 use WRITE12 but not before the LBA given by value @since 0.4.6 */ void burn_write_opts_set_stream_recording(struct burn_write_opts *opts, int value); /* ts A91115 */ /** Overrides the write chunk size for DVD and BD media which is normally determined according to media type and setting of stream recording. A chunk size of 64 KB may improve throughput with bus systems which show latency problems. @param opts The write opts to change @param obs Number of bytes which shall be sent by a single write command. 0 means automatic size, 32768 and 65336 are the only other accepted sizes for now. @since 0.7.4 */ void burn_write_opts_set_dvd_obs(struct burn_write_opts *opts, int obs); /* ts B20406 */ /** Overrides the automatic decision whether to pad up the last write chunk to its full size. This applies to DVD, BD and stdio: pseudo-drives. Note: This override may get enabled fixely already at compile time by defining macro Libburn_dvd_always_obs_paD . @param opts The write opts to change @param pad 1 means to pad up in any case, 0 means automatic decision. @since 1.2.4 */ void burn_write_opts_set_obs_pad(struct burn_write_opts *opts, int pad); /* ts A91115 */ /** Sets the rythm by which stdio pseudo drives force their output data to be consumed by the receiving storage device. This forcing keeps the memory from being clogged with lots of pending data for slow devices. @param opts The write opts to change @param rythm Number of 2KB output blocks after which fsync(2) is performed. -1 means no fsync() 0 means default 1 means fsync() only at end, @since 1.3.8 (noop before 1.3.8) elsewise the value must be >= 32. Default is currently 8192 = 16 MB. @since 0.7.4 */ void burn_write_opts_set_stdio_fsync(struct burn_write_opts *opts, int rythm); /** Sets whether to read in raw mode or not @param opts The read opts to change @param raw_mode If non-zero, reading will be done in raw mode, so that everything in the data tracks on the disc is read, including headers. */ void burn_read_opts_set_raw(struct burn_read_opts *opts, int raw_mode); /** Sets whether to report c2 errors or not @param opts The read opts to change @param c2errors If non-zero, report c2 errors. */ void burn_read_opts_set_c2errors(struct burn_read_opts *opts, int c2errors); /** Sets whether to read subcodes from audio tracks or not @param opts The read opts to change @param subcodes_audio If non-zero, read subcodes from audio tracks on the disc. */ void burn_read_opts_read_subcodes_audio(struct burn_read_opts *opts, int subcodes_audio); /** Sets whether to read subcodes from data tracks or not @param opts The read opts to change @param subcodes_data If non-zero, read subcodes from data tracks on the disc. */ void burn_read_opts_read_subcodes_data(struct burn_read_opts *opts, int subcodes_data); /** Sets whether to recover errors if possible @param opts The read opts to change @param hardware_error_recovery If non-zero, attempt to recover errors if possible. */ void burn_read_opts_set_hardware_error_recovery(struct burn_read_opts *opts, int hardware_error_recovery); /** Sets whether to report recovered errors or not @param opts The read opts to change @param report_recovered_errors If non-zero, recovered errors will be reported. */ void burn_read_opts_report_recovered_errors(struct burn_read_opts *opts, int report_recovered_errors); /** Sets whether blocks with unrecoverable errors should be read or not @param opts The read opts to change @param transfer_damaged_blocks If non-zero, blocks with unrecoverable errors will still be read. */ void burn_read_opts_transfer_damaged_blocks(struct burn_read_opts *opts, int transfer_damaged_blocks); /** Sets the number of retries to attempt when trying to correct an error @param opts The read opts to change @param hardware_error_retries The number of retries to attempt when correcting an error. */ void burn_read_opts_set_hardware_error_retries(struct burn_read_opts *opts, unsigned char hardware_error_retries); /* ts A90815 */ /** Gets the list of profile codes supported by the drive. Profiles depict the feature sets which constitute media types. For known profile codes and names see burn_disc_get_profile(). @param d is the drive to query @param num_profiles returns the number of supported profiles @param profiles returns the profile codes @param is_current returns the status of the corresponding profile code: 1= current, i.e. the matching media is loaded 0= not current, i.e. the matching media is not loaded @return always 1 for now @since 0.7.0 */ int burn_drive_get_all_profiles(struct burn_drive *d, int *num_profiles, int profiles[64], char is_current[64]); /* ts A90815 */ /** Obtains the profile name associated with a profile code. @param profile_code the profile code to be translated @param name returns the profile name (e.g. "DVD+RW") @return 1= known profile code , 0= unknown profile code @since 0.7.0 */ int burn_obtain_profile_name(int profile_code, char name[80]); /** Gets the maximum write speed for a drive and eventually loaded media. The return value might change by the media type of already loaded media, again by call burn_drive_grab() and again by call burn_disc_read_atip(). @param d Drive to query @return Maximum write speed in K/s */ int burn_drive_get_write_speed(struct burn_drive *d); /* ts A61021 */ /** Gets the minimum write speed for a drive and eventually loaded media. The return value might change by the media type of already loaded media, again by call burn_drive_grab() and again by call burn_disc_read_atip(). @param d Drive to query @return Minimum write speed in K/s @since 0.2.6 */ int burn_drive_get_min_write_speed(struct burn_drive *d); /** Gets the maximum read speed for a drive @param d Drive to query @return Maximum read speed in K/s */ int burn_drive_get_read_speed(struct burn_drive *d); /* ts A61226 */ /** Obtain a copy of the current speed descriptor list. The drive's list gets updated on various occasions such as burn_drive_grab() but the copy obtained here stays untouched. It has to be disposed via burn_drive_free_speedlist() when it is not longer needed. Speeds may appear several times in the list. The list content depends much on drive and media type. It seems that .source == 1 applies mostly to CD media whereas .source == 2 applies to any media. @param d Drive to query @param speed_list The copy. If empty, *speed_list gets returned as NULL. @return 1=success , 0=list empty , <0 severe error @since 0.3.0 */ int burn_drive_get_speedlist(struct burn_drive *d, struct burn_speed_descriptor **speed_list); /* ts A70713 */ /** Look up the fastest speed descriptor which is not faster than the given speed_goal. If it is 0, then the fastest one is chosen among the descriptors with the highest end_lba. If it is -1 then the slowest speed descriptor is chosen regardless of end_lba. Parameter flag decides whether the speed goal means write speed or read speed. @param d Drive to query @param speed_goal Upper limit for speed, 0=search for maximum speed , -1 search for minimum speed @param best_descr Result of the search, NULL if no match @param flag Bitfield for control purposes bit0= look for best read speed rather than write speed bit1= look for any source type (else look for source==2 first and for any other source type only with CD media) @return >0 indicates a valid best_descr, 0 = no valid best_descr @since 0.3.8 */ int burn_drive_get_best_speed(struct burn_drive *d, int speed_goal, struct burn_speed_descriptor **best_descr, int flag); /* ts A61226 */ /** Dispose a speed descriptor list copy which was obtained by burn_drive_get_speedlist(). @param speed_list The list copy. *speed_list gets set to NULL. @return 1=list disposed , 0= *speedlist was already NULL @since 0.3.0 */ int burn_drive_free_speedlist(struct burn_speed_descriptor **speed_list); /* ts A70203 */ /* @since 0.3.2 */ /** The reply structure for burn_disc_get_multi_caps() */ struct burn_multi_caps { /* Multi-session capability can keep the media appendable after writing a session. It also guarantees that the drive will be able to predict and use the appropriate Next Writeable Address to place the next session on the media without overwriting the existing ones. It does not guarantee that the selected write type is able to do an appending session after the next session. (E.g. CD SAO is capable of multi-session by keeping a disc appendable. But .might_do_sao will be 0 afterwards, when checking the appendable media.) 1= media may be kept appendable by burn_write_opts_set_multi(o,1) 0= media will not be appendable */ int multi_session; /* Multi-track capability can write more than one track source during a single session. The written tracks can later be found in libburn's TOC model with their start addresses and sizes. 1= multiple tracks per session are allowed 0= only one track per session allowed */ int multi_track; /* Start-address capability can set a non-zero address with burn_write_opts_set_start_byte(). Eventually this has to respect .start_alignment and .start_range_low, .start_range_high in this structure. 1= non-zero start address is allowed 0= only start address 0 is allowed (to depict the drive's own idea about the appropriate write start) */ int start_adr; /** The alignment for start addresses. ( start_address % start_alignment ) must be 0. */ off_t start_alignment; /** The lowest permissible start address. */ off_t start_range_low; /** The highest addressable start address. */ off_t start_range_high; /** Potential availability of write modes 4= needs no size prediction, not to be chosen automatically 3= needs size prediction, not to be chosen automatically 2= available, no size prediction necessary 1= available, needs exact size prediction 0= not available With CD media (profiles 0x09 and 0x0a) check also the elements *_block_types of the according write mode. */ int might_do_tao; int might_do_sao; int might_do_raw; /** Generally advised write mode. Not necessarily the one chosen by burn_write_opts_auto_write_type() because the burn_disc structure might impose particular demands. */ enum burn_write_types advised_write_mode; /** Write mode as given by parameter wt of burn_disc_get_multi_caps(). */ enum burn_write_types selected_write_mode; /** Profile number which was current when the reply was generated */ int current_profile; /** Wether the current profile indicates CD media. 1=yes, 0=no */ int current_is_cd_profile; /* ts A70528 */ /* @since 0.3.8 */ /** Wether the current profile is able to perform simulated write */ int might_simulate; }; /** Allocates a struct burn_multi_caps (see above) and fills it with values which are appropriate for the drive and the loaded media. The drive must be grabbed for this call. The returned structure has to be disposed via burn_disc_free_multi_caps() when no longer needed. @param d The drive to inquire @param wt With BURN_WRITE_NONE the best capabilities of all write modes get returned. If set to a write mode like BURN_WRITE_SAO the capabilities with that particular mode are returned and the return value is 0 if the desired mode is not possible. @param caps returns the info structure @param flag Bitfield for control purposes (unused yet, submit 0) @return < 0 : error , 0 : writing seems impossible , 1 : writing possible @since 0.3.2 */ int burn_disc_get_multi_caps(struct burn_drive *d, enum burn_write_types wt, struct burn_multi_caps **caps, int flag); /** Removes from memory a multi session info structure which was returned by burn_disc_get_multi_caps(). The pointer *caps gets set to NULL. @param caps the info structure to dispose (note: pointer to pointer) @return 0 : *caps was already NULL, 1 : memory object was disposed @since 0.3.2 */ int burn_disc_free_multi_caps(struct burn_multi_caps **caps); /** Gets a copy of the toc_entry structure associated with a track @param t Track to get the entry from @param entry Struct for the library to fill out */ void burn_track_get_entry(struct burn_track *t, struct burn_toc_entry *entry); /** Gets a copy of the toc_entry structure associated with a session's lead out @param s Session to get the entry from @param entry Struct for the library to fill out */ void burn_session_get_leadout_entry(struct burn_session *s, struct burn_toc_entry *entry); /** Gets an array of all complete sessions for the disc THIS IS NO LONGER VALID AFTER YOU ADD OR REMOVE A SESSION The result array contains *num + burn_disc_get_incomplete_sessions() elements. All above *num are incomplete sessions. Typically there is at most one incomplete session with one empty track. DVD+R and BD-R seem support more than one track with even readable data. @param d Disc to get session array for @param num Returns the number of sessions in the array @return array of sessions */ struct burn_session **burn_disc_get_sessions(struct burn_disc *d, int *num); /* ts B30112 */ /* @since 1.2.8 */ /** Obtains the number of incomplete sessions which are recorded in the result array of burn_disc_get_sessions() after the complete sessions. See above. @param d Disc object to inquire @return Number of incomplete sessions */ int burn_disc_get_incomplete_sessions(struct burn_disc *d); int burn_disc_get_sectors(struct burn_disc *d); /** Gets an array of all the tracks for a session THIS IS NO LONGER VALID AFTER YOU ADD OR REMOVE A TRACK @param s session to get track array for @param num Returns the number of tracks in the array @return array of tracks */ struct burn_track **burn_session_get_tracks(struct burn_session *s, int *num); int burn_session_get_sectors(struct burn_session *s); /** Gets the mode of a track @param track the track to query @return the track's mode */ int burn_track_get_mode(struct burn_track *track); /** Returns whether the first track of a session is hidden in the pregap @param session the session to query @return non-zero means the first track is hidden */ int burn_session_get_hidefirst(struct burn_session *session); /** Returns the library's version in its parts. This is the runtime counterpart of the three build time macros burn_header_version_* below. @param major The major version number @param minor The minor version number @param micro The micro version number */ void burn_version(int *major, int *minor, int *micro); /* ts A80129 */ /* @since 0.4.4 */ /** These three release version numbers tell the revision of this header file and of the API it describes. They are memorized by applications at build time. Immediately after burn_initialize() an application should do this check: burn_version(&major, &minor, µ); if(major > burn_header_version_major || (major == burn_header_version_major && (minor > burn_header_version_minor || (minor == burn_header_version_minor && micro >= burn_header_version_micro)))) { ... Young enough. Go on with program run .... } else { ... Too old. Do not use this libburn version ... } */ #define burn_header_version_major 1 #define burn_header_version_minor 4 #define burn_header_version_micro 2 /** Note: Above version numbers are also recorded in configure.ac because libtool wants them as parameters at build time. For the library compatibility check, BURN_*_VERSION in configure.ac are not decisive. Only the three numbers above do matter. */ /** Usage discussion: Some developers of the libburnia project have differing opinions how to ensure the compatibility of libaries and applications. It is about whether to use at compile time and at runtime the version numbers isoburn_header_version_* provided here. Thomas Schmitt advises to use them. Vreixo Formoso advises to use other means. At compile time: Vreixo Formoso advises to leave proper version matching to properly programmed checks in the the application's build system, which will eventually refuse compilation. Thomas Schmitt advises to use the macros defined here for comparison with the application's requirements of library revisions and to eventually break compilation. Both advises are combinable. I.e. be master of your build system and have #if checks in the source code of your application, nevertheless. At runtime (via *_is_compatible()): Vreixo Formoso advises to compare the application's requirements of library revisions with the runtime library. This is to enable runtime libraries which are young enough for the application but too old for the lib*.h files seen at compile time. Thomas Schmitt advises to compare the header revisions defined here with the runtime library. This is to enforce a strictly monotonous chain of revisions from app to header to library, at the cost of excluding some older libraries. These two advises are mutually exclusive. */ /* ts A91226 */ /** Obtain the id string of the SCSI transport interface. This interface may be a system specific adapter module of libburn or an adapter to a supporting library like libcdio. @param flag Bitfield for control puposes, submit 0 for now @return A pointer to the id string. Do not alter the string content. @since 0.7.6 */ char *burn_scsi_transport_id(int flag); /* ts A60924 : ticket 74 */ /** Control queueing and stderr printing of messages from libburn. Severity may be one of "NEVER", "ABORT", "FATAL", "FAILURE", "SORRY", "WARNING", "HINT", "NOTE", "UPDATE", "DEBUG", "ALL". @param queue_severity Gives the minimum limit for messages to be queued. Default: "NEVER". If you queue messages then you must consume them by burn_msgs_obtain(). @param print_severity Does the same for messages to be printed directly to stderr. Default: "FATAL". @param print_id A text prefix to be printed before the message. @return >0 for success, <=0 for error @since 0.2.6 */ int burn_msgs_set_severities(char *queue_severity, char *print_severity, char *print_id); /* ts A60924 : ticket 74 */ /* @since 0.2.6 */ #define BURN_MSGS_MESSAGE_LEN 4096 /** Obtain the oldest pending libburn message from the queue which has at least the given minimum_severity. This message and any older message of lower severity will get discarded from the queue and is then lost forever. @param minimum_severity may be one of "NEVER", "ABORT", "FATAL", "FAILURE", "SORRY", "WARNING", "HINT", "NOTE", "UPDATE", "DEBUG", "ALL". To call with minimum_severity "NEVER" will discard the whole queue. @param error_code Will become a unique error code as listed in libburn/libdax_msgs.h @param msg_text Must provide at least BURN_MSGS_MESSAGE_LEN bytes. @param os_errno Will become the eventual errno related to the message @param severity Will become the severity related to the message and should provide at least 80 bytes. @return 1 if a matching item was found, 0 if not, <0 for severe errors @since 0.2.6 */ int burn_msgs_obtain(char *minimum_severity, int *error_code, char msg_text[], int *os_errno, char severity[]); /* ts A70922 */ /** Submit a message to the libburn queueing system. It will be queued or printed as if it was generated by libburn itself. @param error_code The unique error code of your message. Submit 0 if you do not have reserved error codes within the libburnia project. @param msg_text Not more than BURN_MSGS_MESSAGE_LEN characters of message text. @param os_errno Eventual errno related to the message. Submit 0 if the message is not related to a operating system error. @param severity One of "ABORT", "FATAL", "FAILURE", "SORRY", "WARNING", "HINT", "NOTE", "UPDATE", "DEBUG". Defaults to "FATAL". @param d An eventual drive to which the message shall be related. Submit NULL if the message is not specific to a particular drive object. @return 1 if message was delivered, <=0 if failure @since 0.4.0 */ int burn_msgs_submit(int error_code, char msg_text[], int os_errno, char severity[], struct burn_drive *d); /* ts A71016 */ /** Convert a severity name into a severity number, which gives the severity rank of the name. @param severity_name A name as with burn_msgs_submit(), e.g. "SORRY". @param severity_number The rank number: the higher, the more severe. @param flag Bitfield for control purposes (unused yet, submit 0) @return >0 success, <=0 failure @since 0.4.0 */ int burn_text_to_sev(char *severity_name, int *severity_number, int flag); /* ts A80202 */ /** Convert a severity number into a severity name @param severity_number The rank number: the higher, the more severe. @param severity_name A name as with burn_msgs_submit(), e.g. "SORRY". @param flag Bitfield for control purposes (unused yet, submit 0) @return >0 success, <=0 failure @since 0.4.4 */ int burn_sev_to_text(int severity_number, char **severity_name, int flag); /* ts B21214 */ /** Return a blank separated list of severity names. Sorted from low to high severity. @param flag Bitfield for control purposes (unused yet, submit 0) @return A constant string with the severity names @since 1.2.6 */ char *burn_list_sev_texts(int flag); /* ts A70915 */ /** Replace the messenger object handle of libburn by a compatible handle obtained from a related library. See also: libisofs, API function iso_get_messenger(). @param messenger The foreign but compatible message handle. @return 1 : success, <=0 : failure @since 0.4.0 */ int burn_set_messenger(void *messenger); /* ts A61002 */ /* @since 0.2.6 */ /** The prototype of a handler function suitable for burn_set_signal_handling() Such a function has to return -2 if it does not want the process to exit with value 1. */ typedef int (*burn_abort_handler_t)(void *handle, int signum, int flag); /** Control built-in signal handling. Either by setting an own handler or by activating the built-in signal handler. A function parameter handle of NULL activates the built-in abort handler. Depending on mode it may cancel all drive operations, wait for all drives to become idle, exit(1). It may also prepare function burn_drive_get_status() for waiting and performing exit(1). Parameter handle may be NULL or a text that shall be used as prefix for pacifier messages of burn_abort_pacifier(). Other than with an application provided handler, the prefix char array does not have to be kept existing until the eventual signal event. Before version 0.7.8 only action 0 was available. I.e. the built-in handler waited for the drives to become idle and then performed exit(1) directly. But during burn_disc_write() onto real CD or DVD, FreeBSD 8.0 pauses the other threads until the signal handler returns. The new actions try to avoid this deadlock. It is advised to use action 3 at least during burn_disc_write(), burn_disc_erase(), burn_disc_format(): burn_set_signal_handling(text, NULL, 0x30); and to call burn_is_aborting(0) when the drive is BURN_DRIVE_IDLE. If burn_is_aborting(0) returns 1, then call burn_abort() and exit(1). @param handle Opaque handle eventually pointing to an application provided memory object @param handler A function to be called on signals, if the handling bits in parameter mode are set 0. It will get parameter handle as argument. flag will be 0. It should finally call burn_abort(). See there. If the handler function returns 2 or -2, then the wrapping signal handler of libburn will return and let the program continue its operations. Any other return value causes exit(1). @param mode : bit0 - bit3: Handling of received signals: 0 Install libburn wrapping signal handler, which will call handler(handle, signum, 0) on nearly all signals 1 Enable system default reaction on all signals 2 Try to ignore nearly all signals 10 like mode 2 but handle SIGABRT like with mode 0 bit4 - bit7: With handler == NULL : Action of built-in handler. "control thread" is the one which called burn_set_signal_handling(). All actions activate receive mode 2 to ignore further signals. 0 Same as 1 (for pre-0.7.8 backward compatibility) @since 0.7.8 1 Catch the control thread in abort handler, call burn_abort() with a patience value > 0 and finally exit(1). Does not always work with FreeBSD. 2 Call burn_abort() with patience -1 and return from handler. When the control thread calls burn_drive_get_status(), then call burn_abort() with patience 1 instead, and finally exit(1). Does not always work with FreeBSD. 3 Call burn_abort() with patience -1, return from handler. It is duty of the application to detect a pending abort condition by calling burn_is_aborting() and to wait for all drives to become idle. E.g. by calling burn_abort() with patience >0. 4 Like 3, but without calling burn_abort() with -1. Only the indicator of burn_is_aborting() gets set. bit8: @since 1.3.2 try to ignore SIGPIPE (regardless of bit0 - bit3) @since 0.2.6 */ void burn_set_signal_handling(void *handle, burn_abort_handler_t handler, int mode); /* ts B00304 */ /* Inquire whether the built-in abort handler was triggered by a signal. This has to be done to detect pending abort handling if signal handling was set to the built-in handler and action was set to 2 or 3. @param flag Bitfield for control purposes (unused yet, submit 0) @return 0 = no abort was triggered >0 = action that was triggered (action 0 is reported as 1) @since 0.7.8 */ int burn_is_aborting(int flag); /* ts A70811 */ /** Write data in random access mode. The drive must be grabbed successfully before calling this function which circumvents usual libburn session processing and rather writes data without preparations or finalizing. This will work only with overwriteable media which are also suitable for burn_write_opts_set_start_byte(). The same address alignment restrictions as with this function apply. I.e. for DVD it is best to align to 32 KiB blocks (= 16 LBA units). The amount of data to be written is subject to the same media dependent alignment rules. Again, 32 KiB is most safe. Call burn_disc_get_multi_caps() can obtain the necessary media info. See resulting struct burn_multi_caps elements .start_adr , .start_alignment , .start_range_low , .start_range_high . Other than burn_disc_write() this is a synchronous call which returns only after the write transaction has ended (sucessfully or not). So it is wise not to transfer giant amounts of data in a single call. Important: Data have to fit into the already formatted area of the media. @param d The drive to which to write @param byte_address The start address of the write in byte (1 LBA unit = 2048 bytes) (do respect media alignment) @param data The bytes to be written @param data_count The number of those bytes (do respect media alignment) data_count == 0 is permitted (e.g. to flush the drive buffer without further data transfer). @param flag Bitfield for control purposes: bit0 = flush the drive buffer after eventual writing @return 1=sucessful , <=0 : number of transfered bytes * -1 @since 0.4.0 */ int burn_random_access_write(struct burn_drive *d, off_t byte_address, char *data, off_t data_count, int flag); /* ts A81215 */ /** Inquire the maximum amount of readable data. It is supposed that all LBAs in the range from 0 to media_read_acpacity-1 can be read via burn_read_data() although some of them may never have been recorded. If tracks are recognizable then it is better to only read LBAs which are part of some track. If the drive is actually a large file or block device, then the capacity is curbed to a maximum of 0x7ffffff0 blocks = 4 TB - 32 KB. @param d The drive from which to read @param capacity Will return the result if valid @param flag Bitfield for control purposes: Unused yet, submit 0. @return 1=sucessful , <=0 an error occured @since 0.6.0 */ int burn_get_read_capacity(struct burn_drive *d, int *capacity, int flag); /* ts A70812 */ /** Read data in random access mode. The drive must be grabbed successfully before calling this function. With all currently supported drives and media the byte_address has to be aligned to 2048 bytes. Only data tracks with 2048 bytes per sector can be read this way. I.e. not CD-audio, not CD-video-stream ... This is a synchronous call which returns only after the full read job has ended (sucessfully or not). So it is wise not to read giant amounts of data in a single call. @param d The drive from which to read @param byte_address The start address of the read in byte (aligned to 2048) @param data A memory buffer capable of taking data_size bytes @param data_size The amount of data to be read. This does not have to be aligned to any block size. @param data_count The amount of data actually read (interesting on error) The counted bytes are supposed to be valid. @param flag Bitfield for control purposes: bit0= - reserved - bit1= do not submit error message if read error bit2= on error do not try to read a second time with single block steps. @since 0.5.2 bit3= return -2 on permission denied error rather than issueing a warning message. @since 1.0.6 bit4= return -3 on SCSI error 5 64 00 ILLEGAL MODE FOR THIS TRACK and prevent this error from being reported as event message. Do not retry reading in this case. (Useful to try the last two blocks of a CD track which might be non-data because of TAO.) @since 1.2.6 bit5= issue messages with severity DEBUG if they would be suppressed by bit1. @since 1.4.0 @return 1=sucessful , <=0 an error occured with bit3: -2= permission denied error @since 0.4.0 */ int burn_read_data(struct burn_drive *d, off_t byte_address, char data[], off_t data_size, off_t *data_count, int flag); /* ts B21119 */ /** Read CD audio sectors in random access mode. The drive must be grabbed successfully before calling this function. Only CD audio tracks with 2352 bytes per sector can be read this way. I.e. not data tracks, not CD-video-stream, ... Note that audio data do not have exact block addressing. If you read a sequence of successive blocks then you will get a seamless stream of data. But the actual start and end position of this audio stream will differ by a few dozens of milliseconds, depending on individual CD and individual drive. Expect leading and trailing zeros, as well as slight truncation. @param d The drive from which to read. It must be a real MMC drive (i.e. not a stdio file) and it must have a CD loaded (i.e. not DVD or BD). @param sector_no The sector number (Logical Block Address) It may be slightly below 0, depending on drive and medium. -150 is a lower limit. @param data A memory buffer capable of taking data_size bytes @param data_size The amount of data to be read. This must be aligned to full multiples of 2352. @param data_count The amount of data actually read (interesting on error) @param flag Bitfield for control purposes: bit0= - reserved - bit1= do not submit error message if read error bit2= on error do not try to read a second time with single block steps. bit3= Enable DAP : "flaw obscuring mechanisms like audio data mute and interpolate" bit4= return -3 on SCSI error 5 64 00 ILLEGAL MODE FOR THIS TRACK and prevent this error from being reported as event message. Do not retry reading in this case. (Useful to try the last two blocks of a CD track which might be non-audio because of TAO.) bit5= issue messages with severity DEBUG if they would be suppressed by bit1. @since 1.4.0 @return 1=sucessful , <=0 an error occured with bit3: -2= permission denied error @since 1.2.6 */ int burn_read_audio(struct burn_drive *d, int sector_no, char data[], off_t data_size, off_t *data_count, int flag); /* ts B30522 */ /** Extract an interval of audio sectors from CD and store it as a WAVE audio file on hard disk. @param drive The drive from which to read. @param start_sector The logical block address of the first audio sector which shall be read. @param sector_count The number of audio sectors to be read. Each sector consists of 2352 bytes. @param target_path The address of the file where to store the extracted audio data. Will be opened O_WRONLY | O_CREAT. The file name should have suffix ".wav". @param flag Bitfield for control purposes: bit0= Report about progress by UPDATE messages bit3= Enable DAP : "flaw obscuring mechanisms like audio data mute and interpolate" @since 1.3.2 */ int burn_drive_extract_audio(struct burn_drive *drive, int start_sector, int sector_count, char *target_path, int flag); /* ts B30522 */ /** Extract all audio sectors of a track from CD and store them as a WAVE audio file on hard disk. @param drive The drive from which to read. @param track The track which shall be extracted. @param target_path The address of the file where to store the extracted audio data. Will be opened O_WRONLY | O_CREAT. The file name should have suffix ".wav". @param flag Bitfield for control purposes: bit0= Report about progress by UPDATE messages bit3= Enable DAP : "flaw obscuring mechanisms like audio data mute and interpolate" @since 1.3.2 */ int burn_drive_extract_audio_track(struct burn_drive *drive, struct burn_track *track, char *target_path, int flag); /* ts A70904 */ /** Inquire whether the drive object is a real MMC drive or a pseudo-drive created by a stdio: address. @param d The drive to inquire @return 0= null-drive 1= real MMC drive 2= stdio-drive, random access, read-write 3= stdio-drive, sequential, write-only 4= stdio-drive, random access, read-only (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 */ int burn_drive_get_drive_role(struct burn_drive *d); /* ts B10312 */ /** Allow drive role 4 "random access read-only" and drive role 5 "random access write-only". By default a random access file assumes drive role 2 "read-write" regardless whether it is actually readable or writeable. If enabled, random-access file objects which recognizably permit no writing will be classified as role 4 and those which permit no reading will get role 5. Candidates are drive addresses of the form stdio:/dev/fd/# , where # is the integer number of an open file descriptor. If this descriptor was opened read-only or write-only, then it gets role 4 or role 5, respectively. Other paths may get tested by an attempt to open them for read-write (role 2) or read-only (role 4) or write-only (role 5). See bit1. @param allowed Bitfield for control purposes: bit0= Enable roles 4 and 5 for drives which get aquired after this call bit1= with bit0: Test whether the file can be opened for read-write, read-only, or write-only. Classify as roles 2, 4, 5. bit2= with bit0 and bit1: Classify files which cannot be opened at all as role 0 : useless dummy. Else classify as role 2. bit3= Classify non-empty role 5 drives as BURN_DISC_APPENDABLE with Next Writeable Address after the end of the file. It is nevertheless possible to change this address by call burn_write_opts_set_start_byte(). @since 1.0.6 */ void burn_allow_drive_role_4(int allowed); /* ts A70923 */ /** Find out whether a given address string would lead to the given drive object. This should be done in advance for track source addresses with parameter drive_role set to 2. Although a real MMC drive should hardly exist as two drive objects at the same time, this can easily happen with stdio-drives. So if more than one drive is used by the application, then this gesture is advised: burn_drive_d_get_adr(d2, adr2); if (burn_drive_equals_adr(d1, adr2, burn_drive_get_drive_role(d2))) ... Both drive objects point to the same storage facility ... @param d1 Existing drive object @param adr2 Address string to be tested. Prefix "stdio:" overrides parameter drive_role2 by either 0 or 2 as appropriate. The string must be shorter than BURN_DRIVE_ADR_LEN. @param drive_role2 Role as burn_drive_get_drive_role() would attribute to adr2 if it was a drive. Use value 2 for checking track sources or pseudo-drive addresses without "stdio:". Use 1 for checking drive addresses including those with prefix "stdio:". @return 1= adr2 leads to d1 , 0= adr2 seems not to lead to d1, -1 = adr2 is bad @since 0.4.0 */ int burn_drive_equals_adr(struct burn_drive *d1, char *adr2, int drive_role2); /* Audio track data extraction facility. */ /* Maximum size for address paths and fmt_info strings */ #define LIBDAX_AUDIOXTR_STRLEN 4096 /** Extractor object encapsulating intermediate states of extraction. The clients of libdax_audioxtr shall only allocate pointers to this struct and get a storage object via libdax_audioxtr_new(). Appropriate initial value for the pointer is NULL. */ struct libdax_audioxtr; /** Open an audio file, check wether suitable, create extractor object. @param xtr Opaque handle to extractor. Gets attached extractor object. @param path Address of the audio file to extract. "-" is stdin (but might be not suitable for all futurely supported formats). @param flag Bitfield for control purposes (unused yet, submit 0) @return >0 success 0 unsuitable format -1 severe error -2 path not found @since 0.2.4 */ int libdax_audioxtr_new(struct libdax_audioxtr **xtr, char *path, int flag); /** Obtain identification parameters of opened audio source. @param xtr Opaque handle to extractor @param fmt Gets pointed to the audio file format id text: ".wav" , ".au" @param fmt_info Gets pointed to a format info text telling parameters @param num_channels e.g. 1=mono, 2=stereo, etc @param sample_rate e.g. 11025, 44100 @param bits_per_sample e.g. 8= 8 bits per sample, 16= 16 bits ... @param msb_first Byte order of samples: 0= Intel = Little Endian 1= Motorola = Big Endian @param flag Bitfield for control purposes (unused yet, submit 0) @return >0 success, <=0 failure @since 0.2.4 */ int libdax_audioxtr_get_id(struct libdax_audioxtr *xtr, char **fmt, char **fmt_info, int *num_channels, int *sample_rate, int *bits_per_sample, int *msb_first, int flag); /** Obtain a prediction about the extracted size based on internal information of the formatted file. @param xtr Opaque handle to extractor @param size Gets filled with the predicted size @param flag Bitfield for control purposes (unused yet, submit 0) @return 1 prediction was possible , 0 no prediction could be made @since 0.2.4 */ int libdax_audioxtr_get_size(struct libdax_audioxtr *o, off_t *size, int flag); /** Obtain next buffer full of extracted data in desired format (only raw audio for now). @param xtr Opaque handle to extractor @param buffer Gets filled with extracted data @param buffer_size Maximum number of bytes to be filled into buffer @param flag Bitfield for control purposes bit0= do not stop at predicted end of data @return >0 number of valid buffer bytes, 0 End of file -1 operating system reports error -2 usage error by application @since 0.2.4 */ int libdax_audioxtr_read(struct libdax_audioxtr *xtr, char buffer[], int buffer_size, int flag); /** Try to obtain a file descriptor which will deliver extracted data to normal calls of read(2). This may fail because the format is unsuitable for that, but WAVE (.wav) is ok. If this call succeeds the xtr object will have forgotten its file descriptor and libdax_audioxtr_read() will return a usage error. One may use *fd after libdax_audioxtr_destroy() and will have to close it via close(2) when done with it. @param xtr Opaque handle to extractor @param fd Eventually returns the file descriptor number @param flag Bitfield for control purposes bit0= do not dup(2) and close(2) but hand out original fd @return 1 success, 0 cannot hand out fd , -1 severe error @since 0.2.4 */ int libdax_audioxtr_detach_fd(struct libdax_audioxtr *o, int *fd, int flag); /** Clean up after extraction and destroy extractor object. @param xtr Opaque handle to extractor, *xtr is allowed to be NULL, *xtr is set to NULL by this function @param flag Bitfield for control purposes (unused yet, submit 0) @return 1 = destroyed object, 0 = was already destroyed @since 0.2.4 */ int libdax_audioxtr_destroy(struct libdax_audioxtr **xtr, int flag); #ifndef DOXYGEN BURN_END_DECLS #endif /* ts A91205 */ /* The following experiments may be interesting in future: */ /* Perform OPC explicitely. # define Libburn_pioneer_dvr_216d_with_opC 1 */ /* Load mode page 5 and modify it rather than composing from scratch. # define Libburn_pioneer_dvr_216d_load_mode5 1 */ /* Inquire drive events and react by reading configuration or starting unit. # define Libburn_pioneer_dvr_216d_get_evenT 1 */ /* ts A91112 */ /* Do not probe CD modes but declare only data and audio modes supported. For other modes or real probing one has to call burn_drive_probe_cd_write_modes(). */ #define Libburn_dummy_probe_write_modeS 1 /* ts B30112 */ /* Handle DVD+R with reserved tracks in incomplete first session by loading info about the incomplete session into struct burn_disc */ #define Libburn_disc_with_incomplete_sessioN 1 /* Early experimental: Do not define Libburn_develop_quality_scaN unless you want to work towards a usable implementation. If it gets enabled, then the call must be published in libburn/libburn.ver */ #ifdef Libburn_develop_quality_scaN /* ts B21108 */ /* Experiments mit quality scan command F3 on Optiarc drive */ int burn_nec_optiarc_rep_err_rate(struct burn_drive *d, int start_lba, int rate_period, int flag); #endif /* Libburn_develop_quality_scaN */ /* Linux 3.16 problems with ABh Read Media Serial Number: - as normal user lets ioctl(SG_IO) return -1 and errno = EFAULT - as superuser renders LG BH16NS40 unusable until power cycle #de fine Libburn_enable_scsi_cmd_ABh yes #de fine Libburn_enable_scsi_cmd_ABh_pretend_currenT yes */ #endif /*LIBBURN_H*/ �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������libburn-1.4.2/libburn/read.c������������������������������������������������������������������������0000644�0001757�0001751�00000046617�12652644224�012645� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */ /* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens Copyright (c) 2006 - 2014 Thomas Schmitt <scdbackup@gmx.net> Provided under GPL version 2 or later. */ #ifdef HAVE_CONFIG_H #include "../config.h" #endif #include <stdlib.h> #include <unistd.h> #include <signal.h> /* ts A61007 */ /* #include <a ssert.h> */ #include <stdio.h> #include <string.h> #include <ctype.h> #include <fcntl.h> #include <errno.h> /* ts B41126 : O_BINARY is needed for Cygwin but undefined elsewhere */ #ifndef O_BINARY #define O_BINARY 0 #endif #include "sector.h" #include "libburn.h" #include "drive.h" #include "transport.h" /* ts A60925 : obsoleted by libdax_msgs.h #include "message.h" */ #include "crc.h" #include "debug.h" #include "init.h" #include "toc.h" #include "util.h" #include "mmc.h" #include "sg.h" #include "read.h" #include "options.h" /* ts A70812 */ #include "error.h" #include "libdax_msgs.h" extern struct libdax_msgs *libdax_messenger; void burn_disc_read(struct burn_drive *d, const struct burn_read_opts *o) { #if 0 int i, end, maxsects, finish; int seclen; int drive_lba; unsigned short crc; unsigned char fakesub[96]; struct buffer page; <- needs to become dynamic memory int speed; /* ts A61007 : if this function gets revived, then these tests have to be done more graceful */ a ssert((o->version & 0xfffff000) == (OPTIONS_VERSION & 0xfffff000)); a ssert(!d->busy); a ssert(d->toc->valid); a ssert(o->datafd != -1); /* moved up from spc_select_error_params alias d->send_parameters() */ a ssert(d->mdata->valid); /* XXX not sure this is a good idea. copy it? */ /* XXX also, we have duplicated data now, do we remove the fds from struct drive, or only store a subset of the _opts structs in drives */ /* set the speed on the drive */ speed = o->speed > 0 ? o->speed : d->mdata->max_read_speed; d->set_speed(d, speed, 0); d->params.retries = o->hardware_error_retries; d->send_parameters(d, o); d->cancel = 0; d->busy = BURN_DRIVE_READING; d->currsession = 0; /* drive_lba = 232000; d->currtrack = 18; */ d->currtrack = 0; drive_lba = 0; /* XXX removal of this line obviously breaks * d->track_end = burn_track_end(d, d->currsession, d->currtrack);*/ printf("track ends at %d\n", d->track_end); page.sectors = 0; page.bytes = 0; if (o->subfd != -1) { memset(fakesub, 0xFF, 12); memset(fakesub + 12, 0, 84); fakesub[13] = 1; fakesub[14] = 1; fakesub[20] = 2; fakesub[12] = (d->toc->toc_entry[0].control << 4) + d->toc->toc_entry[0].adr; #ifdef Libburn_no_crc_C crc = 0; /* dummy */ #else crc = crc_ccitt(fakesub + 12, 10); #endif fakesub[22] = crc >> 8; fakesub[23] = crc & 0xFF; write(o->subfd, fakesub, 96); } while (1) { seclen = burn_sector_length_read(d, o); for (i = 0; i < page.sectors; i++) { burn_packet_process(d, page.data + seclen * i, o); d->track_end--; drive_lba++; } if ((d->cancel) || (drive_lba == LAST_SESSION_END(d))) { d->busy = BURN_DRIVE_IDLE; if (!d->cancel) d->toc->complete = 1; return; } /* XXX: removal of this line obviously breaks * end = burn_track_end(d, d->currsession, d->currtrack); */ if (drive_lba == end) { d->currtrack++; if (d->currtrack > d->toc->session[d->currsession].lasttrack) { d->currsession++; /* session switch to d->currsession */ /* skipping a lead out */ drive_lba = CURRENT_SESSION_START(d); /* XXX more of the same end = burn_track_end(d, d->currsession, d->currtrack); */ } } page.sectors = 0; page.bytes = 0; maxsects = BUFFER_SIZE / seclen; finish = end - drive_lba; d->track_end = finish; page.sectors = (finish < maxsects) ? finish : maxsects; printf("reading %d sectors from %d\n", page.sectors, drive_lba); /* >>> ts A61009 : ensure page.sectors >= 0 before calling */ /* >>> ts B21123 : Would now be d->read_cd() with with sectype = 0 , mainch = 0xf8 */ d->r ead_sectors(d, drive_lba, page.sectors, o, &page); printf("Read %d\n", page.sectors); } #endif } int burn_sector_length_read(struct burn_drive *d, const struct burn_read_opts *o) { int dlen = 2352; int data; /*XXX how do we handle this crap now?*/ /* data = d->toc->track[d->currtrack].toc_entry->control & 4;*/ data = 1; if (o->report_recovered_errors) dlen += 294; if ((o->subcodes_data) && data) dlen += 96; if ((o->subcodes_audio) && !data) dlen += 96; return dlen; } static int bitcount(unsigned char *data, int n) { int i, j, count = 0; unsigned char tem; for (i = 0; i < n; i++) { tem = data[i]; for (j = 0; j < 8; j++) { count += tem & 1; tem >>= 1; } } return count; } void burn_packet_process(struct burn_drive *d, unsigned char *data, const struct burn_read_opts *o) { unsigned char sub[96]; int ptr = 2352, i, j, code, fb; int audio = 1; #ifndef Libburn_no_crc_C unsigned short crc; #endif if (o->c2errors) { fb = bitcount(data + ptr, 294); if (fb) { /* bitcount(data + ptr, 294) damaged bits */; } ptr += 294; } /* if (d->toc->track[d->currtrack].mode == BURN_MODE_UNINITIALIZED) { if ((d->toc->track[d->currtrack].toc_entry->control & 4) == 0) d->toc->track[d->currtrack].mode = BURN_MODE_AUDIO; else switch (data[15]) { case 0: d->toc->track[d->currtrack].mode = BURN_MODE0; break; case 1: d->toc->track[d->currtrack].mode = BURN_MODE1; break; case 2: d->toc->track[d->currtrack].mode = BURN_MODE2_FORMLESS; break; } } */ if ((audio && o->subcodes_audio) || (!audio && o->subcodes_data)) { memset(sub, 0, sizeof(sub)); for (i = 0; i < 12; i++) { for (j = 0; j < 8; j++) { for (code = 0; code < 8; code++) { sub[code * 12 + i] <<= 1; if (data[ptr + j + i * 8] & (1 << (7 - code))) sub[code * 12 + i]++; } } } #ifndef Libburn_no_crc_C crc = (*(sub + 22) << 8) + *(sub + 23); if (crc != crc_ccitt(sub + 12, 10)) { /* burn_print(1, "sending error on %s %s\n", d->idata->vendor, d->idata->product); e = burn_error(); e->drive = d; burn_print(1, "crc mismatch in Q\n"); */; } #endif /* else process_q(d, sub + 12); */ /* if (o->subfd != -1) write(o->subfd, sub, 96); */ } /* if ((d->track_end <= 150) && (drive_lba + 150 < CURRENT_SESSION_END(d)) && (TOC_ENTRY(d->toc, d->currtrack).control == 4) && (TOC_ENTRY(d->toc, d->currtrack + 1).control == 0)) { burn_print(12, "pregap : %d\n", d->track_end); write(o->binfd, zeros, 2352); #warning XXX WHERE ARE MY SUBCODES } else *//* write(o->datafd, data, 2352); */ } /* so yeah, when you uncomment these, make them write zeros insted of crap static void write_empty_sector(int fd) { static char sec[2352], initialized = 0; if (!initialized) { memset(sec, 0, 2352); initialized = 1; } burn_print(1, "writing an 'empty' sector\n"); write(fd, sec, 2352); } static void write_empty_subcode(int fd) { char sub[96]; write(fd, sub, 96); } static void flipq(unsigned char *sub) { *(sub + 12 + 10) = ~*(sub + 12 + 10); *(sub + 12 + 11) = ~*(sub + 12 + 11); } */ /** @param flag bit1= be silent on failure bit5= report failure with severity DEBUG */ static int burn_stdio_seek(int fd, off_t byte_address, struct burn_drive *d, int flag) { char msg[80]; if (lseek(fd, byte_address, SEEK_SET) != -1) return 1; if (!(flag & 2)) { sprintf(msg, "Cannot address start byte %.f", (double) byte_address); libdax_msgs_submit(libdax_messenger, d->global_index, 0x00020147, (flag & 32) ? LIBDAX_MSGS_SEV_DEBUG : LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH, msg, errno, 0); } return 0; } /* ts A70904 */ /** @param flag bit0= be silent on data shortage bit5= report data shortage with severity DEBUG */ int burn_stdio_read(int fd, char *buf, int bufsize, struct burn_drive *d, int flag) { int todo, count = 0; for(todo = bufsize; todo > 0; ) { count = read(fd, buf + (bufsize - todo), todo); if(count <= 0) break; todo -= count; } if(todo > 0 && !(flag & 1)) { libdax_msgs_submit(libdax_messenger, d->global_index, 0x0002014a, (flag & 32) ? LIBDAX_MSGS_SEV_DEBUG : LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH, "Cannot read desired amount of data", errno, 0); } if (count < 0) return -1; return (bufsize - todo); } /* With DVD and BD media, the minimum ECC entity is read instead of single blocks. @param flag see burn_read_data() in libburn.h */ static int retry_mmc_read(struct burn_drive *d, int chunksize, int sose_mem, int start, char **wpt, off_t *data_count, int flag) { int i, err, todo; int retry_at, retry_size; retry_at = start; retry_size = chunksize; todo = chunksize; retry_size = 16; /* DVD ECC block size */ if (d->current_is_cd_profile) { retry_size = 1; /* CD block size */ } else if (d->current_profile >= 0x40 && d->current_profile <= 0x43) { retry_size = 32; /* BD cluster size */ } for (i = 0; todo > 0; i++) { if (flag & 2) d->silent_on_scsi_error = 1; else if (flag & 32) d->silent_on_scsi_error = 3; retry_at = start + i * retry_size; if (retry_size > todo) retry_size = todo; err = d->read_10(d, retry_at, retry_size, d->buffer); if (flag & (2 | 32)) d->silent_on_scsi_error = sose_mem; if (err == BE_CANCELLED) return 0; memcpy(*wpt, d->buffer->data, retry_size * 2048); *wpt += retry_size * 2048; *data_count += retry_size * 2048; todo -= retry_size; } return 1; } /* @param flag see burn_read_data() in libburn.h */ static int retry_stdio_read(struct burn_drive *d, int fd, int chunksize, int start, char **wpt, off_t *data_count, int flag) { int i, ret, to_read, todo; ret = burn_stdio_seek(fd, ((off_t) start) * 2048, d, flag & 2); if (ret <= 0) return ret; todo = chunksize * 2048; for (i = 0; todo > 0; i += 2048) { to_read = todo; if (to_read > 2048) to_read = 2048; ret = burn_stdio_read(fd, (char *) d->buffer->data, to_read, d, 1); if (ret <= 0) return 0; memcpy(*wpt, d->buffer->data, to_read); *wpt += to_read; *data_count += to_read; todo -= to_read; } return 1; } /* ts A70812 : API function */ int burn_read_data(struct burn_drive *d, off_t byte_address, char data[], off_t data_size, off_t *data_count, int flag) { int alignment = 2048, start, upto, chunksize = 1, err, cpy_size; int sose_mem = 0, fd = -1, ret; char msg[81], *wpt; struct buffer *buf = NULL, *buffer_mem = d->buffer; /* #define Libburn_read_data_adr_logginG 1 */ #ifdef Libburn_read_data_adr_logginG static FILE *log_fp= NULL; if(log_fp == NULL) log_fp = fopen("/tmp/burn_read_data_log", "a"); if(log_fp!=NULL) fprintf(log_fp, "%d\n", (int) (byte_address / 2048)); #endif /* Libburn_read_data_logginG */ BURN_ALLOC_MEM(buf, struct buffer, 1); *data_count = 0; sose_mem = d->silent_on_scsi_error; if (d->released) { libdax_msgs_submit(libdax_messenger, d->global_index, 0x00020142, LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH, "Drive is not grabbed on random access read", 0, 0); {ret = 0; goto ex;} } if (d->drive_role == 0) { libdax_msgs_submit(libdax_messenger, d->global_index, 0x00020146, LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH, "Drive is a virtual placeholder (null-drive)", 0, 0); {ret = 0; goto ex;} } else if (d->drive_role == 3) { libdax_msgs_submit(libdax_messenger, d->global_index, 0x00020151, LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH, "Read attempt on write-only drive", 0, 0); {ret = 0; goto ex;} } if ((byte_address % alignment) != 0) { sprintf(msg, "Read start address not properly aligned (%d bytes)", alignment); libdax_msgs_submit(libdax_messenger, d->global_index, 0x00020143, LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH, msg, 0, 0); {ret = 0; goto ex;} } if (d->media_read_capacity != 0x7fffffff && byte_address >= ((off_t) d->media_read_capacity + (off_t) 1) * (off_t) 2048) { if (!(flag & 2)) { sprintf(msg, "Read start address %ds larger than number of readable blocks %d", (int) (byte_address / 2048 + !!(byte_address % 2048)), d->media_read_capacity); libdax_msgs_submit(libdax_messenger, d->global_index, 0x00020172, (flag & 32) ? LIBDAX_MSGS_SEV_DEBUG : LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH, msg, 0, 0); } {ret = 0; goto ex;} } if (d->busy != BURN_DRIVE_IDLE) { libdax_msgs_submit(libdax_messenger, d->global_index, 0x00020145, LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH, "Drive is busy on attempt to read data", 0, 0); {ret = 0; goto ex;} } if (d->drive_role != 1) { /* <<< We need _LARGEFILE64_SOURCE defined by the build system. */ #ifndef O_LARGEFILE #define O_LARGEFILE 0 #endif fd = d->stdio_fd; if (fd < 0) d->stdio_fd = fd = open(d->devname, O_RDONLY | O_LARGEFILE | O_BINARY); if (fd == -1) { if (errno == EACCES && (flag & 2)) { if (!(flag & 8)) libdax_msgs_submit(libdax_messenger, d->global_index, 0x00020183, LIBDAX_MSGS_SEV_WARNING, LIBDAX_MSGS_PRIO_HIGH, "Failed to open device (a pseudo-drive) for reading", errno, 0); } else if (errno != ENOENT || !(flag & 2)) libdax_msgs_submit(libdax_messenger, d->global_index, 0x00020005, (flag & 32) && errno == ENOENT ? LIBDAX_MSGS_SEV_DEBUG : LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH, "Failed to open device (a pseudo-drive) for reading", errno, 0); ret = 0; if (errno == EACCES && (flag & 8)) ret= -2; goto ex; } ret = burn_stdio_seek(fd, byte_address, d, flag & (2 | 32)); if (ret <= 0) goto ex; } d->busy = BURN_DRIVE_READING_SYNC; d->buffer = buf; start = byte_address / 2048; upto = start + data_size / 2048; if (data_size % 2048) upto++; wpt = data; for (; start < upto; start += chunksize) { chunksize = upto - start; if (chunksize > (BUFFER_SIZE / 2048)) { chunksize = (BUFFER_SIZE / 2048); cpy_size = BUFFER_SIZE; } else cpy_size = data_size - *data_count; if (flag & 2) d->silent_on_scsi_error = 1; else if (flag & 32) d->silent_on_scsi_error = 3; if (flag & 16) { d->had_particular_error &= ~1; if (!d->silent_on_scsi_error) d->silent_on_scsi_error = 2; } if (d->drive_role == 1) { err = d->read_10(d, start, chunksize, d->buffer); } else { ret = burn_stdio_read(fd, (char *) d->buffer->data, cpy_size, d, (flag & 32) | !!(flag & 2)); err = 0; if (ret <= 0) err = BE_CANCELLED; } if (flag & (2 | 16 | 32)) d->silent_on_scsi_error = sose_mem; if (err == BE_CANCELLED) { if ((flag & 16) && (d->had_particular_error & 1)) {ret = -3; goto ex;} /* Retry: with CD read by single blocks with other media: retry in full chunks */ if(flag & 4) goto bad_read; if (d->drive_role == 1) { ret = retry_mmc_read(d, chunksize, sose_mem, start, &wpt, data_count, flag); } else { ret = retry_stdio_read(d, fd, chunksize, start, &wpt, data_count, flag); } if (ret <= 0) goto bad_read; } else { memcpy(wpt, d->buffer->data, cpy_size); wpt += cpy_size; *data_count += cpy_size; } } ret = 1; ex:; BURN_FREE_MEM(buf); d->buffer = buffer_mem; d->busy = BURN_DRIVE_IDLE; return ret; bad_read:; if (!(flag & 2)) libdax_msgs_submit(libdax_messenger, d->global_index, 0x00020000, LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH, "burn_read_data() returns 0", 0, 0); ret = 0; goto ex; } /* ts B21119 : API function*/ int burn_read_audio(struct burn_drive *d, int sector_no, char data[], off_t data_size, off_t *data_count, int flag) { int alignment = 2352, start, upto, chunksize = 1, err, cpy_size, i; int sose_mem = 0, ret; char msg[81], *wpt; struct buffer *buf = NULL, *buffer_mem = d->buffer; BURN_ALLOC_MEM(buf, struct buffer, 1); *data_count = 0; sose_mem = d->silent_on_scsi_error; if (d->released) { libdax_msgs_submit(libdax_messenger, d->global_index, 0x00020142, LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH, "Drive is not grabbed on random access read", 0, 0); {ret = 0; goto ex;} } if (d->drive_role != 1) { libdax_msgs_submit(libdax_messenger, d->global_index, 0x00020146, LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH, "Drive is a virtual placeholder (stdio-drive or null-drive)", 0, 0); {ret = 0; goto ex;} } if ((data_size % alignment) != 0) { sprintf(msg, "Audio read size not properly aligned (%d bytes)", alignment); libdax_msgs_submit(libdax_messenger, d->global_index, 0x0002019d, LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH, msg, 0, 0); {ret = 0; goto ex;} } if (d->busy != BURN_DRIVE_IDLE) { libdax_msgs_submit(libdax_messenger, d->global_index, 0x00020145, LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH, "Drive is busy on attempt to read audio", 0, 0); {ret = 0; goto ex;} } d->busy = BURN_DRIVE_READING_SYNC; d->buffer = buf; start = sector_no; upto = start + data_size / alignment; wpt = data; for (; start < upto; start += chunksize) { chunksize = upto - start; if (chunksize > (BUFFER_SIZE / alignment)) chunksize = (BUFFER_SIZE / alignment); cpy_size = chunksize * alignment; if (flag & 2) d->silent_on_scsi_error = 1; else if (flag & 32) d->silent_on_scsi_error = 3; if (flag & 16) { d->had_particular_error &= ~1; if (!d->silent_on_scsi_error) d->silent_on_scsi_error = 2; } err = d->read_cd(d, start, chunksize, 1, 0x10, NULL, d->buffer, (flag & 8) >> 3); if (flag & (2 | 16 | 32)) d->silent_on_scsi_error = sose_mem; if (err == BE_CANCELLED) { if ((flag & 16) && (d->had_particular_error & 1)) {ret = -3; goto ex;} if(!(flag & 4)) for (i = 0; i < chunksize - 1; i++) { if (flag & 2) d->silent_on_scsi_error = 1; else if (flag & 32) d->silent_on_scsi_error = 3; err = d->read_cd(d, start + i, 1, 1, 0x10, NULL, d->buffer, (flag & 8) >> 3); if (flag & (2 | 32)) d->silent_on_scsi_error = sose_mem; if (err == BE_CANCELLED) break; memcpy(wpt, d->buffer->data, alignment); wpt += alignment; *data_count += alignment; } ret = 0; goto ex; } memcpy(wpt, d->buffer->data, cpy_size); wpt += cpy_size; *data_count += cpy_size; } ret = 1; ex: BURN_FREE_MEM(buf); d->buffer = buffer_mem; d->busy = BURN_DRIVE_IDLE; return ret; } #ifdef Libburn_develop_quality_scaN /* B21108 ts */ int burn_nec_optiarc_rep_err_rate(struct burn_drive *d, int start_lba, int rate_period, int flag) { int ret, lba = 0, error_rate1 = 0, error_rate2 = 0, enabled = 0, dret; /* Sub Operation Code 1 : Enable Error Rate reporting function */ ret = mmc_nec_optiarc_f3(d, 1, start_lba, rate_period, &lba, &error_rate1, &error_rate2); if (ret <= 0) goto ex; enabled = 1; /* >>> Sub Operation Code 2 : Seek to starting address start_lba , rate_period */; /* >>> Loop with Sub Operation Code 3 : Send Error Rate information reply: 4-byte LBA , 2-byte C1/PIE , 2-byte C2/PIF */; ret = 1; ex:; if (enabled) { /* Code F : Disable Error Rate reporting function */ dret = mmc_nec_optiarc_f3(d, 0xf, 0, 0, &lba, &error_rate1, &error_rate2); if (dret < ret) ret = dret; } return ret; } #endif /* Libburn_develop_quality_scaN */ �����������������������������������������������������������������������������������������������������������������libburn-1.4.2/libburn/write.c�����������������������������������������������������������������������0000644�0001757�0001751�00000262203�12652644224�013053� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */ /* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens Copyright (c) 2006 - 2012 Thomas Schmitt <scdbackup@gmx.net> Provided under GPL version 2 or later. */ #ifdef HAVE_CONFIG_H #include "../config.h" #endif #include <unistd.h> #include <signal.h> /* ts A61009 */ /* #include <a ssert.h> */ /* ts A61106 : Deliberate defect provocation macros DO NOT DEFINE THESE IF YOU WANT SUCCESSFUL TAO ! #define Libburn_experimental_no_close_tracK 1 #define Libburn_experimental_no_close_sessioN 1 */ /* ts A61114 : Highly experimental : try to achieve SAO on appendables THIS DOES NOT WORK YET ! #define Libburn_sao_can_appenD 1 */ #include <sys/types.h> #include <stdio.h> #include <string.h> #include <ctype.h> #include <stdlib.h> #include <fcntl.h> #include <errno.h> #include <sys/stat.h> #include <sys/time.h> /* ts B41126 : O_BINARY is needed for Cygwin but undefined elsewhere */ #ifndef O_BINARY #define O_BINARY 0 #endif #include "error.h" #include "sector.h" #include "libburn.h" #include "drive.h" #include "transport.h" #include "debug.h" #include "init.h" #include "toc.h" #include "util.h" #include "sg.h" #include "write.h" #include "options.h" #include "structure.h" #include "source.h" #include "mmc.h" #include "spc.h" #include "libdax_msgs.h" extern struct libdax_msgs *libdax_messenger; /* ts A91120 : <<< experimental */ #ifdef Libburn_mmap_write_buffeR #include <sys/mman.h> #endif /* The maximum output size to be used with CD media. This is also curbed by BURN_OS_TRANSPORT_BUFFER_SIZE. The smaller number gets into effect. */ #define Libburn_cd_obS (32 * 1024) /* The size to be used with DVD media. */ #define Libburn_dvd_obS (32 * 1024) /* The size to be used with BD-RE media in normal, not streamed mode. */ #define Libburn_bd_re_obS (64 * 1024) /* The size to be used with BD-R media in normal, not streamed mode. */ #define Libburn_bd_r_obS (64 * 1024) /* The size to be used with BD-RE and BD-R media in streamed mode. */ #define Libburn_bd_streamed_obS (64 * 1024) /* The number of retries if write(2) returns a short, non-negative write count. */ #define Libburn_stdio_write_retrieS 16 static int type_to_ctrl(int mode) { int ctrl = 0; int data = BURN_MODE2 | BURN_MODE1 | BURN_MODE0; if (mode & data) { ctrl |= 4; } else if (mode & BURN_AUDIO) { if (mode & BURN_4CH) ctrl |= 8; if (mode & BURN_PREEMPHASIS) ctrl |= 1; } else /* ts A61008 */ /* a ssert(0); */ return -1; if (mode & BURN_COPY) ctrl |= 2; return ctrl; } /* only the ctrl nibble is set here (not adr) */ /* ts A61009 : removed "static" , reacted on type_to_ctrl() == -1 preserved ignorance towards unknown modes (for now) */ void type_to_form(int mode, unsigned char *ctladr, int *form) { int ret; ret = type_to_ctrl(mode) << 4; if (ret == -1) { *ctladr = 0xff; *form = -1; return; } *ctladr = ret; if (mode & BURN_AUDIO) *form = 0; if (mode & BURN_MODE0) { /* ts A61009 */ /* a ssert(0); */ *form = -1; return; } if (mode & BURN_MODE1) *form = 0x10; if (mode & BURN_MODE2) { /* ts A61009 */ /* a ssert(0); */ /* XXX someone's gonna want this sometime */ *form = -1; return; } if (mode & BURN_MODE_RAW) *form = 0; if (mode & BURN_SUBCODE_P16) /* must be expanded to R96 */ *form |= 0x40; if (mode & BURN_SUBCODE_P96) *form |= 0xC0; if (mode & BURN_SUBCODE_R96) *form |= 0x40; } /* ts A71002 : outsourced from burn_write_flush() : no sync cache here */ int burn_write_flush_buffer(struct burn_write_opts *o,struct burn_track *track) { struct burn_drive *d = o->drive; if (d->buffer->bytes && !d->cancel) { int err; err = d->write(d, d->nwa, d->buffer); if (err == BE_CANCELLED) return 0; /* A61101 */ if(track != NULL) { track->writecount += d->buffer->bytes; track->written_sectors += d->buffer->sectors; } /* ts A61119 */ d->progress.buffered_bytes += d->buffer->bytes; d->nwa += d->buffer->sectors; d->buffer->bytes = 0; d->buffer->sectors = 0; } return 1; } int burn_write_flush(struct burn_write_opts *o, struct burn_track *track) { int ret; struct burn_drive *d = o->drive; ret = burn_write_flush_buffer(o, track); if (ret <= 0) return ret; d->sync_cache(d); return 1; } /* ts A71002 : outsourced from burn_write_close_track() */ int burn_write_track_minsize(struct burn_write_opts *o, struct burn_session *s, int tnum) { char msg[81]; struct burn_drive *d; struct burn_track *t; int todo, step, cancelled, seclen; d = o->drive; t = s->track[tnum]; /* ts A61103 : pad up track to minimum size of 600 sectors */ if (t->written_sectors < 300) { todo = 300 - t->written_sectors; sprintf(msg,"Padding up track to minimum size (+ %d sectors)", todo); libdax_msgs_submit(libdax_messenger, o->drive->global_index, 0x0002011a, LIBDAX_MSGS_SEV_NOTE, LIBDAX_MSGS_PRIO_HIGH, msg,0,0); step = BUFFER_SIZE / 4096; /* shall fit any sector size */ seclen = burn_sector_length(t->mode); if (seclen <= 0) seclen = 2048; memset(d->buffer, 0, sizeof(struct buffer)); cancelled = d->cancel; for (; todo > 0; todo -= step) { if (step > todo) step = todo; d->buffer->bytes = step*seclen; d->buffer->sectors = step; d->cancel = 0; d->write(d, d->nwa, d->buffer); d->nwa += d->buffer->sectors; t->writecount += d->buffer->bytes; t->written_sectors += d->buffer->sectors; d->progress.buffered_bytes += d->buffer->bytes; } d->cancel = cancelled; } return 1; } /* ts A61030 */ int burn_write_close_track(struct burn_write_opts *o, struct burn_session *s, int tnum) { char msg[81]; struct burn_drive *d; /* ts A61106 */ #ifdef Libburn_experimental_no_close_tracK return 1; #endif d = o->drive; d->busy = BURN_DRIVE_CLOSING_TRACK; sprintf(msg, "Closing track %2.2d", tnum+1); libdax_msgs_submit(libdax_messenger, o->drive->global_index,0x00020119, LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH, msg,0,0); /* MMC-1 mentions track number 0xFF for "the incomplete track", MMC-3 does not. I tried both. 0xFF was in effect when other bugs finally gave up and made way for readable tracks. */ /* ts A70129 Probably the right value for appendables is d->last_track_no */ d->close_track_session(o->drive, 0, 0xff); d->busy = BURN_DRIVE_WRITING; return 1; } /* ts A61030 */ int burn_write_close_session(struct burn_write_opts *o) { /* ts A61106 */ #ifdef Libburn_experimental_no_close_sessioN return 1; #endif libdax_msgs_submit(libdax_messenger, o->drive->global_index,0x00020119, LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH, "Closing session", 0, 0); /* ts A61102 */ o->drive->busy = BURN_DRIVE_CLOSING_SESSION; o->drive->close_track_session(o->drive, 1, 0); /* ts A61102 */ o->drive->busy = BURN_DRIVE_WRITING; return 1; } /* ts A60819, B20101: This is useful only when changes about CD SAO get tested. # define Libburn_write_with_function_print_cuE yes */ #ifdef Libburn_write_with_function_print_cuE static char cue_printify(char c) { if (c >= 32 && c < 127) return c; return '#'; } static void print_cue(struct cue_sheet *sheet) { int i; unsigned char *unit; printf("\n"); printf("ctladr|trno|indx|form|scms| msf | text\n"); printf("------+----+----+----+----+----------+--------\n"); for (i = 0; i < sheet->count; i++) { unit = sheet->data + 8 * i; if ((unit[0] & 0xf) == 2) { printf( " %1X %1X | | | | | | %c%c%c%c%c%c%c\n", (unit[0] & 0xf0) >> 4, unit[0] & 0xf, cue_printify(unit[1]), cue_printify(unit[2]), cue_printify(unit[3]), cue_printify(unit[4]), cue_printify(unit[5]), cue_printify(unit[6]), unit[7] == 0 ? ' ' : cue_printify(unit[7])); } else if ((unit[0] & 0xf) == 3) { printf( " %1X %1X | %2d | | | | | %c%c%c%c%c%c\n", (unit[0] & 0xf0) >> 4, unit[0] & 0xf, unit[1], cue_printify(unit[2]), cue_printify(unit[3]), cue_printify(unit[4]), cue_printify(unit[5]), cue_printify(unit[6]), cue_printify(unit[7])); } else if (unit[1] > 99) { printf(" %1X %1X |0x%02X| %2d | %02X | %02X |", (unit[0] & 0xf0) >> 4, unit[0] & 0xf, unit[1], unit[2], unit[3], unit[4]); printf(" %02d:%02d:%02d |\n", unit[5], unit[6], unit[7]); } else { printf(" %1X %1X | %2d | %2d | %02X | %02X |", (unit[0] & 0xf0) >> 4, unit[0] & 0xf, unit[1], unit[2], unit[3], unit[4]); printf(" %02d:%02d:%02d |\n", unit[5], unit[6], unit[7]); } } fflush(stdout); } #endif /* Libburn_write_with_print_cuE */ /* ts B11226 */ static int new_cue(struct cue_sheet *sheet, int number, int flag) { unsigned char *ptr; ptr = realloc(sheet->data, (sheet->count + number) * 8); if (ptr == NULL) { libdax_msgs_submit(libdax_messenger, -1, 0x00020111, LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH, "Could not allocate new auxiliary object (cue_sheet->data)", 0, 0); return -1; } sheet->data = ptr; sheet->count += number; return 1; } /* ts B11226 : outsourced new_cue() */ /** @return 1 = success , <=0 failure */ static int add_cue(struct cue_sheet *sheet, unsigned char ctladr, unsigned char tno, unsigned char indx, unsigned char form, unsigned char scms, int lba) { unsigned char *unit; int m, s, f, ret; burn_lba_to_msf(lba, &m, &s, &f); ret = new_cue(sheet, 1, 0); if (ret <= 0) return -1; unit = sheet->data + (sheet->count - 1) * 8; unit[0] = ctladr; unit[1] = tno; unit[2] = indx; unit[3] = form; unit[4] = scms; unit[5] = m; unit[6] = s; unit[7] = f; return 1; } /* ts B11226 */ static int add_catalog_cue(struct cue_sheet *sheet, unsigned char catalog[13]) { unsigned char *unit; int i, ret; ret = new_cue(sheet, 2, 0); if (ret <= 0) return -1; unit = sheet->data + (sheet->count - 2) * 8; unit[0] = unit[8] = 0x02; for (i = 0; i < 13; i++) unit[1 + (i >= 7) * 8 + (i % 7)] = catalog[i]; unit[15] = 0x00; return 1; } /* ts B11226 */ static int add_isrc_cue(struct cue_sheet *sheet, unsigned char ctladr, int tno, struct isrc *isrc) { unsigned char *unit; int i, ret; char text[8]; ret = new_cue(sheet, 2, 0); if (ret <= 0) return -1; unit = sheet->data + (sheet->count - 2) * 8; unit[0] = unit[8] = (ctladr & 0xf0) | 0x03; unit[1] = unit[9] = tno; unit[2] = isrc->country[0]; unit[3] = isrc->country[1]; unit[4] = isrc->owner[0]; unit[5] = isrc->owner[1]; unit[6] = isrc->owner[2]; sprintf(text, "%-2.2u%-5.5u", (unsigned int) isrc->year, isrc->serial); unit[7] = text[0]; for (i = 1; i < 7; i++) unit[9 + i] = text[i]; return 1; } /* ts A61114: added parameter nwa */ struct cue_sheet *burn_create_toc_entries(struct burn_write_opts *o, struct burn_session *session, int nwa) { int i, m, s, f, form, runtime = -150, ret, track_length; int leadin_form, leadin_start, pregap = 150, postgap; unsigned char ctladr, scms; struct burn_drive *d; struct burn_toc_entry *e; struct cue_sheet *sheet; struct burn_track **tar = session->track; int ntr = session->tracks; int rem = 0; #define Libburn_track_multi_indeX yes #ifdef Libburn_track_multi_indeX int j; #else int pform; #endif if (ntr < 1) { libdax_msgs_submit(libdax_messenger, -1, 0x0002019c, LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH, "Session has no defined tracks", 0, 0); return NULL; } d = o->drive; #ifdef Libburn_sao_can_appenD if (d->status == BURN_DISC_APPENDABLE) runtime = nwa-150; #endif sheet = calloc(1, sizeof(struct cue_sheet)); /* ts A61009 : react on failures of calloc(), add_cue_sheet() type_to_form() */ if (sheet == NULL) { libdax_msgs_submit(libdax_messenger, -1, 0x00020111, LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH, "Could not allocate new auxiliary object (cue_sheet)", 0, 0); return NULL; } sheet->data = NULL; sheet->count = 0; type_to_form(tar[0]->mode, &ctladr, &form); if (form == -1) { libdax_msgs_submit(libdax_messenger, -1, 0x00020116, LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH, "Track mode has unusable value", 0, 0); goto failed; } if (tar[0]->mode & BURN_AUDIO) leadin_form = 0x01; else leadin_form = 0x14; if (o->num_text_packs > 0) { leadin_form |= 0x40; } else { /* Check for CD-TEXT in session. Not the final creation, because the cue sheet content might be needed for CD-TEXT pack type 0x88 "TOC". */ if (o->text_packs == NULL) { ret = burn_cdtext_from_session(session, NULL, NULL, 1); if (ret < 0) goto failed; else if (ret > 0) leadin_form |= 0x40; } } if (o->has_mediacatalog) ret = add_catalog_cue(sheet, o->mediacatalog); else if (session->mediacatalog[0]) ret = add_catalog_cue(sheet, session->mediacatalog); else ret = 1; if (ret <= 0) goto failed; /* ts B11225 MMC-5 6.33.3.15 Data Form of Sub-channel seems to indicate that for leadin_form 0x41 one should announce d->start_lba as start of the leadin (e.g. -12490) and that data block type should 2 or 3 with mode page 05h. But my drives refuse on that. It works with LBA -150 and data block type 0. Shrug. */ leadin_start = runtime; ret = add_cue(sheet, (ctladr & 64) | 1, 0, 0, leadin_form, 0, leadin_start); if (ret <= 0) goto failed; d->toc_entries = ntr + 3; /* ts A61009 */ /* a ssert(d->toc_entry == NULL); */ if (d->toc_entry != NULL) { /* ts A61109 : this happens with appendable CDs >>> Open question: is the existing TOC needed ? */ /* ts A61109 : for non-SAO, this sheet is thrown away later */ free((char *) d->toc_entry); /* libdax_msgs_submit(libdax_messenger, d->global_index, 0x00020117, LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH, "toc_entry of drive is already in use", 0, 0); goto failed; */ } if (session->firsttrack + ntr - 1 > 99) { libdax_msgs_submit(libdax_messenger, -1, 0x0002019b, LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH, "CD track number exceeds 99", 0, 0); goto failed; } session->lasttrack = session->firsttrack + ntr - 1; d->toc_entry = calloc(d->toc_entries, sizeof(struct burn_toc_entry)); e = d->toc_entry; e[0].point = 0xA0; if (tar[0]->mode & BURN_AUDIO) e[0].control = TOC_CONTROL_AUDIO; else e[0].control = TOC_CONTROL_DATA; e[0].pmin = session->firsttrack; e[0].psec = o->format; e[0].adr = 1; e[1].point = 0xA1; e[1].pmin = session->lasttrack; e[1].adr = 1; if (tar[ntr - 1]->mode & BURN_AUDIO) e[1].control = TOC_CONTROL_AUDIO; else e[1].control = TOC_CONTROL_DATA; e[2].point = 0xA2; e[2].control = e[1].control; e[2].adr = 1; tar[0]->pregap2 = 1; if (tar[0]->pregap2_size < 150) tar[0]->pregap2_size = 150; #ifndef Libburn_track_multi_indeX pform = form; #endif for (i = 0; i < ntr; i++) { /* ts A70125 : Still not understanding the sense behind linking tracks, i decided to at least enforce the MMC specs' minimum track length. */ track_length = burn_track_get_sectors_2(tar[i], 1); if (track_length < 300 && !burn_track_is_open_ended(tar[i])) { track_length = 300; if (!tar[i]->pad) tar[i]->pad = 1; burn_track_set_sectors(tar[i], track_length); } type_to_form(tar[i]->mode, &ctladr, &form); if (tar[i]->mode & BURN_SCMS) scms = 0x80; else scms = 0; if (tar[i]->isrc.has_isrc) { ret = add_isrc_cue(sheet, ctladr, i + session->firsttrack, &(tar[i]->isrc)); if (ret <= 0) goto failed; } pregap = 0; if (tar[i]->pregap2) pregap = tar[i]->pregap2_size; postgap = 0; if (tar[i]->postgap) { if (tar[i]->indices >= 99) { libdax_msgs_submit(libdax_messenger, -1, 0x0002019a, LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH, "Post-gap index number exceeds 99", 0, 0); goto failed; } if (tar[i]->indices < 2) tar[i]->indices = 2; tar[i]->index[tar[i]->indices] = track_length; postgap = tar[i]->postgap_size; } #ifdef Libburn_track_multi_indeX for(j = 0; j < (tar[i]->indices + !!tar[i]->postgap) || j < 2; j++) { if(tar[i]->index[j] == 0x7fffffff) { if (j > 1) break; if (j == 0 && pregap <= 0) continue; /* force existence of mandatory index */ tar[i]->index[j] = 0; } else if (j == 0) { tar[i]->index[j] = 0; } else if (j == 1 && tar[i]->index[0] == 0x7fffffff) { tar[i]->index[j] = 0; } if (j == 1) { tar[i]->entry = &e[3 + i]; e[3 + i].point = i + session->firsttrack; burn_lba_to_msf(runtime, &m, &s, &f); e[3 + i].pmin = m; e[3 + i].psec = s; e[3 + i].pframe = f; e[3 + i].adr = 1; e[3 + i].control = type_to_ctrl(tar[i]->mode); } /* >>> ??? else if j == 0 && mode change to -data : Extended pregap */; /* >>> check index with track size */; tar[i]->index[j] += runtime; ret = add_cue(sheet, ctladr | 1, i + session->firsttrack, j, form, scms, tar[i]->index[j]); if (ret <= 0) goto failed; runtime += pregap; pregap = 0; } runtime += track_length + postgap; #else /* Libburn_track_multi_indeX */ if (i == 0) { ret = add_cue(sheet, ctladr | 1, session->firsttrack, 0, form, 0, runtime); if (ret <= 0) goto failed; runtime += 150; } else if (pform != form) { /* ts A70121 : This seems to be thw wrong test. Correct would be to compare tar[]->mode or bit2 of ctladr. */ ret = add_cue(sheet, ctladr | 1, i + session->firsttrack, 0, form, scms, runtime); if (ret <= 0) goto failed; runtime += 150; /* XXX fix pregap interval 1 for data tracks */ /* ts A60813 silence righteous compiler warning about C++ style comments This is possibly not a comment but rather a trace of Derek Foreman experiments. Thus not to be beautified - but to be preserved rectified. / / if (!(form & BURN_AUDIO)) / / tar[i]->pregap1 = 1; */ /* ts A70121 : it is unclear why (form & BURN_AUDIO) should prevent pregap1. I believe, correct would be: runtime += 75; tar[i]->pregap1 = 1; The test for pform != form is wrong anyway. Next one has to care for Post-gap: table 555 in mmc5r03c.pdf does not show any although 6.33.3.19 would prescribe some. ts B20111: Table 1 of MMC-1 shows two post-gaps. The first matches the precriptions with SEND CUE SHEET. The second one is riddling. Both are part of a track and occupy the range of the last index of the track. Length is 2 seconds for each. Nobody seems to have ever tested this situation, up to now. It is banned for now in burn_disc_write(). Warning have been placed in libburn.h . */ tar[i]->pregap2 = 1; } /* XXX HERE IS WHERE WE DO INDICES IN THE CUE SHEET */ /* XXX and we should make sure the gaps conform to ecma-130... */ tar[i]->entry = &e[3 + i]; e[3 + i].point = i + session->firsttrack; burn_lba_to_msf(runtime, &m, &s, &f); e[3 + i].pmin = m; e[3 + i].psec = s; e[3 + i].pframe = f; e[3 + i].adr = 1; e[3 + i].control = type_to_ctrl(tar[i]->mode); ret = add_cue(sheet, ctladr | 1, i + session->firsttrack, 1, form, scms, runtime); if (ret <= 0) goto failed; runtime += track_length; #endif /* ! Libburn_track_multi_indeX */ /* if we're padding, we'll clear any current shortage. if we're not, we'll slip toc entries by a sector every time our shortage is more than a sector XXX this is untested :) */ if (!tar[i]->pad) { rem += burn_track_get_shortage(tar[i]); /* ts A61101 : I doubt that linking would yield a desireable effect. With TAO it is counterproductive in any way. */ if (o->write_type == BURN_WRITE_TAO) tar[i]->source->next = NULL; else if (i +1 != ntr) tar[i]->source->next = tar[i+1]->source; } else if (rem) { rem = 0; runtime++; } if (rem > burn_sector_length(tar[i]->mode)) { rem -= burn_sector_length(tar[i]->mode); runtime--; } #ifndef Libburn_track_multi_indeX pform = form; #endif } burn_lba_to_msf(runtime, &m, &s, &f); e[2].pmin = m; e[2].psec = s; e[2].pframe = f; ret = add_cue(sheet, ctladr | 1, 0xAA, 1, leadin_form & 0x3f, 0, runtime); if (ret <= 0) goto failed; return sheet; failed:; if (sheet != NULL) free((char *) sheet); return NULL; } int burn_sector_length(int tracktype) { if (tracktype & BURN_AUDIO) return 2352; if (tracktype & BURN_MODE_RAW) return 2352; if (tracktype & BURN_MODE1) return 2048; /* ts A61009 */ /* a ssert(0); */ return -1; } int burn_subcode_length(int tracktype) { if (tracktype & BURN_SUBCODE_P16) return 16; if ((tracktype & BURN_SUBCODE_P96) || (tracktype & BURN_SUBCODE_R96)) return 96; return 0; } int burn_write_leadin(struct burn_write_opts *o, struct burn_session *s, int first) { struct burn_drive *d = o->drive; int count; d->busy = BURN_DRIVE_WRITING_LEADIN; if (first) count = 0 - d->alba - 150; else count = 4500; d->progress.start_sector = d->alba; d->progress.sectors = count; d->progress.sector = 0; while (count != 0) { if (!sector_toc(o, s->track[0]->mode)) return 0; count--; d->progress.sector++; } d->busy = BURN_DRIVE_WRITING; return 1; } int burn_write_leadout(struct burn_write_opts *o, int first, unsigned char control, int mode) { struct burn_drive *d = o->drive; int count; d->busy = BURN_DRIVE_WRITING_LEADOUT; d->rlba = -150; if (first) count = 6750; else count = 2250; d->progress.start_sector = d->alba; d->progress.sectors = count; d->progress.sector = 0; while (count != 0) { if (!sector_lout(o, control, mode)) return 0; count--; d->progress.sector++; } d->busy = BURN_DRIVE_WRITING; return 1; } static int burn_create_text_packs(struct burn_write_opts *o, struct burn_session *s, int flag) { int ret, num_packs = 0; unsigned char *text_packs = NULL; ret = burn_cdtext_from_session(s, &text_packs, &num_packs, 0); if (ret > 0) { if (o->text_packs != NULL) free(o->text_packs); o->text_packs = text_packs; o->num_text_packs = num_packs; } return(ret); } static int burn_write_leadin_cdtext(struct burn_write_opts *o, struct burn_session *s, int flag) { int ret, i, j, si, lba, sub_cursor = 0, err, write_lba, sectors = 0; int self_made_text_packs = 0; unsigned char *subdata = NULL; struct burn_drive *d = o->drive; struct buffer *buf = NULL; enum burn_drive_status was_busy = o->drive->busy; #ifdef Libburn_debug_cd_texT unsigned char *packs; #endif if (o->num_text_packs <= 0) { if (o->text_packs != NULL) {ret = 1; goto ex;} /* Try to create CD-TEXT from .cdtext_* of session and track */ ret = burn_create_text_packs(o, s, 0); self_made_text_packs = 1; if (ret <= 0) goto ex; if (o->num_text_packs <= 0) {ret = 1; goto ex;} } if (!o->no_text_pack_crc_check) { ret = burn_cdtext_crc_mismatches(o->text_packs, o->num_text_packs, 0); if (ret != 0) { libdax_msgs_submit(libdax_messenger, -1, 0x0002018f, LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH, "Program error: CD-TEXT pack CRC mismatch", 0, 0); { ret = 0; goto ex; } } } d->busy = BURN_DRIVE_WRITING_LEADIN; #ifdef Libburn_debug_cd_texT packs = o->text_packs; fprintf(stderr, "libburn_DEBUG: 8 bit CD-TEXT packs to be transmitted:\n"); for (i = 0; i < 18 * o->num_text_packs; i += 18) { fprintf(stderr, "%4d :", i / 18); for (j = 0; j < 18; j++) { if (j >= 4 && j <= 15 && packs[i + j] >= 32 && packs[i + j] <= 126 && packs[i] != 0x88 && packs[i] != 0x89 && packs[i] != 0x8f) fprintf(stderr, " %c", packs[i + j]); else fprintf(stderr, " %2.2X", packs[i + j]); } fprintf(stderr, "\n"); } #endif /* Libburn_debug_cd_texT */ /* Chop from 8 bit text pack to 6 bit subchannel */ BURN_ALLOC_MEM(subdata, unsigned char, o->num_text_packs * 24); for (i = 0; i < 18 * o->num_text_packs; i += 3) { si = i / 3 * 4; subdata[si + 0] = (o->text_packs[i + 0] >> 2) & 0x3f; subdata[si + 1] = (o->text_packs[i + 0] << 4) & 0x30; subdata[si + 1] |= (o->text_packs[i + 1] >> 4) & 0x0f; subdata[si + 2] = (o->text_packs[i + 1] << 2) & 0x3c; subdata[si + 2] |= (o->text_packs[i + 2] >> 6) & 0x03; subdata[si + 3] = (o->text_packs[i + 2] >> 0) & 0x3f; } /* Start at Lead-in address of ATIP and write blocks up to -150 */ BURN_ALLOC_MEM(buf, struct buffer, 1); write_lba = d->start_lba; for (lba = d->start_lba; lba < -150; lba++) { /* Collect subdata in buf */ for (j = 0; j < 4; j++) { memcpy(buf->data + buf->bytes, subdata + sub_cursor * 24, 24); sub_cursor = (sub_cursor + 1) % o->num_text_packs; buf->bytes += 24; } buf->sectors++; sectors++; /* When full or last sector : perform WRITE */ if (buf->bytes + 96 >= 32768 || lba == -151) { #ifdef Libburn_debug_cd_texT fprintf(stderr, "libburn_DEBUG: 6 bit data to be transmitted:\n"); for (i = 0; i < buf->bytes; i += 24) { fprintf(stderr, "%4d :", i / 24); for (j = 0; j < 24; j++) fprintf(stderr, " %2.2X", buf->data[i + j]); fprintf(stderr, "\n"); } #endif /* Libburn_debug_cd_texT */ err = d->write(d, write_lba, buf); if (err == BE_CANCELLED) { ret = 0; goto ex; } write_lba += sectors; sectors = buf->sectors = buf->bytes = 0; } } ret = 1; ex:; if (self_made_text_packs) { if (o->text_packs != NULL) free(o->text_packs); o->text_packs = NULL; o->num_text_packs = 0; } BURN_FREE_MEM(subdata); BURN_FREE_MEM(buf); d->busy = was_busy; return ret; } int burn_write_session(struct burn_write_opts *o, struct burn_session *s) { struct burn_drive *d = o->drive; int i, ret; if (o->write_type == BURN_WRITE_SAO) { ret = burn_write_leadin_cdtext(o, s, 0); if (ret <= 0) goto ex; } d->rlba = 0; for (i = 0; i < s->tracks; i++) { if (!burn_write_track(o, s, i)) { ret = 0; goto ex; } } /* ts A61103 */ ret = 1; ex:; if (o->write_type == BURN_WRITE_TAO) burn_write_close_session(o); return ret; } /* ts A61218 : outsourced from burn_write_track() */ int burn_disc_init_track_status(struct burn_write_opts *o, struct burn_session *s, struct burn_track *t, int tnum, int sectors) { struct burn_drive *d = o->drive; /* Update progress */ d->progress.start_sector = d->nwa; d->progress.sectors = sectors; d->progress.sector = 0; /* ts A60831: added tnum-line, extended print message on proposal by bonfire-app@wanadoo.fr in http://libburn.pykix.org/ticket/58 */ d->progress.track = tnum; /* ts B20113 */ d->progress.indices = t->indices; d->progress.index = 0; if (d->progress.indices > 1) if (t->index[0] == 0x7fffffff) d->progress.index = 1; /* ts A61102 */ d->busy = BURN_DRIVE_WRITING; return 1; } int burn_write_track(struct burn_write_opts *o, struct burn_session *s, int tnum) { struct burn_track *t = s->track[tnum]; struct burn_drive *d = o->drive; int i, tmp = 0, open_ended = 0, ret= 0, nwa, lba; int sectors; char msg[160]; d->rlba = -150; /* XXX for tao, we don't want the pregaps but still want post? */ if (o->write_type != BURN_WRITE_TAO) { /* ts A61102 */ d->busy = BURN_DRIVE_WRITING_PREGAP; if (t->pregap1) d->rlba += 75; if (t->pregap2) d->rlba += t->pregap2_size; if (t->pregap1) { struct burn_track *pt; /* ts A70121 : Removed pseudo suicidal initializer = s->track[tnum - 1]; */ if (tnum == 0) { /* ts A70121 : This is not possible because track 1 cannot have a pregap at all. MMC-5 6.33.3.2 precribes a mandatory pause prior to any track 1. Pre-gap is prescribed for mode changes like audio-to-data. To set burn_track.pregap1 for track 1 is kindof a dirty hack. */ printf("first track should not have a pregap1\n"); pt = t; } else pt = s->track[tnum - 1]; /* ts A70121 */ for (i = 0; i < 75; i++) if (!sector_pregap(o, t->entry->point, pt->entry->control, pt->mode)) { ret = 0; goto ex; } } if (t->pregap2) for (i = 0; i < t->pregap2_size; i++) if (!sector_pregap(o, t->entry->point, t->entry->control, t->mode)) { ret = 0; goto ex; } /* ts B20113 : Flush buffer to avoid influence pregap on track counter */ ret = sector_write_buffer(d, NULL, 0); if (ret <= 0) goto ex; } else { o->control = t->entry->control; d->send_write_parameters(d, s, tnum, o); /* ts A61103 */ ret = d->get_nwa(d, -1, &lba, &nwa); /* ts A70213: CD-TAO: eventually expand size of track to max */ burn_track_apply_fillup(t, d->media_capacity_remaining, 0); /* <<< */ sprintf(msg, "TAO pre-track %2.2d : get_nwa(%d)=%d, d=%d , demand=%.f , cap=%.f\n", tnum+1, nwa, ret, d->nwa, (double) burn_track_get_sectors_2(t, 1) * 2048.0, (double) d->media_capacity_remaining); libdax_msgs_submit(libdax_messenger, d->global_index, 0x00000002, LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_ZERO, msg, 0, 0); /* ts A91003 */ if (nwa < d->nwa) { libdax_msgs_submit(libdax_messenger, d->global_index, 0x00020173, LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH, "Drive tells NWA smaller than last written address", 0, 0); d->sync_cache(d); return 0; } d->nwa = nwa; } /* user data */ sectors = burn_track_get_sectors_2(t, 1); open_ended = burn_track_is_open_ended(t); burn_disc_init_track_status(o, s, t, tnum, sectors); /* ts A61030 : this cannot happen. tnum is always < s->tracks */ if (tnum == s->tracks) tmp = sectors > 150 ? 150 : sectors; for (i = 0; open_ended || i < sectors - tmp; i++) { /* ts A61023 : http://libburn.pykix.org/ticket/14 From time to time inquire drive buffer */ if ((i%64)==0) d->read_buffer_capacity(d); if (!sector_data(o, t, 0)) { ret = 0; goto ex; } /* ts A61031 */ if (open_ended) { d->progress.sectors = sectors = i; if (burn_track_is_data_done(t)) break; } /* update current progress */ d->progress.sector++; } for (; i < sectors; i++) { /* ts A61030: program execution never gets to this point */ fprintf(stderr,"LIBBURN_DEBUG: TNUM=%d TRACKS=%d TMP=%d\n", tnum, s->tracks, tmp); /* ts A61023 */ if ((i%64)==0) d->read_buffer_capacity(d); if (!sector_data(o, t, 1)) { ret = 0; goto ex; } /* update progress */ d->progress.sector++; } /* ts B20113 : Flush buffer to get buffered bytes assigned to the track counter */ ret = sector_write_buffer(d, t, 0); if (ret <= 0) goto ex; if (t->postgap && o->write_type != BURN_WRITE_TAO) { for (i = 0; i < t->postgap_size; i++) if (!sector_postgap(o, t->entry->point, t->entry->control, t->mode)) { ret = 0; goto ex; } ret = sector_write_buffer(d, NULL, 0); if (ret <= 0) goto ex; } /* ts A61103 */ ret = 1; ex:; if (d->cancel) burn_source_cancel(t->source); if (o->write_type == BURN_WRITE_TAO) { /* ts A71002 */ if (!burn_write_flush_buffer(o, t)) ret = 0; /* Ensure that at least 600 kB get written */ burn_write_track_minsize(o, s, tnum); d->sync_cache(d); /* ts A61030 */ /* ts A91003 : At least in simulation mode this causes NWA=0 for the next track. cdrecord does not use CLOSE TRACK at all but ends the tracks by SYNCHRONIZE CACHE alone. */ /* ts A91202 : Peng Shao reports that his LG GH22LS30 issues an SCSI error on CLOSE TRACK even in non-dummy mode. So i better give up this gesture which seems not be needed by any drive. if (!o->simulate) if (burn_write_close_track(o, s, tnum) <= 0) ret = 0; */ } return ret; } /* ts A61009 */ /* @param flag bit1 = do not libdax_msgs_submit() */ int burn_disc_write_is_ok(struct burn_write_opts *o, struct burn_disc *disc, int flag) { int i, t; char msg[80]; for (i = 0; i < disc->sessions; i++) for (t = 0; t < disc->session[i]->tracks; t++) if (sector_headers_is_ok( o, disc->session[i]->track[t]->mode) != 1) goto bad_track_mode_found; return 1; bad_track_mode_found:; sprintf(msg, "Unsuitable track mode 0x%x in track %d of session %d", disc->session[i]->track[t]->mode, i+1, t+1); if (!(flag & 2)) libdax_msgs_submit(libdax_messenger, -1, 0x0002010a, LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH, msg, 0, 0); return 0; } /* ts A61218 : outsourced from burn_disc_write_sync() */ int burn_disc_init_write_status(struct burn_write_opts *o, struct burn_disc *disc) { struct burn_drive *d = o->drive; struct burn_track *t = NULL; int sx, tx, ret; d->cancel = 0; #ifdef Libburn_reset_progress_asynC /* <<< This is now done in async.c */ /* init progress before showing the state */ d->progress.session = 0; d->progress.sessions = disc->sessions; d->progress.track = 0; d->progress.tracks = disc->session[0]->tracks; /* TODO: handle indices */ d->progress.index = 0; d->progress.indices = disc->session[0]->track[0]->indices; /* TODO: handle multissession discs */ /* XXX: sectors are only set during write track */ d->progress.start_sector = 0; d->progress.sectors = 0; d->progress.sector = 0; d->progress.track = 0; #endif /* Libburn_reset_progress_asynC */ /* ts A61023 */ d->progress.buffer_capacity = 0; d->progress.buffer_available = 0; d->progress.buffered_bytes = 0; d->progress.buffer_min_fill = 0xffffffff; /* ts A70711 */ d->pessimistic_buffer_free = 0; d->pbf_altered = 0; d->pessimistic_writes = 0; d->waited_writes = 0; d->waited_tries = 0; d->waited_usec = 0; /* Set eventual media fill up for last track only */ for (sx = 0; sx < disc->sessions; sx++) for (tx = 0 ; tx < disc->session[sx]->tracks; tx++) { t = disc->session[sx]->track[tx]; burn_track_set_fillup(t, 0); } if (o->fill_up_media && t != NULL) burn_track_set_fillup(t, 1); d->was_feat21h_failure = 0; if(d->write_opts != NULL) burn_write_opts_free(d->write_opts); ret = burn_write_opts_clone(o, &(d->write_opts), 0); if (ret <= 0) return ret; d->busy = BURN_DRIVE_WRITING; return 1; } static int precheck_write_is_audio(struct burn_disc *disc, int flag) { struct burn_session **sessions; int num_sessions, i, j; sessions = burn_disc_get_sessions(disc, &num_sessions); for (i = 0; i < num_sessions; i++) for (j = 0; j < sessions[i]->tracks; j++) if (!(sessions[i]->track[j]->mode & BURN_AUDIO)) return 0; return 1; } static int precheck_disc_has_cdtext(struct burn_disc *disc, int flag) { struct burn_session **sessions; int num_sessions, i, ret; sessions = burn_disc_get_sessions(disc, &num_sessions); for (i = 0; i < num_sessions; i++) { ret = burn_cdtext_from_session(sessions[i], NULL, NULL, 1); if (ret > 0) return 1; } return 0; } /* ts A70219 : API */ int burn_precheck_write(struct burn_write_opts *o, struct burn_disc *disc, char reasons[BURN_REASONS_LEN], int silent) { enum burn_write_types wt; struct burn_drive *d = o->drive; char *msg = NULL, *reason_pt; int no_media = 0, ret, has_cdtext; reason_pt= reasons; reasons[0] = 0; if (d->drive_role == 0 || d->drive_role == 4) { if (d->drive_role == 0) sprintf(reasons, "DRIVE: is a virtual placeholder (null-drive)"); else sprintf(reasons, "DRIVE: read-only pseudo drive"); no_media = 1; goto ex; } /* check write mode against write job */ wt = burn_write_opts_auto_write_type(o, disc, reasons, 1); if (wt == BURN_WRITE_NONE) { if (strncmp(reasons, "MEDIA: ", 7)==0) no_media = 1; goto ex; } sprintf(reasons, "%s: ", d->current_profile_text); reason_pt= reasons + strlen(reasons); if (d->status == BURN_DISC_UNSUITABLE) goto unsuitable_profile; if (o->num_text_packs > 0) { has_cdtext = 1; } else { has_cdtext = precheck_disc_has_cdtext(disc, 0); } if (has_cdtext > 0) { if (d->current_profile == 0x09 || d->current_profile == 0x0a) { ret = precheck_write_is_audio(disc, 0); if (ret <= 0) strcat(reasons, "CD-TEXT supported only with pure audio CD media, "); } else { strcat(reasons, "CD-TEXT supported only with CD media, "); } } if (d->drive_role == 2 || d->drive_role == 5 || d->current_profile == 0x1a || d->current_profile == 0x12 || d->current_profile == 0x43) { /* DVD+RW , DVD-RAM , BD-RE, emulated drive on stdio file */ if (o->start_byte >= 0 && (o->start_byte % 2048)) strcat(reasons, "write start address not properly aligned to 2048, "); } else if (d->current_profile == 0x09 || d->current_profile == 0x0a) { /* CD-R , CD-RW */ if (!burn_disc_write_is_ok(o, disc, (!!silent) << 1)) strcat(reasons, "unsuitable track mode found, "); if (o->start_byte >= 0) strcat(reasons, "write start address not supported, "); if (o->num_text_packs > 0) { if (o->write_type != BURN_WRITE_SAO) strcat(reasons, "CD-TEXT supported only with write type SAO, "); if (d->start_lba == -2000000000) strcat(reasons, "No Lead-in start address known with CD-TEXT, "); } } else if (d->current_profile == 0x13) { /* DVD-RW Restricted Overwrite */ if (o->start_byte >= 0 && (o->start_byte % 32768)) strcat(reasons, "write start address not properly aligned to 32k, "); } else if (d->drive_role == 3 || d->current_profile == 0x11 || d->current_profile == 0x14 || d->current_profile == 0x15 || d->current_profile == 0x1b || d->current_profile == 0x2b || d->current_profile == 0x41) { /* DVD-R* Sequential , DVD+R[/DL] , BD-R, sequential stdio "drive" */ if (o->start_byte >= 0) strcat(reasons, "write start address not supported, "); } else { unsuitable_profile:; msg = calloc(1, 160); if (msg != NULL && !silent) { sprintf(msg, "Unsuitable media detected. Profile %4.4Xh %s", d->current_profile, d->current_profile_text); libdax_msgs_submit(libdax_messenger, d->global_index, 0x0002011e, LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH, msg, 0, 0); } if (msg != NULL) free(msg); strcat(reasons, "no suitable media profile detected, "); return 0; } ex:; if (reason_pt[0]) { if (no_media) { if (!silent) libdax_msgs_submit(libdax_messenger, d->global_index, 0x0002013a, LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH, "No suitable media detected", 0, 0); return -1; } if (!silent) libdax_msgs_submit(libdax_messenger, d->global_index, 0x00020139, LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH, "Write job parameters are unsuitable", 0, 0); return 0; } return 1; } /* ts A70129 : learned much from dvd+rw-tools-7.0/growisofs_mmc.cpp */ int burn_disc_open_track_dvd_minus_r(struct burn_write_opts *o, struct burn_session *s, int tnum) { struct burn_drive *d = o->drive; char *msg = NULL; int ret, lba, nwa; off_t size; BURN_ALLOC_MEM(msg, char, 160); d->send_write_parameters(d, NULL, -1, o); ret = d->get_nwa(d, -1, &lba, &nwa); sprintf(msg, "DVD pre-track %2.2d : get_nwa(%d), ret= %d , d->nwa= %d", tnum+1, nwa, ret, d->nwa); libdax_msgs_submit(libdax_messenger, d->global_index, 0x00000002, LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_ZERO, msg,0,0); if (nwa > d->nwa) d->nwa = nwa; /* ts A70214 : eventually adjust already expanded size of track */ burn_track_apply_fillup(s->track[tnum], d->media_capacity_remaining,1); #ifdef Libburn_pioneer_dvr_216d_with_opC fprintf(stderr, "libburn_DEBUG: Libburn_pioneer_dvr_216d_with_opC : num_opc_tables = %d\n", d->num_opc_tables); if (d->num_opc_tables <= 0 && !o->simulate) { fprintf(stderr, "libburn_DEBUG: Libburn_pioneer_dvr_216d_with_opC : performing OPC\n"); d->perform_opc(d); fprintf(stderr, "libburn_DEBUG: Libburn_pioneer_dvr_216d_with_opC : done\n"); } #endif #ifdef Libburn_pioneer_dvr_216d_get_evenT mmc_get_event(d); #endif if (o->write_type == BURN_WRITE_SAO) { /* DAO */ size = ((off_t) burn_track_get_sectors_2(s->track[tnum], 1)) * (off_t) 2048; /* Eventually round track size up to write chunk */ if (o->obs_pad && (size % o->obs)) size += (off_t) (o->obs - (size % o->obs)); ret = d->reserve_track(d, size); if (ret <= 0) { sprintf(msg, "Cannot reserve track of %.f bytes", (double) size); libdax_msgs_submit(libdax_messenger, d->global_index, 0x00020138, LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH, msg, 0, 0); {ret = 0; goto ex;} } } ret = 1; ex:; BURN_FREE_MEM(msg); return ret; } /* ts A70226 */ int burn_disc_open_track_dvd_plus_r(struct burn_write_opts *o, struct burn_session *s, int tnum) { struct burn_drive *d = o->drive; char *msg = NULL; int ret, lba, nwa; off_t size; BURN_ALLOC_MEM(msg, char, 160); ret = d->get_nwa(d, -1, &lba, &nwa); sprintf(msg, "DVD+R pre-track %2.2d : get_nwa(%d), ret= %d , d->nwa= %d", tnum+1, nwa, ret, d->nwa); libdax_msgs_submit(libdax_messenger, d->global_index, 0x00000002, LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_ZERO, msg,0,0); if (nwa > d->nwa) d->nwa = nwa; /* ts A70214 : eventually adjust already expanded size of track */ burn_track_apply_fillup(s->track[tnum], d->media_capacity_remaining,1); if (o->write_type == BURN_WRITE_SAO && ! burn_track_is_open_ended(s->track[tnum])) { /* Reserve track */ size = ((off_t) burn_track_get_sectors_2(s->track[tnum], 1)) * (off_t) 2048; if (o->obs_pad) { /* Round track size up to write chunk size */ /* o->obs should be 32k or 64k already. But 32k alignment was once performed in d->reserve_track()*/ if (o->obs % 32768) o->obs += 32768 - (o->obs % 32768); if (size % o->obs) size += (off_t) (o->obs - (size % o->obs)); } /* <<< Only for now until the first DVD+R succeeded */ if (!o->obs_pad) { sprintf(msg, "Program error: encountered DVD+R without chunk padding"); libdax_msgs_submit(libdax_messenger, d->global_index, 0x00000004, LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH, msg, 0, 0); {ret = 0; goto ex;} } ret = d->reserve_track(d, size); if (ret <= 0) { sprintf(msg, "Cannot reserve track of %.f bytes", (double) size); libdax_msgs_submit(libdax_messenger, d->global_index, 0x00020138, LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH, msg, 0, 0); {ret = 0; goto ex;} } } ret = 1; ex:; BURN_FREE_MEM(msg); return ret; } /* ts A70129 */ int burn_disc_close_track_dvd_minus_r(struct burn_write_opts *o, int tnum) { struct burn_drive *d = o->drive; char msg[80]; /* only with Incremental writing */ if (o->write_type != BURN_WRITE_TAO) return 2; sprintf(msg, "Closing track %2.2d (absolute track number %d)", tnum + 1, d->last_track_no); libdax_msgs_submit(libdax_messenger, o->drive->global_index,0x00020119, LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH, msg,0,0); d->busy = BURN_DRIVE_CLOSING_SESSION; /* Ignoring tnum here and hoping that d->last_track_no is correct */ d->close_track_session(d, 0, d->last_track_no); /* CLOSE TRACK, 001b */ d->busy = BURN_DRIVE_WRITING; d->last_track_no++; return 1; } /* ts A70229 */ int burn_disc_finalize_dvd_plus_r(struct burn_write_opts *o) { struct burn_drive *d = o->drive; char msg[80]; sprintf(msg, "Finalizing %s ...", d->current_profile_text); libdax_msgs_submit(libdax_messenger, d->global_index, 0x00000002, LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_ZERO, msg, 0, 0); if(d->current_profile == 0x41) { /* BD-R */ /* CLOSE SESSION, 110b, Finalize Disc */ d->close_track_session(d, 3, 0); /* (3<<1)|0 = 6 */ } else { /* CLOSE SESSION, 101b, Finalize with minimal radius */ d->close_track_session(d, 2, 1); /* (2<<1)|1 = 5 */ } sprintf(msg, "... finalizing %s done ", d->current_profile_text); libdax_msgs_submit(libdax_messenger, d->global_index, 0x00000002, LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_ZERO, msg, 0, 0); return 1; } /* ts A70226 */ int burn_disc_close_track_dvd_plus_r(struct burn_write_opts *o, int tnum, int is_last_track) { struct burn_drive *d = o->drive; char msg[80]; sprintf(msg, "Closing track %2.2d (absolute track and session number %d)", tnum + 1, d->last_track_no); libdax_msgs_submit(libdax_messenger, o->drive->global_index,0x00020119, LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH, msg,0,0); d->busy = BURN_DRIVE_CLOSING_SESSION; d->close_track_session(d, 0, d->last_track_no); /* CLOSE TRACK, 001b */ /* Each session becomes a single logical track. So to distinguish them, it is mandatory to close the session together with each track. */ if (is_last_track && !o->multi) burn_disc_finalize_dvd_plus_r(o); else d->close_track_session(d, 1, 0); /* CLOSE SESSION, 010b */ d->busy = BURN_DRIVE_WRITING; d->last_track_no++; return 1; } /* <<< #define Libburn_simplified_dvd_chunk_transactioN 1 */ #ifdef Libburn_simplified_dvd_chunk_transactioN /* ts A91114 : EXPERIMENTAL, NOT COMPLETELY IMPLEMENTED Simplified data transmission for DVD. libburn via GNU/Linux USB is 30 % slower than growisofs or cdrecord when transmitting 32 KB chunks. With 64 KB chunks it is 20% faster than the competitors. No heavy CPU load is visible but there might be subtle race conditions in the USB driver which work better with shorter time gaps between WRITE commands. Insight: It is actually about the interference of track source reading with SCSI writing via USB. growisofs reads with O_DIRECT into a mmap()ed buffer. When doing the same, libburn with 32 KB chunks reaches similar write speed. On the other hand, 64 KB chunks are 20% faster than that and are not improved by reading O_DIRECT. O_DIRECT is a property of the input fd of struct burn_source. It can only be done with properly aligned memory and with aligned read size. Alignment size is file system system specific. System call mmap(NULL, (size_t) buffer_size, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, (off_t) 0); is supposed to allocate a properly aligned buffer. 64 KB is supposed to be a safe size. Actually mmap() seems to be the main cause for a positive effect of O_DIRECT. This simplified transmission function did not bring visible benefit. So for now it is not worth to teach it all applicable details of old CD sector oriented transmission. @return 1= ok, go on , 2= no input with track->open_ended = nothing written <= 0 = error */ static int transact_dvd_chunk(struct burn_write_opts *opts, struct burn_track *track) { int curr = 0, valid, err; struct burn_drive *d = opts->drive; struct buffer *out = d->buffer; unsigned char *data = out->data; #ifdef Libburn_log_in_and_out_streaM /* ts A61031 */ static int tee_fd= -1; if(tee_fd==-1) tee_fd= open("/tmp/libburn_sg_readin", O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, S_IRUSR | S_IWUSR); #endif /* Libburn_log_in_and_out_streaM */ /* Read a chunk full of data */ /* ??? Do we have offset padding ? >>> First produce offset padding */; /* <<<< */ if (0 && !track->eos) { for (curr = 0; curr < opts->obs; curr += 2048) { if (track->source->read != NULL) valid = track->source->read(track->source, data + curr, 2048); else valid = track->source->read_xt(track->source, data + curr, 2048); if (valid <= 0) { track->eos = 1; break; } track->sourcecount += valid; #ifdef Libburn_log_in_and_out_streaM if(tee_fd!=-1 && valid>0) { write(tee_fd, data + curr, valid); } #endif /* Libburn_log_in_and_out_streaM */ } } else if (!track->eos){ valid = track->source->read(track->source, data, opts->obs); if (valid <= 0) { track->eos = 1; } else { track->sourcecount += valid; curr = valid; #ifdef Libburn_log_in_and_out_streaM if(tee_fd!=-1 && valid>0) { write(tee_fd, data, valid); } #endif /* Libburn_log_in_and_out_streaM */ } } if (curr == 0 && track->open_ended) { /* >>> allow tail padding */; return 2; } if (curr < opts->obs) memset(data + curr , 0, opts->obs - curr); /* Write chunk */ out->bytes = opts->obs; out->sectors = out->bytes / 2048; err = d->write(d, d->nwa, out); if (err == BE_CANCELLED) return 0; track->writecount += out->bytes; track->written_sectors += out->sectors; d->progress.buffered_bytes += out->bytes; d->nwa += out->sectors; out->bytes = 0; out->sectors = 0; return 1; } #endif /* Libburn_simplified_dvd_chunk_transactioN */ /* ts A61218 - A81208 */ int burn_dvd_write_track(struct burn_write_opts *o, struct burn_session *s, int tnum, int is_last_track) { struct burn_track *t = s->track[tnum]; struct burn_drive *d = o->drive; struct buffer *out = d->buffer; int sectors; int i, open_ended = 0, ret= 0, is_flushed = 0, track_open = 0; int first_buf_cap = 0, further_cap = 0, buf_cap_step = 1024; /* ts A70213 : eventually expand size of track to max */ burn_track_apply_fillup(t, d->media_capacity_remaining, 0); if (d->current_profile == 0x11 || d->current_profile == 0x14 || d->current_profile == 0x15) { /* DVD-R, DVD-RW Sequential, DVD-R/DL Sequential */ ret = burn_disc_open_track_dvd_minus_r(o, s, tnum); if (ret <= 0) goto ex; /* Pioneer DVR-216D rev 1.09 hates multiple buffer inquiries before the drive buffer is full. */ first_buf_cap = 0; further_cap = -1; } else if (d->current_profile == 0x1b || d->current_profile == 0x2b) { /* DVD+R , DVD+R/DL */ ret = burn_disc_open_track_dvd_plus_r(o, s, tnum); if (ret <= 0) goto ex; } else if (d->current_profile == 0x41) { /* BD-R SRM */ ret = burn_disc_open_track_dvd_plus_r(o, s, tnum); if (ret <= 0) goto ex; } track_open = 1; sectors = burn_track_get_sectors_2(t, 1); open_ended = burn_track_is_open_ended(t); /* (offset padding is done within sector_data()) */ burn_disc_init_track_status(o, s, t, tnum, sectors); for (i = 0; open_ended || i < sectors; i++) { /* From time to time inquire drive buffer */ /* ts A91110: Eventually avoid to do this more than once before the drive buffer is full. See above DVD- */ if (i == first_buf_cap || ((i % buf_cap_step) == 0 && (i >= further_cap || further_cap < 0))) { d->read_buffer_capacity(d); if (further_cap < 0) further_cap = d->progress.buffer_capacity / 2048 + 128; } #ifdef Libburn_simplified_dvd_chunk_transactioN ret = transact_dvd_chunk(o, t); if (ret <= 0) {ret = 0; goto ex;} i += o->obs / 2048 - 1; d->progress.sector += o->obs / 2048 - 1; #else /* transact a (CD sized) sector */ if (!sector_data(o, t, 0)) { ret = 0; goto ex; } #endif if (open_ended) { d->progress.sectors = sectors = i; if (burn_track_is_data_done(t)) break; } /* update current progress */ d->progress.sector++; } /* (tail padding is done in sector_data()) */ /* Pad up buffer to next full o->obs (usually 32 kB) */ if (o->obs_pad && out->bytes > 0 && out->bytes < o->obs) { memset(out->data + out->bytes, 0, o->obs - out->bytes); out->sectors += (o->obs - out->bytes) / 2048; out->bytes = o->obs; } ret = burn_write_flush(o, t); if (ret <= 0) goto ex; is_flushed = 1; /* Eventually finalize track */ if (d->current_profile == 0x11 || d->current_profile == 0x14 || d->current_profile == 0x15) { /* DVD-R, DVD-RW Sequential, DVD-R/DL Sequential */ ret = burn_disc_close_track_dvd_minus_r(o, tnum); if (ret <= 0) goto ex; } else if (d->current_profile == 0x1b || d->current_profile == 0x2b) { /* DVD+R , DVD+R/DL */ ret = burn_disc_close_track_dvd_plus_r(o, tnum, is_last_track); if (ret <= 0) goto ex; } else if (d->current_profile == 0x41) { /* BD-R SRM */ ret = burn_disc_close_track_dvd_plus_r(o, tnum, is_last_track); if (ret <= 0) goto ex; } ret = 1; ex:; if (d->cancel) burn_source_cancel(t->source); if (track_open && !is_flushed) d->sync_cache(d); /* burn_write_flush() was not called */ return ret; } /* ts A61219 */ int burn_disc_close_session_dvd_plus_rw(struct burn_write_opts *o, struct burn_session *s) { struct burn_drive *d = o->drive; d->busy = BURN_DRIVE_CLOSING_SESSION; /* This seems to be a quick end : "if (!dvd_compat)" */ /* >>> Stop de-icing (ongoing background format) quickly by mmc_close() (but with opcode[2]=0). Wait for unit to get ready. return 1; */ /* Else: end eventual background format in a "DVD-RO" compatible way */ d->close_track_session(d, 1, 0); /* same as CLOSE SESSION for CD */ d->busy = BURN_DRIVE_WRITING; return 1; } /* ts A61228 */ int burn_disc_close_session_dvd_minus_rw(struct burn_write_opts *o, struct burn_session *s) { struct burn_drive *d = o->drive; d->busy = BURN_DRIVE_CLOSING_SESSION; if (d->current_profile == 0x13) { d->close_track_session(d, 1, 0); /* CLOSE SESSION, 010b */ /* ??? under what circumstances to use close functiom 011b "Finalize disc" ? */ } d->busy = BURN_DRIVE_WRITING; return 1; } /* ts A70129 : for profile 0x11 DVD-R, 0x14 DVD-RW Seq, 0x15 DVD-R/DL Seq */ int burn_disc_close_session_dvd_minus_r(struct burn_write_opts *o) { struct burn_drive *d = o->drive; /* only for Incremental writing */ if (o->write_type != BURN_WRITE_TAO) return 2; #ifdef Libburn_dvd_r_dl_multi_no_close_sessioN if (d->current_profile == 0x15 && o->multi) return 2; #endif libdax_msgs_submit(libdax_messenger, o->drive->global_index,0x00020119, LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH, "Closing session", 0, 0); d->busy = BURN_DRIVE_CLOSING_SESSION; d->close_track_session(d, 1, 0); /* CLOSE SESSION, 010b */ d->busy = BURN_DRIVE_WRITING; return 1; } /* ts A61218 */ int burn_dvd_write_session(struct burn_write_opts *o, struct burn_session *s, int is_last_session) { int i, ret, multi_mem; struct burn_drive *d = o->drive; /* ts A90108 */ if (d->current_profile == 0x41 && d->status == BURN_DISC_APPENDABLE && d->state_of_last_session == 1) { /* last session on BD-R is still open */; /* BR-R were not closed by libburn-0.6.0.pl00 if o->multi==0. This leads to an unreadable, but recoverable) media state. Technically they are appendable although the last session is not readable. By default the open session gets closed here before the new session is written. E.g. after writing a small dummy seesion number 2 one can read session 1 and write session 3 which points to data of session 1. For the case that no media with 3 sessions is desired it is possible to activate the following coarse single-session closing code: No new session will be written but calling programs will report success. Quite misleading. Activate only if really needed by # define Libburn_bug_A90108_close_disC yes */ #ifdef Libburn_bug_A90108_close_disC /* Close open session and media. That was the goal of the failed run which led to the unreadable (but recoverable) media state. It is not easy to implement a general close function for all media types. Therefore this pseudo write code is under control of #ifdef. */ libdax_msgs_submit(libdax_messenger, d->global_index, 0x00020171, LIBDAX_MSGS_SEV_NOTE, LIBDAX_MSGS_PRIO_HIGH, "Closing BD-R with accidently open session", 0, 0); d->close_track_session(d, 3, 0); /* CLOSE SESSION, 110b */ d->state_of_last_session = 3; /* mark as complete session */ d->status = BURN_DISC_FULL; sleep(3); /* The caller might need time to arrange itself */ return 1; #else /* Libburn_bug_A90108_close_disC */ /* This is the default mode. */ libdax_msgs_submit(libdax_messenger, d->global_index, 0x00020170, LIBDAX_MSGS_SEV_NOTE, LIBDAX_MSGS_PRIO_HIGH, "Closing open session before writing new one", 0, 0); d->close_track_session(d, 1, 0); /* CLOSE SESSION, 010b */ d->state_of_last_session = 3; /* mark as complete session */ #endif /* ! Libburn_bug_A90108_close_disC */ } for (i = 0; i < s->tracks; i++) { ret = burn_dvd_write_track(o, s, i, is_last_session && i == (s->tracks - 1)); if (ret <= 0) break; } if (d->current_profile == 0x11 || d->current_profile == 0x14 || d->current_profile == 0x15) { /* DVD-R , DVD-RW Sequential, DVD-R/DL Sequential */ /* If feature 21h failed on write 0: do not close session */ if (d->was_feat21h_failure != 2) { multi_mem = o->multi; if (!is_last_session) o->multi = 1; ret = burn_disc_close_session_dvd_minus_r(o); o->multi = multi_mem; if (ret <= 0) return 0; } } else if (d->current_profile == 0x12 || d->current_profile == 0x43) { /* DVD-RAM , BD-RE */ /* ??? any finalization needed ? */; } else if (d->current_profile == 0x13) { /* DVD-RW restricted overwrite */ if (d->needs_close_session) { ret = burn_disc_close_session_dvd_minus_rw(o, s); if (ret <= 0) return 0; } } else if (d->current_profile == 0x1a) { /* DVD+RW */ if (d->needs_close_session) { ret = burn_disc_close_session_dvd_plus_rw(o, s); if (ret <= 0) return 0; } } else if (d->current_profile == 0x1b || d->current_profile == 0x2b) { /* DVD+R , DVD+R/DL do each track as an own session */; } else if (d->current_profile == 0x41) { /* BD-R SRM do each track as an own session */; } return 1; } /* ts A61218 : learned much from dvd+rw-tools-7.0/growisofs_mmc.cpp */ int burn_disc_setup_dvd_plus_rw(struct burn_write_opts *o, struct burn_disc *disc) { struct burn_drive *d = o->drive; int ret; if (d->bg_format_status==0 || d->bg_format_status==1) { d->busy = BURN_DRIVE_FORMATTING; /* start or re-start dvd_plus_rw formatting */ ret = d->format_unit(d, (off_t) 0, 0); if (ret <= 0) return 0; d->busy = BURN_DRIVE_WRITING; d->needs_close_session = 1; } /* >>> perform OPC if needed */; /* >>> ? what else ? */; return 1; } /* ts A61228 : learned much from dvd+rw-tools-7.0/growisofs_mmc.cpp */ int burn_disc_setup_dvd_minus_rw(struct burn_write_opts *o, struct burn_disc *disc) { struct burn_drive *d = o->drive; char msg[60]; int ret; d->nwa = 0; if (o->start_byte >= 0) { d->nwa = o->start_byte / 32768; /* align to 32 kB */ sprintf(msg, "Write start address is %d * 32768", d->nwa); libdax_msgs_submit(libdax_messenger, d->global_index, 0x00020127, LIBDAX_MSGS_SEV_NOTE, LIBDAX_MSGS_PRIO_HIGH, msg, 0, 0); d->nwa *= 16; /* convert to 2048 block units */ } /* ??? mmc5r03c.pdf 7.5.2 : "For DVD-RW media ... If a medium is in Restricted overwrite mode, this mode page shall not be used." But growisofs composes a page 5 and sends it. mmc5r03c.pdf 5.3.16 , table 127 specifies that mode page 5 shall be supported with feature 0026h Restricted Overwrite. 5.3.22 describes a feature 002Ch Rigid Restrictive Overwrite which seems to apply to DVD-RW and does not mention page 5. 5.4.14 finally states that profile 0013h includes feature 002Ch rather than 0026h. d->send_write_parameters(d, NULL, -1, o); */ d->busy = BURN_DRIVE_FORMATTING; /* "quick grow" to at least byte equivalent of d->nwa */ ret = d->format_unit(d, (off_t) d->nwa * (off_t) 2048, (d->nwa > 0) << 3); if (ret <= 0) return 0; d->busy = BURN_DRIVE_WRITING; /* >>> perform OPC if needed */; return 1; } /* ts A70129 : for DVD-R[W] Sequential Recoding */ int burn_disc_setup_dvd_minus_r(struct burn_write_opts *o, struct burn_disc *disc) { struct burn_drive *d = o->drive; /* most setup is in burn_disc_setup_track_dvd_minus_r() */; d->nwa = 0; return 1; } /* ts A70226 : for DVD+R , DVD+R/DL */ int burn_disc_setup_dvd_plus_r(struct burn_write_opts *o, struct burn_disc *disc) { struct burn_drive *d = o->drive; /* most setup is in burn_disc_setup_track_dvd_plus_r() */; d->nwa = 0; return 1; } /* ts A61218 - A70415 */ int burn_dvd_write_sync(struct burn_write_opts *o, struct burn_disc *disc) { int i, ret, o_end; off_t default_size = 0; struct burn_drive *d = o->drive; struct burn_track *t; char *msg = NULL; BURN_ALLOC_MEM(msg, char, 160); d->needs_close_session = 0; /* buffer flush trigger for sector.c:get_sector() */ o->obs = Libburn_dvd_obS; if (d->current_profile == 0x1a || d->current_profile == 0x12 || d->current_profile == 0x43) { /* DVD+RW , DVD-RAM , BD-RE */ ret = 1; if (d->current_profile == 0x1a) ret = burn_disc_setup_dvd_plus_rw(o, disc); if (ret <= 0) { sprintf(msg, "Write preparation setup failed for DVD+RW"); libdax_msgs_submit(libdax_messenger, d->global_index, 0x00020121, LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH, msg, 0, 0); goto early_failure; } d->nwa = 0; if (o->start_byte >= 0) { d->nwa = o->start_byte / 2048; sprintf(msg, "Write start address is %d * 2048", d->nwa); libdax_msgs_submit(libdax_messenger, d->global_index, 0x00020127, LIBDAX_MSGS_SEV_NOTE, LIBDAX_MSGS_PRIO_HIGH, msg, 0, 0); } if (o->obs_pad < 2) o->obs_pad = 0; /* no filling-up of last 32k buffer */ if (d->current_profile == 0x43) /* BD-RE */ o->obs = Libburn_bd_re_obS; if (d->do_stream_recording) { if (o->obs_pad < 2) o->obs_pad = 1; if (d->current_profile == 0x43) /* BD-RE */ o->obs = Libburn_bd_streamed_obS; } } else if (d->current_profile == 0x13) { /* DVD-RW Restricted Overwrite */ ret = burn_disc_setup_dvd_minus_rw(o, disc); if (ret <= 0) { sprintf(msg, "Write preparation setup failed for DVD-RW"); libdax_msgs_submit(libdax_messenger, d->global_index, 0x00020121, LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH, msg, 0, 0); goto early_failure; } /* _Rigid_ Restricted Overwrite demands this */ o->obs_pad = 1; /* fill-up track's last 32k buffer */ } else if (d->current_profile == 0x11 || d->current_profile == 0x14 || d->current_profile == 0x15) { /* DVD-R , DVD-RW Sequential , DVD-R/DL Sequential */ t = disc->session[0]->track[0]; o_end = ( burn_track_is_open_ended(t) && !o->fill_up_media ); default_size = burn_track_get_default_size(t); if (o->write_type == BURN_WRITE_SAO && o_end) { sprintf(msg, "Activated track default size %.f", (double) default_size); libdax_msgs_submit(libdax_messenger, d->global_index, 0x0002012e, LIBDAX_MSGS_SEV_NOTE, LIBDAX_MSGS_PRIO_HIGH, msg, 0, 0); burn_track_set_size(t, default_size); } /* Whether to fill-up last 32k buffer of track. */ if (o->obs_pad < 2) o->obs_pad = (o->write_type != BURN_WRITE_SAO); ret = burn_disc_setup_dvd_minus_r(o, disc); if (ret <= 0) { sprintf(msg, "Write preparation setup failed for DVD-R[W]"); libdax_msgs_submit(libdax_messenger, d->global_index, 0x00020121, LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH, msg, 0, 0); goto early_failure; } } else if (d->current_profile == 0x1b || d->current_profile == 0x2b || d->current_profile == 0x41) { /* DVD+R , DVD+R/DL , BD-R SRM */ /* >>> ts A81208 : with BD-R set o->obs to 64 kB ? */ t = disc->session[0]->track[0]; o_end = ( burn_track_is_open_ended(t) && !o->fill_up_media ); default_size = burn_track_get_default_size(t); if (o->write_type == BURN_WRITE_SAO && o_end) { sprintf(msg, "Activated track default size %.f", (double) default_size); libdax_msgs_submit(libdax_messenger, d->global_index, 0x0002012e, LIBDAX_MSGS_SEV_NOTE, LIBDAX_MSGS_PRIO_HIGH, msg, 0, 0); burn_track_set_size(t, default_size); } ret = burn_disc_setup_dvd_plus_r(o, disc); if (ret <= 0) { sprintf(msg, "Write preparation setup failed for %s", d->current_profile == 0x41 ? "BD-R" : "DVD+R"); libdax_msgs_submit(libdax_messenger, d->global_index, 0x00020121, LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH, msg, 0, 0); goto early_failure; } /* ??? padding needed ??? cowardly doing it for now */ if (o->obs_pad < 2) o->obs_pad = 1; /* fill-up track's last obs buffer */ if (d->current_profile == 0x41) /* BD-R */ o->obs = Libburn_bd_r_obS; if (d->do_stream_recording) { if (d->current_profile == 0x41) /* BD-R */ o->obs = Libburn_bd_streamed_obS; } } #ifdef Libburn_dvd_obs_default_64K o->obs = 64 * 1024; #endif /* <<< test only : Does this increase effective speed with USB ? ts A90801 : 64kB: speed with 16x DVD-R is 12 rather than 8 128kB: glibc complains about double free With BURN_OS_TRANSPORT_BUFFER_SIZE enlarged to 128 MB, the first WRITE fails with an i/o error. o->obs = 64 * 1024; */ if (o->dvd_obs_override >= 32 * 1024) o->obs = o->dvd_obs_override; if (o->obs > BUFFER_SIZE) { sprintf(msg, "Chosen write chunk size %d exceeds system dependent buffer size", o->obs); libdax_msgs_submit(libdax_messenger, d->global_index, 0x00000002, LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_ZERO, msg, 0, 0); o->obs = 32 * 1024; /* This size is required to work */ } if (d->do_stream_recording && (d->current_profile == 0x43 || d->current_profile == 0x41) && o->obs < Libburn_bd_streamed_obS) { /* LG GGW-H20 writes junk with stream recording and obs=32k */ sprintf(msg, "Stream recording disabled because of small output buffer"); libdax_msgs_submit(libdax_messenger, d->global_index, 0x00020176, LIBDAX_MSGS_SEV_NOTE, LIBDAX_MSGS_PRIO_HIGH, msg, 0, 0); d->do_stream_recording = 0; } sprintf(msg, "dvd/bd Profile= %2.2Xh , obs= %d , obs_pad= %d", d->current_profile, o->obs, o->obs_pad); libdax_msgs_submit(libdax_messenger, d->global_index, 0x00000002, LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_ZERO, msg, 0, 0); for (i = 0; i < disc->sessions; i++) { /* update progress */ d->progress.session = i; d->progress.tracks = disc->session[i]->tracks; ret = burn_dvd_write_session(o, disc->session[i], i == (disc->sessions - 1)); if (ret <= 0) goto ex; /* XXX: currently signs an end of session */ d->progress.sector = 0; d->progress.start_sector = 0; d->progress.sectors = 0; } ret = 1; ex:; /* >>> eventual emergency finalization measures */ /* update media state records */ burn_drive_mark_unready(d, 0); burn_drive_inquire_media(d); if (d->current_profile == 0x41 && d->complete_sessions >= 300) { sprintf(msg, "Sequential BD-R media now contains %d sessions. It is likely to soon fail writing.", d->complete_sessions); libdax_msgs_submit(libdax_messenger, d->global_index, 0x0002017b, LIBDAX_MSGS_SEV_WARNING, LIBDAX_MSGS_PRIO_ZERO, msg, 0, 0); } BURN_FREE_MEM(msg); return ret; early_failure:; BURN_FREE_MEM(msg); return 0; } /* ts A70904 */ int burn_stdio_open_write(struct burn_drive *d, off_t start_byte, int sector_size, int flag) { /* We normally need _LARGEFILE64_SOURCE defined by the build system. Nevertheless the system might use large address integers by default. */ #ifndef O_LARGEFILE #define O_LARGEFILE 0 #endif int fd = -1; int mode = O_RDWR | O_CREAT | O_LARGEFILE; char msg[60]; off_t lseek_res; if(d->drive_role == 4) { libdax_msgs_submit(libdax_messenger, d->global_index, 0x00020181, LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH, "Pseudo-drive is a read-only file. Cannot write.", 0, 0); return 0; } if (d->drive_role == 5 || d->drive_role == 3) mode = O_WRONLY | O_CREAT | O_LARGEFILE; if (d->devname[0] == 0) /* null drives should not come here */ return -1; fd = burn_drive__fd_from_special_adr(d->devname); if (fd >= 0) fd = dup(fd); /* check validity and make closeable */ else fd = open(d->devname, mode | O_BINARY, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH); if (fd == -1) { libdax_msgs_submit(libdax_messenger, d->global_index, 0x00020005, LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH, "Failed to open device (a pseudo-drive)", errno, 0); d->cancel = 1; return -1; } if (start_byte < 0) start_byte = 0; if (d->drive_role == 2 || d->drive_role == 5) { lseek_res = lseek(fd, start_byte, SEEK_SET); if (lseek_res == -1) { sprintf(msg, "Cannot address start byte %.f", (double) start_byte); libdax_msgs_submit(libdax_messenger, d->global_index, 0x00020147, LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH, msg, errno, 0); close(fd); d->cancel = 1; fd = -1; } } d->nwa = start_byte / sector_size; return fd; } /* ts A70904 */ int burn_stdio_read_source(struct burn_source *source, char *buf, int bufsize, struct burn_write_opts *o, int flag) { int count= 0, todo; for(todo = bufsize; todo > 0; todo -= count) { if(source->read!=NULL) count = source->read(source, (unsigned char *) (buf + (bufsize - todo)), todo); else count = source->read_xt(source, (unsigned char *) (buf + (bufsize - todo)), todo); if (count <= 0) break; } return (bufsize - todo); } /* ts A70904 */ int burn_stdio_write(int fd, char *buf, int count, struct burn_drive *d, int flag) { int ret = 0; char *msg = NULL; int todo, done, retries; if (d->cancel || count <= 0) return 0; todo = count; done = 0; for (retries = 0; todo > 0 && retries <= Libburn_stdio_write_retrieS; retries++) { /* fprintf(stderr, "libburn_DEBUG: write(%d, %lX, %d)\n", fd, (unsigned long) buf, count); */ ret = write(fd, buf + done, todo); if (ret < 0) break; done += ret; todo -= ret; } if (done != count) { BURN_ALLOC_MEM(msg, char, 160); sprintf(msg, "Cannot write desired amount of %d bytes.", count); if (retries > 1) sprintf(msg + strlen(msg), " Did %d retries. Last", retries - 1); sprintf(msg + strlen(msg), " write(2) returned %d.", ret); libdax_msgs_submit(libdax_messenger, d->global_index, 0x00020148, LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH, msg, errno, 0); d->cancel = 1; ret = 0; goto ex; } ex:; BURN_FREE_MEM(msg); return ret; } /* ts A70910 : to be used as burn_drive.write(), emulating mmc_write() */ int burn_stdio_mmc_write(struct burn_drive *d, int start, struct buffer *buf) { int ret; off_t start_byte; if (d->cancel) return BE_CANCELLED; if (d->stdio_fd < 0) { libdax_msgs_submit(libdax_messenger, d->global_index, 0x0002017d, LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH, "Invalid file descriptor with stdio pseudo-drive", 0, 0); d->cancel = 1; return BE_CANCELLED; } if (start != d->nwa) { char msg[80]; start_byte = ((off_t) start) * (off_t) (buf->bytes / buf->sectors); if (lseek(d->stdio_fd, start_byte, SEEK_SET)==-1) { sprintf(msg, "Cannot address start byte %.f", (double) start_byte); libdax_msgs_submit(libdax_messenger, d->global_index, 0x00020147, LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH, msg, errno, 0); d->cancel = 1; return BE_CANCELLED; } d->nwa = start; } ret = burn_stdio_write(d->stdio_fd,(char *)buf->data, buf->bytes, d,0); if (ret <= 0) return BE_CANCELLED; d->nwa += buf->sectors; return 0; } /* ts A70910 : to be used as burn_drive.write(), emulating mmc_write() with simulated writing. */ int burn_stdio_mmc_dummy_write(struct burn_drive *d, int start, struct buffer *buf) { if (d->cancel) return BE_CANCELLED; d->nwa = start + buf->sectors; return 0; } /* ts A70911 */ /* Flush stdio system buffer to physical device. @param flag bit0= do not report debug message (intermediate sync) bit1= do fsync(2) unconditionally */ int burn_stdio_sync_cache(int fd, struct burn_drive *d, int flag) { int ret, do_fsync; char *msg = NULL; if (fd < 0) { libdax_msgs_submit(libdax_messenger, d->global_index, 0x0002017d, LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH, "Invalid file descriptor with stdio pseudo-drive", 0, 0); d->cancel = 1; ret = 0; goto ex; } d->needs_sync_cache = 0; do_fsync = 0; if (flag & 2) do_fsync = 1; else if (d->write_opts != NULL) do_fsync = (d->write_opts->stdio_fsync_size >= 0); if (do_fsync) { if (!(flag & 1)) libdax_msgs_submit(libdax_messenger, -1, 0x00000002, LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_ZERO, "syncing cache (stdio fsync)", 0, 0); ret = fsync(fd); } else { ret = 0; } if (ret != 0 && errno == EIO) { 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, 0x00020148, LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH, msg, errno, 0); d->cancel = 1; ret = 0; goto ex; } ret = 1; ex:; BURN_FREE_MEM(msg); return ret; } /* ts A70911 : to be used as burn_drive.sync_cache(), emulating mmc_sync_cache() */ void burn_stdio_mmc_sync_cache(struct burn_drive *d) { burn_stdio_sync_cache(d->stdio_fd, d, 0); } /* ts A70912 */ /* Enforces eventual nominal write speed. @param flag bit0= initialize *prev_time */ int burn_stdio_slowdown(struct burn_drive *d, struct timeval *prev_time, int amount, int flag) { struct timeval tnow; struct timezone dummy_tz; double to_wait; if (flag & 1) { gettimeofday(prev_time, &dummy_tz); return 1; } if(d->nominal_write_speed <= 0) return 2; gettimeofday(&tnow, &dummy_tz); to_wait = ( ((double) amount) / (double) d->nominal_write_speed ) - (double) ( tnow.tv_sec - prev_time->tv_sec ) - (double) ( tnow.tv_usec - prev_time->tv_usec ) / 1.0e6 - 0.001; /* best would be 1 / kernel granularity HZ */ if (to_wait >= 0.0001) { usleep((int) (to_wait * 1000000.0)); } gettimeofday(prev_time, &dummy_tz); return 1; } /* ts A70904 */ int burn_stdio_write_track(struct burn_write_opts *o, struct burn_session *s, int tnum, int flag) { int open_ended, bufsize = 16 * 2048, ret, sectors; struct burn_track *t = s->track[tnum]; struct burn_drive *d = o->drive; char *buf = NULL; int i, prev_sync_sector = 0; struct buffer *out = d->buffer; struct timeval prev_time; BURN_ALLOC_MEM(buf, char, bufsize); sectors = burn_track_get_sectors_2(t, 1); burn_disc_init_track_status(o, s, t, tnum, sectors); open_ended = burn_track_is_open_ended(t); t->end_on_premature_eoi = (o->write_type == BURN_WRITE_TAO); /* attach stdio emulators for mmc_*() functions */ if (o->simulate) d->write = burn_stdio_mmc_dummy_write; else d->write = burn_stdio_mmc_write; d->sync_cache = burn_stdio_mmc_sync_cache; burn_stdio_slowdown(d, &prev_time, 0, 1); /* initialize */ for (i = 0; open_ended || i < sectors; i++) { /* transact a (CD sized) sector */ if (!sector_data(o, t, 0)) {ret= 0; goto ex;} if (open_ended) d->progress.sectors = sectors = d->progress.sector; if (open_ended || t->end_on_premature_eoi) { if (burn_track_is_data_done(t)) break; } d->progress.sector++; /* Flush to disk from time to time */ if (d->progress.sector - prev_sync_sector >= o->stdio_fsync_size && o->stdio_fsync_size > 0) { prev_sync_sector = d->progress.sector; if (!o->simulate) burn_stdio_sync_cache(d->stdio_fd, d, 1); } if ((d->progress.sector % 512) == 0) burn_stdio_slowdown(d, &prev_time, 512 * 2, 0); } /* Pad up buffer to next full o->obs (usually 32 kB) */ if (o->obs_pad && out->bytes > 0 && out->bytes < o->obs) { memset(out->data + out->bytes, 0, o->obs - out->bytes); out->sectors += (o->obs - out->bytes) / 2048; out->bytes = o->obs; } ret = burn_write_flush(o, t); ret= 1; ex:; if (d->cancel) burn_source_cancel(t->source); if (t->end_on_premature_eoi == 2) d->cancel = 1; BURN_FREE_MEM(buf); return ret; } /* ts A70904 */ int burn_stdio_write_sync(struct burn_write_opts *o, struct burn_disc *disc) { int ret; struct burn_drive *d = o->drive; d->needs_close_session = 0; if (o->obs_pad < 2) o->obs_pad = 0; /* no filling-up of track's last 32k buffer */ o->obs = 32*1024; /* buffer size */ if (disc->sessions != 1) {ret= 0 ; goto ex;} if (disc->session[0]->tracks != 1) {ret= 0 ; goto ex;} /* update progress */ d->progress.session = 0; d->progress.tracks = 1; /* >>> adjust sector size (2048) to eventual audio or even raw */ /* >>> ??? ts B11004 : Why this eagerness to close and open ? */ /* open target file */ if (d->stdio_fd >= 0) close(d->stdio_fd); if (d->drive_role == 5 && d->status == BURN_DISC_APPENDABLE && o->start_byte < 0) o->start_byte = d->role_5_nwa * 2048; d->stdio_fd = burn_stdio_open_write(d, o->start_byte, 2048, 0); if (d->stdio_fd == -1) {ret = 0; goto ex;} ret = burn_stdio_write_track(o, disc->session[0], 0, 0); if (ret <= 0) goto ex; /* XXX: currently signs an end of session */ d->progress.sector = 0; d->progress.start_sector = 0; d->progress.sectors = 0; ret = 1; ex:; /* >>> ??? ts B11004 : Why this eagerness to close ? */ if (d->stdio_fd >= 0) close(d->stdio_fd); d->stdio_fd = -1; /* update pseudo-media state records by re-grabbing */ burn_drive_mark_unready(d, 8); burn_drive_grab_stdio(d, 1); return ret; } void burn_disc_write_sync(struct burn_write_opts *o, struct burn_disc *disc) { struct cue_sheet *sheet; struct burn_drive *d = o->drive; struct buffer *buffer_mem = o->drive->buffer; struct burn_session *s; struct burn_track *lt, *t; int first = 1, i, ret, lba, nwa = 0, multi_mem; off_t default_size; char msg[80]; /* ts A60924 : libburn/message.c gets obsoleted burn_message_clear_queue(); */ /* ts A61224 */ burn_disc_init_write_status(o, disc); /* must be done very early */ /* ts A80412 , A90227 */ d->do_stream_recording = !!o->do_stream_recording; if (o->do_stream_recording >= 16) d->stream_recording_start = o->do_stream_recording; else d->stream_recording_start = 0; /* ts A91122 : Get buffer suitable for sources made by burn_os_open_track_src() */ d->buffer = burn_os_alloc_buffer(sizeof(struct buffer), 0); if (d->buffer == NULL) goto fail_wo_sync; /* >>> ts A90321 memset(d->buffer, 0, sizeof(struct buffer)); fprintf(stderr, "libburn_DEBUG: d->buffer = %lX , size = %d\n", (unsigned long) d->buffer, (int) sizeof(struct buffer)); calloc() seems not to have the desired effect. valgrind warns: ==18251== Syscall param write(buf) points to uninitialised byte(s) ==18251== at 0x5071DEB: (within /lib64/libpthread-2.5.so) ==18251== by 0x4723FA: burn_stdio_write (write.c:1850) ==18251== by 0x4725DC: burn_stdio_mmc_write (write.c:1894) ==18251== by 0x483B7A: get_sector (sector.c:229) ==18251== by 0x484F11: sector_data (sector.c:639) ==18251== by 0x4729FE: burn_stdio_write_track (write.c:2012) ==18251== by 0x472CF4: burn_stdio_write_sync (write.c:2072) ==18251== by 0x472E8D: burn_disc_write_sync (write.c:2125) <<< we are here ==18251== by 0x460254: write_disc_worker_func (async.c:514) ==18251== by 0x506B09D: start_thread (in /lib64/libpthread-2.5.so) ==18251== by 0x55484CC: clone (in /lib64/libc-2.5.so) */ d->rlba = -150; d->toc_temp = 9; if(d->drive_role == 4) { libdax_msgs_submit(libdax_messenger, d->global_index, 0x00020181, LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH, "Pseudo-drive is a read-only file. Cannot write.", 0, 0); goto fail_wo_sync; } /* ts A70904 */ if (d->drive_role != 1) { ret = burn_stdio_write_sync(o, disc); if (ret <= 0) goto fail_wo_sync; goto ex; } /* ts A61218 */ if (! d->current_is_cd_profile) { ret = burn_dvd_write_sync(o, disc); if (ret <= 0) goto fail_wo_sync; goto ex; } /* ts A70521 : GNU/Linux 2.4 USB audio fails with 64 kiB */ /* ts A80414 : might need 64 kiB for BD-RE streaming */ /* buffer flush trigger for sector.c:get_sector() */ o->obs = Libburn_cd_obS; sprintf(msg, "cd Profile= %2.2Xh , obs= %d , obs_pad= %d", d->current_profile, o->obs, o->obs_pad); libdax_msgs_submit(libdax_messenger, d->global_index, 0x00000002, LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_ZERO, msg, 0, 0); /* ts A70218 */ if (o->write_type == BURN_WRITE_SAO) { for (i = 0 ; i < disc->session[0]->tracks; i++) { t = disc->session[0]->track[i]; if (burn_track_is_open_ended(t)) { default_size = burn_track_get_default_size(t); sprintf(msg, "Activated track default size %.f", (double) default_size); libdax_msgs_submit(libdax_messenger, d->global_index, 0x0002012e, LIBDAX_MSGS_SEV_NOTE, LIBDAX_MSGS_PRIO_HIGH, msg, 0, 0); burn_track_set_size(t, default_size); } } } /* Apparently some drives require this command to be sent, and a few drives return crap. so we send the command, then ignore the result. */ /* ts A61107 : moved up send_write_parameters because LG GSA-4082B seems to dislike get_nwa() in advance */ d->alba = d->start_lba; /* ts A61114: this looks senseless */ d->nwa = d->alba; if (o->write_type == BURN_WRITE_TAO) { nwa = 0; /* get_nwa() will be called in burn_track() */ } else { if (disc->sessions > 0) s = disc->session[0]; else s = NULL; d->send_write_parameters(d, s, -1, o); ret = d->get_nwa(d, -1, &lba, &nwa); sprintf(msg, "SAO|RAW: Inquired nwa: %d , ret= %d , cap=%.f\n", nwa, ret, (double) d->media_capacity_remaining); libdax_msgs_submit(libdax_messenger, d->global_index, 0x00000002, LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_ZERO, msg,0, 0); /* >>> ts A70212 : CD-DAO/SAO : eventually expand size of last track to maximum */; } for (i = 0; i < disc->sessions; i++) { /* update progress */ d->progress.session = i; d->progress.tracks = disc->session[i]->tracks; /* ts A61114: added parameter nwa */ sheet = burn_create_toc_entries(o, disc->session[i], nwa); /* ts A61009 */ if (sheet == NULL) goto fail_wo_sync; #ifdef Libburn_write_with_function_print_cuE print_cue(sheet); /* goto fail_wo_sync; */ #endif /* Libburn_write_with_function_print_cuE */ ret = 1; if (o->write_type == BURN_WRITE_SAO) ret = d->send_cue_sheet(d, sheet); if (sheet->data != NULL) free(sheet->data); free(sheet); if (ret <= 0) goto fail_wo_sync; /* --- From here on, final sync is needed. --- */ if (o->write_type == BURN_WRITE_RAW) { if (!burn_write_leadin(o, disc->session[i], first)) goto fail; } else { if (first) { /* ts A61030 : 0 made the burner take data. */ /* ts A61103 : Meanwhile d->nwa is updated in burn_write_track() */ if(o->write_type == BURN_WRITE_TAO) { d->nwa= d->alba = 0; } else { #ifdef Libburn_sao_can_appenD /* ts A61114: address for d->write() */ if (d->status == BURN_DISC_APPENDABLE && o->write_type == BURN_WRITE_SAO) { d->nwa = d->alba = nwa-150; sprintf(msg, "SAO appendable d->nwa= %d\n", d->nwa); libdax_msgs_submit( libdax_messenger, d->global_index, 0x00000002, LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_ZERO, msg, 0, 0); } else { d->nwa = -150; d->alba = -150; } #else d->nwa = -150; d->alba = -150; #endif /* ! Libburn_sao_can_appenD */ } } else { d->nwa += 4500; d->alba += 4500; } } multi_mem = o->multi; if(i < disc->sessions - 1) o->multi = 1; ret = burn_write_session(o, disc->session[i]); o->multi = multi_mem; if (!ret) goto fail; lt = disc->session[i]->track[disc->session[i]->tracks - 1]; if (o->write_type == BURN_WRITE_RAW) { if (!burn_write_leadout(o, first, lt->entry->control, lt->mode)) goto fail; } else { /* ts A61030 */ if (o->write_type != BURN_WRITE_TAO) if (!burn_write_flush(o, NULL)) goto fail; d->nwa += first ? 6750 : 2250; d->alba += first ? 6750 : 2250; } if (first) first = 0; /* XXX: currently signs an end of session */ d->progress.sector = 0; d->progress.start_sector = 0; d->progress.sectors = 0; } /* ts A61030: extended skipping of flush to TAO: session is closed */ if (o->write_type != BURN_WRITE_SAO && o->write_type != BURN_WRITE_TAO) if (!burn_write_flush(o, NULL)) goto fail; sleep(1); /* ts A61125 : update media state records */ burn_drive_mark_unready(d, 0); burn_drive_inquire_media(d); /* ts A61012 : This return was traditionally missing. I suspect this to have caused Cdrskin_eject() failures */ goto ex; fail: d->sync_cache(d); fail_wo_sync:; usleep(500001); /* ts A61222: to avoid a warning from remove_worker()*/ libdax_msgs_submit(libdax_messenger, d->global_index, 0x0002010b, LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH, "Burn run failed", 0, 0); d->cancel = 1; /* <<< d->busy = BURN_DRIVE_IDLE; */ ex:; d->do_stream_recording = 0; if (d->buffer != NULL) burn_os_free_buffer((char *) d->buffer, sizeof(struct buffer), 0); d->buffer = buffer_mem; if (d->write_opts != NULL) { burn_write_opts_free(d->write_opts); d->write_opts = NULL; } return; } /* ts A70811 : API function */ int burn_random_access_write(struct burn_drive *d, off_t byte_address, char *data, off_t data_count, int flag) { int alignment = 0, start, upto, chunksize, err, fd = -1, ret; int do_close = 0, getfl_ret; char msg[81], *rpt; struct buffer *buf = NULL, *buffer_mem = d->buffer; BURN_ALLOC_MEM(buf, struct buffer, 1); if (d->released) { libdax_msgs_submit(libdax_messenger, d->global_index, 0x00020142, LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH, "Drive is not grabbed on random access write", 0, 0); {ret = 0; goto ex;} } if(d->drive_role == 0) { libdax_msgs_submit(libdax_messenger, d->global_index, 0x00020146, LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH, "Drive is a virtual placeholder (null-drive)", 0, 0); {ret = 0; goto ex;} } if(d->drive_role == 4) { libdax_msgs_submit(libdax_messenger, d->global_index, 0x00020181, LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH, "Pseudo-drive is a read-only file. Cannot write.", 0, 0); {ret = 0; goto ex;} } if(d->drive_role == 2 || d->drive_role == 5) alignment = 2 * 1024; if (d->current_profile == 0x12) /* DVD-RAM */ alignment = 2 * 1024; if (d->current_profile == 0x13) /* DVD-RW restricted overwrite */ alignment = 32 * 1024; if (d->current_profile == 0x1a) /* DVD+RW */ alignment = 2 * 1024; if (d->current_profile == 0x43) /* BD-RE */ alignment = 2 * 1024; if (alignment == 0) { sprintf(msg, "Write start address not supported"); libdax_msgs_submit(libdax_messenger, d->global_index, 0x00020125, LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH, "Write start address not supported", 0, 0); {ret = 0; goto ex;} } if ((byte_address % alignment) != 0) { sprintf(msg, "Write start address not properly aligned (%d bytes)", alignment); libdax_msgs_submit(libdax_messenger, d->global_index, 0x00020126, LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH, msg, 0, 0); {ret = 0; goto ex;} } if ((data_count % alignment) != 0) { sprintf(msg, "Write data count not properly aligned (%ld bytes)", (long) alignment); libdax_msgs_submit(libdax_messenger, d->global_index, 0x00020141, LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH, msg, 0, 0); {ret = 0; goto ex;} } if (d->busy != BURN_DRIVE_IDLE) { libdax_msgs_submit(libdax_messenger, d->global_index, 0x00020140, LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH, "Drive is busy on attempt to write random access",0,0); {ret = 0; goto ex;} } if (d->drive_role != 1) { if (d->stdio_fd >= 0) { /* Avoid to have a read-only fd open */ getfl_ret = fcntl(d->stdio_fd, F_GETFL); if (((O_RDWR | O_WRONLY | O_RDONLY) & getfl_ret) == O_RDONLY) { close(d->stdio_fd); d->stdio_fd = -1; } } if (d->stdio_fd >= 0) { /* Avoid to have two fds open */ fd = d->stdio_fd; } else { fd = burn_stdio_open_write(d, byte_address, 2048, 0); if (fd == -1) {ret = 0; goto ex;} do_close = 1; } } d->cancel = 0; d->busy = BURN_DRIVE_WRITING_SYNC; d->buffer = buf; start = byte_address / 2048; upto = start + data_count / 2048; rpt = data; for (; start < upto; start += 16) { chunksize = upto - start; if (chunksize > 16) chunksize = 16; d->buffer->bytes = chunksize * 2048; memcpy(d->buffer->data, rpt, d->buffer->bytes); rpt += d->buffer->bytes; d->buffer->sectors = chunksize; d->nwa = start; if(d->drive_role == 1) { err = d->write(d, d->nwa, d->buffer); } else { ret = burn_stdio_write(fd, (char *) d->buffer->data, d->buffer->bytes, d, 0); err = 0; if (ret <= 0) err = BE_CANCELLED; } if (err == BE_CANCELLED) { d->busy = BURN_DRIVE_IDLE; if(fd >= 0 && do_close) close(fd); {ret = -(start * 2048 - byte_address); goto ex;} } } if(d->drive_role == 1) d->needs_sync_cache = 1; if(flag & 1) { if(d->drive_role == 1) d->sync_cache(d); else burn_stdio_sync_cache(fd, d, 2); d->needs_sync_cache = 0; } if(fd >= 0 && do_close) close(fd); d->buffer = buffer_mem; d->busy = BURN_DRIVE_IDLE; ret = 1; ex: BURN_FREE_MEM(buf); return ret; } /* ts B10527 */ /* @param bit0= force close, even if no damage was seen */ int burn_disc_close_damaged(struct burn_write_opts *o, int flag) { struct burn_drive *d; int ret; enum burn_drive_status busy; d = o->drive; busy = d->busy; if (busy != BURN_DRIVE_IDLE) { libdax_msgs_submit(libdax_messenger, d->global_index, 0x00020106, LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH, "Drive is busy on attempt to close damaged session", 0, 0); {ret = 0; goto ex;} } if (!((d->next_track_damaged & 1) || (flag & 1))) { libdax_msgs_submit(libdax_messenger, d->global_index, 0x00020187, LIBDAX_MSGS_SEV_NOTE, LIBDAX_MSGS_PRIO_HIGH, "Track not marked as damaged. No action taken.", 0, 0); {ret = 0; goto ex;} } d->busy = BURN_DRIVE_WRITING; if (d->current_profile == 0x09 || d->current_profile == 0x0a) { /* Close CD track and session */ o->write_type = BURN_WRITE_TAO; /* no action without TAO */ /* Send mode page 5 */; d->send_write_parameters(d, NULL, -1, o); ret = burn_write_close_session(o); if (ret <= 0) goto ex; } else if(d->current_profile == 0x11 || d->current_profile == 0x14) { /* Close DVD-R[W] track and session */ o->write_type = BURN_WRITE_TAO; /* no action without TAO */ /* Send mode page 5 */; d->send_write_parameters(d, NULL, -1, o); ret = burn_disc_close_track_dvd_minus_r(o, 0); if (ret <= 0) goto ex; ret = burn_disc_close_session_dvd_minus_r(o); if (ret <= 0) goto ex; } else if(d->current_profile == 0x1b || d->current_profile == 0x2b) { /* Close DVD+R track and session */ ret = burn_disc_close_track_dvd_plus_r(o, d->last_track_no, 1); if (ret <= 0) goto ex; } else if(d->current_profile == 0x41) { /* Close BD-R track and session */ ret = burn_disc_close_track_dvd_plus_r(o, d->last_track_no, 1); if (ret <= 0) goto ex; } else { libdax_msgs_submit(libdax_messenger, d->global_index, 0x00020188, LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH, "Cannot close damaged track on given media type", 0, 0); {ret = 0; goto ex;} } ret = 1; ex:; d->busy = busy; /* Record with drive that repair was attempted */ d->next_track_damaged &= ~1; return ret; } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������libburn-1.4.2/libburn/file.h������������������������������������������������������������������������0000644�0001757�0001751�00000004137�12652644224�012645� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */ /* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens Copyright (c) 2006 - 2010 Thomas Schmitt <scdbackup@gmx.net> Provided under GPL version 2 or later. */ #ifndef BURN__FILE_H #define BURN__FILE_H struct burn_source_file { char magic[4]; int datafd; int subfd; off_t fixed_size; }; /* ts A70126 : burn_source_file obsoleted burn_source_fd */ /* ts A70930 */ struct burn_source_fifo { char magic[4]; /* The fifo stays inactive and unequipped with eventual resources until its read() method is called for the first time. Only then burn_fifo_start() gets called, allocates the complete resources, starts a thread with burn_fifo_source_shuffler() which shuffles data and finally destroys the resources. This late start is to stay modest in case of multiple tracks in one disc. */ int is_started; void *thread_handle; /* actually a pointer to a thread_t */ int thread_pid; int thread_is_valid; /* the burn_source for which this fifo is acting as proxy */ struct burn_source *inp; int inp_read_size; /* <<< up to now it was only a pipe. This is on its way out. */ int outlet[2]; /* The ring buffer mechanism */ int chunksize; int chunks; char *buf; volatile int buf_writepos; volatile int buf_readpos; volatile int end_of_input; volatile int input_error; volatile int end_of_consumption; off_t in_counter; off_t out_counter; int total_min_fill; int interval_min_fill; int put_counter; int get_counter; int empty_counter; int full_counter; }; /** The worker behind the fifo thread. Gets started from burn_fifo_start() in async.c */ int burn_fifo_source_shoveller(struct burn_source *source, int flag); /* ts B00922 */ struct burn_source_offst { /* See burn_offst_source_new() */ struct burn_source *inp; struct burn_source *prev; off_t start; off_t size; int size_adjustable; /* for set_size/get_size */ int nominal_size; /* To help offst_free() */ struct burn_source *next; /* The current reading position */ int running; off_t pos; }; #endif /* LIBBURN__FILE_H */ ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������libburn-1.4.2/libburn/init.c������������������������������������������������������������������������0000644�0001757�0001751�00000042600�12652644224�012661� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */ /* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens Copyright (c) 2006 - 2013 Thomas Schmitt <scdbackup@gmx.net> Provided under GPL version 2 or later. */ #ifdef HAVE_CONFIG_H #include "../config.h" #endif #include <unistd.h> /* ts A61007 */ /* #include <a ssert.h> */ #include <stdio.h> #include <signal.h> #include <string.h> #include <stdlib.h> #include <pthread.h> /* ts A70928 : init.h is for others, not for init .c #include "init.h" */ #include "sg.h" #include "error.h" #include "libburn.h" #include "drive.h" #include "transport.h" #include "util.h" /* ts A60825 : The storage location for back_hacks.h variables. */ #define BURN_BACK_HACKS_INIT 1 #include "back_hacks.h" /* ts A60924 : a new message handling facility */ #include "libdax_msgs.h" struct libdax_msgs *libdax_messenger= NULL; int burn_running = 0; double lib_start_time; /* ts A60813 : GNU/Linux: whether to use O_EXCL on open() of device files ts B00212 : FreeBSD: whether to use flock(LOCK_EX) after open() */ int burn_sg_open_o_excl = 1; /* ts A70403 : GNU/Linux: wether to use fcntl(,F_SETLK,) after open() of device files */ int burn_sg_fcntl_f_setlk = 1; /* ts A70314 : GNU/Linux: what device family to use : 0= default family 1= sr 2= scd (3= st) 4= sg */ int burn_sg_use_family = 0; /* O_NONBLOCK was hardcoded in enumerate_ata() which i hardly use. For enumerate_sg() it seems ok. So it should stay default mode until enumerate_ata() without O_NONBLOCK has been thoroughly tested. */ int burn_sg_open_o_nonblock = 1; /* wether to take a busy drive as an error */ /* Caution: this is implemented by a rough hack and eventually leads to unconditional abort of the process */ int burn_sg_open_abort_busy = 0; /* The message returned from sg_id_string() and/or sg_initialize() */ static char sg_initialize_msg[1024] = {""}; /* ts A61002 */ #include "cleanup.h" /* Parameters for builtin abort handler */ static char abort_message_prefix[81] = {"libburn : "}; static pid_t abort_control_pid= 0; static pthread_t abort_control_thread; volatile int burn_global_abort_level= 0; int burn_global_abort_signum= 0; void *burn_global_signal_handle = NULL; burn_abort_handler_t burn_global_signal_handler = NULL; int burn_builtin_signal_action = 0; /* burn_set_signal_handling() */ volatile int burn_builtin_triggered_action = 0; /* burn_is_aborting() */ /* ts A70223 : wether implemented untested profiles are supported */ int burn_support_untested_profiles = 0; /* ts A91111 : whether to log SCSI commands (to be implemented in sg-*.c) bit0= log in /tmp/libburn_sg_command_log bit1= log to stderr bit2= flush every line */ int burn_sg_log_scsi = 0; /* ts B10312 : Whether to map random-access readonly files to drive role 4. Else it is role 2 overwriteable drive */ int burn_drive_role_4_allowed = 0; /* ts A60925 : ticket 74 */ /** Create the messenger object for libburn. */ int burn_msgs_initialize(void) { int ret; if(libdax_messenger == NULL) { ret = libdax_msgs_new(&libdax_messenger,0); if (ret <= 0) return 0; } libdax_msgs_set_severities(libdax_messenger, LIBDAX_MSGS_SEV_NEVER, LIBDAX_MSGS_SEV_FATAL, "libburn: ", 0); return 1; } /* ts A60924 : ticket 74 : Added use of global libdax_messenger */ int burn_initialize(void) { int ret; if (burn_running) return 1; lib_start_time = burn_get_time(0); burn_support_untested_profiles = 0; ret = burn_msgs_initialize(); if (ret <= 0) return 0; ret = sg_initialize(sg_initialize_msg, 0); if (ret <= 0) { libdax_msgs_submit(libdax_messenger, -1, 0x00020175, LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH, sg_initialize_msg, 0, 0); return 0; } burn_running = 1; return 1; } void burn_finish(void) { /* ts A61007 : assume no messageing system */ /* a ssert(burn_running); */ if (!burn_running) return; /* ts A61007 */ /* burn_wait_all(); */ if (!burn_drives_are_clear(0)) { libdax_msgs_submit(libdax_messenger, -1, 0x00020107, LIBDAX_MSGS_SEV_WARNING, LIBDAX_MSGS_PRIO_HIGH, "A drive is still busy on shutdown of library", 0, 0); usleep(1000001); burn_abort(4440, burn_abort_pacifier, abort_message_prefix); } /* ts A60904 : ticket 62, contribution by elmom : name addon "_all" */ burn_drive_free_all(); /* ts A60924 : ticket 74 */ libdax_msgs_destroy(&libdax_messenger,0); sg_shutdown(0); burn_drive_clear_whitelist(); burn_running = 0; } /* ts A91226 */ /** API function. See libburn.h */ char *burn_scsi_transport_id(int flag) { if (!burn_running) sg_id_string(sg_initialize_msg, 0); return sg_initialize_msg; } /* ts A60813 */ /** API function. See libburn.h */ void burn_preset_device_open(int exclusive, int blocking, int abort_on_busy) { /* ts A61007 */ /* a ssert(burn_running); */ if (!burn_running) return; burn_sg_open_o_excl = exclusive & 3; burn_sg_fcntl_f_setlk = !!(exclusive & 32); burn_sg_use_family = (exclusive >> 2) & 7; burn_sg_open_o_nonblock = !blocking; burn_sg_open_abort_busy = !!abort_on_busy; } /* ts A60924 : ticket 74 */ /** Control queueing and stderr printing of messages from libburn. Severity may be one of "NEVER", "FATAL", "SORRY", "WARNING", "HINT", "NOTE", "UPDATE", "DEBUG", "ALL". @param queue_severity Gives the minimum limit for messages to be queued. Default: "NEVER". If you queue messages then you must consume them by burn_msgs_obtain(). @param print_severity Does the same for messages to be printed directly to stderr. @param print_id A text prefix to be printed before the message. @return >0 for success, <=0 for error */ int burn_msgs_set_severities(char *queue_severity, char *print_severity, char *print_id) { int ret, queue_sevno, print_sevno; ret = libdax_msgs__text_to_sev(queue_severity, &queue_sevno, 0); if (ret <= 0) return 0; ret = libdax_msgs__text_to_sev(print_severity, &print_sevno, 0); if (ret <= 0) return 0; ret = libdax_msgs_set_severities(libdax_messenger, queue_sevno, print_sevno, print_id, 0); if (ret <= 0) return 0; return 1; } /* ts A60924 : ticket 74 */ #define BURM_MSGS_MESSAGE_LEN 4096 /** Obtain the oldest pending libburn message from the queue which has at least the given minimum_severity. This message and any older message of lower severity will get discarded from the queue and is then lost forever. Severity may be one of "NEVER", "FATAL", "SORRY", "WARNING", "HINT", "NOTE", "UPDATE", "DEBUG", "ALL". To call with minimum_severity "NEVER" will discard the whole queue. @param error_code Will become a unique error code as liste in libburn/libdax_msgs.h @param msg_text Must provide at least BURM_MSGS_MESSAGE_LEN bytes. @param os_errno Will become the eventual errno related to the message @param severity Will become the severity related to the message and should provide at least 80 bytes. @return 1 if a matching item was found, 0 if not, <0 for severe errors */ int burn_msgs_obtain(char *minimum_severity, int *error_code, char msg_text[], int *os_errno, char severity[]) { int ret, minimum_sevno, sevno, priority; char *textpt, *sev_name; struct libdax_msgs_item *item = NULL; ret = libdax_msgs__text_to_sev(minimum_severity, &minimum_sevno, 0); if (ret <= 0) return 0; if (libdax_messenger == NULL) return 0; ret = libdax_msgs_obtain(libdax_messenger, &item, minimum_sevno, LIBDAX_MSGS_PRIO_ZERO, 0); if (ret <= 0) goto ex; ret = libdax_msgs_item_get_msg(item, error_code, &textpt, os_errno, 0); if (ret <= 0) goto ex; strncpy(msg_text, textpt, BURM_MSGS_MESSAGE_LEN-1); if(strlen(textpt) >= BURM_MSGS_MESSAGE_LEN) msg_text[BURM_MSGS_MESSAGE_LEN-1] = 0; severity[0]= 0; ret = libdax_msgs_item_get_rank(item, &sevno, &priority, 0); if(ret <= 0) goto ex; ret = libdax_msgs__sev_to_text(sevno, &sev_name, 0); if(ret <= 0) goto ex; strcpy(severity,sev_name); ret = 1; ex: libdax_msgs_destroy_item(libdax_messenger, &item, 0); return ret; } /* ts A70922 : API */ int burn_msgs_submit(int error_code, char msg_text[], int os_errno, char severity[], struct burn_drive *d) { int ret, sevno, global_index = -1; ret = libdax_msgs__text_to_sev(severity, &sevno, 0); if (ret <= 0) sevno = LIBDAX_MSGS_SEV_ALL; if (error_code <= 0) { switch(sevno) { case LIBDAX_MSGS_SEV_ABORT: error_code = 0x00040000; break; case LIBDAX_MSGS_SEV_FATAL: error_code = 0x00040001; break; case LIBDAX_MSGS_SEV_SORRY: error_code = 0x00040002; break; case LIBDAX_MSGS_SEV_WARNING: error_code = 0x00040003; break; case LIBDAX_MSGS_SEV_HINT: error_code = 0x00040004; break; case LIBDAX_MSGS_SEV_NOTE: error_code = 0x00040005; break; case LIBDAX_MSGS_SEV_UPDATE: error_code = 0x00040006; break; case LIBDAX_MSGS_SEV_DEBUG: error_code = 0x00040007; break; default: error_code = 0x00040008; } } if (d != NULL) global_index = d->global_index; ret = libdax_msgs_submit(libdax_messenger, global_index, error_code, sevno, LIBDAX_MSGS_PRIO_HIGH, msg_text, os_errno, 0); return ret; } /* ts A71016 API */ int burn_text_to_sev(char *severity_name, int *sevno, int flag) { int ret; ret = libdax_msgs__text_to_sev(severity_name, sevno, 0); return ret; } /* ts A80202 API */ int burn_sev_to_text(int severity_number, char **severity_name, int flag) { int ret; ret = libdax_msgs__sev_to_text(severity_number, severity_name, 0); return ret; } /* ts B21214 API */ char *burn_list_sev_texts(int flag) { char *sev_list; libdax_msgs__sev_to_text(0, &sev_list, 1); return sev_list; } /* ts B00224 */ char *burn_util_thread_id(pid_t pid, pthread_t tid, char text[80]) { int i, l; sprintf(text, "[%lu,", (unsigned long int) getpid()); l= strlen(text); for(i= 0; i < ((int) sizeof(pthread_t)) && 2 * i < 80 - l - 3; i++) sprintf(text + l + 2 * i, "%2.2X", ((unsigned char *) &tid)[i]); sprintf(text + l + 2 * i, "]"); return text; } /* ts B20122 */ /* @param value 0=return rather than exit(value) */ int burn_abort_exit(int value) { burn_abort(4440, burn_abort_pacifier, abort_message_prefix); fprintf(stderr, "\n%sABORT : Program done. Even if you do not see a shell prompt.\n\n", abort_message_prefix); if (value) exit(value); burn_global_abort_level = -2; return(1); } int burn_builtin_abort_handler(void *handle, int signum, int flag) { #define Libburn_new_thread_signal_handleR 1 /* #define Libburn_signal_handler_verbouS 1 */ int ret; struct burn_drive *d; #ifdef Libburn_signal_handler_verbouS char text[80]; fprintf(stderr, "libburn_ABORT: in = %s\n", burn_util_thread_id(getpid(), pthread_self(), text)); fprintf(stderr, "libburn_ABORT: ctrl = %s\n", burn_util_thread_id(abort_control_pid, abort_control_thread, text)); if (burn_global_signal_handler == burn_builtin_abort_handler) fprintf(stderr, "libburn_ABORT: signal action = %d\n", burn_builtin_signal_action); /* >>> find writing drives and report their tid fprintf(stderr, "libburn_ABORT: wrt = %s\n", burn_util_thread_id(0, burn_write_thread_id, text)); fprintf(stderr, "libburn_ABORT: sig= %d\n", signum); */ #endif burn_builtin_triggered_action = burn_builtin_signal_action; burn_global_abort_level = -1; if (burn_builtin_signal_action > 1) { Cleanup_set_handlers(NULL, NULL, 2); if (burn_builtin_signal_action == 4) return -2; fprintf(stderr,"%sABORT : Trying to shut down busy drives\n", abort_message_prefix); fprintf(stderr, "%sABORT : Wait the normal burning time before any kill -9\n", abort_message_prefix); burn_abort_5(0, burn_abort_pacifier, abort_message_prefix, 0, 1); libdax_msgs_submit(libdax_messenger, -1, 0x00020177, LIBDAX_MSGS_SEV_ABORT, LIBDAX_MSGS_PRIO_HIGH, "Urged drive worker threads to do emergency halt", 0, 0); return -2; } /* ---- old deprecated stuck-in-abort-handler loop ---- */ /* ts A70928: Must be quick. Allowed to coincide with other thread and to share the increment with that one. It must not decrease, though, and yield at least 1 if any thread calls this function. */ burn_global_abort_level++; burn_global_abort_signum= signum; if(getpid() != abort_control_pid) { #ifdef Libburn_new_thread_signal_handleR ret = burn_drive_find_by_thread_pid(&d, getpid(), pthread_self()); if (ret > 0 && d->busy == BURN_DRIVE_WRITING) { /* This is an active writer thread */ #ifdef Libburn_signal_handler_verbouS fprintf(stderr, "libburn_ABORT: pid %d found drive busy with writing, (level= %d)\n", (int) getpid(), burn_global_abort_level); #endif d->sync_cache(d); /* >>> perform a more qualified end of burn process */; d->busy = BURN_DRIVE_IDLE; if (burn_global_abort_level > 0) { /* control process did not show up yet */ #ifdef Libburn_signal_handler_verbouS fprintf(stderr, "libburn_ABORT: pid %d sending signum %d to pid %d\n", (int) getpid(), (int) signum, (int) abort_control_pid); #endif kill(abort_control_pid, signum); } #ifdef Libburn_signal_handler_verbouS fprintf(stderr, "libburn_ABORT: pid %d signum %d returning -2\n", (int) getpid(), (int) signum); #endif return -2; } else { usleep(1000000); /* calm down */ return -2; } #else usleep(1000000); /* calm down */ return -2; #endif /* ! Libburn_new_thread_signal_handleR */ } burn_global_abort_level = -1; Cleanup_set_handlers(NULL, NULL, 2); fprintf(stderr,"%sABORT : Trying to shut down drive and library\n", abort_message_prefix); fprintf(stderr, "%sABORT : Wait the normal burning time before any kill -9\n", abort_message_prefix); close(0); /* somehow stdin as input blocks abort until EOF */ burn_abort_exit(0); return (1); } /* ts A61002 : API */ void burn_set_signal_handling(void *handle, burn_abort_handler_t handler, int mode) { /* fprintf(stderr, "libburn_experimental: burn_set_signal_handling, handler==%lx mode=%d\n", (unsigned long) handler, mode); */ if(handler == NULL) { handler = burn_builtin_abort_handler; /* if ((mode & ~4) == 0) fprintf(stderr, "libburn_experimental: activated burn_builtin_abort_handler() with handle '%s'\n",(handle==NULL ? "libburn : " : (char *) handle)); */ } strcpy(abort_message_prefix, "libburn : "); abort_message_prefix[0] = 0; if(handle != NULL && handler == burn_builtin_abort_handler) strncpy(abort_message_prefix, (char *) handle, sizeof(abort_message_prefix)-1); abort_message_prefix[sizeof(abort_message_prefix)-1] = 0; abort_control_pid = getpid(); abort_control_thread = pthread_self(); burn_builtin_signal_action = (mode >> 4) & 15; if((mode & 11) != 0) burn_builtin_signal_action = 0; if(burn_builtin_signal_action > 1) burn_builtin_triggered_action = 0; if(burn_builtin_signal_action == 0) burn_builtin_signal_action = 1; Cleanup_set_handlers(handle, (Cleanup_app_handler_T) handler, (mode & 15) | 4 | (mode & 256)); burn_global_signal_handle = handle; burn_global_signal_handler = handler; } /* ts B00304 : API */ int burn_is_aborting(int flag) { return burn_builtin_triggered_action; } /* ts B00225 */ /* @return 0= no abort action 2 pending , 1= not control thread */ int burn_init_catch_on_abort(int flag) { if (burn_builtin_triggered_action != 2) return 0; if (abort_control_pid != getpid() || abort_control_thread != pthread_self()) return 1; burn_abort(4440, burn_abort_pacifier, abort_message_prefix); fprintf(stderr, "\n%sABORT : Program done. Even if you do not see a shell prompt.\n\n", abort_message_prefix); exit(1); } /* B20122 */ /* Temporarily disable builtin actions 0,1,2 to avoid that burn_abort() waits for its own thread to end grabbing. */ int burn_grab_prepare_sig_action(int *signal_action_mem, int flag) { *signal_action_mem = -1; if (burn_global_signal_handler == burn_builtin_abort_handler && burn_builtin_signal_action >= 0 && burn_builtin_signal_action <= 2) { *signal_action_mem = burn_builtin_signal_action; burn_builtin_signal_action = 3; } return 1; } /* B20122 */ /* Re-enable builtin actions 0,1,2 and perform delayed signal reactions */ int burn_grab_restore_sig_action(int signal_action_mem, int flag) { if (signal_action_mem >= 0) burn_builtin_signal_action = signal_action_mem; if (burn_is_aborting(0) && signal_action_mem >= 0) { if (signal_action_mem == 0 || signal_action_mem == 1) { burn_abort_exit(1); /* Never comes back */ } else if (signal_action_mem == 2) { burn_builtin_triggered_action = signal_action_mem; } } return 1; } /* ts A70223 : API */ void burn_allow_untested_profiles(int yes) { burn_support_untested_profiles = !!yes; } /* ts A70915 : API */ int burn_set_messenger(void *messenger) { struct libdax_msgs *pt; if (libdax_msgs_refer(&pt, messenger, 0) <= 0) return 0; libdax_msgs_destroy(&libdax_messenger, 0); libdax_messenger = (struct libdax_msgs *) pt; return 1; } /* ts A91111 API */ void burn_set_scsi_logging(int flag) { burn_sg_log_scsi = flag & 7; } /* ts B10312 API */ void burn_allow_drive_role_4(int allowed) { burn_drive_role_4_allowed = (allowed & 0xf); } /* ts B10606 */ void *burn_alloc_mem(size_t size, size_t count, int flag) { void *pt; pt = calloc(count, size); if(pt == NULL) libdax_msgs_submit(libdax_messenger, -1, 0x00000003, LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH, "Out of virtual memory", 0, 0); return pt; } ��������������������������������������������������������������������������������������������������������������������������������libburn-1.4.2/libburn/os-solaris.h������������������������������������������������������������������0000644�0001757�0001751�00000003724�12652644224�014022� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ /* os-solaris.h Operating system specific libburn definitions and declarations. Included by os.h in case of compilation for Solaris based systems, e.g. SunOS 5.11 with Solaris uscsi MMC transport adapter sg-solaris.c Copyright (C) 2010 - 2013 Thomas Schmitt <scdbackup@gmx.net> provided under GPLv2+ */ /** List of all signals which shall be caught by signal handlers and trigger a graceful abort of libburn. (See man signal.h) */ /* Once as system defined macros */ #define BURN_OS_SIGNAL_MACRO_LIST \ SIGHUP, SIGINT, SIGQUIT, SIGILL, SIGABRT, \ SIGFPE, SIGSEGV, SIGPIPE, SIGALRM, SIGTERM, \ SIGUSR1, SIGUSR2, SIGXCPU /* Once as text 1:1 list of strings for messages and interpreters */ #define BURN_OS_SIGNAL_NAME_LIST \ "SIGHUP", "SIGINT", "SIGQUIT", "SIGILL", "SIGABRT", \ "SIGFPE", "SIGSEGV", "SIGPIPE", "SIGALRM", "SIGTERM", \ "SIGUSR1", "SIGUSR2", "SIGXCPU" /* The number of above list items */ #define BURN_OS_SIGNAL_COUNT 13 /** To list all signals which shall surely not be caught */ #define BURN_OS_NON_SIGNAL_MACRO_LIST \ SIGKILL, SIGCHLD, SIGSTOP, SIGTSTP, SIGCONT, SIGTTIN, SIGTTOU, SIGURG, SIGWINCH /* The number of above list items */ #define BURN_OS_NON_SIGNAL_COUNT 9 /* The maximum size for a (SCSI) i/o transaction */ /* Important : MUST be at least 32768 ! */ /* My Blu-ray burner LG GGW-H20 writes junk if stream recording is combined with buffer size 32 kB. So stream recording is allowed only with size 64k. */ #define BURN_OS_TRANSPORT_BUFFER_SIZE 65536 /* >>> */ /* To hold the position of the most recently delivered address from device enumeration. */ struct burn_drive_enumerator_struct { void *dir; }; #define BURN_OS_DEFINE_DRIVE_ENUMERATOR_T \ typedef struct burn_drive_enumerator_struct burn_drive_enumerator_t; /* The list of operating system dependent elements in struct burn_drive. Usually they are initialized in sg-*.c:enumerate_common(). */ #define BURN_OS_TRANSPORT_DRIVE_ELEMENTS \ int fd; ��������������������������������������������libburn-1.4.2/libburn/cleanup.h���������������������������������������������������������������������0000644�0001757�0001751�00000002232�12652644224�013347� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* cleanup.c , Copyright 2006 Thomas Schmitt <scdbackup@gmx.net> A signal handler which cleans up an application and exits. Provided under GPLv2+ within GPL projects, BSD license elsewise. */ #ifndef Cleanup_includeD #define Cleanup_includeD 1 /** Layout of an application provided cleanup function using an application provided handle as first argument and the signal number as second argument. The third argument is a flag bit field with no defined bits yet. If the handler returns 2 or -2 then it has delegated exit() to some other instance and the Cleanup handler shall return rather than exit. */ typedef int (*Cleanup_app_handler_T)(void *, int, int); /** Establish exiting signal handlers on (hopefully) all signals that are not ignored by default or non-catchable. @param handle Opaque object which knows how to cleanup application @param handler Function which uses handle to perform application cleanup @param flag Control Bitfield bit0= reset to default signal handling */ int Cleanup_set_handlers(void *handle, Cleanup_app_handler_T handler, int flag); #endif /* ! Cleanup_includeD */ ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������libburn-1.4.2/libburn/drive.c�����������������������������������������������������������������������0000644�0001757�0001751�00000263712�12652644224�013040� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */ /* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens Copyright (c) 2006 - 2014 Thomas Schmitt <scdbackup@gmx.net> Provided under GPL version 2 or later. */ #ifdef HAVE_CONFIG_H #include "../config.h" #endif #include <sys/types.h> #include <sys/stat.h> #include <stdlib.h> #include <unistd.h> #include <signal.h> #include <dirent.h> /* ts A61007 */ /* #include <a ssert.h> */ #include <stdio.h> #include <string.h> #include <ctype.h> #include <pthread.h> #include <errno.h> #include <fcntl.h> /* ts B41126 : O_BINARY is needed for Cygwin but undefined elsewhere */ #ifndef O_BINARY #define O_BINARY 0 #endif #include "libburn.h" #include "init.h" #include "drive.h" #include "transport.h" #include "debug.h" #include "init.h" #include "toc.h" #include "util.h" #include "sg.h" #include "structure.h" /* ts A70107 : to get BE_CANCELLED */ #include "error.h" /* ts A70219 : for burn_disc_get_write_mode_demands() */ #include "options.h" /* A70225 : to learn about eventual Libburn_dvd_r_dl_multi_no_close_sessioN */ #include "write.h" /* A70903 : for burn_scsi_setup_drive() */ #include "spc.h" /* A90815 : for mmc_obtain_profile_name() */ #include "mmc.h" #include "libdax_msgs.h" extern struct libdax_msgs *libdax_messenger; static struct burn_drive drive_array[255]; static int drivetop = -1; /* ts A80410 : in init.c */ extern int burn_support_untested_profiles; /* ts B10312 : in init.c */ extern int burn_drive_role_4_allowed; /* ts A61021 : the unspecific part of sg.c:enumerate_common() */ int burn_setup_drive(struct burn_drive *d, char *fname) { d->devname = strdup(fname); memset(&d->params, 0, sizeof(struct params)); d->idata = NULL; d->mdata = NULL; d->toc_entry = NULL; d->released = 1; d->stdio_fd = -1; d->status = BURN_DISC_UNREADY; d->erasable = 0; d->current_profile = -1; d->do_stream_recording = 0; d->stream_recording_start= 0; d->role_5_nwa = 0; d->features = NULL; d->drive_serial_number = NULL; d->drive_serial_number_len = -1; d->media_serial_number = NULL; d->media_serial_number_len = -1; return 1; } /* ts A70903 */ void burn_drive_free_subs(struct burn_drive *d) { if (d->idata != NULL) free((void *) d->idata); d->idata = NULL; if (d->mdata != NULL) { burn_mdata_free_subs(d->mdata); free((void *) d->mdata); } d->mdata = NULL; if(d->toc_entry != NULL) free((void *) d->toc_entry); d->toc_entry = NULL; if (d->devname != NULL) free(d->devname); d->devname = NULL; if (d->stdio_fd >= 0) close (d->stdio_fd); d->stdio_fd = -1; burn_feature_descr_free(&(d->features), 0); BURN_FREE_MEM(d->drive_serial_number); BURN_FREE_MEM(d->media_serial_number); d->drive_serial_number = d->media_serial_number = NULL; d->drive_serial_number_len = d->media_serial_number_len = 0; sg_dispose_drive(d, 0); } /* ts A60904 : ticket 62, contribution by elmom */ /* splitting former burn_drive_free() (which freed all, into two calls) */ void burn_drive_free(struct burn_drive *d) { if (d->global_index == -1) return; /* ts A60822 : close open fds before forgetting them */ if (d->drive_role == 1) if (burn_drive_is_open(d)) { d->unlock(d); d->release(d); } burn_drive_free_subs(d); d->global_index = -1; } void burn_drive_free_all(void) { int i; for (i = 0; i < drivetop + 1; i++) burn_drive_free(&(drive_array[i])); drivetop = -1; memset(drive_array, 0, sizeof(drive_array)); } /* ts A60822 */ int burn_drive_is_open(struct burn_drive *d) { if (d->drive_role != 1) return (d->stdio_fd >= 0); /* ts A61021 : moved decision to sg.c */ return d->drive_is_open(d); } /* ts A60906 */ int burn_drive_force_idle(struct burn_drive *d) { d->busy = BURN_DRIVE_IDLE; return 1; } /* ts A60906 */ int burn_drive_is_released(struct burn_drive *d) { return !!d->released; } /* ts A60906 */ /** Inquires drive status in respect to degree of app usage. @param return -2 = drive is forgotten -1 = drive is closed (i.e. released explicitely) 0 = drive is open, not grabbed (after scan, before 1st grab) 1 = drive is grabbed but BURN_DRIVE_IDLE 2 = drive is grabbed, synchronous read/write interrupted 10 = drive is grabbing (BURN_DRIVE_GRABBING) 100 = drive is busy in cancelable state 1000 = drive is in non-cancelable state Expect a monotonous sequence of usage severity to emerge in future. */ int burn_drive_is_occupied(struct burn_drive *d) { if(d->global_index < 0) return -2; if(!burn_drive_is_open(d)) return -1; if(d->busy == BURN_DRIVE_GRABBING) return 10; if(d->released) return 0; if(d->busy == BURN_DRIVE_IDLE) return 1; if(d->busy == BURN_DRIVE_READING_SYNC || d->busy == BURN_DRIVE_WRITING_SYNC) return 2; if(d->busy == BURN_DRIVE_WRITING || d->busy == BURN_DRIVE_WRITING_LEADIN || d->busy == BURN_DRIVE_WRITING_LEADOUT || d->busy == BURN_DRIVE_WRITING_PREGAP) { /* ts A70928 */ /* >>> how do i learn whether the writer thread is still alive ? */; /* >>> what to do if writer is dead ? At least sync disc ?*/; return 50; } if(d->busy == BURN_DRIVE_READING) { return 50; } return 1000; } /* void drive_read_lead_in(int dnum) { mmc_read_lead_in(&drive_array[dnum], get_4k()); } */ unsigned int burn_drive_count(void) { return drivetop + 1; } /* ts A80801 */ int burn_drive_is_listed(char *path, struct burn_drive **found, int flag) { int i, ret; char *drive_adr = NULL, *off_adr = NULL; BURN_ALLOC_MEM(drive_adr, char, BURN_DRIVE_ADR_LEN); BURN_ALLOC_MEM(off_adr, char, BURN_DRIVE_ADR_LEN); ret = burn_drive_convert_fs_adr(path, off_adr); if (ret <= 0) strcpy(off_adr, path); for (i = 0; i <= drivetop; i++) { if (drive_array[i].global_index < 0) continue; ret = burn_drive_d_get_adr(&(drive_array[i]), drive_adr); if (ret <= 0) continue; if(strcmp(off_adr, drive_adr) == 0) { if (found != NULL) *found= &(drive_array[i]); {ret= 1; goto ex;} } } ret= 0; ex:; BURN_FREE_MEM(drive_adr); BURN_FREE_MEM(off_adr); return ret; } /* ts A61125 : media status aspects of burn_drive_grab() */ int burn_drive_inquire_media(struct burn_drive *d) { /* ts A61225 : after loading the tray, mode page 2Ah can change */ d->getcaps(d); /* ts A61020 : d->status was set to BURN_DISC_BLANK as pure guess */ /* ts A71128 : run read_disc_info() for any recognizeable profile */ if (d->current_profile > 0 || d->current_is_guessed_profile || (d->mdata->p2a_valid > 0 && (d->mdata->cdr_write || d->mdata->cdrw_write || d->mdata->dvdr_write || d->mdata->dvdram_write)) ) { d->read_disc_info(d); } else { if (d->current_profile == -1 || d->current_is_cd_profile) d->read_toc(d); /* ts A70314 , B10712 */ if (d->status != BURN_DISC_EMPTY) d->status = BURN_DISC_UNSUITABLE; } 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, NULL, -1, 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, 0, &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; } /* flag bit0= ( not needed yet: grab even if it is already grabbed ) */ 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, 0, &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 errcode; /* ts A61125 - B20122 */ int ret, sose, signal_action_mem = -1; sose = d->silent_on_scsi_error; if (!d->released) { 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; } if(d->drive_role != 1) { ret = burn_drive_grab_stdio(d, 0); return ret; } d->status = BURN_DISC_UNREADY; errcode = d->grab(d); if (errcode == 0) return 0; burn_grab_prepare_sig_action(&signal_action_mem, 0); d->busy = BURN_DRIVE_GRABBING; if (le) d->load(d); if (d->cancel || burn_is_aborting(0)) {ret = 0; goto ex;} d->lock(d); if (d->cancel || burn_is_aborting(0)) {ret = 0; goto ex;} /* ts A61118 */ d->start_unit(d); if (d->cancel || burn_is_aborting(0)) {ret = 0; goto ex;} /* ts A61202 : gave bit1 of le a meaning */ if (!le) d->silent_on_scsi_error = 1; /* ts A61125 : outsourced media state inquiry aspects */ ret = burn_drive_inquire_media(d); if (d->cancel || burn_is_aborting(0)) {ret = 0; goto ex;} burn_drive_send_default_page_05(d, 0); if (d->cancel || burn_is_aborting(0)) {ret = 0; goto ex;} ex:; if (d->cancel || burn_is_aborting(0)) { d->unlock(d); d->release(d); } d->silent_on_scsi_error = sose; d->busy = BURN_DRIVE_IDLE; burn_grab_restore_sig_action(signal_action_mem, 0); return ret; } /* ts A71015 */ #define Libburn_ticket_62_re_register_is_possiblE 1 struct burn_drive *burn_drive_register(struct burn_drive *d) { #ifdef Libburn_ticket_62_re_register_is_possiblE int i; #endif d->block_types[0] = 0; d->block_types[1] = 0; d->block_types[2] = 0; d->block_types[3] = 0; d->toc_temp = 0; d->nwa = 0; d->alba = 0; d->rlba = 0; d->cancel = 0; d->busy = BURN_DRIVE_IDLE; d->thread_pid = 0; d->thread_pid_valid = 0; memset(&(d->thread_tid), 0, sizeof(d->thread_tid)); d->toc_entries = 0; d->toc_entry = NULL; d->disc = NULL; d->erasable = 0; d->write_opts = NULL; #ifdef Libburn_ticket_62_re_register_is_possiblE /* ts A60904 : ticket 62, contribution by elmom */ /* Not yet accepted because no use case seen yet */ /* ts A71015 : xorriso dialog imposes a use case now */ /* This is supposed to find an already freed drive struct among all the the ones that have been used before */ for (i = 0; i < drivetop + 1; i++) if (drive_array[i].global_index == -1) break; d->global_index = i; memcpy(&drive_array[i], d, sizeof(struct burn_drive)); pthread_mutex_init(&drive_array[i].access_lock, NULL); if (drivetop < i) drivetop = i; return &(drive_array[i]); #else /* Libburn_ticket_62_re_register_is_possiblE */ /* old A60904 : */ /* Still active by default */ d->global_index = drivetop + 1; memcpy(&drive_array[drivetop + 1], d, sizeof(struct burn_drive)); pthread_mutex_init(&drive_array[drivetop + 1].access_lock, NULL); return &drive_array[++drivetop]; #endif /* ! Libburn_ticket_62_re_register_is_possiblE */ } /* unregister most recently registered drive */ int burn_drive_unregister(struct burn_drive *d) { if(d->global_index != drivetop) return 0; burn_drive_free(d); drivetop--; return 1; } /* ts A61021 : after-setup activities from sg.c:enumerate_common() */ struct burn_drive *burn_drive_finish_enum(struct burn_drive *d) { struct burn_drive *t = NULL; char *msg = NULL; int ret; BURN_ALLOC_MEM(msg, char, BURN_DRIVE_ADR_LEN + 160); d->drive_role = 1; /* MMC drive */ t = burn_drive_register(d); /* ts A60821 */ mmc_function_spy(NULL, "enumerate_common : -------- doing grab"); /* try to get the drive info */ ret = t->grab(t); if (ret) { t->getcaps(t); t->unlock(t); t->released = 1; } else { /* ts A90602 */ d->mdata->p2a_valid = -1; sprintf(msg, "Unable to grab scanned drive %s", d->devname); libdax_msgs_submit(libdax_messenger, d->global_index, 0x0002016f, LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_LOW, msg, 0, 0); burn_drive_unregister(t); t = NULL; } /* ts A60821 */ mmc_function_spy(NULL, "enumerate_common : ----- would release "); ex: BURN_FREE_MEM(msg); return t; } /* ts A61125 : model aspects of burn_drive_release */ /* @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 */ d->start_lba= -2000000000; d->end_lba= -2000000000; /* ts A61202 */ d->current_profile = -1; d->current_has_feat21h = 0; d->current_feat2fh_byte4 = -1; d->status = BURN_DISC_UNREADY; if (d->toc_entry != NULL) free(d->toc_entry); d->toc_entry = NULL; d->toc_entries = 0; if (d->write_opts != NULL) { burn_write_opts_free(d->write_opts); d->write_opts = NULL; } if (d->disc != NULL) { burn_disc_free(d->disc); d->disc = NULL; } if (!(flag & 8)) { if (d->stdio_fd >= 0) close (d->stdio_fd); d->stdio_fd = -1; } return 1; } /* ts A70918 : outsourced from burn_drive_release() and enhanced */ /** @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) { if (d->released) { /* ts A61007 */ libdax_msgs_submit(libdax_messenger, d->global_index, 0x00020105, LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH, "Drive is already released", 0, 0); return 0; } /* ts A61007 */ /* ts A60906: one should not assume BURN_DRIVE_IDLE == 0 */ /* a ssert(d->busy == BURN_DRIVE_IDLE); */ if (d->busy != BURN_DRIVE_IDLE) { libdax_msgs_submit(libdax_messenger, d->global_index, 0x00020106, LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH, "Drive is busy on attempt to close", 0, 0); return 0; } if (d->drive_role == 1) { if (d->needs_sync_cache) d->sync_cache(d); if ((flag & 7) != 2) d->unlock(d); if ((flag & 7) == 1) d->eject(d); if (!(flag & 8)) { burn_drive_snooze(d, 0); d->release(d); } } d->needs_sync_cache = 0; /* just to be sure */ if (d->drive_serial_number != NULL) BURN_FREE_MEM(d->drive_serial_number); if (d->media_serial_number != NULL) BURN_FREE_MEM(d->media_serial_number); d->drive_serial_number = d->media_serial_number = NULL; d->drive_serial_number_len = d->media_serial_number_len = 0; d->released = 1; /* ts A61125 : outsourced model aspects */ burn_drive_mark_unready(d, flag & 8); return 1; } /* API */ /* ts A90824 @param flag bit0= wake up (else start snoozing) */ int burn_drive_snooze(struct burn_drive *d, int flag) { if (d->drive_role != 1) return 0; if (flag & 1) d->start_unit(d); else d->stop_unit(d); return 1; } /* API */ void burn_drive_release(struct burn_drive *d, int le) { burn_drive_release_fl(d, !!le); } /* ts B11002 */ /* API */ int burn_drive_re_assess(struct burn_drive *d, int flag) { int ret, signal_action_mem; 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; } burn_grab_prepare_sig_action(&signal_action_mem, 0); d->busy = BURN_DRIVE_GRABBING; ret = burn_drive_inquire_media(d); burn_drive_send_default_page_05(d, 0); d->busy = BURN_DRIVE_IDLE; burn_grab_restore_sig_action(signal_action_mem, 0); d->released = 0; return ret; } /* ts A70918 */ /* API */ int burn_drive_leave_locked(struct burn_drive *d, int flag) { return burn_drive_release_fl(d, 2); } /* ts A61007 : former void burn_wait_all() */ /* @param flag bit0= demand freed drives (else released drives) */ int burn_drives_are_clear(int flag) { int i; for (i = burn_drive_count() - 1; i >= 0; --i) { /* ts A60904 : ticket 62, contribution by elmom */ if (drive_array[i].global_index == -1) continue; if (drive_array[i].released && !(flag & 1)) continue; return 0; } return 1; } #if 0 void burn_wait_all(void) { unsigned int i; int finished = 0; struct burn_drive *d; while (!finished) { finished = 1; d = drive_array; for (i = burn_drive_count(); i > 0; --i, ++d) { /* ts A60904 : ticket 62, contribution by elmom */ if (d->global_index==-1) continue; a ssert(d->released); } if (!finished) sleep(1); } } #endif void burn_disc_erase_sync(struct burn_drive *d, int fast) { int ret, was_error = 0; if (d->drive_role == 5) { /* Random access write-only drive */ ret = truncate(d->devname, (off_t) 0); if (ret == -1) { libdax_msgs_submit(libdax_messenger, -1, 0x00020182, LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH, "Cannot truncate disk file for pseudo blanking", 0, 0); return; } d->role_5_nwa = 0; d->cancel = 0; d->status = BURN_DISC_BLANK; d->busy = BURN_DRIVE_IDLE; d->progress.sector = 0x10000; return; } d->cancel = 0; #ifdef Libburn_reset_progress_asynC /* <<< This is now done in async.c */ /* reset the progress */ d->progress.session = 0; d->progress.sessions = 1; d->progress.track = 0; d->progress.tracks = 1; d->progress.index = 0; d->progress.indices = 1; d->progress.start_sector = 0; d->progress.sectors = 0x10000; d->progress.sector = 0; #endif /* Libburn_reset_progress_asynC */ d->erase(d, fast); d->busy = BURN_DRIVE_ERASING; #ifdef Libburn_old_progress_looP /* read the initial 0 stage */ while (!d->test_unit_ready(d) && d->get_erase_progress(d) == 0) sleep(1); while ((d->progress.sector = d->get_erase_progress(d)) > 0 || !d->test_unit_ready(d)) sleep(1); #else /* Libburn_old_progress_looP */ while (1) { ret = d->get_erase_progress(d); if (ret == -2 || ret > 0) break; if (ret == -3) was_error = 1; sleep(1); } while (1) { ret = d->get_erase_progress(d); if(ret == -2) break; if (ret == -3) was_error = 1; if (ret >= 0) d->progress.sector = ret; sleep(1); } #endif /* ! Libburn_old_progress_looP */ d->progress.sector = 0x10000; /* ts A61125 : update media state records */ burn_drive_mark_unready(d, 0); if (d->drive_role == 1) burn_drive_inquire_media(d); d->busy = BURN_DRIVE_IDLE; if (was_error) d->cancel = 1; } /* @param flag: bit0 = fill formatted size with zeros bit1, bit2 , bit4, bit5, bit7 - bit15 are for d->format_unit() */ void burn_disc_format_sync(struct burn_drive *d, off_t size, int flag) { int ret, buf_secs, err, i, stages = 1, pbase, pfill, pseudo_sector; int was_error = 0; off_t num_bufs; char msg[80]; struct buffer *buf = NULL, *buf_mem = d->buffer; BURN_ALLOC_MEM(buf, struct buffer, 1); #ifdef Libburn_reset_progress_asynC /* <<< This is now done in async.c */ /* reset the progress */ d->progress.session = 0; d->progress.sessions = 1; d->progress.track = 0; d->progress.tracks = 1; d->progress.index = 0; d->progress.indices = 1; d->progress.start_sector = 0; d->progress.sectors = 0x10000; d->progress.sector = 0; #endif /* Libburn_reset_progress_asynC */ stages = 1 + ((flag & 1) && size > 1024 * 1024); d->cancel = 0; d->busy = BURN_DRIVE_FORMATTING; ret = d->format_unit(d, size, flag & 0xfff6); /* forward bits */ if (ret <= 0) d->cancel = 1; #ifdef Libburn_old_progress_looP while (!d->test_unit_ready(d) && d->get_erase_progress(d) == 0) sleep(1); while ((pseudo_sector = d->get_erase_progress(d)) > 0 || !d->test_unit_ready(d)) { d->progress.sector = pseudo_sector / stages; sleep(1); } #else /* Libburn_old_progress_looP */ while (1) { ret = d->get_erase_progress(d); if (ret == -2 || ret > 0) break; if (ret == -3) was_error = 1; sleep(1); } while (1) { pseudo_sector = d->get_erase_progress(d); if(pseudo_sector == -2) break; if (pseudo_sector == -3) was_error = 1; if (pseudo_sector >= 0) d->progress.sector = pseudo_sector / stages; sleep(1); } #endif /* ! Libburn_old_progress_looP */ d->sync_cache(d); if (size <= 0) goto ex; /* update media state records */ burn_drive_mark_unready(d, 0); burn_drive_inquire_media(d); if (flag & 1) { /* write size in zeros */; pbase = 0x8000 + 0x7fff * (stages == 1); pfill = 0xffff - pbase; buf_secs = 16; /* Must not be more than 16 */ num_bufs = size / buf_secs / 2048; if (num_bufs > 0x7fffffff) { d->cancel = 1; goto ex; } /* <<< */ sprintf(msg, "Writing %.f sectors of zeros to formatted media", (double) num_bufs * (double) buf_secs); libdax_msgs_submit(libdax_messenger, d->global_index, 0x00000002, LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_ZERO, msg, 0, 0); d->buffer = buf; memset(d->buffer, 0, sizeof(struct buffer)); d->buffer->bytes = buf_secs * 2048; d->buffer->sectors = buf_secs; d->busy = BURN_DRIVE_WRITING; for (i = 0; i < num_bufs; i++) { d->nwa = i * buf_secs; err = d->write(d, d->nwa, d->buffer); if (err == BE_CANCELLED || d->cancel) { d->cancel = 1; break; } d->progress.sector = pbase + pfill * ((double) i / (double) num_bufs); } d->sync_cache(d); if (d->current_profile == 0x13 || d->current_profile == 0x1a) { /* DVD-RW or DVD+RW */ d->busy = BURN_DRIVE_CLOSING_SESSION; /* CLOSE SESSION, 010b */ d->close_track_session(d, 1, 0); d->busy = BURN_DRIVE_WRITING; } } ex:; d->progress.sector = 0x10000; d->busy = BURN_DRIVE_IDLE; d->buffer = buf_mem; if (was_error) d->cancel = 1; BURN_FREE_MEM(buf); } /* ts A70112 API */ int burn_disc_get_formats(struct burn_drive *d, int *status, off_t *size, unsigned *bl_sas, int *num_formats) { int ret; *status = 0; *size = 0; *bl_sas = 0; *num_formats = 0; if (d->drive_role != 1) return 0; ret = d->read_format_capacities(d, 0x00); if (ret <= 0) return 0; *status = d->format_descr_type; *size = d->format_curr_max_size; *bl_sas = d->format_curr_blsas; *num_formats = d->num_format_descr; return 1; } /* ts A70112 API */ int burn_disc_get_format_descr(struct burn_drive *d, int index, int *type, off_t *size, unsigned *tdp) { *type = 0; *size = 0; *tdp = 0; if (index < 0 || index >= d->num_format_descr) return 0; *type = d->format_descriptors[index].type; *size = d->format_descriptors[index].size; *tdp = d->format_descriptors[index].tdp; return 1; } enum burn_disc_status burn_disc_get_status(struct burn_drive *d) { /* ts A61007 */ /* a ssert(!d->released); */ 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 disc status inquiry", 0, 0); return BURN_DISC_UNGRABBED; } return d->status; } int burn_disc_erasable(struct burn_drive *d) { return d->erasable; } enum burn_drive_status burn_drive_get_status(struct burn_drive *d, struct burn_progress *p) { /* --- Part of asynchronous signal handling --- */ /* This frequently used call may be used to react on messages from the libburn built-in signal handler. */ /* ts B00225 : If aborting with action 2: catch control thread after it returned from signal handler. Let it run burn_abort(4440,...) */ burn_init_catch_on_abort(0); /* ts A70928 : inform control thread of signal in sub-threads */ if (burn_builtin_triggered_action < 2 && burn_global_abort_level > 0) burn_global_abort_level++; if (burn_builtin_triggered_action < 2 && burn_global_abort_level > 5) { if (burn_global_signal_handler == NULL) kill(getpid(), burn_global_abort_signum); else (*burn_global_signal_handler) (burn_global_signal_handle, burn_global_abort_signum, 0); burn_global_abort_level = -1; } /* --- End of asynchronous signal handling --- */ if (p != NULL) { memcpy(p, &(d->progress), sizeof(struct burn_progress)); /* TODO: add mutex */ } return d->busy; } int burn_drive_set_stream_recording(struct burn_drive *d, int recmode, int start, int flag) { if (recmode == 1) d->do_stream_recording = 1; else if (recmode == -1) d->do_stream_recording = 0; d->stream_recording_start = start; return(1); } void burn_drive_cancel(struct burn_drive *d) { /* ts B00225 : these mutexes are unnecessary because "= 1" is atomar. pthread_mutex_lock(&d->access_lock); */ if (!d->cancel) { libdax_msgs_submit(libdax_messenger, -1, 0x00000002, LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_ZERO, "burn_drive_cancel() was called", 0, 0); } d->cancel = 1; /* pthread_mutex_unlock(&d->access_lock); */ } static void strip_spaces(char *str, size_t len) { char *tmp, *tmp2; /* Remove trailing blanks */ for (tmp = str + len - 1; tmp >= str && (isspace(*tmp) || !*tmp); tmp--) *tmp = 0; /* Condense remaining blank intervals to single blanks */ for (tmp = str; tmp < str + len - 1 && *tmp; tmp++) { if (isspace(*tmp) && isspace(*(tmp + 1))) { for (tmp2 = tmp + 1; tmp2 < str + len && *tmp2; tmp2++) *(tmp2 - 1) = *tmp2; *(tmp2 - 1) = '\0'; tmp--; /* try same first blank again */ } } } static int drive_getcaps(struct burn_drive *d, struct burn_drive_info *out) { struct burn_scsi_inquiry_data *id; int i, profile; struct burn_feature_descr *feat; /* ts A61007 : now prevented in enumerate_common() */ #if 0 a ssert(d->idata); a ssert(d->mdata); #endif if(d->idata->valid <= 0) return 0; id = (struct burn_scsi_inquiry_data *)d->idata; memcpy(out->vendor, id->vendor, sizeof(id->vendor)); strip_spaces(out->vendor, sizeof(id->vendor)); memcpy(out->product, id->product, sizeof(id->product)); strip_spaces(out->product, sizeof(id->product)); memcpy(out->revision, id->revision, sizeof(id->revision)); strip_spaces(out->revision, sizeof(id->revision)); strncpy(out->location, d->devname, 16); out->location[16] = '\0'; if (d->mdata->p2a_valid > 0) { out->buffer_size = d->mdata->buffer_size; out->read_dvdram = !!d->mdata->dvdram_read; out->read_dvdr = !!d->mdata->dvdr_read; out->read_dvdrom = !!d->mdata->dvdrom_read; out->read_cdr = !!d->mdata->cdr_read; out->read_cdrw = !!d->mdata->cdrw_read; out->write_dvdram = !!d->mdata->dvdram_write; out->write_dvdr = !!d->mdata->dvdr_write; out->write_cdr = !!d->mdata->cdr_write; out->write_cdrw = !!d->mdata->cdrw_write; out->write_simulate = !!d->mdata->simulate; out->c2_errors = !!d->mdata->c2_pointers; } else { out->buffer_size = out->read_dvdram = out->read_dvdr = 0; out->read_dvdrom = out->read_cdr = out->read_cdrw = 0; out->write_dvdram = out->write_dvdr = out->write_cdr = 0; out->write_cdrw = out->write_simulate = out->c2_errors = 0; for (i = 0; i < d->num_profiles; i++) { profile = (d->all_profiles[i * 4] << 8) | d->all_profiles[i * 4 + 1]; if (profile == 0x09) out->write_cdr = out->read_cdr = 1; else if (profile == 0x0a) out->write_cdrw = out->read_cdrw = 1; else if (profile == 0x10) out->read_dvdrom = 1; else if (profile == 0x11) out->write_dvdr = out->read_dvdr = 1; else if (profile == 0x12) out->write_dvdram = out->read_dvdram = 1; } /* Test Write bit of CD TAO, CD Mastering, DVD-R/-RW Write */ for (i = 0x002D; i <= 0x002F; i++) if (burn_drive_has_feature(d, i, &feat, 0)) if (feat->data_lenght > 0) out->write_simulate |= !!(feat->data[0] & 4); } out->drive = d; #ifdef Libburn_dummy_probe_write_modeS /* ts A91112 */ /* Set default block types. The call d->probe_write_modes() is quite obtrusive. It may be performed explicitely by new API call burn_drive_probe_cd_write_modes(). */ if (out->write_dvdram || out->write_dvdr || out->write_cdrw || out->write_cdr) { out->tao_block_types = d->block_types[BURN_WRITE_TAO] = BURN_BLOCK_MODE1 | BURN_BLOCK_RAW0; out->sao_block_types = d->block_types[BURN_WRITE_SAO] = BURN_BLOCK_SAO; } else { out->tao_block_types = d->block_types[BURN_WRITE_TAO] = 0; out->sao_block_types = d->block_types[BURN_WRITE_SAO] = 0; } out->raw_block_types = d->block_types[BURN_WRITE_RAW] = 0; out->packet_block_types = 0; #else /* Libburn_dummy_probe_write_modeS */ /* update available block types for burners */ if (out->write_dvdram || out->write_dvdr || out->write_cdrw || out->write_cdr) d->probe_write_modes(d); out->tao_block_types = d->block_types[BURN_WRITE_TAO]; out->sao_block_types = d->block_types[BURN_WRITE_SAO]; out->raw_block_types = d->block_types[BURN_WRITE_RAW]; out->packet_block_types = d->block_types[BURN_WRITE_PACKET]; #endif /* ! Libburn_dummy_probe_write_modeS */ return 1; } /* ts A91112 - B00114 API */ /* Probe available CD write modes and block types. */ int burn_drive_probe_cd_write_modes(struct burn_drive_info *dinfo) { struct burn_drive *d = dinfo->drive; if (d == NULL) return 0; if (dinfo->write_dvdram || dinfo->write_dvdr || dinfo->write_cdrw || dinfo->write_cdr) d->probe_write_modes(d); dinfo->tao_block_types = d->block_types[BURN_WRITE_TAO]; dinfo->sao_block_types = d->block_types[BURN_WRITE_SAO]; dinfo->raw_block_types = d->block_types[BURN_WRITE_RAW]; dinfo->packet_block_types = d->block_types[BURN_WRITE_PACKET]; return 1; } /* ts A70907 : added parameter flag */ /* @param flag bit0= reset global drive list */ int burn_drive_scan_sync(struct burn_drive_info *drives[], unsigned int *n_drives, int flag) { /* ts A70907 : There seems to have been a misunderstanding about the role of burn_drive_scan_sync(). It needs no static state because it is only started once during an asynchronous scan operation. Its starter, burn_drive_scan(), is the one which ends immediately and gets called repeatedly. It acts on start of scanning by calling burn_drive_scan_sync(), returns idle while scanning is not done and finally removes the worker object which represented burn_drive_scan_sync(). The scanning itself is not parallel but enumerates sequentially drive by drive (within scsi_enumerate_drives()). I will use "scanned" for marking drives found by previous runs. It will not be static any more. */ /* ts A71015 : this makes only trouble : static int scanning = 0; */ /* ts A70907 : These variables are too small anyway. We got up to 255 drives. static int scanned = 0, found = 0; Variable "found" was only set but never read. */ unsigned char scanned[32]; unsigned count = 0; int i, ret; /* ts A61007 : moved up to burn_drive_scan() */ /* a ssert(burn_running); */ /* ts A61007 : test moved up to burn_drive_scan() burn_wait_all() is obsoleted */ #if 0 /* make sure the drives aren't in use */ burn_wait_all(); /* make sure the queue cleans up before checking for the released state */ #endif /* 0 */ *n_drives = 0; /* ts A70907 : wether to scan from scratch or to extend */ for (i = 0; i < (int) sizeof(scanned); i++) scanned[i] = 0; if (flag & 1) { burn_drive_free_all(); } else { for (i = 0; i <= drivetop; i++) if (drive_array[i].global_index >= 0) scanned[i / 8] |= (1 << (i % 8)); } /* refresh the lib's drives */ /* ts A61115 : formerly sg_enumerate(); ata_enumerate(); */ scsi_enumerate_drives(); count = burn_drive_count(); if (count) { /* ts A70907 : Extra array element marks end of array. */ *drives = calloc(count + 1, sizeof(struct burn_drive_info)); if (*drives == NULL) { libdax_msgs_submit(libdax_messenger, -1, 0x00000003, LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH, "Out of virtual memory", 0, 0); return -1; } else for (i = 0; i <= (int) count; i++) /* invalidate */ (*drives)[i].drive = NULL; } else *drives = NULL; for (i = 0; i < (int) count; ++i) { if (scanned[i / 8] & (1 << (i % 8))) continue; /* device already scanned by previous run */ if (drive_array[i].global_index < 0) continue; /* invalid device */ /* ts A90602 : This old loop is not plausible. See A70907. while (!drive_getcaps(&drive_array[i], &(*drives)[*n_drives])) { sleep(1); } */ /* ts A90602 : A single call shall do (rather than a loop) */ ret = drive_getcaps(&drive_array[i], &(*drives)[*n_drives]); if (ret > 0) (*n_drives)++; scanned[i / 8] |= 1 << (i % 8); } if (*drives != NULL && *n_drives == 0) { free ((char *) *drives); *drives = NULL; } return(1); } /* ts A61001 : internal call */ int burn_drive_forget(struct burn_drive *d, int force) { int occup; occup = burn_drive_is_occupied(d); /* fprintf(stderr, "libburn: experimental: occup == %d\n",occup); */ if(occup <= -2) return 2; if(occup > 0) if(force < 1) return 0; if(occup >= 10) return 0; /* >>> do any drive calming here */; burn_drive_force_idle(d); if(occup > 0 && !burn_drive_is_released(d)) burn_drive_release(d,0); burn_drive_free(d); return 1; } /* API call */ int burn_drive_info_forget(struct burn_drive_info *info, int force) { return burn_drive_forget(info->drive, force); } void burn_drive_info_free(struct burn_drive_info drive_infos[]) { #ifndef Libburn_free_all_drives_on_infO int i; #endif /* ts A60904 : ticket 62, contribution by elmom */ /* clarifying the meaning and the identity of the victim */ if(drive_infos == NULL) return; #ifndef Libburn_free_all_drives_on_infO #ifdef Not_yeT int new_drivetop; /* ts A71015: compute reduced drivetop counter */ new_drivetop = drivetop; for (i = 0; drive_infos[i].drive != NULL; i++) if (drive_infos[i].global_index == new_drivetop && new_drivetop >= 0) { new_drivetop--; i = 0; } #endif /* Not_yeT */ /* ts A70907 : Solution for wrong behavior below */ for (i = 0; drive_infos[i].drive != NULL; i++) burn_drive_free(drive_infos[i].drive); #ifdef Not_yeT drivetop = new_drivetop; #endif /* Not_yeT */ #endif /* ! Libburn_free_all_drives_on_infO */ /* ts A60904 : This looks a bit weird. [ts A70907 : not any more] burn_drive_info is not the manager of burn_drive but only its spokesperson. To my knowlege drive_infos from burn_drive_scan() are not memorized globally. */ free((void *) drive_infos); #ifdef Libburn_free_all_drives_on_infO /* ts A70903 : THIS IS WRONG ! (disabled now) It endangers multi drive usage. This call is not entitled to delete all drives, only the ones of the array which it recieves a parmeter. Problem: It was unclear how many items are listed in drive_infos Solution: Added a end marker element to any burn_drive_info array The mark can be recognized by having drive == NULL */ burn_drive_free_all(); #endif } struct burn_disc *burn_drive_get_disc(struct burn_drive *d) { /* ts A61022: SIGSEGV on calling this function with blank media */ if(d->disc == NULL) return NULL; d->disc->refcnt++; return d->disc; } void burn_drive_set_speed(struct burn_drive *d, int r, int w) { d->nominal_write_speed = w; if(d->drive_role != 1) return; d->set_speed(d, r, w); } /* ts A70711 API function */ int burn_drive_set_buffer_waiting(struct burn_drive *d, int enable, int min_usec, int max_usec, int timeout_sec, int min_percent, int max_percent) { if (enable >= 0) d->wait_for_buffer_free = !!enable; if (min_usec >= 0) d->wfb_min_usec = min_usec; if (max_usec >= 0) d->wfb_max_usec = max_usec; if (timeout_sec >= 0) d->wfb_timeout_sec = timeout_sec; if (min_percent >= 0) { if (min_percent < 25 || min_percent > 100) return 0; d->wfb_min_percent = min_percent; } if (max_percent >= 0) { if (max_percent < 25 || max_percent > 100) return 0; d->wfb_max_percent = max_percent; } return 1; } int burn_msf_to_sectors(int m, int s, int f) { return (m * 60 + s) * 75 + f; } void burn_sectors_to_msf(int sectors, int *m, int *s, int *f) { *m = sectors / (60 * 75); *s = (sectors - *m * 60 * 75) / 75; *f = sectors - *m * 60 * 75 - *s * 75; } int burn_drive_get_read_speed(struct burn_drive *d) { return d->mdata->max_read_speed; } int burn_drive_get_write_speed(struct burn_drive *d) { return d->mdata->max_write_speed; } /* ts A61021 : New API function */ int burn_drive_get_min_write_speed(struct burn_drive *d) { return d->mdata->min_write_speed; } /* ts A51221 */ static char *enumeration_whitelist[BURN_DRIVE_WHITELIST_LEN]; static int enumeration_whitelist_top = -1; /** Add a device to the list of permissible drives. As soon as some entry is in the whitelist all non-listed drives are banned from enumeration. @return 1 success, <=0 failure */ int burn_drive_add_whitelist(char *device_address) { char *new_item; if(enumeration_whitelist_top+1 >= BURN_DRIVE_WHITELIST_LEN) return 0; enumeration_whitelist_top++; new_item = calloc(1, strlen(device_address) + 1); if (new_item == NULL) return -1; strcpy(new_item, device_address); enumeration_whitelist[enumeration_whitelist_top] = new_item; return 1; } /** Remove all drives from whitelist. This enables all possible drives. */ void burn_drive_clear_whitelist(void) { int i; for (i = 0; i <= enumeration_whitelist_top; i++) free(enumeration_whitelist[i]); enumeration_whitelist_top = -1; } int burn_drive_is_banned(char *device_address) { int i; if(enumeration_whitelist_top<0) return 0; for (i = 0; i <= enumeration_whitelist_top; i++) if (strcmp(enumeration_whitelist[i], device_address) == 0) return 0; return 1; } /* ts A80731 */ int burn_drive_whitelist_count(void) { return enumeration_whitelist_top + 1; } char *burn_drive_whitelist_item(int idx, int flag) { if (idx < 0 || idx > enumeration_whitelist_top) return NULL; return enumeration_whitelist[idx]; } static int burn_role_by_access(char *fname, int flag) { /* We normally need _LARGEFILE64_SOURCE defined by the build system. Nevertheless the system might use large address integers by default. */ #ifndef O_LARGEFILE #define O_LARGEFILE 0 #endif int fd; fd = open(fname, O_RDWR | O_LARGEFILE | O_BINARY); if (fd != -1) { close(fd); return 2; } fd = open(fname, O_RDONLY | O_LARGEFILE | O_BINARY); if (fd != -1) { close(fd); return 4; } fd = open(fname, O_WRONLY | O_LARGEFILE | O_BINARY); if (fd != -1) { close(fd); return 5; } if (flag & 1) return 0; return 2; } /* ts A70903 : Implements adquiration of pseudo drives */ int burn_drive_grab_dummy(struct burn_drive_info *drive_infos[], char *fname) { int ret = -1, role = 0, fd; int is_rdwr = 0, stat_ret = -1; /* divided by 512 it needs to fit into a signed long integer */ off_t size = ((off_t) (512 * 1024 * 1024 - 1) * (off_t) 2048); off_t read_size = -1; struct burn_drive *d= NULL, *regd_d; struct stat stbuf; if (fname[0] != 0) { fd = burn_drive__fd_from_special_adr(fname); is_rdwr = burn_drive__is_rdwr(fname, &stat_ret, &stbuf, &read_size, 1 | 2); if (stat_ret == -1 || is_rdwr) { ret = burn_os_stdio_capacity(fname, 0, &size); if (ret == -1) { libdax_msgs_submit(libdax_messenger, -1, 0x00020009, LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH, "Neither stdio-path nor its directory exist", 0, 0); return 0; } else if (ret == -2) { libdax_msgs_submit(libdax_messenger, -1, 0x00020005, LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH, "Failed to open device (a pseudo-drive)", errno, 0); return 0; } if (fname[0] != 0) { if (is_rdwr == 2 && (burn_drive_role_4_allowed & 1)) role = 4; else if (is_rdwr == 3 && (burn_drive_role_4_allowed & 1)) role = 5; else role = 2; if (stat_ret != -1 && role == 2 && fd == -1 && (burn_drive_role_4_allowed & 3) == 3) role = burn_role_by_access(fname, !!(burn_drive_role_4_allowed & 4)); } else role = 0; } else { role = 3; } } d= (struct burn_drive *) calloc(1, sizeof(struct burn_drive)); if (d == NULL) return 0; burn_setup_drive(d, fname); d->status = BURN_DISC_EMPTY; d->drive_role = role; ret = burn_scsi_setup_drive(d, -1, -1, -1, -1, -1, 0); if (ret <= 0) goto ex; regd_d = burn_drive_register(d); if (regd_d == NULL) { ret = -1; goto ex; } free((char *) d); /* all sub pointers have been copied to *regd_d */ d = regd_d; if (d->drive_role >= 2 && d->drive_role <= 5) { if (d->drive_role == 4) { if (read_size > 0) d->status = BURN_DISC_FULL; else d->status = BURN_DISC_EMPTY; d->block_types[BURN_WRITE_TAO] = 0; d->block_types[BURN_WRITE_SAO] = 0; } else { if (d->drive_role == 5 && stat_ret != -1 && S_ISREG(stbuf.st_mode) && stbuf.st_size > 0 && (burn_drive_role_4_allowed & 8)) { d->status = BURN_DISC_APPENDABLE; d->block_types[BURN_WRITE_SAO] = 0; if (stbuf.st_size / (off_t) 2048 >= 0x7ffffff0) { 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; d->block_types[BURN_WRITE_SAO] = BURN_BLOCK_SAO; d->role_5_nwa = 0; } d->block_types[BURN_WRITE_TAO] = BURN_BLOCK_MODE1; } d->current_profile = 0xffff; /* MMC for non-compliant drive */ strcpy(d->current_profile_text,"stdio file"); d->current_is_cd_profile = 0; d->current_is_supported_profile = 1; if (read_size >= 0) /* despite its name : last valid address, not size */ d->media_read_capacity = read_size / 2048 - !(read_size % 2048); burn_drive_set_media_capacity_remaining(d, size); } else d->current_profile = 0; /* Drives return this if empty */ *drive_infos = calloc(2, sizeof(struct burn_drive_info)); if (*drive_infos == NULL) goto ex; (*drive_infos)[0].drive = d; (*drive_infos)[1].drive = NULL; /* End-Of-List mark */ (*drive_infos)[0].tao_block_types = d->block_types[BURN_WRITE_TAO]; (*drive_infos)[0].sao_block_types = d->block_types[BURN_WRITE_SAO]; if (d->drive_role == 2) { strcpy((*drive_infos)[0].vendor,"YOYODYNE"); strcpy((*drive_infos)[0].product,"WARP DRIVE"); strcpy((*drive_infos)[0].revision,"FX01"); } else if (d->drive_role == 3) { strcpy((*drive_infos)[0].vendor,"YOYODYNE"); strcpy((*drive_infos)[0].product,"BLACKHOLE"); strcpy((*drive_infos)[0].revision,"FX02"); } else if (d->drive_role == 4) { strcpy((*drive_infos)[0].vendor,"YOYODYNE"); strcpy((*drive_infos)[0].product,"WARP DRIVE"); strcpy((*drive_infos)[0].revision,"FX03"); } else if (d->drive_role == 5) { strcpy((*drive_infos)[0].vendor,"YOYODYNE"); strcpy((*drive_infos)[0].product,"WARP DRIVE"); strcpy((*drive_infos)[0].revision,"FX04"); } else { strcpy((*drive_infos)[0].vendor,"FERENGI"); strcpy((*drive_infos)[0].product,"VAPORWARE"); strcpy((*drive_infos)[0].revision,"0000"); } d->released = 0; ret = 1; ex:; if (ret <= 0 && d != NULL) { burn_drive_free_subs(d); free((char *) d); } return ret; } /* ts A60823 */ /** Aquire a drive with known persistent address. */ int burn_drive_scan_and_grab(struct burn_drive_info *drive_infos[], char* adr, int load) { unsigned int n_drives; int ret, i; /* check wether drive adress is already registered */ for (i = 0; i <= drivetop; i++) if (drive_array[i].global_index >= 0) if (strcmp(drive_array[i].devname, adr) == 0) break; if (i <= drivetop) { libdax_msgs_submit(libdax_messenger, i, 0x0002014b, LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH, "Drive is already registered resp. scanned", 0, 0); return -1; } if (strncmp(adr, "stdio:", 6) == 0) { ret = burn_drive_grab_dummy(drive_infos, adr + 6); return ret; } burn_drive_clear_whitelist(); burn_drive_add_whitelist(adr); /* fprintf(stderr,"libburn: experimental: burn_drive_scan_and_grab(%s)\n", adr); */ /* ts A70907 : now calling synchronously rather than looping */ ret = burn_drive_scan_sync(drive_infos, &n_drives, 0); if (ret < 0) return -1; if (n_drives == 0) return 0; /* fprintf(stderr, "libburn: experimental: n_drives %d , drivetop %d\n", n_drives, drivetop); if (n_drives > 0) fprintf(stderr, "libburn: experimental: global_index %d\n", drive_infos[0]->drive->global_index); */ ret = burn_drive_grab(drive_infos[0]->drive, load); if (ret != 1) { burn_drive_forget(drive_infos[0]->drive, 0); return -1; } return 1; } /* ts A60925 */ /** Simple debug message frontend to libdax_msgs_submit(). If arg is not NULL, then fmt MUST contain exactly one %s and no other sprintf() %-formatters. */ int burn_drive_adr_debug_msg(char *fmt, char *arg) { int ret; char *msg = NULL, *msgpt; if(libdax_messenger == NULL) return 0; if(arg != NULL) { BURN_ALLOC_MEM(msg, char, 4096); msgpt = msg; sprintf(msg, fmt, arg); } else { msgpt = fmt; } ret = libdax_msgs_submit(libdax_messenger, -1, 0x00000002, LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_ZERO, msgpt, 0, 0); ex:; BURN_FREE_MEM(msg); return ret; } /* ts A60923 */ /* ts A70906 : promoted to API */ /** Inquire the persistent address of the given drive. */ int burn_drive_d_get_adr(struct burn_drive *d, char adr[]) { if (strlen(d->devname) >= BURN_DRIVE_ADR_LEN) { libdax_msgs_submit(libdax_messenger, d->global_index, 0x00020110, LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH, "Persistent drive address too long", 0, 0); return -1; } strcpy(adr,d->devname); return 1; } /* ts A60823 - A60923 */ /* A70906 : Now legacy API call */ /** Inquire the persistent address of the given drive. */ int burn_drive_get_adr(struct burn_drive_info *drive_info, char adr[]) { int ret; ret = burn_drive_d_get_adr(drive_info->drive, adr); return ret; } /* ts A60922 ticket 33 */ /** Evaluate wether the given address would be enumerated by libburn */ int burn_drive_is_enumerable_adr(char *adr) { return sg_is_enumerable_adr(adr); } #define BURN_DRIVE_MAX_LINK_DEPTH 20 /* ts A60922 ticket 33 */ /* @param flag bit0= no debug messages bit1= resolve only links, do not rely on drive list for resolving via st_rdev */ int burn_drive_resolve_link(char *path, char adr[], int *recursion_count, int flag) { int ret, link_target_size = 4096; char *link_target = NULL, *msg = NULL, *link_adr = NULL, *adrpt; struct stat stbuf; BURN_ALLOC_MEM(link_target, char, link_target_size); BURN_ALLOC_MEM(msg, char, link_target_size + 100); BURN_ALLOC_MEM(link_adr, char, link_target_size); if (flag & 1) burn_drive_adr_debug_msg("burn_drive_resolve_link( %s )", path); if (*recursion_count >= BURN_DRIVE_MAX_LINK_DEPTH) { if (flag & 1) burn_drive_adr_debug_msg( "burn_drive_resolve_link aborts because link too deep", NULL); {ret = 0; goto ex;} } (*recursion_count)++; ret = readlink(path, link_target, link_target_size); if (ret == -1) { if (flag & 1) burn_drive_adr_debug_msg("readlink( %s ) returns -1", path); {ret = 0; goto ex;} } if (ret >= link_target_size - 1) { sprintf(msg,"readlink( %s ) returns %d (too much)", path, ret); if (flag & 1) burn_drive_adr_debug_msg(msg, NULL); {ret = -1; goto ex;} } link_target[ret] = 0; adrpt = link_target; if (link_target[0] != '/') { strcpy(link_adr, path); if ((adrpt = strrchr(link_adr, '/')) != NULL) { strcpy(adrpt + 1, link_target); adrpt = link_adr; } else adrpt = link_target; } if (flag & 2) { /* Link-only recursion */ if (lstat(adrpt, &stbuf) == -1) { ; } else if((stbuf.st_mode & S_IFMT) == S_IFLNK) { ret = burn_drive_resolve_link(adrpt, adr, recursion_count, flag); } else { strcpy(adr, adrpt); } } else { /* Link and device number recursion */ ret = burn_drive_convert_fs_adr_sub(adrpt, adr, recursion_count); sprintf(msg,"burn_drive_convert_fs_adr( %s ) returns %d", link_target, ret); } if (flag & 1) burn_drive_adr_debug_msg(msg, NULL); ex:; BURN_FREE_MEM(link_target); BURN_FREE_MEM(msg); BURN_FREE_MEM(link_adr); return ret; } /* ts A60922 - A61014 ticket 33 */ /* Try to find an enumerated address with the given stat.st_rdev number */ int burn_drive_find_devno(dev_t devno, char adr[]) { char *fname = NULL, *msg = NULL; int ret = 0, first = 1, fname_size = 4096; struct stat stbuf; burn_drive_enumerator_t enm; BURN_ALLOC_MEM(fname, char, fname_size); BURN_ALLOC_MEM(msg, char, fname_size + 100); while (1) { ret = sg_give_next_adr(&enm, fname, fname_size, first); if(ret <= 0) break; first = 0; ret = stat(fname, &stbuf); if(ret == -1) continue; if(devno != stbuf.st_rdev) continue; if(strlen(fname) >= BURN_DRIVE_ADR_LEN) {ret= -1; goto ex;} sprintf(msg, "burn_drive_find_devno( 0x%lX ) found %s", (long) devno, fname); burn_drive_adr_debug_msg(msg, NULL); strcpy(adr, fname); { ret = 1; goto ex;} } ret = 0; ex:; if (first == 0) sg_give_next_adr(&enm, fname, fname_size, -1); BURN_FREE_MEM(fname); BURN_FREE_MEM(msg); return ret; } /* ts A60923 */ /** Try to obtain host,channel,target,lun from path. @return 1 = success , 0 = failure , -1 = severe error */ int burn_drive_obtain_scsi_adr(char *path, int *bus_no, int *host_no, int *channel_no, int *target_no, int *lun_no) { int ret, i; char *adr = NULL; BURN_ALLOC_MEM(adr, char, BURN_DRIVE_ADR_LEN); /* open drives cannot be inquired by sg_obtain_scsi_adr() */ for (i = 0; i < drivetop + 1; i++) { if (drive_array[i].global_index < 0) continue; ret = burn_drive_d_get_adr(&(drive_array[i]),adr); if (ret < 0) {ret = 1; goto ex;} if (ret == 0) continue; if (strcmp(adr, path) == 0) { *host_no = drive_array[i].host; *channel_no = drive_array[i].channel; *target_no = drive_array[i].id; *lun_no = drive_array[i].lun; *bus_no = drive_array[i].bus_no; if (*host_no < 0 || *channel_no < 0 || *target_no < 0 || *lun_no < 0) {ret = 0; goto ex;} {ret = 1; goto ex;} } } ret = sg_obtain_scsi_adr(path, bus_no, host_no, channel_no, target_no, lun_no); ex:; BURN_FREE_MEM(adr); return ret; } /* ts A60923 */ int burn_drive_convert_scsi_adr(int bus_no, int host_no, int channel_no, int target_no, int lun_no, char adr[]) { char *fname = NULL, *msg = NULL; int ret = 0, first = 1, i_bus_no = -1, fname_size = 4096; int i_host_no = -1, i_channel_no = -1, i_target_no = -1, i_lun_no = -1; burn_drive_enumerator_t enm; BURN_ALLOC_MEM(fname, char, fname_size); BURN_ALLOC_MEM(msg, char, fname_size + 100); sprintf(msg,"burn_drive_convert_scsi_adr( %d,%d,%d,%d,%d )", bus_no, host_no, channel_no, target_no, lun_no); burn_drive_adr_debug_msg(msg, NULL); while (1) { ret= sg_give_next_adr(&enm, fname, fname_size, first); if(ret <= 0) break; first = 0; ret = burn_drive_obtain_scsi_adr(fname, &i_bus_no, &i_host_no, &i_channel_no, &i_target_no, &i_lun_no); if(ret <= 0) continue; if(bus_no >=0 && i_bus_no != bus_no) continue; if(host_no >=0 && i_host_no != host_no) continue; if(channel_no >= 0 && i_channel_no != channel_no) continue; if(target_no >= 0 && i_target_no != target_no) continue; if(lun_no >= 0 && i_lun_no != lun_no) continue; if(strlen(fname) >= BURN_DRIVE_ADR_LEN) { ret = -1; goto ex;} burn_drive_adr_debug_msg( "burn_drive_convert_scsi_adr() found %s", fname); strcpy(adr, fname); { ret = 1; goto ex;} } ret = 0; ex:; if (first == 0) sg_give_next_adr(&enm, fname, fname_size, -1); BURN_FREE_MEM(fname); BURN_FREE_MEM(msg); return ret; } /* ts A60922 ticket 33 */ /* Try to find an enumerated address with the same host,channel,target,lun as path */ int burn_drive_find_scsi_equiv(char *path, char adr[]) { int ret = 0; int bus_no, host_no, channel_no, target_no, lun_no; char msg[4096]; ret = burn_drive_obtain_scsi_adr(path, &bus_no, &host_no, &channel_no, &target_no, &lun_no); if(ret <= 0) { sprintf(msg,"burn_drive_obtain_scsi_adr( %s ) returns %d", path, ret); burn_drive_adr_debug_msg(msg, NULL); return 0; } sprintf(msg, "burn_drive_find_scsi_equiv( %s ) : (%d),%d,%d,%d,%d", path, bus_no, host_no, channel_no, target_no, lun_no); burn_drive_adr_debug_msg(msg, NULL); ret= burn_drive_convert_scsi_adr(-1, host_no, channel_no, target_no, lun_no, adr); return ret; } /* ts A60922 ticket 33 */ /** Try to convert a given existing filesystem address into a persistent drive address. */ int burn_drive_convert_fs_adr_sub(char *path, char adr[], int *rec_count) { int ret; struct stat stbuf; burn_drive_adr_debug_msg("burn_drive_convert_fs_adr( %s )", path); if (strncmp(path, "stdio:", 6) == 0 || burn_drive_is_enumerable_adr(path)) { if(strlen(path) >= BURN_DRIVE_ADR_LEN) return -1; if (strncmp(path, "stdio:", 6) != 0) burn_drive_adr_debug_msg( "burn_drive_is_enumerable_adr( %s ) is true", path); strcpy(adr, path); return 1; } if(lstat(path, &stbuf) == -1) { burn_drive_adr_debug_msg("lstat( %s ) returns -1", path); return 0; } if((stbuf.st_mode & S_IFMT) == S_IFLNK) { ret = burn_drive_resolve_link(path, adr, rec_count, 0); if(ret > 0) return 1; burn_drive_adr_debug_msg("link fallback via stat( %s )", path); if(stat(path, &stbuf) == -1) { burn_drive_adr_debug_msg("stat( %s ) returns -1",path); return 0; } } if((stbuf.st_mode&S_IFMT) == S_IFBLK || (stbuf.st_mode&S_IFMT) == S_IFCHR) { ret = burn_drive_find_devno(stbuf.st_rdev, adr); if(ret > 0) return 1; ret = burn_drive_find_scsi_equiv(path, adr); if(ret > 0) return 1; } burn_drive_adr_debug_msg("Nothing found for %s", path); return 0; } /* API */ /** Try to convert a given existing filesystem address into a persistent drive address. */ int burn_drive_convert_fs_adr(char *path, char adr[]) { int ret, rec_count = 0; ret = burn_drive_convert_fs_adr_sub(path, adr, &rec_count); return ret; } /* 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. @param handle If not NULL, a pointer to a text suitable for printf("%s") */ int burn_abort_pacifier(void *handle, int patience, int elapsed) { char *prefix= "libburn : "; if(handle!=NULL) prefix= handle; fprintf(stderr, "\r%sABORT : Waiting for drive to finish ( %d s, %d max)", (char *) prefix, elapsed, patience); return(1); } /* ts B00226 : Outsourced backend of burn_abort() @param flag bit0= do not call burn_finish() */ int burn_abort_5(int patience, int (*pacifier_func)(void *handle, int patience, int elapsed), void *handle, int elapsed, int flag) { int ret, i, occup, still_not_done= 1, pacifier_off= 0, first_round= 1; unsigned long wait_grain= 100000; time_t start_time, current_time, pacifier_time, end_time; #ifndef NIX time_t stdio_patience = 3; #endif /* fprintf(stderr, "libburn_EXPERIMENTAL: burn_abort_5(%d,%d)\n", patience, flag); */ current_time = start_time = pacifier_time = time(0); start_time -= elapsed; end_time = start_time + patience; /* >>> ts A71002 : are there any threads at work ? If not, then one can force abort because the drives will not change status on their own. */ while(current_time < end_time || (patience <= 0 && first_round)) { still_not_done = 0; for(i = 0; i < drivetop + 1; i++) { occup = burn_drive_is_occupied(&(drive_array[i])); if(occup == -2) continue; if(drive_array[i].drive_role != 1) { #ifdef NIX /* ts A90302 <<< this causes a race condition with drive usage and drive disposal. */ drive_array[i].busy = BURN_DRIVE_IDLE; burn_drive_forget(&(drive_array[i]), 1); continue; #else /* NIX */ /* ts A90318 >>> but if a pipe breaks then the drive never gets idle. So for now with a short patience timespan and eventually a deliberate memory leak. */ if (current_time - start_time > stdio_patience) { drive_array[i].global_index = -1; continue; } #endif /* ! NIX */ } if(occup < 10) { if (!drive_array[i].cancel) burn_drive_cancel(&(drive_array[i])); if (drive_array[i].drive_role != 1) /* occup == -1 comes early */ usleep(1000000); burn_drive_forget(&(drive_array[i]), 1); } else if(occup <= 100) { if (!drive_array[i].cancel) burn_drive_cancel(&(drive_array[i])); still_not_done++; } else if(occup <= 1000) { still_not_done++; } } first_round = 0; if(still_not_done == 0 || patience <= 0) break; usleep(wait_grain); current_time = time(0); if(current_time>pacifier_time) { if(pacifier_func != NULL && !pacifier_off) { ret = (*pacifier_func)(handle, patience, current_time-start_time); pacifier_off = (ret <= 0); } pacifier_time = current_time; } } if (!(flag & 1)) burn_finish(); return(still_not_done == 0); } /** Abort any running drive operation and finish libburn. @param patience Maximum number of seconds to wait for drives to finish @param pacifier_func Function to produce appeasing messages. See burn_abort_pacifier() for an example. @return 1 ok, all went well 0 had to leave a drive in unclean state <0 severe error, do no use libburn again */ int burn_abort(int patience, int (*pacifier_func)(void *handle, int patience, int elapsed), void *handle) { int ret, flg = 0; if (patience < 0) { patience = 0; flg |= 1; } ret = burn_abort_5(patience, pacifier_func, handle, 0, flg); return ret; } /* ts A61020 API function */ int burn_drive_get_start_end_lba(struct burn_drive *d, int *start_lba, int *end_lba, int flag) { if (d->start_lba == -2000000000 || d->end_lba == -2000000000) return 0; *start_lba = d->start_lba; *end_lba= d->end_lba; return 1; } /* ts A61020 API function */ int burn_disc_pretend_blank(struct burn_drive *d) { if (d->drive_role == 0) return 0; if (d->status != BURN_DISC_UNREADY && d->status != BURN_DISC_UNSUITABLE) return 0; d->status = BURN_DISC_BLANK; return 1; } /* ts A61106 API function */ int burn_disc_pretend_full(struct burn_drive *d) { if (d->drive_role == 0) return 0; if (d->status != BURN_DISC_UNREADY && d->status != BURN_DISC_UNSUITABLE) return 0; d->status = BURN_DISC_FULL; return 1; } /* ts B31110 API function */ int burn_disc_pretend_full_uncond(struct burn_drive *d) { d->status = BURN_DISC_FULL; return 1; } /* ts A61021: new API function */ int burn_disc_read_atip(struct burn_drive *d) { if (burn_drive_is_released(d)) { libdax_msgs_submit(libdax_messenger, d->global_index, 0x0002010e, LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH, "Attempt to read ATIP from ungrabbed drive", 0, 0); return -1; } if(d->drive_role != 1) return 0; if ((d->current_profile == -1 || d->current_is_cd_profile) && ((d->mdata->p2a_valid > 0 && d->mdata->cdrw_write) || d->current_profile != 0x08)) { d->read_atip(d); /* >>> some control of success would be nice :) */ } else { /* mmc5r03c.pdf 6.26.3.6.3 : ATIP is undefined for non-CD (and it seems meaningless for non-burners). ts A90823: Pseudo-CD U3 memory stick stalls with ATIP. It is !cdrw_write and profile is 0x08. */ return 0; } return 1; } /* ts A61110 : new API function */ int burn_disc_track_lba_nwa(struct burn_drive *d, struct burn_write_opts *o, int trackno, int *lba, int *nwa) { int ret; if (burn_drive_is_released(d)) { libdax_msgs_submit(libdax_messenger, d->global_index, 0x0002011b, LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH, "Attempt to read track info from ungrabbed drive", 0, 0); return -1; } if (d->busy != BURN_DRIVE_IDLE) { libdax_msgs_submit(libdax_messenger, d->global_index, 0x0002011c, LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH, "Attempt to read track info from busy drive", 0, 0); return -1; } *lba = *nwa = 0; if (d->drive_role == 5 && trackno == 0 && d->status == BURN_DISC_APPENDABLE) { *lba = *nwa = d->role_5_nwa; return 1; } if (d->drive_role != 1) return 0; if (o != NULL) d->send_write_parameters(d, NULL, -1, o); ret = d->get_nwa(d, trackno, lba, nwa); return ret; } /* ts A70131 : new API function */ int burn_disc_get_msc1(struct burn_drive *d, int *start) { int ret, trackno; if (burn_drive_is_released(d)) { libdax_msgs_submit(libdax_messenger, d->global_index, 0x0002011b, LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH, "Attempt to read track info from ungrabbed drive", 0, 0); return -1; } if (d->busy != BURN_DRIVE_IDLE) { libdax_msgs_submit(libdax_messenger, d->global_index, 0x0002011c, LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH, "Attempt to read track info from busy drive", 0, 0); return -1; } *start = 0; if (d->drive_role != 1) return 0; ret = d->read_multi_session_c1(d, &trackno, start); return ret; } /* ts A70213 : new API function */ off_t burn_disc_available_space(struct burn_drive *d, struct burn_write_opts *o) { int lba, nwa, ret; off_t bytes, start_byte = 0; if (burn_drive_is_released(d)) return 0; if (d->busy != BURN_DRIVE_IDLE) return 0; if (d->drive_role == 0) return 0; if (d->drive_role != 1) { if (o != NULL) start_byte = o->start_byte; ret = burn_os_stdio_capacity(d->devname, start_byte, &bytes); if (ret != 1) bytes = d->media_capacity_remaining; if (bytes <= 0) bytes = (off_t) (512 * 1024 * 1024 - 1) * (off_t) 2048; if (bytes != d->media_capacity_remaining) burn_drive_set_media_capacity_remaining(d, bytes); } else { if (o != NULL) d->send_write_parameters(d, NULL, -1, o); d->get_nwa(d, -1, &lba, &nwa); } if (o != NULL) { if (o->start_byte > 0) { if (o->start_byte > d->media_capacity_remaining) return 0; return d->media_capacity_remaining - o->start_byte; } } return d->media_capacity_remaining; } /* ts A61202 : New API function */ int burn_disc_get_profile(struct burn_drive *d, int *pno, char name[80]) { *pno = d->current_profile; strcpy(name,d->current_profile_text); return *pno >= 0; } /* ts A90815 : New API function */ int burn_drive_get_all_profiles(struct burn_drive *d, int *num_profiles, int profiles[64], char is_current[64]) { int i; *num_profiles = d->num_profiles; for (i = 0; i < d->num_profiles; i++) { profiles[i] = (d->all_profiles[i * 4] << 8) | d->all_profiles[i * 4 + 1]; is_current[i] = d->all_profiles[i * 4 + 2] & 1; } return 1; } /* ts A90815 : New API function */ int burn_obtain_profile_name(int profile_number, char name[80]) { strcpy(name, mmc_obtain_profile_name(profile_number)); return(name[0] != 0); } /* ts A61223 : New API function */ int burn_drive_wrote_well(struct burn_drive *d) { return !d->cancel; } /* ts A61226 */ int burn_speed_descriptor_new(struct burn_speed_descriptor **s, struct burn_speed_descriptor *prev, struct burn_speed_descriptor *next, int flag) { struct burn_speed_descriptor *o; (*s) = o = calloc(1, sizeof(struct burn_speed_descriptor)); if (o == NULL) return -1; o->source = 0; o->profile_loaded = -2; o->profile_name[0] = 0; o->wrc = 0; o->exact = 0; o->mrw = 0; o->end_lba = -1; o->write_speed = 0; o->read_speed = 0; o->prev = prev; if (prev != NULL) { next = prev->next; prev->next = o; } o->next = next; if (next != NULL) next->prev = o; return 1; } /* ts A61226 */ /* @param flag bit0= destroy whole next-chain of descriptors */ int burn_speed_descriptor_destroy(struct burn_speed_descriptor **s, int flag) { struct burn_speed_descriptor *next, *o; if ((*s) == NULL) return 0; if (flag&1) for (o = (*s); o->prev != NULL; o = o->prev); else o = (*s); next = o->next; if (next != NULL) next->prev = o->prev; if (o->prev != NULL) o->prev->next = next; free((char *) (*s)); (*s) = NULL; if (flag&1) return burn_speed_descriptor_destroy(&next, flag&1); return 1; } /* ts A61226 */ int burn_speed_descriptor_copy(struct burn_speed_descriptor *from, struct burn_speed_descriptor *to, int flag) { to->source = from->source; to->profile_loaded = from->profile_loaded; strcpy(to->profile_name, from->profile_name); to->wrc = from->wrc; to->exact = from->exact; to->mrw = from->mrw; to->end_lba = from->end_lba; to->write_speed = from->write_speed; to->read_speed = from->read_speed; return 1; } /* ts A61226 : free dynamically allocated sub data of struct scsi_mode_data */ int burn_mdata_free_subs(struct scsi_mode_data *m) { burn_speed_descriptor_destroy(&(m->speed_descriptors), 1); return 1; } /* ts A61226 : API function */ int burn_drive_get_speedlist(struct burn_drive *d, struct burn_speed_descriptor **speed_list) { int ret; struct burn_speed_descriptor *sd, *csd = NULL; (*speed_list) = NULL; for (sd = d->mdata->speed_descriptors; sd != NULL; sd = sd->next) { ret = burn_speed_descriptor_new(&csd, NULL, csd, 0); if (ret <= 0) return -1; burn_speed_descriptor_copy(sd, csd, 0); } (*speed_list) = csd; return (csd != NULL); } /* ts A70713 : API function */ int burn_drive_get_best_speed(struct burn_drive *d, int speed_goal, struct burn_speed_descriptor **best_descr, int flag) { struct burn_speed_descriptor *sd; int best_speed = 0, best_lba = 0, source= 2, speed; if (flag & 2) source = -1; if (speed_goal < 0) best_speed = 2000000000; *best_descr = NULL; for (sd = d->mdata->speed_descriptors; sd != NULL; sd = sd->next) { if (flag & 1) speed = sd->read_speed; else speed = sd->write_speed; if ((source >= 0 && sd->source != source) || speed <= 0) continue; if (speed_goal < 0) { if (speed < best_speed) { best_speed = speed; *best_descr = sd; } } else if (speed_goal == 0) { if ((source == 2 && sd->end_lba > best_lba) || ((source !=2 || sd->end_lba == best_lba) && speed > best_speed)) { best_lba = sd->end_lba; best_speed = speed; *best_descr = sd; } } else if (speed <= speed_goal) { if (speed > best_speed) { best_speed = speed; *best_descr = sd; } } } if (d->current_is_cd_profile && *best_descr == NULL && ! (flag & 2)) /* Mode page 2Ah is deprecated in MMC-5 although all known burners still support it with CD media. */ return burn_drive_get_best_speed(d, speed_goal, best_descr, flag | 2); return (*best_descr != NULL); } /* ts A61226 : API function */ int burn_drive_free_speedlist(struct burn_speed_descriptor **speed_list) { return burn_speed_descriptor_destroy(speed_list, 1); } /* ts A70203 : API function */ int burn_disc_get_multi_caps(struct burn_drive *d, enum burn_write_types wt, struct burn_multi_caps **caps, int flag) { enum burn_disc_status s; struct burn_multi_caps *o; int status, num_formats, ret, type, i; off_t size; unsigned dummy; *caps = NULL; s = burn_disc_get_status(d); if(s == BURN_DISC_UNGRABBED) return -1; *caps = o = (struct burn_multi_caps *) calloc(1, sizeof(struct burn_multi_caps)); if(*caps == NULL) return -1; /* Default says nothing is available */ o->multi_session = o->multi_track = 0; o-> start_adr = 0; o->start_alignment = o->start_range_low = o->start_range_high = 0; o->might_do_tao = o->might_do_sao = o->might_do_raw = 0; o->advised_write_mode = BURN_WRITE_NONE; o->selected_write_mode = wt; o->current_profile = d->current_profile; o->current_is_cd_profile = d->current_is_cd_profile; o->might_simulate = 0; if (d->drive_role == 0 || d->drive_role == 4) return 0; if (d->drive_role == 2) { /* stdio file drive : random access read-write */ o->start_adr = 1; size = d->media_capacity_remaining; burn_os_stdio_capacity(d->devname, 0, &size); burn_drive_set_media_capacity_remaining(d, size); o->start_range_high = d->media_capacity_remaining - 2048; o->start_alignment = 2048; /* imposting a drive, not a file */ o->might_do_sao = 4; o->might_do_tao = 2; o->advised_write_mode = BURN_WRITE_TAO; o->might_simulate = 1; } else if (d->drive_role == 5) { /* stdio file drive : random access write-only */ o->start_adr = 1; size = d->media_capacity_remaining; burn_os_stdio_capacity(d->devname, 0, &size); burn_drive_set_media_capacity_remaining(d, size); /* >>> start_range_low = file size rounded to 2048 */; o->start_range_high = d->media_capacity_remaining - 2048; o->start_alignment = 2048; /* imposting a drive, not a file */ if (s == BURN_DISC_APPENDABLE) { if (wt == BURN_WRITE_SAO || wt == BURN_WRITE_RAW) return 0; o->might_do_sao = 0; } else o->might_do_sao = 4; o->might_do_tao = 2; o->advised_write_mode = BURN_WRITE_TAO; o->might_simulate = 1; } else if (d->drive_role != 1) { /* stdio file drive : sequential access write-only */ o->might_do_sao = 4; o->might_do_tao = 2; o->advised_write_mode = BURN_WRITE_TAO; o->might_simulate = 1; } else if (s != BURN_DISC_BLANK && s != BURN_DISC_APPENDABLE) { return 0; } else if (s == BURN_DISC_APPENDABLE && (wt == BURN_WRITE_SAO || wt == BURN_WRITE_RAW)) { return 0; } else if (wt == BURN_WRITE_RAW && !d->current_is_cd_profile) { return 0; } else if (d->current_profile == 0x09 || d->current_profile == 0x0a) { /* CD-R , CD-RW */ if (d->block_types[BURN_WRITE_TAO]) { o->multi_session = o->multi_track = 1; o->might_do_tao = 2; if (o->advised_write_mode == BURN_WRITE_NONE) o->advised_write_mode = BURN_WRITE_TAO; } if (d->block_types[BURN_WRITE_SAO]) { o->multi_session = o->multi_track = 1; o->might_do_sao = 1; if (o->advised_write_mode == BURN_WRITE_NONE) o->advised_write_mode = BURN_WRITE_SAO; } if (d->block_types[BURN_WRITE_RAW]) { o->might_do_raw = 1; if (o->advised_write_mode == BURN_WRITE_NONE) o->advised_write_mode = BURN_WRITE_RAW; } if (wt == BURN_WRITE_RAW) o->multi_session = o->multi_track = 0; else if(wt == BURN_WRITE_NONE || wt == BURN_WRITE_SAO || wt == BURN_WRITE_TAO) o->might_simulate = !!(d->mdata->p2a_valid > 0 && d->mdata->simulate); } else if (d->current_profile == 0x11 || d->current_profile == 0x14 || d->current_profile == 0x15) { /* DVD-R , sequential DVD-RW , DVD-R/DL Sequential */ if (s == BURN_DISC_BLANK) { o->might_do_sao = 1; o->advised_write_mode = BURN_WRITE_SAO; } if (d->current_has_feat21h) { #ifndef Libburn_dvd_r_dl_multi_no_close_sessioN if (d->current_profile != 0x15) #endif o->multi_session = 1; o->multi_track = 1; o->might_do_tao = 2; o->advised_write_mode = BURN_WRITE_TAO; } if (wt == BURN_WRITE_SAO) o->multi_session = o->multi_track = 0; if (wt == BURN_WRITE_NONE || wt == BURN_WRITE_SAO || wt == BURN_WRITE_TAO) o->might_simulate = 1; } else if (d->current_profile == 0x12 || d->current_profile == 0x13 || d->current_profile == 0x1a || d->current_profile == 0x43 ) { /* DVD-RAM, overwriteable DVD-RW, DVD+RW, BD-RE */ o->start_adr = 1; ret = burn_disc_get_formats(d, &status, &size, &dummy, &num_formats); if (ret == 1) { if (status == BURN_FORMAT_IS_FORMATTED) o->start_range_high = size - 2048; if (d->current_profile == 0x13) { o->start_alignment = 32 * 1024; for (i = 0; i < num_formats; i++) { ret = burn_disc_get_format_descr(d, i, &type, &size, &dummy); if (ret <= 0) continue; if (type == 0x13) /* expandable */ break; } if (i >= num_formats) /* not expandable */ o->start_range_high -= 32 * 1024; if (o->start_range_high < 0) o->start_range_high = 0; } else { o->start_alignment = 2 * 1024; if (d->best_format_size - 2048 > o->start_range_high) o->start_range_high = d->best_format_size - 2048; } } o->might_do_sao = 4; o->might_do_tao = 2; o->advised_write_mode = BURN_WRITE_TAO; } else if (d->current_profile == 0x1b || d->current_profile == 0x2b || d->current_profile == 0x41) { /* DVD+R , DVD+R/DL , BD-R SRM */ o->multi_session = o->multi_track = 1; o->might_do_tao = 2; o->might_do_sao = 1; o->advised_write_mode = BURN_WRITE_TAO; } else /* unknown media */ return 0; if (s == BURN_DISC_APPENDABLE) o->might_do_sao = o->might_do_raw = 0; if (wt == BURN_WRITE_TAO && !o->might_do_tao) return 0; else if (wt == BURN_WRITE_SAO && !o->might_do_sao) return 0; else if (wt == BURN_WRITE_RAW && !o->might_do_raw) return 0; return 1; } /* ts A70203 : API function */ int burn_disc_free_multi_caps(struct burn_multi_caps **caps) { if (*caps == NULL) return 0; free((char *) *caps); *caps = NULL; return 1; } /* ts A70207 : evaluate write mode related peculiarities of a disc @param flag bit0= fill_up_media is active */ int burn_disc_get_write_mode_demands(struct burn_disc *disc, struct burn_write_opts *opts, struct burn_disc_mode_demands *result, int flag) { struct burn_session *session; struct burn_track *track; int i, j, mode, unknown_track_sizes = 0, last_track_is_unknown = 0; enum burn_disc_status s; memset((char *) result, 0, sizeof(struct burn_disc_mode_demands)); if (disc == NULL) return 2; s = burn_disc_get_status(opts->drive); if (s == BURN_DISC_APPENDABLE || disc->sessions > 1) result->will_append = 1; if (disc->sessions > 1) result->multi_session = 1; for (i = 0; i < disc->sessions; i++) { session = disc->session[i]; if (session->tracks <= 0) continue; mode = session->track[0]->mode; if (session->tracks > 1) result->multi_track = 1; for (j = 0; j < session->tracks; j++) { track = session->track[j]; if (burn_track_is_open_ended(track)) { if (burn_track_get_default_size(track) > 0) { if (result->unknown_track_size == 0) result->unknown_track_size = 2; } else result->unknown_track_size = 1; unknown_track_sizes++; last_track_is_unknown = 1; } else last_track_is_unknown = 0; if ((mode & BURN_MODE_BITS) != (track->mode & BURN_MODE_BITS)) result->mixed_mode = 1; if (track->mode & BURN_MODE1) { result->block_types |= BURN_BLOCK_MODE1; } else if (track->mode & BURN_AUDIO) { result->audio = 1; result->block_types |= BURN_BLOCK_RAW0; result->exotic_track = 1; } else { result->block_types |= opts->block_type; result->exotic_track = 1; } } } if (flag&1) {/* fill_up_media will define the size of the last track */ if (unknown_track_sizes == 1 && last_track_is_unknown) result->unknown_track_size = 0; } return (disc->sessions > 0); } /* ts A70903 : API */ int burn_drive_get_drive_role(struct burn_drive *d) { return d->drive_role; } /* ts A70923 Hands out pointers *dpt to directory path and *npt to basename. Caution: the last '/' in adr gets replaced by a 0. */ static int burn__split_path(char *adr, char **dpt, char **npt) { *dpt = adr; *npt = strrchr(*dpt, '/'); if (*npt == NULL) { *npt = *dpt; *dpt = "."; return 1; } **npt = 0; if(*npt == *dpt) *dpt = "/"; (*npt)++; return 2; } /* ts A70923 : API */ int burn_drive_equals_adr(struct burn_drive *d1, char *adr2_in, int role2) { struct stat stbuf1, stbuf2; char *adr1 = NULL, *adr2 = adr2_in; char *conv_adr1 = NULL, *conv_adr2 = NULL; char *npt1, *dpt1, *npt2, *dpt2; int role1, stat_ret1, stat_ret2, conv_ret2, exact_role_matters = 0, fd; int ret; BURN_ALLOC_MEM(adr1, char, BURN_DRIVE_ADR_LEN); BURN_ALLOC_MEM(conv_adr1, char, BURN_DRIVE_ADR_LEN); BURN_ALLOC_MEM(conv_adr2, char, BURN_DRIVE_ADR_LEN); role1 = burn_drive_get_drive_role(d1); burn_drive_d_get_adr(d1, adr1); stat_ret1 = stat(adr1, &stbuf1); /* If one of the candidate paths depicts an open file descriptor then its read-write capability decides about its role and the difference between roles 2 and 3 does matter. */ fd = burn_drive__fd_from_special_adr(d1->devname); if (fd != -1) exact_role_matters = 1; if (strncmp(adr2, "stdio:", 6) == 0) { adr2+= 6; if (adr2[0] == 0) { role2 = 0; } else { fd = burn_drive__fd_from_special_adr(adr2); if (fd != -1) exact_role_matters = 1; ret = burn_drive__is_rdwr(adr2, NULL, NULL, NULL, 1 | 2); if (ret == 2 && (burn_drive_role_4_allowed & 1)) role2 = 4; else if (ret == 3 && (burn_drive_role_4_allowed & 1)) role2 = 5; else if (ret > 0) role2 = 2; else role2 = 3; if (fd == -1 && role2 == 2 && (burn_drive_role_4_allowed & 3) == 3) role2 = burn_role_by_access(adr2, !!(burn_drive_role_4_allowed & 4)); } } if (strlen(adr2) >= BURN_DRIVE_ADR_LEN) {ret = -1; goto ex;} stat_ret2 = stat(adr2, &stbuf2); conv_ret2 = burn_drive_convert_fs_adr(adr2, conv_adr2); if (!exact_role_matters) { /* roles >= 2 have the same name space and object interpretation */ if (role1 >= 2) role1 = 2; if (role2 >= 2) role2 = 2; } if (strcmp(adr1, adr2) == 0 && role1 == role2) {ret = 1; goto ex;} /* equal role and address */ if (role1 == 1 && role2 == 1) { /* MMC drive meets wannabe MMC drive */ if (conv_ret2 <= 0) {ret = 0; goto ex;} /* no MMC drive at adr2 */ if (strcmp(adr1, conv_adr2) == 0) {ret = 1; goto ex;} /* equal real MMC drives */ {ret = 0; goto ex;} } else if (role1 == 0 || role2 == 0) {ret = 0; goto ex;} /* one null-drive, one not */ else if (role1 != 1 && role2 != 1) { /* pseudo-drive meets file object */ if (role1 != role2) {ret = 0; goto ex;} if (stat_ret1 == -1 || stat_ret2 == -1) { if (stat_ret1 != -1 || stat_ret2 != -1) {ret = 0; goto ex;} /* one adress existing, one not */ /* Two non-existing file objects */ strcpy(conv_adr1, adr1); burn__split_path(conv_adr1, &dpt1, &npt1); strcpy(conv_adr2, adr2); burn__split_path(conv_adr2, &dpt2, &npt2); if (strcmp(npt1, npt2)) {ret = 0; goto ex;} /* basenames differ */ stat_ret1= stat(adr1, &stbuf1); stat_ret2= stat(adr2, &stbuf2); if (stat_ret1 != stat_ret2) {ret = 0; goto ex;} /* one dir existing, one not */ /* Both directories exist. The basenames are equal. So the adresses are equal if the directories are equal.*/ } if (stbuf1.st_ino == stbuf2.st_ino && stbuf1.st_dev == stbuf2.st_dev) {ret = 1; goto ex;} /* same filesystem object */ if (S_ISBLK(stbuf1.st_mode) && S_ISBLK(stbuf2.st_mode) && stbuf1.st_rdev == stbuf2.st_rdev) {ret = 1; goto ex;}/* same major,minor device number */ if (S_ISCHR(stbuf1.st_mode) && S_ISCHR(stbuf2.st_mode) && stbuf1.st_rdev == stbuf2.st_rdev) {ret = 1; goto ex;}/* same major,minor device number */ /* Are both filesystem objects related to the same MMC drive */ if (conv_ret2 <= 0) {ret = 0; goto ex;} /* no MMC drive at adr2 */ if (burn_drive_convert_fs_adr(adr1, conv_adr1) <= 0) {ret = 0; goto ex;} /* no MMC drive at adr1 */ if (strcmp(conv_adr1, conv_adr2) == 0) {ret = 1; goto ex;} /* same MMC drive */ {ret = 0; goto ex;} /* all filesystem disguises are checked */ } else if (role1 == 1 && role2 != 1) { /* MMC drive meets file object */ if (conv_ret2 <= 0) {ret = 0; goto ex;} /* no MMC drive at adr2 */ if (strcmp(adr1, conv_adr2) == 0) {ret = 1; goto ex;} /* same MMC drive */ {ret = 0; goto ex;} } else if (role1 != 1 && role2 == 1) { /* stdio-drive meets wannabe MMC drive */ if (conv_ret2 <= 0) {ret = 0; goto ex;} /* no MMC drive at adr2 */ if (burn_drive_convert_fs_adr(adr1, conv_adr1) <= 0) {ret = 0; goto ex;} /* no MMC drive at adr1 */ if (strcmp(conv_adr1, conv_adr2) == 0) {ret = 1; goto ex;} /* same MMC drive */ {ret = 0; goto ex;} } ret = 0; ex:; BURN_FREE_MEM(adr1); BURN_FREE_MEM(conv_adr1); BURN_FREE_MEM(conv_adr2); return ret; } int burn_drive_find_by_thread_pid(struct burn_drive **d, pid_t pid, pthread_t tid) { int i; for (i = 0; i < drivetop + 1; i++) { /* if (drive_array[i].thread_pid_valid) fprintf(stderr, "libburn_EXPERIMENTAL : drive %d , thread_pid %d\n", i, drive_array[i].thread_pid); */ if (drive_array[i].thread_pid_valid && drive_array[i].thread_pid == pid && pthread_equal(drive_array[i].thread_tid, tid)) { *d = &(drive_array[i]); return 1; } } return 0; } /* ts A80422 : centralizing this setting for debugging purposes */ 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; return 1; } /* ts A81215 : API */ int burn_get_read_capacity(struct burn_drive *d, int *capacity, int flag) { *capacity = d->media_read_capacity + 1; return (d->media_read_capacity != 0x7fffffff); } /* ts A90903 : API */ int burn_disc_get_media_id(struct burn_drive *d, char **product_id, char **media_code1, char **media_code2, char **book_type, int flag) { int ret; *product_id = *media_code1 = *media_code2 = *book_type = NULL; if (burn_drive_get_drive_role(d) != 1) return 0; ret = mmc_get_media_product_id(d, product_id, media_code1, media_code2, book_type, flag & 1); return ret; } /* ts A90909 : API */ /** @param valid Replies bits which indicate the validity of other reply parameters or the state of certain CD info bits: bit0= disc_type valid bit1= disc_id valid bit2= bar_code valid bit3= disc_app_code valid bit4= Disc is unrestricted (URU bit) bit5= Disc is nominally erasable (Erasable bit) This will be set with overwriteable media which libburn normally considers to be unerasable blank. */ int burn_disc_get_cd_info(struct burn_drive *d, char disc_type[80], unsigned int *disc_id, char bar_code[9], int *app_code, int *valid) { if (d->disc_type == 0x00) { strcpy(disc_type, "CD-DA or CD-ROM"); } else if (d->disc_type == 0x10) { strcpy(disc_type, "CD-I"); } else if (d->disc_type == 0x20) { strcpy(disc_type, "CD-ROM XA"); } else { strcpy(disc_type, "undefined"); } *disc_id = d->disc_id; memcpy(bar_code, d->disc_bar_code, 8); bar_code[8]= 0; *app_code = d->disc_app_code; *valid = d->disc_info_valid; return 1; } /* ts B00924 : API */ int burn_disc_get_bd_spare_info(struct burn_drive *d, int *alloc_blocks, int *free_blocks, int flag) { int ret; if (burn_drive_get_drive_role(d) != 1) return 0; *alloc_blocks = *free_blocks = 0; ret = mmc_get_bd_spare_info(d, alloc_blocks, free_blocks, 0); return ret; } /* 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 */ int burn_disc_next_track_is_damaged(struct burn_drive *d, int flag) { return d->next_track_damaged; } /* ts B11201 : API */ /* Read the CD-TEXT data from the Lead-in of an Audio CD */ int burn_disc_get_leadin_text(struct burn_drive *d, unsigned char **text_packs, int *num_packs, int flag) { int ret; ret = mmc_get_leadin_text(d, text_packs, num_packs, 0); return ret; } /* ts B31023 API */ /* Inquire for DVD-RW failure of TAO */ int burn_drive_was_feat21_failure(struct burn_drive *d) { return !!d->was_feat21h_failure; } /* ts B40106 */ int burn_feature_descr_new(struct burn_feature_descr **new, unsigned char *descr, int descr_len, int flag) { struct burn_feature_descr *o; *new = NULL; if (descr_len < 4) return 0; (*new) = o = calloc(1, sizeof(struct burn_feature_descr)); if (o == NULL) return -1; o->feature_code = (descr[0] << 8) | descr[1]; o->flags = descr[2]; if (descr[3] > descr_len - 4) o->data_lenght = 0; else o->data_lenght = descr[3]; o->data = NULL; o->next = NULL; if (o->data_lenght > 0) { o->data = calloc(1, o->data_lenght); if (o->data == NULL) { burn_feature_descr_free(new, 0); return -1; } memcpy(o->data, descr + 4, o->data_lenght); } return 1; } /* ts B40106 */ int burn_feature_descr_free(struct burn_feature_descr **descr, int flag) { struct burn_feature_descr *o, *next; if (*descr == NULL) return 0; for (o = *descr; o != NULL; o = next) { next = o->next; if (o->data != NULL) free(o->data); free((char *) o); } *descr = NULL; return 1; } /* ts B40107 */ int burn_drive_has_feature(struct burn_drive *d, int feature_code, struct burn_feature_descr **descr, int flag) { struct burn_feature_descr *o; for (o = d->features; o != NULL; o = o->next) { if (o->feature_code == feature_code) { if (descr != NULL) *descr = o; return 1; } } return 0; } /* ts B51016 API */ int burn_drive_get_serial_no(struct burn_drive *d, char **sno, int *sno_len) { int ret; if (*sno != NULL) BURN_FREE_MEM(*sno); if (d->drive_serial_number_len > 0) *sno_len = d->drive_serial_number_len; else *sno_len = 0; BURN_ALLOC_MEM(*sno, char, *sno_len + 1); if (d->drive_serial_number_len > 0) memcpy(*sno, d->drive_serial_number, *sno_len); (*sno)[*sno_len] = 0; ret = 1; ex: return ret; } /* ts B51016 API */ int burn_drive_get_media_sno(struct burn_drive *d, char **sno, int *sno_len) { int ret; #ifdef Libburn_enable_scsi_cmd_ABh struct burn_feature_descr *feat; #endif if (*sno != NULL) BURN_FREE_MEM(*sno); *sno = NULL; if (d->media_serial_number_len == -1) { #ifdef Libburn_enable_scsi_cmd_ABh if (burn_drive_has_feature(d, 0x109, &feat, 0)) #ifndef Libburn_enable_scsi_cmd_ABh_pretend_currenT if (feat->flags & 1) /* current */ #endif spc_read_media_serial_number(d); #else ; #endif /* ! Libburn_enable_scsi_cmd_ABh */ } if (d->media_serial_number_len > 0) *sno_len = d->media_serial_number_len; else *sno_len = 0; BURN_ALLOC_MEM(*sno, char, *sno_len + 1); if (*sno_len > 0) memcpy(*sno, d->media_serial_number, *sno_len); (*sno)[*sno_len] = 0; ret = 1; ex: return ret; } ������������������������������������������������������libburn-1.4.2/libburn/write.h�����������������������������������������������������������������������0000644�0001757�0001751�00000004062�12652644224�013055� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */ /* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens Copyright (c) 2006 - 2010 Thomas Schmitt <scdbackup@gmx.net> Provided under GPL version 2 or later. */ #ifndef BURN__WRITE_H #define BURN__WRITE_H struct cue_sheet; struct burn_session; struct burn_write_opts; struct burn_disc; struct cue_sheet *burn_create_toc_entries(struct burn_write_opts *o, struct burn_session *session, int nwa); int burn_sector_length(int trackmode); int burn_subcode_length(int trackmode); /* ts A61009 */ int burn_disc_write_is_ok(struct burn_write_opts *o, struct burn_disc *disc, int flag); void burn_disc_write_sync(struct burn_write_opts *o, struct burn_disc *disc); int burn_write_leadin(struct burn_write_opts *o, struct burn_session *s, int first); int burn_write_leadout(struct burn_write_opts *o, int first, unsigned char control, int mode); int burn_write_session(struct burn_write_opts *o, struct burn_session *s); int burn_write_track(struct burn_write_opts *o, struct burn_session *s, int tnum); int burn_write_flush(struct burn_write_opts *o, struct burn_track *track); /* ts A61030 : necessary for TAO */ int burn_write_close_track(struct burn_write_opts *o, struct burn_session *s, int tnum); int burn_write_close_session(struct burn_write_opts *o); /* @param flag bit0= repair checksum bit1= repair checksum if all pack CRCs are 0 @return 0= no mismatch , >0 number of unrepaired mismatches <0 number of repaired mismatches */ int burn_cdtext_crc_mismatches(unsigned char *packs, int num_packs, int flag); /* mmc5r03c.pdf 6.3.3.3.3: DVD-R DL: Close Function 010b: Close Session "When the recording mode is Incremental Recording, the disc is single session." Enable this macro to get away from growisofs which uses Close Session but also states "// DVD-R DL Seq has no notion of multi-session". #define Libburn_dvd_r_dl_multi_no_close_sessioN 1 */ #endif /* BURN__WRITE_H */ ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������libburn-1.4.2/libburn/cdtext.c����������������������������������������������������������������������0000755�0001757�0001751�00000136272�12652644224�013225� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ /* Copyright (c) 2011 Thomas Schmitt <scdbackup@gmx.net> Provided under GPL version 2 or later. */ #ifdef HAVE_CONFIG_H #include "../config.h" #endif #include <stdio.h> #include <stdlib.h> #include <string.h> #include <ctype.h> #include <sys/types.h> #include <sys/stat.h> #include <unistd.h> #include <errno.h> #include "libburn.h" #include "init.h" #include "structure.h" #include "options.h" #include "util.h" #include "libdax_msgs.h" extern struct libdax_msgs *libdax_messenger; /* --------------------- Production of CD-TEXT packs -------------------- */ struct burn_pack_cursor { unsigned char *packs; int num_packs; int td_used; int hiseq[8]; int pack_count[16]; int track_offset; }; /* @param flag bit0= double_byte characters */ int burn_create_new_pack(int pack_type, int track_no, int double_byte, int block, int char_pos, struct burn_pack_cursor *crs, int flag) { int idx; if (crs->num_packs >= Libburn_leadin_cdtext_packs_maX) { libdax_msgs_submit(libdax_messenger, -1, 0x0002018b, LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH, "Too many CD-TEXT packs", 0, 0); return 0; } if (crs->hiseq[block] >= 255) { libdax_msgs_submit(libdax_messenger, -1, 0x0002018e, LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH, "Too many CD-TEXT packs in block", 0, 0); return 0; } if (char_pos > 15) char_pos = 15; else if (char_pos < 0) char_pos = 0; idx = crs->num_packs * 18; crs->packs[idx++] = pack_type; crs->packs[idx++] = track_no; crs->packs[idx++] = crs->hiseq[block]; crs->packs[idx++] = ((flag & 1) << 7) | (block << 4) | char_pos; crs->hiseq[block]++; crs->td_used = 0; crs->pack_count[pack_type - Libburn_pack_type_basE]++; return 1; } /* Plain implementation of polynomial division on a Galois field, where addition and subtraction both are binary exor. Euclidian algorithm. Divisor is x^16 + x^12 + x^5 + 1 = 0x11021. */ static int crc_11021(unsigned char *data, int count, int flag) { int acc = 0, i; for (i = 0; i < count * 8 + 16; i++) { acc = (acc << 1); if (i < count * 8) acc |= ((data[i / 8] >> (7 - (i % 8))) & 1); if (acc & 0x10000) acc ^= 0x11021; } return acc; } /* @param flag bit0= repair mismatching checksums bit1= repair checksums if all pack CRCs are 0 @return 0= no mismatch , >0 number of unrepaired mismatches <0 number of repaired mismatches that were not 0 */ int burn_cdtext_crc_mismatches(unsigned char *packs, int num_packs, int flag) { int i, residue, count = 0, repair; unsigned char crc[2]; repair = flag & 1; if (flag & 2) { for (i = 0; i < num_packs * 18; i += 18) if (packs[i + 16] || packs[i + 17]) break; if (i == num_packs * 18) repair = 1; } for (i = 0; i < num_packs * 18; i += 18) { residue = crc_11021(packs + i, 16, 0); crc[0] = ((residue >> 8) & 0xff) ^ 0xff; crc[1] = ((residue ) & 0xff) ^ 0xff; if(crc[0] != packs[i + 16] || crc[1] != packs[i + 17]) { if (repair) { if (packs[i + 16] || packs[i + 17]) count--; packs[i + 16] = crc[0]; packs[i + 17] = crc[1]; } else count++; } } return count; } static int burn_finalize_text_pack(struct burn_pack_cursor *crs, int flag) { int residue = 0, i, idx; idx = 18 * crs->num_packs; for(i = 4 + crs->td_used; i < 16; i++) crs->packs[idx + i] = 0; crs->td_used = 12; /* MMC-3 Annex J : CRC Field consists of 2 bytes. The polynomial is X16 + X12 + X5 + 1. All bits shall be inverted. */ residue = crc_11021(crs->packs + idx, 16, 0) ^ 0xffff; crs->packs[idx + 16] = (residue >> 8) & 0xff; crs->packs[idx + 17] = residue & 0xff; crs->num_packs++; crs->td_used = 0; return 1; } /* @param flag bit0= double_byte characters */ static int burn_create_tybl_packs(unsigned char *payload, int length, int track_no, int pack_type, int block, struct burn_pack_cursor *crs, int flag) { int i, ret, binary_part = 0, char_pos; if (pack_type == 0x87) binary_part = 2; else if ((pack_type >= 0x88 && pack_type <= 0x8c) || pack_type == 0x8f) binary_part = length; for(i = 0; i < length; i++) { if (crs->td_used == 0 || crs->td_used >= 12) { if (crs->td_used > 0) { ret = burn_finalize_text_pack(crs, 0); if (ret <= 0) return ret; } char_pos = (i - binary_part) / (1 + (flag & 1)); ret = burn_create_new_pack(pack_type, track_no, (flag & 1), block, char_pos, crs, flag & 1); if (ret <= 0) return ret; } crs->packs[crs->num_packs * 18 + 4 + crs->td_used] = payload[i]; crs->td_used++; } return 1; } /* Finalize block by 0x8f. Set bytes 20 to 27 to 0 for now. */ static int burn_create_bl_size_packs(int block, unsigned char *char_codes, unsigned char *copyrights, unsigned char *languages, int num_tracks, struct burn_pack_cursor *crs, int flag) { int i, ret; unsigned char payload[12]; payload[0] = char_codes[block]; payload[1] = crs->track_offset; payload[2] = num_tracks + crs->track_offset - 1; payload[3] = copyrights[block]; for (i = 0; i < 8; i++) payload[i + 4] = crs->pack_count[i]; ret = burn_create_tybl_packs(payload, 12, 0, 0x8f, block, crs, 0); if (ret <= 0) return ret; for (i = 0; i < 7; i++) payload[i] = crs->pack_count[i + 8]; payload[7] = 3; /* always 3 packs of type 0x8f */ for (i = 0; i < 4; i++) { /* Will be set when all blocks are done */ payload[i + 8] = 0; } ret = burn_create_tybl_packs(payload, 12, 1, 0x8f, block, crs, 0); if (ret <= 0) return ret; for (i = 0; i < 4; i++) { /* Will be set when all blocks are done */ payload[i] = 0; } for (i = 0; i < 8; i++) { payload[i + 4] = languages[i]; } ret = burn_create_tybl_packs(payload, 12, 2, 0x8f, block, crs, 0); if (ret <= 0) return ret; ret = burn_finalize_text_pack(crs, 0); if (ret <= 0) return ret; for (i = 0; i < 16; i++) crs->pack_count[i] = 0; return 1; } /* Text packs of track for type and block @param flag bit0= write TAB, because content is identical to previous track */ static int burn_create_tybl_t_packs(struct burn_track *t, int track_no, int pack_type, int block, struct burn_pack_cursor *crs, int flag) { int ret, length = 0, idx, double_byte, flags= 0; unsigned char *payload = NULL, dummy[8]; struct burn_cdtext *cdt; cdt = t->cdtext[block]; idx = pack_type - Libburn_pack_type_basE; if (cdt != NULL) { if (cdt->length[idx] > 0) { payload = cdt->payload[idx]; length = cdt->length[idx]; } flags = cdt->flags; } if (payload == NULL) { dummy[0]= 0; payload = dummy; length = strlen((char *) dummy) + 1; } double_byte = !!(flags & (1 <<(pack_type - Libburn_pack_type_basE))); if (flag & 1) { length = 0; dummy[length++] = 9; if (double_byte) dummy[length++] = 9; dummy[length++] = 0; if (double_byte) dummy[length++] = 0; payload = dummy; } ret = burn_create_tybl_packs(payload, length, track_no, pack_type, block, crs, double_byte); return ret; } /* Check whether the content is the same as in the previous pack. If so, advise to use the TAB abbreviation. */ static int burn_decide_cdtext_tab(int block, int pack_type, struct burn_cdtext *cdt_curr, struct burn_cdtext *cdt_prev, int flag) { int length, j, idx; idx = pack_type - Libburn_pack_type_basE; if (cdt_curr == NULL || cdt_prev == NULL) return 0; if (((cdt_curr->flags >> idx) & 1) != ((cdt_prev->flags >> idx) & 1)) return 0; length = cdt_curr->length[idx]; if (length != cdt_prev->length[idx] || length <= 1 + ((cdt_curr->flags >> idx) & 1)) return 0; for (j = 0; j < length; j++) if (cdt_curr->payload[idx][j] != cdt_prev->payload[idx][j]) break; if (j < length) return 0; return 1; } /* Text packs of session and of tracks (if applicable), for type and block */ static int burn_create_tybl_s_packs(struct burn_session *s, int pack_type, int block, struct burn_pack_cursor *crs, int flag) { int i, ret, idx, double_byte, use_tab; struct burn_cdtext *cdt; cdt = s->cdtext[block]; idx = pack_type - Libburn_pack_type_basE; if (cdt->length[idx] == 0 || cdt->payload[idx] == NULL) return 1; double_byte = !!(cdt->flags & (1 <<(pack_type - Libburn_pack_type_basE))); ret = burn_create_tybl_packs(cdt->payload[idx], cdt->length[idx], 0, pack_type, block, crs, double_byte); if (ret <= 0) return ret; if ((pack_type < 0x80 || pack_type > 0x85) && pack_type != 0x8e) { ret = burn_finalize_text_pack(crs, 0); return ret; } for (i = 0; i < s->tracks; i++) { if (i > 0) use_tab = burn_decide_cdtext_tab(block, pack_type, s->track[i]->cdtext[block], s->track[i - 1]->cdtext[block], 0); else use_tab = 0; ret = burn_create_tybl_t_packs(s->track[i], i + crs->track_offset, pack_type, block, crs, use_tab); if (ret <= 0) return ret; } /* Fill up last pack with 0s */ ret = burn_finalize_text_pack(crs, 0); return ret; } /* ts B11210 : API */ /* @param flag bit0= do not return CD-TEXT packs, but return number of packs */ int burn_cdtext_from_session(struct burn_session *s, unsigned char **text_packs, int *num_packs, int flag) { int pack_type, block, ret, i, idx, j, residue; struct burn_pack_cursor crs; if (text_packs == NULL || num_packs == NULL) { flag |= 1; } else if (!(flag & 1)) { *text_packs = NULL; *num_packs = 0; } memset(&crs, 0, sizeof(struct burn_pack_cursor)); crs.track_offset = s->firsttrack; BURN_ALLOC_MEM(crs.packs, unsigned char, Libburn_leadin_cdtext_packs_maX * 18); for (block = 0; block < 8; block++) if (s->cdtext[block] != NULL) break; if (block == 8) {ret = 1; goto ex;} for (block= 0; block < 8; block++) { if (s->cdtext[block] == NULL) continue; for (pack_type = 0x80; pack_type < 0x80 + Libburn_pack_num_typeS; pack_type++) { if (pack_type == 0x8f) continue; ret = burn_create_tybl_s_packs(s, pack_type, block, &crs, 0); if (ret <= 0) goto ex; } ret = burn_create_bl_size_packs(block, s->cdtext_char_code, s->cdtext_copyright, s->cdtext_language, s->tracks, &crs, 0); if (ret <= 0) goto ex; } /* Insert the highest sequence numbers of each block into the 0x8f packs 2 and 3 (bytes 20 to 27) */ for (i = 0; i < crs.num_packs; i++) { idx = i * 18; if (crs.packs[idx] == 0x8f && crs.packs[idx + 1] == 1) { for (j = 0; j < 4; j++) if (crs.hiseq[j] > 0) crs.packs[idx + 4 + 8 + j] = crs.hiseq[j] - 1; else crs.packs[idx + 4 + 8 + j] = 0; } else if (crs.packs[idx] == 0x8f && crs.packs[idx + 1] == 2) { for (j = 0; j < 4; j++) if (crs.hiseq[j + 4] > 0) crs.packs[idx + 4 + j] = crs.hiseq[j + 4] - 1; else crs.packs[idx + 4 + j] = 0; } else continue; /* Re-compute checksum */ residue = crc_11021(crs.packs + idx, 16, 0) ^ 0xffff; crs.packs[idx + 16] = (residue >> 8) & 0xff; crs.packs[idx + 17] = residue & 0xff; } ret = 1; ex:; if (ret <= 0 || (flag & 1)) { if (ret > 0) ret = crs.num_packs; else if (flag & 1) ret = -1; BURN_FREE_MEM(crs.packs); } else { if (crs.num_packs > 0) *text_packs = crs.packs; else BURN_FREE_MEM(crs.packs); *num_packs = crs.num_packs; } return(ret); } /* ---------------- Reader of Sony Input Sheet Version 0.7T ------------- */ /* @param flag bit0= allow two byte codes 0xNNNN or 0xNN 0xNN */ static int v07t_hexcode(char *payload, int flag) { unsigned int x; int lo, hi, l; char buf[10], *cpt; l = strlen(payload); if (strncmp(payload, "0x", 2) != 0) return -1; if ((l == 6 || l == 9) && (flag & 1)) goto double_byte; if (strlen(payload) != 4) return -1; if (!(isxdigit(payload[2]) && isxdigit(payload[3]))) return -1; sscanf(payload + 2, "%x", &x); return x; double_byte:; strcpy(buf, payload); buf[4] = 0; hi = v07t_hexcode(buf, 0); if (strlen(payload) == 6) { buf[4] = payload[4]; buf[2] = '0'; buf[3] = 'x'; cpt = buf + 2; } else { if(payload[4] != 32 && payload[4] != 9) return(-1); cpt = buf + 5; } lo = v07t_hexcode(cpt, 0); if (lo < 0 || hi < 0) return -1; return ((hi << 8) | lo); } static int v07t_cdtext_char_code(char *payload, int flag) { int ret; char *msg = NULL; ret = v07t_hexcode(payload, 0); if (ret >= 0) return ret; if (strstr(payload, "8859") != NULL) return 0x00; else if(strstr(payload, "ASCII") != NULL) return 0x01; else if(strstr(payload, "JIS") != NULL) return 0x80; BURN_ALLOC_MEM(msg, char, 160); sprintf(msg, "Unknown v07t Text Code '%.80s'", payload); libdax_msgs_submit(libdax_messenger, -1, 0x00020191, LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH, burn_printify(msg), 0, 0); ret = -1; ex:; BURN_FREE_MEM(msg); return ret; } static int v07t_cdtext_lang_code(char *payload, int flag) { int i, ret; static char *languages[128] = { BURN_CDTEXT_LANGUAGES_0X00, BURN_CDTEXT_FILLER, BURN_CDTEXT_LANGUAGES_0X45 }; char *msg = NULL; ret = v07t_hexcode(payload, 0); if (ret >= 0) return ret; if (payload[0] != 0) for(i = 0; i < 128; i++) if(strcmp(languages[i], payload) == 0) return i; BURN_ALLOC_MEM(msg, char, 160); sprintf(msg, "Unknown v07t Language Code '%.80s'", payload); libdax_msgs_submit(libdax_messenger, -1, 0x00020191, LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH, burn_printify(msg), 0, 0); ret = -1; ex:; BURN_FREE_MEM(msg); return ret; } static int v07t_cdtext_genre_code(char *payload, int flag) { int i, ret; static char *genres[BURN_CDTEXT_NUM_GENRES] = { BURN_CDTEXT_GENRE_LIST }; char *msg = NULL; ret = v07t_hexcode(payload, 1); if(ret >= 0) return ret; for (i= 0; i < BURN_CDTEXT_NUM_GENRES; i++) if (strcmp(genres[i], payload) == 0) return i; BURN_ALLOC_MEM(msg, char, 160); sprintf(msg, "Unknown v07t Genre Code '%.80s'", payload); libdax_msgs_submit(libdax_messenger, -1, 0x00020191, LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH, burn_printify(msg), 0, 0); ret = -1; ex:; BURN_FREE_MEM(msg); return ret; } static int v07t_cdtext_len_db(char *payload, int *char_code, int *length, int *double_byte, int flag) { if (*char_code < 0) *char_code = 0x00; *double_byte = (*char_code == 0x80); *length = strlen(payload) + 1 + *double_byte; return 1; } static int v07t_cdtext_to_session(struct burn_session *session, int block, char *payload, int *char_code, int pack_type, char *pack_type_name, int flag) { int length, double_byte, ret; ret = v07t_cdtext_len_db(payload, char_code, &length, &double_byte, 0); if (ret <= 0) return ret; ret = burn_session_set_cdtext(session, block, pack_type, pack_type_name, (unsigned char *) payload, length, double_byte); return ret; } static int v07t_cdtext_to_track(struct burn_track *track, int block, char *payload, int *char_code, int pack_type, char *pack_type_name, int flag) { int length, double_byte, ret; ret = v07t_cdtext_len_db(payload, char_code, &length, &double_byte, 0); if (ret <= 0) return ret; ret = burn_track_set_cdtext(track, block, pack_type, pack_type_name, (unsigned char *) payload, length, double_byte); return ret; } static int v07t_apply_to_session(struct burn_session *session, int block, int char_codes[8], int copyrights[8], int languages[8], int session_attr_seen[16], int track_attr_seen[16], int genre_code, char *genre_text, int flag) { int i, ret, length; char *line = NULL; BURN_ALLOC_MEM(line, char, 4096); for (i= 0x80; i <= 0x8e; i++) { if (i > 0x85 && i != 0x8e) continue; if (session_attr_seen[i - 0x80] || !track_attr_seen[i - 0x80]) continue; ret = v07t_cdtext_to_session(session, block, "", char_codes + block, i, NULL, 0); if (ret <= 0) goto ex; } if (genre_code >= 0 && genre_text[0]) { line[0] = (genre_code >> 8) & 0xff; line[1] = genre_code & 0xff; strcpy(line + 2, genre_text); length = 2 + strlen(line + 2) + 1; ret = burn_session_set_cdtext(session, block, 0, "GENRE", (unsigned char *) line, length, 0); if (ret <= 0) goto ex; } ret = burn_session_set_cdtext_par(session, char_codes, copyrights, languages, 0); if (ret <= 0) goto ex; for (i = 0; i < 8; i++) char_codes[i] = copyrights[i] = languages[i]= -1; for (i = 0; i < 16; i++) session_attr_seen[i] = track_attr_seen[i] = 0; genre_text[0] = 0; ret = 1; ex: BURN_FREE_MEM(line); return ret; } /* ts B11215 API */ /* @param flag bit0= permission to read multiple blocks from the same sheet bit1= do not attach CATALOG to session or ISRC to track for writing to Q sub-channel */ int burn_session_input_sheet_v07t(struct burn_session *session, char *path, int block, int flag) { int ret = 0, num_tracks, char_codes[8], copyrights[8], languages[8], i; int genre_code = -1, track_offset = 1, pack_type, tno, tnum; int session_attr_seen[16], track_attr_seen[16]; int int0x00 = 0x00, int0x01 = 0x01; int additional_blocks = -1, line_count = 0, enable_multi_block = 0; struct stat stbuf; FILE *fp = NULL; char *line = NULL, *eq_pos, *payload, *genre_text = NULL, track_txt[3]; char *msg = NULL; struct burn_track **tracks; BURN_ALLOC_MEM(msg, char, 4096); BURN_ALLOC_MEM(line, char, 4096); BURN_ALLOC_MEM(genre_text, char, 160); for (i = 0; i < 8; i++) char_codes[i] = copyrights[i] = languages[i]= -1; for (i = 0; i < 16; i++) session_attr_seen[i] = track_attr_seen[i] = 0; genre_text[0] = 0; tracks = burn_session_get_tracks(session, &num_tracks); if (stat(path, &stbuf) == -1) { cannot_open:; sprintf(msg, "Cannot open CD-TEXT input sheet v07t '%.4000s'", path); libdax_msgs_submit(libdax_messenger, -1, 0x00020193, LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH, burn_printify(msg), errno, 0); ret = 0; goto ex; } if (!S_ISREG(stbuf.st_mode)) { sprintf(msg, "File is not of usable type: CD-TEXT input sheet v07t '%s'", path); libdax_msgs_submit(libdax_messenger, -1, 0x00020193, LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH, burn_printify(msg), 0, 0); ret = 0; goto ex; } fp = fopen(path, "rb"); if (fp == NULL) goto cannot_open; while (1) { if (burn_sfile_fgets(line, 4095, fp) == NULL) { if (!ferror(fp)) break; sprintf(msg, "Cannot read all bytes from CD-TEXT input sheet v07t '%.4000s'", path); libdax_msgs_submit(libdax_messenger, -1, 0x00020193, LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH, burn_printify(msg), 0, 0); ret = 0; goto ex; } line_count++; if (strlen(line) == 0) continue; eq_pos = strchr(line, '='); if (eq_pos == NULL) { sprintf(msg, "CD-TEXT v07t input sheet line without '=' : '%.4000s'", line); libdax_msgs_submit(libdax_messenger, -1, 0x00020194, LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH, burn_printify(msg), 0, 0); ret = 0; goto ex; } for (payload = eq_pos + 1; *payload == 32 || *payload == 9; payload++); *eq_pos = 0; for (eq_pos--; (*eq_pos == 32 || *eq_pos == 9) && eq_pos > line; eq_pos--) *eq_pos= 0; if (payload[0] == 0) continue; if (strcmp(line, "Text Code") == 0) { ret = v07t_cdtext_char_code(payload, 0); if (ret < 0) goto ex; if (char_codes[block] >= 0 && char_codes[block] != ret) { libdax_msgs_submit(libdax_messenger, -1, 0x00020192, LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH, "Unexpected v07t Text Code change", 0, 0); ret = 0; goto ex; } char_codes[block] = ret; } else if (strcmp(line, "Language Code") == 0) { ret = v07t_cdtext_lang_code(payload, 0); if(ret < 0) goto ex; languages[block] = ret; } else if (strcmp(line, "0x80") == 0 || strcmp(line, "Album Title") == 0) { ret = v07t_cdtext_to_session(session, block, payload, char_codes + block, 0, "TITLE", 0); if (ret <= 0) goto ex; session_attr_seen[0x0] = 1; } else if (strcmp(line, "0x81") == 0 || strcmp(line, "Artist Name") == 0) { ret = v07t_cdtext_to_session(session, block, payload, char_codes + block, 0, "PERFORMER", 0); if (ret <= 0) goto ex; session_attr_seen[0x1] = 1; } else if (strcmp(line, "0x82") == 0 || strcmp(line, "Songwriter") == 0) { ret = v07t_cdtext_to_session(session, block, payload, char_codes + block, 0, "SONGWRITER", 0); if (ret <= 0) goto ex; session_attr_seen[0x2] = 1; } else if (strcmp(line, "0x83") == 0 || strcmp(line, "Composer") == 0) { ret = v07t_cdtext_to_session(session, block, payload, char_codes + block, 0, "COMPOSER", 0); if (ret <= 0) goto ex; session_attr_seen[0x3] = 1; } else if (strcmp(line, "0x84") == 0 || strcmp(line, "Arranger") == 0) { ret = v07t_cdtext_to_session(session, block, payload, char_codes + block, 0, "ARRANGER", 0); if (ret <= 0) goto ex; session_attr_seen[0x4] = 1; } else if (strcmp(line, "0x85") == 0 || strcmp(line, "Album Message") == 0) { ret = v07t_cdtext_to_session(session, block, payload, char_codes + block, 0, "MESSAGE", 0); if (ret <= 0) goto ex; session_attr_seen[0x5] = 1; } else if (strcmp(line, "0x86") == 0 || strcmp(line, "Catalog Number") == 0) { ret = v07t_cdtext_to_session(session, block, payload, &int0x01, 0, "DISCID", 0); if(ret <= 0) goto ex; } else if (strcmp(line, "Genre Code") == 0) { genre_code = v07t_cdtext_genre_code(payload, 0); if (genre_code < 0) { ret = 0; goto ex; } } else if (strcmp(line, "Genre Information") == 0) { strncpy(genre_text, payload, 159); genre_text[159] = 0; } else if (strcmp(line, "0x8d") == 0 || strcmp(line, "Closed Information") == 0) { ret = v07t_cdtext_to_session(session, block, payload, &int0x00, 0, "CLOSED", 0); if (ret <= 0) goto ex; } else if(strcmp(line, "0x8e") == 0 || strcmp(line, "UPC / EAN") == 0) { ret = v07t_cdtext_to_session(session, block, payload, &int0x01, 0, "UPC_ISRC", 0); if (ret <= 0) goto ex; if (!(flag & 2)) { memcpy(session->mediacatalog, payload, 13); session->mediacatalog[13] = 0; } session_attr_seen[0xe] = 1; } else if (strncmp(line, "Disc Information ", 17) == 0) { /* >>> ??? is this good for anything ? */; } else if (strcmp(line, "Input Sheet Version") == 0) { if (strcmp(payload, "0.7T") != 0) { sprintf(msg, "Wrong Input Sheet Version '%.4000s'. Expected '0.7T'.", payload); libdax_msgs_submit(libdax_messenger, -1, 0x00020194, LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH, burn_printify(msg), 0, 0); ret = 0; goto ex; } if (flag & 1) if (line_count == 1) enable_multi_block = 1; if (enable_multi_block) { if (additional_blocks >= 0) { if (block == 7) { libdax_msgs_submit( libdax_messenger, -1, 0x000201a0, LIBDAX_MSGS_SEV_WARNING, LIBDAX_MSGS_PRIO_HIGH, "Maximum number of CD-TEXT blocks exceeded", 0, 0); break; } ret = v07t_apply_to_session( session, block, char_codes, copyrights, languages, session_attr_seen, track_attr_seen, genre_code, genre_text, 0); if (ret <= 0) goto ex; block++; } additional_blocks++; } } else if (strcmp(line, "Remarks") == 0) { ; } else if (strcmp(line, "Text Data Copy Protection") == 0) { ret = v07t_hexcode(payload, 0); if (ret >= 0) copyrights[block] = ret; else if (strcmp(payload, "ON") == 0) copyrights[block] = 0x03; else if (strcmp(payload, "OFF") == 0) copyrights[block] = 0x00; else { sprintf(msg, "Unknown v07t Text Data Copy Protection '%.4000s'", payload); libdax_msgs_submit(libdax_messenger, -1, 0x00020191, LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH, burn_printify(msg), 0, 0); ret = 0; goto ex; } } else if (strcmp(line, "First Track Number") == 0) { ret = -1; sscanf(payload, "%d", &ret); if (ret <= 0 || ret > 99) { bad_tno:; sprintf(msg, "Inappropriate v07t First Track Number '%.4000s'", payload); libdax_msgs_submit(libdax_messenger, -1, 0x00020194, LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH, burn_printify(msg), 0, 0); ret = 0; goto ex; } else { track_offset = ret; ret = burn_session_set_start_tno(session, track_offset, 0); if (ret <= 0) goto ex; } } else if (strcmp(line, "Last Track Number") == 0) { ret = -1; sscanf(payload, "%d", &ret); if (ret < 0) { goto bad_tno; } else { /* >>> ??? Is it good for anything ? */; } } else if (strncmp(line, "Track ", 6) == 0) { tno = -1; sscanf(line + 6, "%d", &tno); if (tno < 1 || tno - track_offset < 0 || tno - track_offset >= num_tracks) { track_txt[0] = line[6]; track_txt[1] = line[7]; track_txt[2] = 0; bad_track_no:; sprintf(msg, "Inappropriate v07t Track number '%.3900s'", track_txt); sprintf(msg + strlen(msg), " (acceptable range: %2.2d to %2.2d)", track_offset, num_tracks + track_offset - 1); libdax_msgs_submit(libdax_messenger, -1, 0x00020194, LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH, burn_printify(msg), 0, 0); ret = 0; goto ex; } tnum = tno - track_offset; if (strcmp(line, "0x80") == 0 || strcmp(line + 9, "Title") == 0) pack_type = 0x80; else if (strcmp(line + 9, "0x81") == 0 || strcmp(line + 9, "Artist") == 0) pack_type = 0x81; else if (strcmp(line + 9, "0x82") == 0 || strcmp(line + 9, "Songwriter") == 0) pack_type = 0x82; else if (strcmp(line + 9, "0x83") == 0 || strcmp(line + 9, "Composer") == 0) pack_type = 0x83; else if (strcmp(line + 9, "0x84") == 0 || strcmp(line + 9, "Arranger") == 0) pack_type = 0x84; else if (strcmp(line + 9, "0x85") == 0 || strcmp(line + 9, "Message") == 0) pack_type = 0x85; else if (strcmp(line + 9, "0x8e") == 0 || strcmp(line + 9, "ISRC") == 0) { pack_type = 0x8e; if (!(flag & 2)) { ret = burn_track_set_isrc_string( tracks[tnum], payload, 0); if (ret <= 0) goto ex; } } else { sprintf(msg, "Unknown v07t Track purpose specifier '%s'", line + 9); libdax_msgs_submit(libdax_messenger, -1, 0x00020191, LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH, burn_printify(msg), 0, 0); ret = 0; goto ex; } ret = v07t_cdtext_to_track(tracks[tnum], block, payload, &int0x00, pack_type, "", 0); if (ret <= 0) goto ex; track_attr_seen[pack_type - 0x80] = 1; } else if (strncmp(line, "ISRC ", 5) == 0) { /* Track variation of UPC EAN = 0x8e */ tno = -1; sscanf(line + 5, "%d", &tno); if (tno <= 0 || tno - track_offset < 0 || tno - track_offset >= num_tracks) { track_txt[0] = line[5]; track_txt[1] = line[6]; track_txt[2] = 0; goto bad_track_no; } tnum = tno - track_offset; if (!(flag & 2)) { ret = burn_track_set_isrc_string( tracks[tnum], payload, 0); if (ret <= 0) goto ex; } ret = v07t_cdtext_to_track(tracks[tnum], block, payload, &int0x00, 0x8e, "", 0); if (ret <= 0) goto ex; track_attr_seen[0xe] = 1; } else { sprintf(msg, "Unknown v07t purpose specifier '%.4000s'", line); libdax_msgs_submit(libdax_messenger, -1, 0x00020191, LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH, burn_printify(msg), 0, 0); ret = 0; goto ex; } } ret = v07t_apply_to_session(session, block, char_codes, copyrights, languages, session_attr_seen, track_attr_seen, genre_code, genre_text, 0); if (ret <= 0) goto ex; ret = 1; if (additional_blocks > 0) ret += additional_blocks;; ex:; if(fp != NULL) fclose(fp); BURN_FREE_MEM(genre_text); BURN_FREE_MEM(line); BURN_FREE_MEM(msg); return ret; } /* ts B11221 API */ int burn_cdtext_from_packfile(char *path, unsigned char **text_packs, int *num_packs, int flag) { int ret = 0, residue = 0; struct stat stbuf; FILE *fp = NULL; unsigned char head[4], tail[1]; char *msg = NULL; BURN_ALLOC_MEM(msg, char, 4096); *text_packs = NULL; if (stat(path, &stbuf) == -1) { cannot_open:; sprintf(msg, "Cannot open CD-TEXT pack file '%.4000s'", path); libdax_msgs_submit(libdax_messenger, -1, 0x00020198, LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH, burn_printify(msg), errno, 0); ret = 0; goto ex; } if (!S_ISREG(stbuf.st_mode)) goto not_a_textfile; residue = (stbuf.st_size % 18); if(residue != 4 && residue != 0 && residue != 1) { not_a_textfile:; sprintf(msg, "File is not of usable type or content for CD-TEXT packs: '%.4000s'", path); libdax_msgs_submit(libdax_messenger, -1, 0x00020198, LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH, burn_printify(msg), 0, 0); ret = 0; goto ex; } if (stbuf.st_size < 18) goto not_a_textfile; fp = fopen(path, "rb"); if (fp == NULL) goto cannot_open; if (residue == 4) { /* This is for files from cdrecord -vv -toc */ ret = fread(head, 4, 1, fp); if (ret != 1) { cannot_read:; sprintf(msg, "Cannot read all bytes from CD-TEXT pack file '%.4000s'", path); libdax_msgs_submit(libdax_messenger, -1, 0x00020198, LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH, burn_printify(msg), errno, 0); ret = 0; goto ex; } if (head[0] * 256 + head[1] != stbuf.st_size - 2) goto not_a_textfile; } *num_packs = (stbuf.st_size - residue) / 18; if (*num_packs > 2048) { /* Each block can have 256 text packs. There are 8 blocks at most. */ sprintf(msg, "CD-Text pack file too large (max. 36864 bytes): '%.4000s'", path); libdax_msgs_submit(libdax_messenger, -1, 0x0002018b, LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH, burn_printify(msg), 0, 0); ret = 0; goto ex; } if (*num_packs <= 0) { strcpy(msg, "CD-Text pack file contains no complete text pack"); libdax_msgs_submit(libdax_messenger, -1, 0x000201aa, LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH, burn_printify(msg), 0, 0); ret = 0; goto ex; } BURN_ALLOC_MEM(*text_packs, unsigned char, *num_packs * 18); ret = fread(*text_packs, *num_packs * 18, 1, fp); if (ret != 1) goto cannot_read; if (residue == 1) { /* This is for Sony CDTEXT files */ ret = fread(tail, 1, 1, fp); if (ret != 1) goto cannot_read; if (tail[0] != 0) goto not_a_textfile; } ret= 1; ex:; if (ret <= 0) { BURN_FREE_MEM(*text_packs); *text_packs = NULL; *num_packs = 0; } if (fp != NULL) fclose(fp); BURN_FREE_MEM(msg); return ret; } /* --------------------------------- make_v07t -------------------------- */ static int search_pack(unsigned char *text_packs, int num_packs, int start_no, int pack_type, int block, unsigned char **found_pack, int *found_no, int flag) { int i; for (i = start_no; i < num_packs; i++) { if (pack_type >= 0) if (text_packs[i * 18] != pack_type) continue; if (block >= 0) if (((text_packs[i * 18 + 3] >> 4) & 7) != block) continue; *found_pack = text_packs + i * 18; *found_no = i; return 1; } *found_pack = NULL; *found_no = num_packs; return 0; } static void write_v07t_line(char **respt, char *spec, char *value, int vlen, int *result_len, int flag) { int len; if (vlen == -1) vlen = strlen(value); len = strlen(spec); if (len < 19) len = 19; len += 3 + vlen + 1; if(flag & 1) { *result_len += len; return; } sprintf(*respt, "%-19s = ", spec); if (vlen > 0) memcpy(*respt + strlen(*respt), value, vlen); (*respt)[len - 1] = '\n'; (*respt)[len] = 0; *respt+= len; } /* @return -1 error 0 no pack of block,pack_type found 1 packs found, delimiter is single 0-byte 2 packs found, delimiter is double 0-byte */ static int collect_payload(unsigned char *text_packs, int num_packs, int pack_type, int block, unsigned char **payload, int *payload_count, int flag) { unsigned char *pack; int pack_no, ret, double_byte = 0; *payload_count = 0; for (pack_no = 0; ; pack_no++) { ret = search_pack(text_packs, num_packs, pack_no, pack_type, block, &pack, &pack_no, 0); if (ret <= 0) break; *payload_count += 12; } if (*payload_count == 0) return 0; *payload = burn_alloc_mem(*payload_count + 1, 1, 0); if (*payload == NULL) return -1; *payload_count = 0; for (pack_no = 0; ; pack_no++) { ret = search_pack(text_packs, num_packs, pack_no, pack_type, block, &pack, &pack_no, 0); if (ret <= 0) break; memcpy(*payload + *payload_count, pack + 4, 12); *payload_count += 12; if (pack[4] & 128) double_byte = 1; } (*payload)[*payload_count] = 0; return 1 + double_byte; } /* @param flag bit0= use double 0 as delimiter */ static int is_payload_text_end(unsigned char *payload, int payload_count, int i, int flag) { if (i >= payload_count) return 1; if (payload[i]) return 0; if (!(flag & 1)) return 1; if (i + 1 >= payload_count) return 1; if (payload[i + 1] == 0) return 1; return 0; } /* @param flag Bitfield for control purposes. bit0= use double 0 as delimiter bit1= replace TAB resp. TAB TAB by text of previous tno */ static int pick_payload_text(unsigned char *payload, int payload_count, int tno, unsigned char **text_start, int *text_len, int flag) { int i, skipped = 0, end_found = 0; again:; if (tno <= 0) { *text_start = payload; *text_len = 0; for (i = 0; i < payload_count; i += 1 + (flag & 1)) { end_found = is_payload_text_end(payload, payload_count, i, flag & 1); if (end_found) { *text_len = i; break; } } return 1; } *text_start = NULL; *text_len = 0; for (i = 0; i < payload_count; i += 1 + (flag & 1)) { end_found = is_payload_text_end(payload, payload_count, i, flag & 1); if (end_found) { skipped++; if (skipped == tno) { *text_start = payload + (i + 1 + (flag & 1)); } else if (skipped == tno + 1) { *text_len = i - (*text_start - payload); goto found; } } } if (*text_start == NULL) return 0; *text_len = payload_count - (*text_start - payload); found:; if (flag & 2) { /* If TAB resp. TAB TAB, then look back */ if (flag & 1) { if (*text_len == 2) { if ((*text_start)[0] == '\t' && (*text_start)[1] == '\t') { skipped = 0; tno--; goto again; } } } else if (*text_len == 1) { if ((*text_start)[0] == '\t') { skipped = 0; tno--; goto again; } } } return 1; } static int write_v07t_textline(unsigned char *text_packs, int num_packs, int pack_type, int block, int tno, int first_tno, char *spec, char **respt, int *result_len, int flag) { unsigned char *payload = NULL, *text_start; int ret, payload_count = 0, text_len, tab_flag = 0; char msg[80]; if ((pack_type >= 0x80 && pack_type <= 0x85) || pack_type == 0x8e) tab_flag = 2; ret = collect_payload(text_packs, num_packs, pack_type, block, &payload, &payload_count, 0); if(ret > 0) { ret = pick_payload_text(payload, payload_count, tno, &text_start, &text_len, (ret == 2) | tab_flag); if (ret > 0) { if (tno > 0 && strcmp(spec, "ISRC") == 0) sprintf(msg, "%s %-2.2d", spec, tno + first_tno - 1); else if (tno > 0) sprintf(msg, "Track %-2.2d %s", tno + first_tno - 1, spec); else strcpy(msg, spec); write_v07t_line(respt, msg, (char *) text_start, text_len, result_len, flag & 1); ret = 1; } } BURN_FREE_MEM(payload); return ret; } static int report_track(unsigned char *text_packs, int num_packs, int block, int tno, int first_tno, char **respt, int *result_len, int flag) { int ret, i; static char *track_specs[6] = { "Title", "Artist", "Songwriter", "Composer", "Arranger", "Message" }; for (i = 0; i < 6; i++) { ret = write_v07t_textline(text_packs, num_packs, 0x80 + i, block, tno, first_tno, track_specs[i], respt, result_len, flag & 1); if (ret < 0) return -1; } ret = write_v07t_textline(text_packs, num_packs, 0x8e, block, tno, first_tno, "ISRC", respt, result_len, flag & 1); if (ret < 0) return -1; return 1; } /* @param flag Bitfield for control purposes. bit0= Do not store text in result but only determine the minimum size for the result array. It is permissible to submit result == NULL. Submit the already occupied size as result_size. @return > 0 tells the number of valid text bytes in result resp. with flag bit0 the prediction of that number. This does not include the trailing 0-byte. = 0 indicates that the block is not present < 0 indicates failure. */ static int report_block(unsigned char *text_packs, int num_packs, int block, int first_tno, int last_tno, int char_code, char *result, int result_size, int flag) { char *respt = NULL; unsigned char *pack, *payload = NULL; int result_len = 0, pack_no, ret, i, lang, payload_count = 0, genre; char msg[80]; static char *languages[] = { BURN_CDTEXT_LANGUAGES_0X00, BURN_CDTEXT_FILLER, BURN_CDTEXT_LANGUAGES_0X45 }; static char *volume_specs[7] = { "Album Title", "Artist Name", "Songwriter", "Composer", "Arranger", "Album Message", "Catalog Number", }; static char *genres[BURN_CDTEXT_NUM_GENRES] = { BURN_CDTEXT_GENRE_LIST }; /* Search for any pack of the block. But do not accept 0x8f as first.*/ ret = search_pack(text_packs, num_packs, 0, -1, block, &pack, &pack_no, 0); if (ret <= 0) return 0; if (pack[0] == 0x8f) return 0; if (flag & 1) { result_len = result_size; } else { respt = result + result_size; } write_v07t_line(&respt, "Input Sheet Version", "0.7T", -1, &result_len, flag & 1); sprintf(msg, "Libburn report of CD-TEXT Block %d", block); write_v07t_line(&respt, "Remarks ", msg, -1, &result_len, flag & 1); write_v07t_line(&respt, "Text Code ", char_code == 0 ? "8859" : char_code == 0x01 ? "ASCII" : "MS-JIS", -1, &result_len, flag & 1); pack_no = 0; for (i = 0; i < 3; i++) { ret = search_pack(text_packs, num_packs, pack_no, 0x8f, -1, &pack, &pack_no, 0); if (ret <= 0) { libdax_msgs_submit(libdax_messenger, -1, 0x0002019f, LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH, "No third CD-TEXT pack 0x8f found. No language code defined", 0, 0); goto failure; } pack_no++; } lang = pack[8 + block]; if (lang > 127) { sprintf(msg, "CD-TEXT with unknown language code %2.2x", (unsigned int) lang); libdax_msgs_submit(libdax_messenger, -1, 0x0002019f, LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH, msg, 0, 0); goto failure; } write_v07t_line(&respt, "Language Code", languages[lang], -1, &result_len, flag & 1); for (i = 0; i < 7; i++) { ret = write_v07t_textline(text_packs, num_packs, 0x80 + i, block, 0, 0, volume_specs[i], &respt, &result_len, flag & 1); if (ret < 0) goto failure; } ret = collect_payload(text_packs, num_packs, 0x87, block, &payload, &payload_count, 0); if(ret > 0) { genre = (payload[0] << 8) | payload[1]; if (genre < BURN_CDTEXT_NUM_GENRES) strcpy(msg, genres[genre]); else sprintf(msg, "0x%-4.4x", (unsigned int) genre); write_v07t_line(&respt, "Genre Code", msg, -1, &result_len, flag & 1); write_v07t_line(&respt, "Genre Information", (char *) payload + 2, -1, &result_len, flag & 1); BURN_FREE_MEM(payload); payload = NULL; } ret = collect_payload(text_packs, num_packs, 0x8d, block, &payload, &payload_count, 0); if(ret > 0) { write_v07t_line(&respt, "Closed Information", (char *) payload, -1, &result_len, flag & 1); BURN_FREE_MEM(payload); payload = NULL; } ret = write_v07t_textline(text_packs, num_packs, 0x8e, block, 0, 0, "UPC / EAN", &respt, &result_len, flag & 1); if (ret < 0) goto failure; ret = search_pack(text_packs, num_packs, 0, 0x8f, -1, &pack, &pack_no, 0); if (ret < 0) goto failure; if (pack[7] == 0x00) strcpy(msg, "OFF"); else if (pack[7] == 0x03) strcpy(msg, "ON"); else sprintf(msg, "0x%2.2x", (unsigned int) pack[7]); write_v07t_line(&respt, "Text Data Copy Protection", msg, -1, &result_len, flag & 1); sprintf(msg, "%d", first_tno); write_v07t_line(&respt, "First Track Number", msg, -1, &result_len, flag & 1); sprintf(msg, "%d", last_tno); write_v07t_line(&respt, "Last Track Number", msg, -1, &result_len, flag & 1); for (i = 0; i < last_tno - first_tno + 1; i++) { ret = report_track(text_packs, num_packs, block, i + 1, first_tno, &respt, &result_len, flag & 1); if (ret < 0) goto failure; } if (flag & 1) return result_len; return respt - result; failure:; BURN_FREE_MEM(payload); return -1; } /* @param result A byte buffer of sufficient size. It will be filled by the text for the v07t sheet file plus a trailing 0-byte. (Be aware that double-byte characters might contain 0-bytes, too.) @param result_size The number of bytes in result. To be determined by a run with flag bit0 set. @param flag Bitfield for control purposes. bit0= Do not store text in result but only determine the minimum size for the result array. It is permissible to submit result == NULL and result_size == 0. @return > 0 tells the number of valid text bytes in result resp. with flag bit0 the prediction of that number. This does not include the trailing 0-byte. <= 0 indicates failure. */ static int burn_make_v07t(unsigned char *text_packs, int num_packs, int first_tno, int track_count, char *result, int result_size, int *char_code, int flag) { int pack_no = 0, ret, block, last_tno = 0; unsigned char *pack; char msg[80]; /* >>> ??? Verify checksums ? */; /* Check character code, reject unknown ones */ ret = search_pack(text_packs, num_packs, 0, 0x8f, -1, &pack, &pack_no, 0); if (ret <= 0) { libdax_msgs_submit(libdax_messenger, -1, 0x0002019f, LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH, "No CD-TEXT pack 0x8f found. No character code defined", 0, 0); return 0; } *char_code = pack[4]; if (*char_code != 0x00 && *char_code != 0x01 && *char_code != 0x80) { sprintf(msg, "CD-TEXT with unknown character code %2.2x", (unsigned int) *char_code); libdax_msgs_submit(libdax_messenger, -1, 0x0002019f, LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH, msg, 0, 0); return 0; } /* Obtain first_tno and last_tno from type 0x88 if present. */ if (first_tno <= 0) { if (pack[5] > 0 && pack[5] + pack[6] < 100 && pack[5] <= pack[6]) { first_tno = pack[5]; last_tno = pack[6]; } else { sprintf(msg, "CD-TEXT with illegal track range %d to %d", (int) pack[5], (int) pack[6]); libdax_msgs_submit(libdax_messenger, -1, 0x0002019f, LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH, msg, 0, 0); return 0; } } if (last_tno <= 0) { if (track_count > 0) { last_tno = first_tno + track_count - 1; } else { last_tno = 99; } } /* Report content */ result_size = 0; for (block = 0; block < 8; block++) { ret = report_block(text_packs, num_packs, block, first_tno, last_tno, *char_code, result, result_size, flag & 1); if (ret < 0) return ret; if (ret == 0) continue; result_size = ret; } #ifdef NIX if (flag & 1) return result_size; return (int) strlen((char *) result); #else /* NIX */ return result_size; #endif /* ! NIX */ } /* Convert an array of CD-TEXT packs into the text format of Sony CD-TEXT Input Sheet Version 0.7T . @param text_packs Array of bytes which form CD-TEXT packs of 18 bytes each. For a description of the format of the array, see file doc/cdtext.txt. No header of 4 bytes must be prepended which would tell the number of pack bytes + 2. This parameter may be NULL if the currently attached array of packs shall be removed. @param num_packs The number of 18 byte packs in text_packs. @param start_tno The start number of track counting, if known from CD table-of-content or orther sources. Submit 0 to enable the attempt to read it and the track_count from pack type 0x8f. @param track_count The number of tracks, if known from CD table-of-content or orther sources. @param result Will return the buffer with Sheet text. Dispose by free() when no longer needed. It will be filled by the text for the v07t sheet file plus a trailing 0-byte. (Be aware that double-byte characters might contain 0-bytes, too.) Each CD-TEXT language block starts by the line "Input Sheet Version = 0.7T" and a "Remarks" line that tells the block number. @param char_code Returns the character code of the pack array: 0x00 = ISO-8859-1 0x01 = 7 bit ASCII 0x80 = MS-JIS (japanese Kanji, double byte characters) The presence of a code value that is not in this list will cause this function to fail. @param flag Bitfield for control purposes. Unused yet. Submit 0. @return > 0 tells the number of valid text bytes in result. This does not include the trailing 0-byte. <= 0 indicates failure. */ int burn_make_input_sheet_v07t(unsigned char *text_packs, int num_packs, int start_tno, int track_count, char **result, int *char_code, int flag) { int ret, result_size = 0; ret = burn_make_v07t(text_packs, num_packs, start_tno, track_count, NULL, 0, char_code, 1); if (ret <= 0) return ret; result_size = ret + 1; *result = burn_alloc_mem(result_size, 1, 0); if (*result == NULL) return -1; ret = burn_make_v07t(text_packs, num_packs, start_tno, track_count, *result, result_size, char_code, 0); if (ret <= 0) { free(*result); return ret; } return result_size - 1; } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������libburn-1.4.2/libburn/sg-netbsd.c�������������������������������������������������������������������0000644�0001757�0001751�00000061055�12652644224�013611� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */ /* Copyright (c) 2010 - 2014 Thomas Schmitt <scdbackup@gmx.net> Provided under GPL version 2 or later. Derived 2014 from libburn/sg-solaris.c with information learned from dvd+rw-tools, http://fxr.watson.org/fxr/source/sys/scsiio.h?v=NETBSD, http://netbsd.gw.com/cgi-bin/man-cgi?scsi+4+NetBSD-current, and experiments made by Freddy Fisker. */ /* This is the main operating system dependent SCSI part of libburn. It implements the transport level aspects of SCSI control and command i/o. Present implementation: NetBSD 6, ioctl SCIOCCOMMAND >>> ??? for OpenBSD too ? PORTING: Porting libburn typically will consist of adding a new operating system case to the following switcher files: os.h Operating system specific libburn definitions and declarations. sg.c Operating system dependent transport level modules. and of deriving the following system specific files from existing examples: os-*.h Included by os.h. You will need some general system knowledge about signals and knowledge about the storage object needs of your transport level module sg-*.c. sg-*.c This source module. You will need special system knowledge about how to detect all potentially available drives, how to open them, eventually how to exclusively reserve them, how to perform SCSI transactions, how to inquire the (pseudo-)SCSI driver. You will not need to care about CD burning, MMC or other high-level SCSI aspects. Said sg-*.c operations are defined by a public function interface, which has to be implemented in a way that provides libburn with the desired services: sg_id_string() returns an id string of the SCSI transport adapter. It may be called before initialization but then may return only a preliminary id. sg_initialize() performs global initialization of the SCSI transport adapter and eventually needed operating system facilities. Checks for compatibility of supporting software components. sg_shutdown() performs global finalizations and releases golbally aquired resources. sg_give_next_adr() iterates over the set of potentially useful drive address strings. scsi_enumerate_drives() brings all available, not-whitelist-banned, and accessible drives into libburn's list of drives. sg_dispose_drive() finalizes adapter specifics of struct burn_drive on destruction. Releases resources which were aquired underneath scsi_enumerate_drives(). sg_drive_is_open() tells wether libburn has the given drive in use. sg_grab() opens the drive for SCSI commands and ensures undisturbed access. sg_release() closes a drive opened by sg_grab() sg_issue_command() sends a SCSI command to the drive, receives reply, and evaluates wether the command succeeded or shall be retried or finally failed. sg_obtain_scsi_adr() tries to obtain SCSI address parameters. burn_os_is_2k_seekrw() tells whether the given path leads to a file object that can be used in 2 kB granularity by lseek(2), read(2), and possibly write(2) if not read-only.. E.g. a USB stick or a hard disk. burn_os_stdio_capacity() estimates the emulated media space of stdio-drives. burn_os_open_track_src() opens a disk file in a way that offers best throughput with file reading and/or SCSI write command transmission. burn_os_alloc_buffer() allocates a memory area that is suitable for file descriptors issued by burn_os_open_track_src(). The buffer size may be rounded up for alignment reasons. burn_os_free_buffer() delete a buffer obtained by burn_os_alloc_buffer(). Porting hints are marked by the text "PORTING:". Send feedback to libburn-hackers@pykix.org . */ #ifdef HAVE_CONFIG_H #include "../config.h" #endif /** PORTING : ------- OS dependent headers and definitions ------ */ #include <unistd.h> #include <stdio.h> #include <sys/types.h> #include <errno.h> #include <fcntl.h> #include <sys/stat.h> #include <string.h> #include <stdlib.h> #ifdef Libburn_os_has_statvfS #include <sys/statvfs.h> #endif /* Libburn_os_has_stavtfS */ #include <sys/ioctl.h> #include <sys/scsiio.h> /** PORTING : ------ libburn portable headers and definitions ----- */ #include "transport.h" #include "drive.h" #include "sg.h" #include "spc.h" #include "sbc.h" #include "debug.h" #include "toc.h" #include "util.h" #include "init.h" #include "libdax_msgs.h" extern struct libdax_msgs *libdax_messenger; /* is in portable part of libburn */ int burn_drive_is_banned(char *device_address); int burn_drive_resolve_link(char *path, char adr[], int *recursion_count, int flag); /* drive.c */ /* Whether to log SCSI commands: bit0= log in /tmp/libburn_sg_command_log bit1= log to stderr bit2= flush every line */ extern int burn_sg_log_scsi; /* ------------------------------------------------------------------------ */ /* PORTING: Private definitions. Port only if needed by public functions. */ /* (Public functions are listed below) */ /* ------------------------------------------------------------------------ */ /* Storage object is in libburn/init.c whether to strive for exclusive access to the drive */ extern int burn_sg_open_o_excl; /* ------------------------------------------------------------------------ */ /* PORTING: Private functions. Port only if needed by public functions */ /* (Public functions are listed below) */ /* ------------------------------------------------------------------------ */ static int sg_close_drive(struct burn_drive * d) { if (d->fd != -1) { close(d->fd); d->fd = -1; return 1; } return 0; } /* ----------------------------------------------------------------------- */ /* PORTING: Private functions which contain publicly needed functionality. */ /* Their portable part must be performed. So it is probably best */ /* to replace the non-portable part and to call these functions */ /* in your port, too. */ /* ----------------------------------------------------------------------- */ /** Wraps a detected drive into libburn structures and hands it over to libburn drive list. */ static void enumerate_common(char *fname, int bus_no, int host_no, int channel_no, int target_no, int lun_no) { int ret; struct burn_drive out; /* General libburn drive setup */ burn_setup_drive(&out, fname); /* This transport adapter uses SCSI-family commands and models (seems the adapter would know better than its boss, if ever) */ ret = burn_scsi_setup_drive(&out, bus_no, host_no, channel_no, target_no, lun_no, 0); if (ret <= 0) return; /* PORTING: ------------------- non portable part --------------- */ /* Transport adapter is NetBSD SCIOCCOMMAND */ /* Adapter specific handles and data */ out.fd = -1; /* PORTING: ---------------- end of non portable part ------------ */ /* Adapter specific functions with standardized names */ out.grab = sg_grab; out.release = sg_release; out.drive_is_open = sg_drive_is_open; out.issue_command = sg_issue_command; /* Finally register drive and inquire drive information */ burn_drive_finish_enum(&out); } static int start_enum_rcdNx(burn_drive_enumerator_t *idx, int flag) { idx->cdno = -1; return 1; } /* Trying /dev/rcd[0..63][dc] */ #define Libburn_netbsd_max_cdnuM 63 static int next_enum_rcdNx(burn_drive_enumerator_t *idx, char adr[], int adr_size, int flag) { static char suffix[2] = {'d', 'c'}; struct stat stbuf; int i, stat_ret; char path[16]; while (idx->cdno < Libburn_netbsd_max_cdnuM) { idx->cdno++; for (i = 0; i < 2; i++) { sprintf(path, "/dev/rcd%d%c", idx->cdno, suffix[i]); stat_ret = stat(path, &stbuf); if (stat_ret == -1) continue; if (!S_ISCHR(stbuf.st_mode)) continue; if ((int) strlen(path) >= adr_size) continue; strcpy(adr, path); return 1; } } return 0; } /* Searching the first byte address that cannot be lseeked and read */ static int guess_size_by_seek_set(int fd, off_t *bytes, int flag) { static off_t abs_limit = ((off_t) 1024) * 1024 * 1024 * 1024 * 1024; off_t i, step = ((off_t) 1024) * 1024 * 1024 * 1024, ret; char buf[1]; *bytes = 0; for (i = step; i < abs_limit; i += step) { ret = lseek(fd, i, SEEK_SET); if (ret == -1) { i -= step; step = step >> 1; if (step > 0) continue; return 1; } ret = read(fd, buf, 1); if (ret == -1) { i -= step; step = step >> 1; if (step > 0) continue; return 1; } *bytes = i + 1; } return 0; } /* ------------------------------------------------------------------------ */ /* PORTING: Public functions. These MUST be ported. */ /* ------------------------------------------------------------------------ */ /** Returns the id string of the SCSI transport adapter and eventually needed operating system facilities. This call is usable even if sg_initialize() was not called yet. In that case a preliminary constant message might be issued if detailed info is not available yet. @param msg returns id string @param flag unused yet, submit 0 @return 1 = success, <=0 = failure */ int sg_id_string(char msg[1024], int flag) { sprintf(msg, "internal NetBSD SCIOCCOMMAND adapter sg-netbsd"); return 1; } /** Performs global initialization of the SCSI transport adapter and eventually needed operating system facilities. Checks for compatibility of supporting software components. @param msg returns ids and/or error messages of eventual helpers @param flag unused yet, submit 0 @return 1 = success, <=0 = failure */ int sg_initialize(char msg[1024], int flag) { return sg_id_string(msg, 0); } /** Performs global finalization of the SCSI transport adapter and eventually needed operating system facilities. Releases globally aquired resources. @param flag unused yet, submit 0 @return 1 = success, <=0 = failure */ int sg_shutdown(int flag) { return 1; } /** Finalizes BURN_OS_TRANSPORT_DRIVE_ELEMENTS, the components of struct burn_drive which are defined in os-*.h. The eventual initialization of those components was made underneath scsi_enumerate_drives(). This will be called when a burn_drive gets disposed. @param d the drive to be finalized @param flag unused yet, submit 0 @return 1 = success, <=0 = failure */ int sg_dispose_drive(struct burn_drive *d, int flag) { return 1; } /** Returns the next index number and the next enumerated drive address. The enumeration has to cover all available and accessible drives. It is allowed to return addresses of drives which are not available but under some (even exotic) circumstances could be available. It is on the other hand allowed, only to hand out addresses which can really be used right in the moment of this call. (This implementation chooses the former.) @param idx An opaque handle. Make no own theories about it. @param adr Takes the reply @param adr_size Gives maximum size of reply including final 0 @param initialize 1 = start new, 0 = continue, use no other values for now -1 = finish @return 1 = reply is a valid address , 0 = no further address available -1 = severe error (e.g. adr_size too small) */ int sg_give_next_adr(burn_drive_enumerator_t *idx, char adr[], int adr_size, int initialize) { int ret; if (initialize == 1) { ret = start_enum_rcdNx(idx, 0); if (ret <= 0) return ret; } else if (initialize == -1) { return 0; } ret = next_enum_rcdNx(idx, adr, adr_size, 0); return ret; } /** Brings all available, not-whitelist-banned, and accessible drives into libburn's list of drives. */ int scsi_enumerate_drives(void) { burn_drive_enumerator_t idx; int initialize = 1, ret, i_bus_no = -1, buf_size = 4096; int i_host_no = -1, i_channel_no = -1, i_target_no = -1, i_lun_no = -1; char *buf = NULL; BURN_ALLOC_MEM(buf, char, buf_size); while(1) { ret = sg_give_next_adr(&idx, buf, buf_size, initialize); initialize = 0; if (ret <= 0) break; if (burn_drive_is_banned(buf)) continue; sg_obtain_scsi_adr(buf, &i_bus_no, &i_host_no, &i_channel_no, &i_target_no, &i_lun_no); enumerate_common(buf, i_bus_no, i_host_no, i_channel_no, i_target_no, i_lun_no); } sg_give_next_adr(&idx, buf, buf_size, -1); ret = 1; ex:; BURN_FREE_MEM(buf); return ret; } /** Tells whether libburn has the given drive in use or exclusively reserved. If it is "open" then libburn will eventually call sg_release() on it when it is time to give up usage and reservation. */ /** Published as burn_drive.drive_is_open() */ int sg_drive_is_open(struct burn_drive * d) { return (d->fd != -1); } /** Opens the drive for SCSI commands and - if burn activities are prone to external interference on your system - obtains an exclusive access lock on the drive. (Note: this is not physical tray locking.) A drive that has been opened with sg_grab() will eventually be handed over to sg_release() for closing and unreserving. */ int sg_grab(struct burn_drive *d) { char *msg = NULL; int os_errno, ret; BURN_ALLOC_MEM(msg, char, 4096); if (d->fd != -1) { d->released = 0; {ret = 1; goto ex;} } d->fd = open(d->devname, O_RDWR | O_NDELAY); if (d->fd == -1) { os_errno = errno; sprintf(msg, "Could not grab drive '%s'", d->devname); /* (errno == ENXIO is a device file with no drive attached) */ libdax_msgs_submit(libdax_messenger, d->global_index, 0x00020003, errno == ENXIO ? LIBDAX_MSGS_SEV_DEBUG : LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH, msg, os_errno, 0); {ret = 0; goto ex;} } d->released = 0; /* Make sure by INQUIRY that this is really a MMC drive */ ret = spc_confirm_cd_drive(d, 0); if (ret <= 0) goto revoke; /* # define Libburn_sg_netbsd_scsi_debuG */ #ifdef Libburn_sg_netbsd_scsi_debuG { static int sc_db = SC_DB_CMDS | SC_DB_FLOW; ret = ioctl(d->fd, SCIOCDEBUG, &sc_db); if (ret == -1) fprintf(stderr, "libburn_DEBUG: ioctl(%d, SCIOCDEBUG, &(0x%X)) returns %d, errno = %d\n", d->fd, (unsigned int) sc_db, ret, errno); } #endif {ret = 1; goto ex;} revoke:; sprintf(msg, "Could not grab drive '%s'.", d->devname); libdax_msgs_submit(libdax_messenger, d->global_index, 0x00020003, LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH, msg, 0, 0); if (d->fd >= 0) { close(d->fd); d->fd = -1; d->released = 1; } ret = 0; ex:; BURN_FREE_MEM(msg); return ret; } /** PORTING: Is mainly about the call to sg_close_drive() and whether it implements the demanded functionality. */ /** Gives up the drive for SCSI commands and releases eventual access locks. (Note: this is not physical tray locking.) */ int sg_release(struct burn_drive *d) { if (d->fd < 0) return 0; sg_close_drive(d); return 0; } /** Sends a SCSI command to the drive, receives reply and evaluates wether the command succeeded or shall be retried or finally failed. Returned SCSI errors shall not lead to a return value indicating failure. The callers get notified by c->error. An SCSI failure which leads not to a retry shall be notified via scsi_notify_error(). The Libburn_log_sg_commandS facility might be of help when problems with a drive have to be examined. It shall stay disabled for normal use. @return: 1 success , <=0 failure */ int sg_issue_command(struct burn_drive *d, struct command *c) { int i, timeout_ms, ret, key, asc, ascq, done = 0, sense_len, max_sl; time_t start_time; scsireq_t req; char msg[160]; static FILE *fp = NULL; c->error = 0; if (d->fd == -1) return 0; if (burn_sg_log_scsi & 1) { if (fp == NULL) { fp= fopen("/tmp/libburn_sg_command_log", "a"); fprintf(fp, "\n-----------------------------------------\n"); } } if (burn_sg_log_scsi & 3) scsi_log_cmd(c,fp,0); if (c->timeout > 0) timeout_ms = c->timeout; else timeout_ms = 200000; memset (&req, 0, sizeof(req)); memcpy(req.cmd, c->opcode, c->oplen); req.cmdlen = c->oplen; req.databuf = (caddr_t) c->page->data; req.flags = SCCMD_ESCAPE; /* probably to make req.cmdlen significant */ req.timeout = timeout_ms; max_sl = sizeof(c->sense) > SENSEBUFLEN ? SENSEBUFLEN : sizeof(c->sense); req.senselen = max_sl; if (c->dir == TO_DRIVE) { req.datalen = c->page->bytes; req.flags |= SCCMD_WRITE; } else if (c->dir == FROM_DRIVE) { req.flags |= SCCMD_READ; if (c->dxfer_len >= 0) req.datalen = c->dxfer_len; else req.datalen = BUFFER_SIZE; /* touch page so we can use valgrind */ memset(c->page->data, 0, BUFFER_SIZE); } else { req.flags |= SCCMD_READ; req.datalen = 0; } /* retry-loop */ start_time = time(NULL); for(i = 0; !done; i++) { memset(c->sense, 0, sizeof(c->sense)); c->start_time = burn_get_time(0); ret = ioctl(d->fd, SCIOCCOMMAND, &req); /* <<< Fault mock-up if (c->opcode[0] == 0x28) { ret = -1; errno = 9; } */ c->end_time = burn_get_time(0); /* #define Libburn_debug_sg_netbsD */ #ifdef Libburn_debug_sg_netbsD fprintf(stderr, "libburn_DEBUG: ret= %d, retsts = 0x%X, senselen_used = %d, status = 0x%X, error= 0x%X\n", ret, (unsigned int) req.retsts, (int) req.senselen_used, (unsigned int) req.status, req.error); fprintf(stderr, "libburn_DEBUG: datalen_used = %u\n", (unsigned int) req.datalen_used); #endif if (ret != 0 || (req.retsts != SCCMD_SENSE && req.retsts != SCCMD_OK)) { sprintf(msg, "Failed to transfer command to drive. (ioctl(%d, SCIOCCOMMAND) = %d, scsireq_t.retsts = 0x%X, errno= %d)", d->fd, ret, (unsigned int) req.retsts, errno); if (burn_sg_log_scsi & 3) scsi_log_message(d, fp, msg, 0); libdax_msgs_submit(libdax_messenger, d->global_index, 0x0002010c, LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH, msg, errno, 0); sg_close_drive(d); d->released = 1; d->busy = BURN_DRIVE_IDLE; c->error = 1; return -1; } sense_len = 0; if (req.retsts == SCCMD_SENSE) { memcpy(c->sense, req.sense, max_sl); sense_len = req.senselen > max_sl ? max_sl : req.senselen; } spc_decode_sense(c->sense, sense_len, &key, &asc, &ascq); if (key || asc || ascq) sense_len = req.senselen; else sense_len = 0; /* <<< Fault mock-up if (c->opcode[0] == 0x5a) { req.datalen_used = 0; memset(c->page->data, 0, BUFFER_SIZE); } */ if (c->dir == FROM_DRIVE && sense_len == 0 && req.datalen > 0 && req.datalen_used < req.datalen) { sprintf(msg, "Short reply from SCSI command %2.2X: expected: %d, got: %d, req.retsts: 0x%X", (unsigned int) c->opcode[0], (int) req.datalen, (int) req.datalen_used, (unsigned int) req.retsts); if (burn_sg_log_scsi & 3) scsi_log_message(d, fp, msg, 0); libdax_msgs_submit(libdax_messenger, d->global_index, 0x00000002, LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH, msg, 0, 0); if (req.datalen_used == 0) c->error = 1; c->dxfer_len = req.datalen_used; } done = scsi_eval_cmd_outcome(d, c, fp, c->sense, sense_len, start_time, timeout_ms, i, 0); if (d->cancel) done = 1; } /* end of retry-loop */ return 1; } /** Tries to obtain SCSI address parameters. @return 1 is success , 0 is failure */ int sg_obtain_scsi_adr(char *path, int *bus_no, int *host_no, int *channel_no, int *target_no, int *lun_no) { int ret, fd = -1; struct scsi_addr addr; fd = open(path, O_RDWR | O_NDELAY); if (fd == -1) return 0; *bus_no = *host_no = *channel_no = *target_no = *lun_no = 0; memset(&addr, 0, sizeof(addr)); ret = ioctl(fd, SCIOCIDENTIFY, &addr); if (ret != 0) {ret = 0; goto ex;} if (addr.type != TYPE_SCSI) {ret = 0; goto ex;} *bus_no = *host_no = addr.addr.scsi.scbus; *channel_no = 0; *target_no = addr.addr.scsi.target; *lun_no = addr.addr.scsi.lun; ret = 1; ex:; if (fd != -1) close(fd); return (0); } /** Tells wether a text is a persistent address as listed by the enumeration functions. */ int sg_is_enumerable_adr(char* adr) { burn_drive_enumerator_t idx; int initialize = 1, ret; char buf[64]; while(1) { ret = sg_give_next_adr(&idx, buf, sizeof(buf), initialize); initialize = 0; if (ret <= 0) break; if (strcmp(adr, buf) == 0) { sg_give_next_adr(&idx, buf, sizeof(buf), -1); return 1; } } sg_give_next_adr(&idx, buf, sizeof(buf), -1); return (0); } /* Return 1 if the given path leads to a regular file or a device that can be seeked, read, and possibly written with 2 kB granularity. */ int burn_os_is_2k_seekrw(char *path, int flag) { struct stat stbuf; int l, i, dev, tl; char try[16]; /* >>> ??? Is this a comprehensive list of lseek()-capable devices ? */ /* http://www.netbsd.org/docs/guide/en/chap-rmmedia.html */ static char dev_names[][4] = { "fd", "rfd", "sd" , "cd", "rcd", "wd", ""}; if (path[0] == 0) return 0; if (stat(path, &stbuf) == -1) return 0; if (S_ISREG(stbuf.st_mode)) return 1; if (S_ISBLK(stbuf.st_mode)) return 1; /* Look for known device names which promise the desired capabilities */ if (strncmp(path, "/dev/", 5) != 0) return 0; l = strlen(path); for (dev = 0; dev_names[dev][0] != 0; dev++) { sprintf(try, "/dev/%s", dev_names[dev]); tl = strlen(try); if (strncmp(path, try, tl) != 0) continue; l -= tl; for (i = 0; i < Libburn_netbsd_max_cdnuM; i++) { sprintf(try + tl, "%d", i); if (strncmp(path, try, strlen(try)) == 0) break; } if (i >= Libburn_netbsd_max_cdnuM) continue; tl += strlen(try + tl); if (l == tl) return 1; if (l > tl + 1) continue; if (path[l - 1] >= 'a' && path[l - 1] <= 'z') return 1; } return 0; } /** Estimate the potential payload capacity of a file address. @param path The address of the file to be examined. If it does not exist yet, then the directory will be inquired. @param bytes The pointed value gets modified, but only if an estimation is possible. @return -2 = cannot perform necessary operations on file object -1 = neither path nor dirname of path exist 0 = could not estimate size capacity of file object 1 = estimation has been made, bytes was set */ int burn_os_stdio_capacity(char *path, off_t write_start, off_t *bytes) { struct stat stbuf; int ret; #ifdef Libburn_os_has_statvfS struct statvfs vfsbuf; #endif char *testpath = NULL, *cpt; off_t add_size = 0; BURN_ALLOC_MEM(testpath, char, 4096); testpath[0] = 0; if (stat(path, &stbuf) == -1) { strcpy(testpath, path); cpt = strrchr(testpath, '/'); if(cpt == NULL) strcpy(testpath, "."); else if(cpt == testpath) testpath[1] = 0; else *cpt = 0; if (stat(testpath, &stbuf) == -1) {ret = -1; goto ex;} } else if(S_ISBLK(stbuf.st_mode)) { int open_mode = O_RDONLY, fd; fd = open(path, open_mode); if (fd == -1) {ret = -2; goto ex;} *bytes = lseek(fd, 0, SEEK_END); if (*bytes <= 0) guess_size_by_seek_set(fd, bytes, 0); close(fd); if (*bytes == -1) { *bytes = 0; {ret = 0; goto ex;} } } else if(S_ISREG(stbuf.st_mode)) { add_size = burn_sparse_file_addsize(write_start, &stbuf); strcpy(testpath, path); } else {ret = 0; goto ex;} if (testpath[0]) { #ifdef Libburn_os_has_statvfS if (statvfs(testpath, &vfsbuf) == -1) {ret = -2; goto ex;} *bytes = add_size + ((off_t) vfsbuf.f_frsize) * (off_t) vfsbuf.f_bavail; #else /* Libburn_os_has_statvfS */ {ret = 0; goto ex;} #endif /* ! Libburn_os_has_stavtfS */ } ret = 1; ex:; BURN_FREE_MEM(testpath); return ret; } /* ts A91122 : an interface to open(O_DIRECT) or similar OS tricks. */ #ifdef Libburn_read_o_direcT /* No special O_DIRECT-like precautions are implemented here */ #endif /* Libburn_read_o_direcT */ int burn_os_open_track_src(char *path, int open_flags, int flag) { int fd; fd = open(path, open_flags); return fd; } void *burn_os_alloc_buffer(size_t amount, int flag) { void *buf = NULL; buf = calloc(1, amount); return buf; } int burn_os_free_buffer(void *buffer, size_t amount, int flag) { if (buffer == NULL) return 0; free(buffer); return 1; } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������libburn-1.4.2/libburn/read.h������������������������������������������������������������������������0000644�0001757�0001751�00000000577�12652644224�012645� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */ #ifndef __LIBBURN_READ #define __LIBBURN_READ struct burn_drive; struct burn_read_opts; int burn_sector_length_read(struct burn_drive *d, const struct burn_read_opts *o); void burn_packet_process(struct burn_drive *d, unsigned char *data, const struct burn_read_opts *o); #endif /* __LIBBURN_READ */ ���������������������������������������������������������������������������������������������������������������������������������libburn-1.4.2/libburn/sg-linux.c��������������������������������������������������������������������0000644�0001757�0001751�00000211112�12652644224�013460� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */ /* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens Copyright (c) 2006 - 2014 Thomas Schmitt <scdbackup@gmx.net> Provided under GPL version 2 or later. */ /* <<< ts A91112 : experiments to get better speed with USB #define Libburn_sgio_as_growisofS 1 */ /* This is the main operating system dependent SCSI part of libburn. It implements the transport level aspects of SCSI control and command i/o. Present implementation: GNU/Linux SCSI Generic (sg) PORTING: Porting libburn typically will consist of adding a new operating system case to the following switcher files: os.h Operating system specific libburn definitions and declarations. sg.c Operating system dependent transport level modules. and of deriving the following system specific files from existing examples: os-*.h Included by os.h. You will need some general system knowledge about signals and knowledge about the storage object needs of your transport level module sg-*.c. sg-*.c This source module. You will need special system knowledge about how to detect all potentially available drives, how to open them, eventually how to exclusively reserve them, how to perform SCSI transactions, how to inquire the (pseudo-)SCSI driver. You will not need to care about CD burning, MMC or other high-level SCSI aspects. Said sg-*.c operations are defined by a public function interface, which has to be implemented in a way that provides libburn with the desired services: sg_id_string() returns an id string of the SCSI transport adapter. It may be called before initialization but then may return only a preliminary id. sg_initialize() performs global initialization of the SCSI transport adapter and eventually needed operating system facilities. Checks for compatibility of supporting software components. sg_shutdown() performs global finalizations and releases golbally aquired resources. sg_give_next_adr() iterates over the set of potentially useful drive address strings. scsi_enumerate_drives() brings all available, not-whitelist-banned, and accessible drives into libburn's list of drives. sg_dispose_drive() finalizes adapter specifics of struct burn_drive on destruction. Releases resources which were aquired underneath scsi_enumerate_drives(). sg_drive_is_open() tells wether libburn has the given drive in use. sg_grab() opens the drive for SCSI commands and ensures undisturbed access. sg_release() closes a drive opened by sg_grab() sg_issue_command() sends a SCSI command to the drive, receives reply, and evaluates wether the command succeeded or shall be retried or finally failed. sg_obtain_scsi_adr() tries to obtain SCSI address parameters. burn_os_is_2k_seekrw() tells whether the given path leads to a file object that can be used in 2 kB granularity by lseek(2) and read(2), and possibly write(2) if not read-only. E.g. a USB stick or a hard disk. burn_os_stdio_capacity() estimates the emulated media space of stdio-drives. burn_os_open_track_src() opens a disk file in a way that offers best throughput with file reading and/or SCSI write command transmission. burn_os_alloc_buffer() allocates a memory area that is suitable for file descriptors issued by burn_os_open_track_src(). The buffer size may be rounded up for alignment reasons. burn_os_free_buffer() delete a buffer obtained by burn_os_alloc_buffer(). Porting hints are marked by the text "PORTING:". Send feedback to libburn-hackers@pykix.org . Hint: You should also look into sg-freebsd-port.c, which is a younger and in some aspects more straightforward implementation of this interface. */ #ifdef HAVE_CONFIG_H #include "../config.h" #endif /** PORTING : ------- OS dependent headers and definitions ------ */ #ifdef Libburn_read_o_direcT # ifndef _GNU_SOURCE # define _GNU_SOURCE # endif #endif /* Libburn_read_o_direcT */ #include <errno.h> #include <unistd.h> #include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <sys/ioctl.h> #include <string.h> #include <sys/poll.h> #include <linux/hdreg.h> #include <stdlib.h> #include <sys/utsname.h> #include <scsi/scsi.h> #include <sys/statvfs.h> /* for ioctl(BLKGETSIZE) */ #include <linux/fs.h> /* for mmap() */ #include <sys/mman.h> #include <scsi/sg.h> /* Values within sg_io_hdr_t indicating success after ioctl(SG_IO) : */ /* .host_status : from http://tldp.org/HOWTO/SCSI-Generic-HOWTO/x291.html */ #define Libburn_sg_host_oK 0 /* .driver_status : from http://tldp.org/HOWTO/SCSI-Generic-HOWTO/x322.html */ #define Libburn_sg_driver_oK 0 /* ts A61211 : to eventually recognize CD devices on /dev/sr* */ #include <limits.h> #include <linux/cdrom.h> /** Indication of the Linux kernel this software is running on */ /* -1 = not evaluated , 0 = unrecognizable , 1 = 2.4 , 2 = 2.6 */ static int sg_kernel_age = -1; /** PORTING : Device file families for bus scanning and drive access. Both device families must support the following ioctls: SG_IO, SG_GET_SCSI_ID SCSI_IOCTL_GET_BUS_NUMBER SCSI_IOCTL_GET_IDLUN as well as mutual exclusively locking with open(O_EXCL). If a device family is left empty, then it will not be used. To avoid misunderstandings: both families are used via identical transport methods as soon as a device file is accepted as CD drive by the family specific function <family>_enumerate(). One difference remains throughout usage: Host,Channel,Id,Lun and Bus address parameters of ATA devices are considered invalid. */ /* Set this to 1 in order to get on stderr messages from sg_enumerate() */ static int linux_sg_enumerate_debug = 0; /* The device file family to use for (emulated) generic SCSI transport. This must be a printf formatter with one single placeholder for int in the range of 0 to 31 . The resulting addresses must provide SCSI address parameters Host, Channel, Id, Lun and also Bus. E.g.: "/dev/sg%d" 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, 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 settings made via burn_preset_device_open(). */ static char linux_sg_device_family[80] = {"/dev/sg%d"}; /* Set this to 1 if you want the default linux_sg_device_family chosen depending on kernel release: sg for <2.6 , sr for >=2.6 */ static int linux_sg_auto_family = 1; /* Set this to 1 in order to accept any TYPE_* (see scsi/scsi.h) */ /* But try with 0 first. There is hope via CDROM_DRIVE_STATUS. */ /* !!! DO NOT SET TO 1 UNLESS YOU PROTECTED ALL INDISPENSIBLE DEVICES chmod -rw !!! */ static int linux_sg_accept_any_type = 0; /* The device file family to use for SCSI transport over ATA. This must be a printf formatter with one single placeholder for a _single_ char in the range of 'a' to 'z'. This placeholder _must_ be at the end of the formatter string. E.g. "/dev/hd%c" */ static char linux_ata_device_family[80] = {"/dev/hd%c"}; /* Set this to 1 in order to get on stderr messages from ata_enumerate() */ static int linux_ata_enumerate_verbous = 0; /** PORTING : ------ libburn portable headers and definitions ----- */ #include "libburn.h" #include "transport.h" #include "drive.h" #include "sg.h" #include "spc.h" #include "mmc.h" #include "sbc.h" #include "debug.h" #include "toc.h" #include "util.h" #include "init.h" #include "libdax_msgs.h" extern struct libdax_msgs *libdax_messenger; /* ts A51221 */ int burn_drive_is_banned(char *device_address); /* ------------------------------------------------------------------------ */ /* PORTING: Private definitions. Port only if needed by public functions. */ /* (Public functions are listed below) */ /* ------------------------------------------------------------------------ */ static void enumerate_common(char *fname, int fd_in, int bus_no, int host_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 whether to use O_EXCL with open(2) of devices whether to use fcntl(,F_SETLK,) after open(2) of devices what device family to use : 0=default, 1=sr, 2=scd, (3=st), 4=sg whether to use O_NOBLOCK with open(2) on devices whether to take O_EXCL rejection as fatal error */ extern int burn_sg_open_o_excl; extern int burn_sg_fcntl_f_setlk; extern int burn_sg_use_family; extern int burn_sg_open_o_nonblock; extern int burn_sg_open_abort_busy; /* ts A91111 : whether to log SCSI commands: bit0= log in /tmp/libburn_sg_command_log bit1= log to stderr bit2= flush every line */ extern int burn_sg_log_scsi; /* ts A60821 debug: for tracing calls which might use open drive fds or for catching SCSI usage of emulated drives. */ int mmc_function_spy(struct burn_drive *d, char * text); /* ------------------------------------------------------------------------ */ /* PORTING: Private functions. Port only if needed by public functions */ /* (Public functions are listed below) */ /* ------------------------------------------------------------------------ */ /* ts A70413 */ /* This finds out wether the software is running on kernel >= 2.6 */ static void sg_evaluate_kernel(void) { struct utsname buf; if (sg_kernel_age >= 0) return; sg_kernel_age = 0; if (uname(&buf) == -1) return; sg_kernel_age = 1; if (strcmp(buf.release, "2.6") >= 0) sg_kernel_age = 2; } /* ts A70314 */ /* This installs the device file family if one was chosen explicitely by burn_preset_device_open() */ static void sg_select_device_family(void) { /* >>> ??? do we need a mutex here ? */ /* >>> (It might be concurrent but is supposed to have always the same effect. Any race condition should be harmless.) */ if (burn_sg_use_family == 1) strcpy(linux_sg_device_family, "/dev/sr%d"); else if (burn_sg_use_family == 2) strcpy(linux_sg_device_family, "/dev/scd%d"); else if (burn_sg_use_family == 3) strcpy(linux_sg_device_family, "/dev/st%d"); else if (burn_sg_use_family == 4) strcpy(linux_sg_device_family, "/dev/sg%d"); else if (linux_sg_auto_family) { sg_evaluate_kernel(); if (sg_kernel_age >= 2) strcpy(linux_sg_device_family, "/dev/sr%d"); else strcpy(linux_sg_device_family, "/dev/sg%d"); linux_sg_auto_family = 0; } } /* ts A80701 */ /* This cares for the case that no /dev/srNN but only /dev/scdNN exists. A theoretical case which has its complement in SuSE 10.2 having /dev/sr but not /dev/scd. */ static int sg_exchange_scd_for_sr(char *fname, int flag) { struct stat stbuf; char scd[17], *msg = NULL; if (burn_sg_use_family != 0 || strncmp(fname, "/dev/sr", 7)!=0 || strlen(fname)>9 || strlen(fname)<8) return 2; if (fname[7] < '0' || fname[7] > '9') return 2; if (fname [8] != 0 && (fname[7] < '0' || fname[7] > '9')) return 2; if (stat(fname, &stbuf) != -1) return 2; strcpy(scd, "/dev/scd"); strcpy(scd + 8, fname + 7); if (stat(scd, &stbuf) == -1) return 2; msg = calloc(strlen(scd) + strlen(fname) + 80, 1); if (msg != NULL) { sprintf(msg, "%s substitutes for non-existent %s", scd, fname); libdax_msgs_submit(libdax_messenger, -1, 0x00000002, LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH, msg, 0, 0); free(msg); } strcpy(fname, scd); return 1; } /* 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 = 0; /* >>> ts B11110 : move this into scsi_log_command() */ if (fp == NULL && (burn_sg_log_scsi & 1)) { fp= fopen("/tmp/libburn_sg_command_log", "a"); if (fp != NULL) fprintf(fp, "\n=========================================\n"); } if (fp != NULL) 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, double duration, int flag) { int ret; ret = scsi_log_reply(opcode, data_dir, data, dxfer_len, fp_in, sense, sense_len, duration, flag); return ret; } static int sgio_test(int fd) { unsigned char test_ops[] = { 0, 0, 0, 0, 0, 0 }; sg_io_hdr_t s; int ret; double c_start_time, c_end_time; memset(&s, 0, sizeof(sg_io_hdr_t)); s.interface_id = 'S'; s.dxfer_direction = SG_DXFER_NONE; s.cmd_len = 6; s.cmdp = test_ops; s.timeout = 12345; sgio_log_cmd(s.cmdp, s.cmd_len, NULL, 0); c_start_time = burn_get_time(0); ret= ioctl(fd, SG_IO, &s); c_end_time = burn_get_time(0); sgio_log_reply(s.cmdp, NO_TRANSFER, NULL, 0, NULL, (unsigned char *) (s.sbp), s.sb_len_wr, c_end_time - c_start_time, 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; double c_start_time, c_end_time; 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); c_start_time = burn_get_time(0); ret = ioctl(fd, SG_IO, &s); c_end_time = burn_get_time(0); 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, (unsigned char *) (s.sbp), s.sb_len_wr, c_end_time - c_start_time, 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", ((unsigned char *) (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; } /* ts A60924 */ static int sg_handle_busy_device(char *fname, int os_errno) { char *msg = NULL; struct stat stbuf; int looks_like_hd= 0, fd, ret; BURN_ALLOC_MEM(msg, char, 4096); /* ts A80713 : check existence of /dev/hdX1 as hint for hard disk rather than CD Hint by Giulio Orsero: check /proc/ide/hdX/media for "disk" */ if (strncmp(fname, "/dev/hd", 7)==0) { sprintf(msg, "%s1", fname); if (stat(msg, &stbuf) != -1) looks_like_hd= 1; sprintf(msg, "/proc/ide/hd%c/media", fname[7]); fd = open(msg, O_RDONLY); if (fd != -1) { ret = read(fd, msg, 10); if (ret < 0) ret = 0; msg[ret]= 0; close(fd); if (strncmp(msg, "disk\n", 5) == 0 || strcmp(msg, "disk") == 0) looks_like_hd= 2; else if (strncmp(msg, "cdrom\n", 6) == 0 || strcmp(msg, "cdrom") == 0) looks_like_hd= 0; } } /* ts A60814 : i saw no way to do this more nicely */ if (burn_sg_open_abort_busy) { fprintf(stderr, "\nlibburn: FATAL : Application triggered abort on busy device '%s'\n", fname); /* ts A61007 */ abort(); /* a ssert("drive busy" == "non fatal"); */ } /* ts A60924 : now reporting to libdax_msgs */ if (looks_like_hd == 2) { /* is surely hard disk */ ; } else if (looks_like_hd) { sprintf(msg, "Could not examine busy device '%s'", fname); libdax_msgs_submit(libdax_messenger, -1, 0x0002015a, LIBDAX_MSGS_SEV_NOTE, LIBDAX_MSGS_PRIO_LOW, msg, os_errno, 0); sprintf(msg, "Busy '%s' seems to be a hard disk, as '%s1' exists. But better check.", fname, fname); libdax_msgs_submit(libdax_messenger, -1, 0x0002015b, LIBDAX_MSGS_SEV_HINT, LIBDAX_MSGS_PRIO_LOW, msg, 0, 0); } else { sprintf(msg, "Cannot open busy device '%s'", fname); libdax_msgs_submit(libdax_messenger, -1, 0x00020001, LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_LOW, msg, os_errno, 0); } ret = 1; ex:; BURN_FREE_MEM(msg); return ret; } /* ts A60925 : ticket 74 */ static int sg_close_drive_fd(char *fname, int driveno, int *fd, int sorry) { int ret, os_errno, sevno= LIBDAX_MSGS_SEV_DEBUG; char *msg = NULL; if(*fd < 0) {ret = 0; goto ex;} BURN_ALLOC_MEM(msg, char, 4096 + 100); #ifdef CDROM_MEDIA_CHANGED_disabled_because_not_helpful #ifdef CDSL_CURRENT /* ts A80217 : wondering whether the os knows about our activities */ ret = ioctl(*fd, CDROM_MEDIA_CHANGED, CDSL_CURRENT); sprintf(msg, "ioctl(CDROM_MEDIA_CHANGED) == %d", ret); libdax_msgs_submit(libdax_messenger, driveno, 0x00000002, LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH, msg, 0, 0); #ifdef BLKFLSBUF_disabled_because_not_helpful ret = ioctl(*fd, BLKFLSBUF, 0); sprintf(msg, "ioctl(BLKFLSBUF) == %d", ret); os_errno = 0; if(ret == -1) os_errno = errno; libdax_msgs_submit(libdax_messenger, driveno, 0x00000002, LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH, msg, os_errno,0); #endif /* BLKFLSBUF */ #endif /* CDSL_CURRENT */ #endif /* CDROM_MEDIA_CHANGED */ ret = close(*fd); *fd = -1337; if(ret != -1) { /* ts A70409 : DDLP-B */ /* >>> release single lock on fname */ {ret = 1; goto ex;} } os_errno= errno; sprintf(msg, "Encountered error when closing drive '%s'", fname); if (sorry) sevno = LIBDAX_MSGS_SEV_SORRY; libdax_msgs_submit(libdax_messenger, driveno, 0x00020002, sevno, LIBDAX_MSGS_PRIO_HIGH, msg, os_errno, 0); ret = 0; ex:; BURN_FREE_MEM(msg); return ret; } /* ts A70401 : fcntl() has the unappealing property to work only after open(). So libburn will by default use open(O_EXCL) first and afterwards as second assertion will use fcntl(F_SETLK). One lock more should not harm. */ static int sg_fcntl_lock(int *fd, char *fd_name, int l_type, int verbous) { struct flock lockthing; char msg[81]; int ret; if (!burn_sg_fcntl_f_setlk) return 1; memset(&lockthing, 0, sizeof(lockthing)); lockthing.l_type = l_type; lockthing.l_whence = SEEK_SET; lockthing.l_start = 0; lockthing.l_len = 0; /* fprintf(stderr,"LIBBURN_EXPERIMENTAL: fcntl(%d, F_SETLK, %s)\n", *fd, l_type == F_WRLCK ? "F_WRLCK" : "F_RDLCK"); */ ret = fcntl(*fd, F_SETLK, &lockthing); if (ret == -1) { if (verbous) { sprintf(msg, "Device busy. Failed to fcntl-lock '%s'", fd_name); libdax_msgs_submit(libdax_messenger, -1, 0x00020008, LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH, msg, errno, 0); } close(*fd); *fd = -1; /* ts A70409 : DDLP-B */ /* >>> release single lock on fd_name */ return(0); } return 1; } /* ts A60926 */ /* @param scan_mode 0= open for drivce aquiration 1= open for scanning with guessed names 2= open for scanning with /proc/sys/dev/cdrom/info names */ static int sg_open_drive_fd(char *fname, int scan_mode) { int open_mode = O_RDWR, fd, tries= 0, is_std_adr, report_as_note = 0; char msg[81]; struct stat stbuf; /* ts A70409 : DDLP-B */ /* >>> obtain single lock on fname */ /* ts A60813 - A60927 O_EXCL with devices is a non-POSIX feature of Linux kernels. Possibly introduced 2002. Mentioned in "The Linux SCSI Generic (sg) HOWTO" */ if(burn_sg_open_o_excl) open_mode |= O_EXCL; /* ts A60813 O_NONBLOCK was already hardcoded in ata_ but not in sg_. There must be some reason for this. So O_NONBLOCK is default mode for both now. Disable on own risk. ts B10904: O_NONBLOCK is prescribed by <linux/cdrom.h> ts A70411 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 with O_NDELAY if you want to avoid them." */ if(burn_sg_open_o_nonblock) open_mode |= O_NDELAY; /* <<< debugging fprintf(stderr, "\nlibburn: experimental: o_excl= %d , o_nonblock= %d, abort_on_busy= %d\n", burn_sg_open_o_excl,burn_sg_open_o_nonblock,burn_sg_open_abort_busy); fprintf(stderr, "libburn: experimental: O_EXCL= %d , O_NDELAY= %d\n", !!(open_mode&O_EXCL),!!(open_mode&O_NDELAY)); */ try_open:; fd = open(fname, open_mode); if (fd == -1) { /* <<< debugging fprintf(stderr, "\nlibburn: experimental: fname= %s , errno= %d\n", fname,errno); */ if (errno == EBUSY) { tries++; /* <<< debugging fprintf(stderr, "\nlibburn_DEBUG: EBUSY , tries= %d\n", tries); */ if (tries < 4) { usleep(2000000); goto try_open; } sg_handle_busy_device(fname, errno); return -1; } sprintf(msg, "Failed to open device '%s'",fname); if (scan_mode) { is_std_adr = (strncmp(fname, "/dev/sr", 7) == 0 || strncmp(fname, "/dev/scd", 8) == 0); if(scan_mode == 1 && is_std_adr && stat(fname, &stbuf) != -1) report_as_note = 1; else if(scan_mode == 2 && (!is_std_adr) && stat(fname, &stbuf) != -1) report_as_note = 1; if (report_as_note) libdax_msgs_submit(libdax_messenger, -1, 0x0002000e, LIBDAX_MSGS_SEV_NOTE, LIBDAX_MSGS_PRIO_HIGH, msg, errno, 0); } else { libdax_msgs_submit(libdax_messenger, -1, 0x00020005, LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH, msg, errno, 0); } return -1; } sg_fcntl_lock(&fd, fname, F_WRLCK, 1); return fd; } /* ts A60926 */ static int sg_release_siblings(int sibling_fds[], char sibling_fnames[][BURN_OS_SG_MAX_NAMELEN], int *sibling_count) { int i; char msg[81]; for(i= 0; i < *sibling_count; i++) sg_close_drive_fd(sibling_fnames[i], -1, &(sibling_fds[i]), 0); if(*sibling_count > 0) { sprintf(msg, "Closed %d O_EXCL scsi siblings", *sibling_count); libdax_msgs_submit(libdax_messenger, -1, 0x00020007, LIBDAX_MSGS_SEV_NOTE, LIBDAX_MSGS_PRIO_HIGH, msg, 0,0); } *sibling_count = 0; return 1; } /* ts A60926 */ static int sg_close_drive(struct burn_drive *d) { int ret; if (!burn_drive_is_open(d)) return 0; sg_release_siblings(d->sibling_fds, d->sibling_fnames, &(d->sibling_count)); ret = sg_close_drive_fd(d->devname, d->global_index, &(d->fd), 0); return ret; } /* ts A60926 */ static int sg_open_scsi_siblings(char *path, int driveno, int sibling_fds[], char sibling_fnames[][BURN_OS_SG_MAX_NAMELEN], int *sibling_count, int host_no, int channel_no, int id_no, int lun_no) { int tld, i, ret, fd, i_bus_no = -1; int i_host_no = -1, i_channel_no = -1, i_target_no = -1, i_lun_no = -1; char *msg = NULL, fname[40]; struct stat stbuf; dev_t last_rdev = 0, path_rdev; static char tldev[][20]= {"/dev/sr%d", "/dev/scd%d", "/dev/sg%d", ""}; /* ts A70609: removed "/dev/st%d" */ if (strlen(path) > BURN_MSGS_MESSAGE_LEN - 160) {ret = 0; goto ex;} BURN_ALLOC_MEM(msg, char, BURN_MSGS_MESSAGE_LEN); if(stat(path, &stbuf) == -1) {ret = 0; goto ex;} path_rdev = stbuf.st_rdev; sg_select_device_family(); if (linux_sg_device_family[0] == 0) {ret = 1; goto ex;} if(host_no < 0 || id_no < 0 || channel_no < 0 || lun_no < 0) {ret = 2; goto ex;} if(*sibling_count > 0) sg_release_siblings(sibling_fds, sibling_fnames, sibling_count); for (tld = 0; tldev[tld][0] != 0; tld++) { if (strcmp(tldev[tld], linux_sg_device_family)==0) continue; for (i = 0; i < 32; i++) { sprintf(fname, tldev[tld], i); if(stat(fname, &stbuf) == -1) continue; if (path_rdev == stbuf.st_rdev) continue; if (*sibling_count > 0 && last_rdev == stbuf.st_rdev) continue; ret = sg_obtain_scsi_adr(fname, &i_bus_no, &i_host_no, &i_channel_no, &i_target_no, &i_lun_no); if (ret <= 0) continue; if (i_host_no != host_no || i_channel_no != channel_no) continue; if (i_target_no != id_no || i_lun_no != lun_no) continue; fd = sg_open_drive_fd(fname, 0); if (fd < 0) goto failed; if (*sibling_count>=BURN_OS_SG_MAX_SIBLINGS) { sprintf(msg, "Too many scsi siblings of '%s'", path); libdax_msgs_submit(libdax_messenger, driveno, 0x00020006, LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH, msg, 0, 0); goto failed; } sprintf(msg, "Opened O_EXCL scsi sibling '%s' of '%s'", fname, path); libdax_msgs_submit(libdax_messenger, driveno, 0x00020004, LIBDAX_MSGS_SEV_NOTE, LIBDAX_MSGS_PRIO_HIGH, msg, 0, 0); sibling_fds[*sibling_count] = fd; strcpy(sibling_fnames[*sibling_count], fname); (*sibling_count)++; last_rdev= stbuf.st_rdev; } } ret = 1; ex:; BURN_FREE_MEM(msg); return ret; failed:; sg_release_siblings(sibling_fds, sibling_fnames, sibling_count); ret = 0; goto ex; } /* ts A80731 */ static int is_ata_drive(char *fname, int fd_in) { int fd; struct hd_driveid tm; if (fd_in >= 0) fd = fd_in; else fd = sg_open_drive_fd(fname, 1); if (fd == -1) { if (linux_ata_enumerate_verbous) fprintf(stderr,"open failed, errno=%d '%s'\n", errno, strerror(errno)); return 0; } memset(&tm, 0, sizeof(tm)); ioctl(fd, HDIO_GET_IDENTITY, &tm); /* not atapi */ if (!(tm.config & 0x8000) || (tm.config & 0x4000)) { if (linux_ata_enumerate_verbous) fprintf(stderr, "not marked as ATAPI\n"); if (fd_in < 0) sg_close_drive_fd(fname, -1, &fd, 0); return 0; } /* if SG_IO fails on an atapi device, we should stop trying to use hd* devices */ if (sgio_test(fd) == -1) { if (linux_ata_enumerate_verbous) fprintf(stderr, "FATAL: sgio_test() failed: errno=%d '%s'\n", errno, strerror(errno)); if (fd_in < 0) sg_close_drive_fd(fname, -1, &fd, 0); return 0; } if (fd_in >= 0) return 1; if (sg_close_drive_fd(fname, -1, &fd, 1) <= 0) { if (linux_ata_enumerate_verbous) fprintf(stderr, "cannot close properly, errno=%d '%s'\n", errno, strerror(errno)); return 0; } return 1; } static int is_scsi_drive(char *fname, int fd_in, int *bus_no, int *host_no, int *channel_no, int *target_no, int *lun_no) { int fd = -1, sid_ret = 0, ret, fail_sev_sorry = 0; struct sg_scsi_id sid; int *sibling_fds = NULL, sibling_count= 0; typedef char burn_sg_sibling_fname[BURN_OS_SG_MAX_NAMELEN]; burn_sg_sibling_fname *sibling_fnames = NULL; BURN_ALLOC_MEM(sibling_fds, int, BURN_OS_SG_MAX_SIBLINGS); BURN_ALLOC_MEM(sibling_fnames, burn_sg_sibling_fname, BURN_OS_SG_MAX_SIBLINGS); if (fd_in >= 0) fd = fd_in; else fd = sg_open_drive_fd(fname, 1); if (fd == -1) { if (linux_sg_enumerate_debug) fprintf(stderr, "open failed, errno=%d '%s'\n", errno, strerror(errno)); {ret = 0; goto ex;} } sid_ret = ioctl(fd, SG_GET_SCSI_ID, &sid); if (sid_ret == -1) { sid.scsi_id = -1; /* mark SCSI address as invalid */ if(linux_sg_enumerate_debug) fprintf(stderr, "ioctl(SG_GET_SCSI_ID) failed, errno=%d '%s' , ", errno, strerror(errno)); if (sgio_test(fd) == -1) { if (linux_sg_enumerate_debug) fprintf(stderr, "FATAL: sgio_test() failed: errno=%d '%s'", errno, strerror(errno)); {ret = 0; goto ex;} } #ifdef CDROM_DRIVE_STATUS /* http://developer.osdl.org/dev/robustmutexes/ src/fusyn.hg/Documentation/ioctl/cdrom.txt */ sid_ret = ioctl(fd, CDROM_DRIVE_STATUS, 0); if(linux_sg_enumerate_debug) fprintf(stderr, "ioctl(CDROM_DRIVE_STATUS) = %d , ", sid_ret); if (sid_ret != -1 && sid_ret != CDS_NO_INFO) sid.scsi_type = TYPE_ROM; else sid_ret = -1; #endif /* CDROM_DRIVE_STATUS */ } 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 /* Hearsay A61005 */ if (ioctl(fd, SCSI_IOCTL_GET_BUS_NUMBER, bus_no) == -1) *bus_no = -1; #endif fail_sev_sorry = (sid.scsi_type == TYPE_ROM); if ( (sid_ret == -1 || sid.scsi_type != TYPE_ROM) && !linux_sg_accept_any_type) { if (linux_sg_enumerate_debug) fprintf(stderr, "sid.scsi_type = %d (!= TYPE_ROM)\n", sid.scsi_type); {ret = 0; goto ex;} } if (sid_ret == -1 || sid.scsi_id < 0) { /* ts A61211 : employ a more general ioctl */ /* ts B11001 : re-use fd */ ret = sg_obtain_scsi_adr_fd(fname, fd, bus_no, host_no, channel_no, target_no, lun_no); if (ret>0) { sid.host_no = *host_no; sid.channel = *channel_no; sid.scsi_id = *target_no; sid.lun = *lun_no; } else { if (linux_sg_enumerate_debug) fprintf(stderr, "sg_obtain_scsi_adr_fd() failed\n"); {ret = 0; goto ex;} } } /* ts A60927 : trying to do locking with growisofs */ if(burn_sg_open_o_excl>1) { ret = sg_open_scsi_siblings( fname, -1, sibling_fds, sibling_fnames, &sibling_count, sid.host_no, sid.channel, sid.scsi_id, sid.lun); if (ret<=0) { if (linux_sg_enumerate_debug) fprintf(stderr, "cannot lock siblings\n"); sg_handle_busy_device(fname, 0); {ret = 0; goto ex;} } /* the final occupation will be done in sg_grab() */ sg_release_siblings(sibling_fds, sibling_fnames, &sibling_count); } #ifdef SCSI_IOCTL_GET_BUS_NUMBER if(*bus_no == -1) *bus_no = 1000 * (sid.host_no + 1) + sid.channel; #else *bus_no = sid.host_no; #endif *host_no= sid.host_no; *channel_no= sid.channel; *target_no= sid.scsi_id; *lun_no= sid.lun; ret = 1; 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_fnames); return ret; } /* @param flag bit0= do not complain about failure to open /dev/sr /dev/scd */ static int sg_open_for_enumeration(char *fname, int flag) { int fd; fd = sg_open_drive_fd(fname, 1 + (flag & 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 then on used used via generic SCSI as is done with (emulated) SCSI drives */ static void ata_enumerate(void) { int ret, i, fd = -1; char fname[10]; if (linux_ata_enumerate_verbous) fprintf(stderr, "libburn_debug: linux_ata_device_family = %s\n", linux_ata_device_family); if (linux_ata_device_family[0] == 0) return; for (i = 0; i < 26; i++) { sprintf(fname, linux_ata_device_family, 'a' + i); if (linux_ata_enumerate_verbous) fprintf(stderr, "libburn_debug: %s : ", fname); /* ts A51221 */ if (burn_drive_is_banned(fname)) { if (linux_ata_enumerate_verbous) fprintf(stderr, "not in whitelist\n"); continue; } fd = sg_open_for_enumeration(fname, 0); if (fd < 0) continue; ret = is_ata_drive(fname, fd); if (ret < 0) break; if (ret == 0) continue; if (linux_ata_enumerate_verbous) fprintf(stderr, "accepting as drive without SCSI address\n"); enumerate_common(fname, fd, -1, -1, -1, -1, -1); } } /** Detects (probably emulated) SCSI drives */ static void sg_enumerate(void) { int i, ret, fd = -1; int bus_no= -1, host_no= -1, channel_no= -1, target_no= -1, lun_no= -1; char fname[17]; sg_select_device_family(); if (linux_sg_enumerate_debug) fprintf(stderr, "libburn_debug: linux_sg_device_family = %s\n", linux_sg_device_family); if (linux_sg_device_family[0] == 0) return; for (i = 0; i < 32; i++) { sprintf(fname, linux_sg_device_family, i); /* ts A80702 */ sg_exchange_scd_for_sr(fname, 0); if (linux_sg_enumerate_debug) fprintf(stderr, "libburn_debug: %s : ", fname); /* ts A51221 */ if (burn_drive_is_banned(fname)) { if (linux_sg_enumerate_debug) fprintf(stderr, "not in whitelist\n"); continue; } fd = sg_open_for_enumeration(fname, 0); if (fd < 0) continue; ret = is_scsi_drive(fname, fd, &bus_no, &host_no, &channel_no, &target_no, &lun_no); if (ret < 0) break; if (ret == 0) continue; if (linux_sg_enumerate_debug) fprintf(stderr, "accepting as SCSI %d,%d,%d,%d bus=%d\n", host_no, channel_no, target_no, lun_no, bus_no); enumerate_common(fname, fd, bus_no, host_no, channel_no, target_no, lun_no); } } /* ts A80805 : eventually produce the other official name of a device file */ static int fname_other_name(char *fname, char other_name[80], int flag) { if(strncmp(fname, "/dev/sr", 7) == 0 && (fname[7] >= '0' && fname[7] <= '9') && (fname[8] == 0 || (fname[8] >= '0' && fname[8] <= '9' && fname[9] == 0))) { sprintf(other_name, "/dev/scd%s", fname + 7); return 1; } if(strncmp(fname, "/dev/scd", 8) == 0 && (fname[8] >= '0' && fname[8] <= '9') && (fname[9] == 0 || (fname[9] >= '0' && fname[9] <= '9' && fname[10] == 0))) { sprintf(other_name, "/dev/sr%s", fname + 8); return 1; } return 0; } /* ts A80805 */ static int fname_drive_is_listed(char *fname, int flag) { char other_fname[80]; if (burn_drive_is_listed(fname, NULL, 0)) return 1; if (fname_other_name(fname, other_fname, 0) > 0) if (burn_drive_is_listed(other_fname, NULL, 0)) return 2; return 0; } /* ts A80731 : Directly open the given address. @param flag bit0= do not complain about missing file bit1= do not check whether drive is already listed bit2= do not complain about failure to open /dev/sr /dev/scd */ static int fname_enumerate(char *fname, int flag) { 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; char *msg = NULL; struct stat stbuf; BURN_ALLOC_MEM(msg, char, BURN_DRIVE_ADR_LEN + 80); if (!(flag & 2)) if (fname_drive_is_listed(fname, 0)) {ret = 2; goto ex;} if (stat(fname, &stbuf) == -1) { sprintf(msg, "File object '%s' not found", fname); if (!(flag & 1)) libdax_msgs_submit(libdax_messenger, -1, 0x0002000b, LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH, msg, 0, 0); {ret = -1; goto ex;} } fd = sg_open_for_enumeration(fname, !!(flag & 4)); if (fd < 0) {ret = 0; goto ex;} is_ata = is_ata_drive(fname, fd); if (is_ata < 0) {ret = -1; goto ex;} if (!is_ata) is_scsi = is_scsi_drive(fname, fd, &bus_no, &host_no, &channel_no, &target_no, &lun_no); if (is_scsi < 0) {ret = -1; goto ex;} if (is_ata == 0 && is_scsi == 0) {ret = 0; goto ex;} if (linux_sg_enumerate_debug) fprintf(stderr, "(single) accepting as SCSI %d,%d,%d,%d bus=%d\n", host_no, channel_no, target_no, lun_no, bus_no); enumerate_common(fname, fd, bus_no, host_no, channel_no, target_no, lun_no); ret = 1; ex:; BURN_FREE_MEM(msg); return ret; } /* ts A80731 : Directly open the given address from a single-item whitlist */ static int single_enumerate(int flag) { int ret, wl_count; char *fname, *msg = NULL; wl_count= burn_drive_whitelist_count(); if (wl_count != 1) {ret = 0; goto ex;} fname= burn_drive_whitelist_item(0, 0); if (fname == NULL) {ret = 0; goto ex;} ret = fname_enumerate(fname, 2); if (ret <= 0) { BURN_ALLOC_MEM(msg, char, BURN_DRIVE_ADR_LEN + 80); sprintf(msg, "Cannot access '%s' as SG_IO CDROM drive", fname); libdax_msgs_submit(libdax_messenger, -1, 0x0002000a, LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH, msg, 0, 0); ret = -1; } ex:; BURN_FREE_MEM(msg); return ret; } /* ts A80801 : looking up drives listed in /proc/sys/dev/cdrom/info line like: drive name: sr1 hdc hda sr0 @parm flag bit0= release list memory and exit */ static int proc_sys_dev_cdrom_info(char ***list, int *count, int flag) { FILE *fp; char *line = NULL, *fname = NULL, *cpt, *retpt, *list_data; int maxl= 0, pass, i, line_size = 1024, ret; BURN_ALLOC_MEM(line, char, line_size); BURN_ALLOC_MEM(fname, char, line_size + 5); if (*list != NULL) { if ((*list)[0] != NULL) free((*list)[0]); free(*list); *list = NULL; *count = 0; } if (flag & 1) {ret = 1; goto ex;} *count = 0; sg_evaluate_kernel(); if (sg_kernel_age < 2) /* addresses are not suitable for kernel 2.4 */ {ret = 1; goto ex;} fp = fopen("/proc/sys/dev/cdrom/info", "r"); if (fp == NULL) {ret = 0; goto ex;} while (1) { retpt = fgets(line, line_size, fp); if (retpt == NULL) break; if(strncmp(line, "drive name:", 11) == 0) break; } fclose(fp); if (retpt == NULL) {ret = 0; goto ex;} strcpy(fname, "/dev/"); for(pass = 0; pass < 2; pass++) { *count = 0; cpt = line + 11; while (*cpt != 0) { for(; *cpt == ' ' || *cpt == '\t'; cpt++); if (*cpt == 0 || *cpt == '\n') break; sscanf(cpt, "%s", fname + 5); if ((int) strlen(fname) > maxl) maxl = strlen(fname); if (pass == 1) strcpy((*list)[*count], fname); (*count)++; for(cpt++; *cpt != ' ' && *cpt != '\t' && *cpt != 0 && *cpt != '\n'; cpt++); } if (pass == 0) { list_data = calloc(*count + 1, maxl+1); *list = calloc(*count + 1, sizeof(char *)); if(list_data == NULL || *list == NULL) { libdax_msgs_submit(libdax_messenger, -1, 0x00000003, LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH, "Out of virtual memory", 0, 0); if (list_data != NULL) free(list_data); if (*list != NULL) free((char *) *list); {ret = -1; goto ex;} } for (i = 0; i <= *count; i++) (*list)[i] = list_data + i * (maxl + 1); } } ret = 1; ex:; BURN_FREE_MEM(line); BURN_FREE_MEM(fname); return ret; } static int add_proc_info_drives(int flag) { int ret, list_count, count = 0, i; char **list= NULL; if (burn_sg_use_family != 0) return(1); /* Looking only for sr , scd , sg */ ret = proc_sys_dev_cdrom_info(&list, &list_count, 0); if (ret <= 0) return ret; for (i = 0; i < list_count; i++) { if (burn_drive_is_banned(list[i])) continue; ret = fname_enumerate(list[i], 1 | 4); if (ret == 1) count++; } proc_sys_dev_cdrom_info(&list, &list_count, 1); /* free memory */ return 1 + count; } /* ts A61115 */ /* ----------------------------------------------------------------------- */ /* PORTING: Private functions which contain publicly needed functionality. */ /* Their portable part must be performed. So it is probably best */ /* to replace the non-portable part and to call these functions */ /* in your port, too. */ /* ----------------------------------------------------------------------- */ /** Wraps a detected drive into libburn structures and hands it over to libburn drive list. */ /* ts A60923 - A61005 : introduced new SCSI parameters */ /* ts A61021 : moved non os-specific code to spc,sbc,mmc,drive */ 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 ret, i; struct burn_drive out; /* General libburn drive setup */ burn_setup_drive(&out, fname); /* This transport adapter uses SCSI-family commands and models (seems the adapter would know better than its boss, if ever) */ ret = burn_scsi_setup_drive(&out, bus_no, host_no, channel_no, target_no, lun_no, 0); if (ret<=0) return; /* PORTING: ------------------- non portable part --------------- */ /* Operating system adapter is GNU/Linux Generic SCSI (sg) */ /* Adapter specific handles and data */ out.fd = -1337; out.sibling_count = 0; for(i= 0; i<BURN_OS_SG_MAX_SIBLINGS; i++) out.sibling_fds[i] = -1337; /* PORTING: ---------------- end of non portable part ------------ */ /* Adapter specific functions with standardized names */ out.grab = sg_grab; out.release = sg_release; out.drive_is_open= sg_drive_is_open; out.issue_command = sg_issue_command; if (fd_in >= 0) out.fd = fd_in; /* Finally register drive and inquire drive information. out is an invalid copy afterwards. Do not use it for anything. */ burn_drive_finish_enum(&out); } /* ts A61115 */ /* ------------------------------------------------------------------------ */ /* PORTING: Public functions. These MUST be ported. */ /* ------------------------------------------------------------------------ */ /** Returns the id string of the SCSI transport adapter and eventually needed operating system facilities. This call is usable even if sg_initialize() was not called yet. In that case a preliminary constant message might be issued if detailed info is not available yet. @param msg returns id string @param flag unused yet, submit 0 @return 1 = success, <=0 = failure */ int sg_id_string(char msg[1024], int flag) { strcpy(msg, "internal GNU/Linux SG_IO adapter sg-linux"); return 1; } /** Performs global initialization of the SCSI transport adapter and eventually needed operating system facilities. Checks for compatibility supporting software components. @param msg returns ids and/or error messages of eventual helpers @param flag unused yet, submit 0 @return 1 = success, <=0 = failure */ int sg_initialize(char msg[1024], int flag) { return sg_id_string(msg, 0); } /** Performs global finalization of the SCSI transport adapter and eventually needed operating system facilities. Releases globally aquired resources. @param flag unused yet, submit 0 @return 1 = success, <=0 = failure */ int sg_shutdown(int flag) { return 1; } /** Finalizes BURN_OS_TRANSPORT_DRIVE_ELEMENTS, the components of struct burn_drive which are defined in os-*.h. The eventual initialization of those components was made underneath scsi_enumerate_drives(). This will be called when a burn_drive gets disposed. @param d the drive to be finalized @param flag unused yet, submit 0 @return 1 = success, <=0 = failure */ int sg_dispose_drive(struct burn_drive *d, int flag) { return 1; } /** PORTING: In this GNU/Linux implementation, this function mirrors the enumeration done in sg_enumerate and ata_enumerate(). It would be better to base those functions on this sg_give_next_adr() but the situation is not inviting. */ /* ts A60922 ticket 33 : called from drive.c */ /** Returns the next index number and the next enumerated drive address. The enumeration has to cover all available and accessible drives. It is allowed to return addresses of drives which are not available but under some (even exotic) circumstances could be available. It is on the other hand allowed, only to hand out addresses which can really be used right in the moment of this call. (This implementation chooses the former.) @param idx An opaque handle. Make no own theories about it. @param adr Takes the reply @param adr_size Gives maximum size of reply including final 0 @param initialize 1 = start new, 0 = continue, use no other values for now -1 = finish @return 1 = reply is a valid address , 0 = no further address available -1 = severe error (e.g. adr_size too small) */ int sg_give_next_adr(burn_drive_enumerator_t *idx, char adr[], int adr_size, int initialize) { /* os-linux.h : typedef int burn_drive_enumerator_t; */ static int sg_limit = 32, ata_limit = 26; int baseno = 0, i; char other_name[80]; if (initialize == -1) { proc_sys_dev_cdrom_info(&(idx->info_list), &(idx->info_count), 1); return 0; } sg_select_device_family(); if (linux_sg_device_family[0] == 0) sg_limit = 0; if (linux_ata_device_family[0] == 0) ata_limit = 0; if (initialize == 1) { idx->pos = -1; idx->info_count= 0; idx->info_list= NULL; proc_sys_dev_cdrom_info(&(idx->info_list), &(idx->info_count), 0); } (idx->pos)++; if (idx->pos >= sg_limit) goto next_ata; if (adr_size < 11) return -1; sprintf(adr, linux_sg_device_family, idx->pos); sg_exchange_scd_for_sr(adr, 0); goto return_1_pre_proc; next_ata:; baseno += sg_limit; if (idx->pos - baseno >= ata_limit) goto next_proc_info; if (adr_size < 9) return -1; sprintf(adr, linux_ata_device_family, 'a' + (idx->pos - baseno)); goto return_1_pre_proc; next_proc_info:; baseno += ata_limit; for (i = 0; i < idx->info_count; i++) { if ((idx->info_list)[i][0] == 0) continue; if (baseno == idx->pos) { if (adr_size < (int) strlen((idx->info_list)[i]) + 1) return -1; strcpy(adr, (idx->info_list)[i]); return 1; } baseno++; } return 0; return_1_pre_proc:; for (i = 0; i < idx->info_count; i++) { if (strcmp((idx->info_list)[i], adr) == 0) (idx->info_list)[i][0] = 0; if (fname_other_name(adr, other_name, 0) > 0) if (strcmp((idx->info_list)[i], other_name) == 0) (idx->info_list)[i][0] = 0; } return 1; } /** Brings all available, not-whitelist-banned, and accessible drives into libburn's list of drives. */ /** PORTING: If not stricken with an incompletely unified situation like in GNU/Linux one would rather implement this by a loop calling sg_give_next_adr(). If needed with your sg_give_next_adr() results, do a test for existence and accessability. If burn activities are prone to external interference on your system it is also necessary to obtain exclusive access locks on the drives. Hand over each accepted drive to enumerate_common() or its replacement within your port. See FreeBSD port sketch sg-freebsd-port.c for such an implementation. */ /* ts A61115: replacing call to sg-implementation internals from drive.c */ int scsi_enumerate_drives(void) { int ret; /* Direct examination of eventually single whitelisted name */ ret = single_enumerate(0); if (ret < 0) return -1; if (ret > 0) return 1; sg_enumerate(); ata_enumerate(); add_proc_info_drives(0); return 1; } /** Tells wether libburn has the given drive in use or exclusively reserved. If it is "open" then libburn will eventually call sg_release() on it when it is time to give up usage and reservation. */ /** Published as burn_drive.drive_is_open() */ int sg_drive_is_open(struct burn_drive * d) { /* a bit more detailed case distinction than needed */ if (d->fd == -1337) return 0; if (d->fd < 0) return 0; return 1; } /** Opens the drive for SCSI commands and - if burn activities are prone to external interference on your system - obtains an exclusive access lock on the drive. (Note: this is not physical tray locking.) A drive that has been opened with sg_grab() will eventually be handed over to sg_release() for closing and unreserving. */ int sg_grab(struct burn_drive *d) { int fd, os_errno= 0, ret; int max_tries = 3, tries = 0; /* ts A60813 */ int open_mode = O_RDWR; /* ts A60821 <<< debug: for tracing calls which might use open drive fds */ if (mmc_function_spy(d, "sg_grab") <= 0) return 0; /* ts A60813 - A60927 O_EXCL with devices is a non-POSIX feature of Linux kernels. Possibly introduced 2002. Mentioned in "The Linux SCSI Generic (sg) HOWTO". */ if(burn_sg_open_o_excl) open_mode |= O_EXCL; /* ts A60813 O_NONBLOCK was hardcoded here. So it should stay default mode. ts A70411 Switched to O_NDELAY for LKML statement 2007/4/11/141 */ if(burn_sg_open_o_nonblock) open_mode |= O_NDELAY; /* ts A60813 - A60822 After enumeration the drive fd is probably still open. -1337 is the initial value of burn_drive.fd and the value after relase of drive. Unclear why not the official error return value -1 of open(2) war used. */ 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:; /* ts A60821 <<< debug: for tracing calls which might use open drive fds */ mmc_function_spy(NULL, "sg_grab ----------- opening"); /* ts A70409 : DDLP-B */ /* >>> obtain single lock on d->devname */ /* ts A60926 */ if(burn_sg_open_o_excl>1) { fd = -1; ret = sg_open_scsi_siblings(d->devname, d->global_index,d->sibling_fds, d->sibling_fnames,&(d->sibling_count), d->host, d->channel, d->id, d->lun); if(ret <= 0) goto drive_is_in_use; } fd = open(d->devname, open_mode); 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) { sg_fcntl_lock(&fd, d->devname, F_WRLCK, 1); if (fd < 0) goto drive_is_in_use; } } else fd= d->fd; if (fd >= 0) { d->fd = fd; fcntl(fd, F_SETOWN, getpid()); d->released = 0; return 1; } else if (errno == EBUSY) goto drive_is_in_use; libdax_msgs_submit(libdax_messenger, d->global_index, 0x00020003, LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH, "Could not grab drive", os_errno, 0); return 0; drive_is_in_use:; 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); goto try_open; } libdax_msgs_submit(libdax_messenger, d->global_index, 0x00020003, LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH, "Could not grab drive - already in use", 0, 0); sg_close_drive(d); d->fd = -1337; return 0; } /** PORTING: Is mainly about the call to sg_close_drive() and wether it implements the demanded functionality. */ /** Gives up the drive for SCSI commands and releases eventual access locks. (Note: this is not physical tray locking.) */ int sg_release(struct burn_drive *d) { /* ts A60821 <<< debug: for tracing calls which might use open drive fds */ if (mmc_function_spy(d, "sg_release") <= 0) return 0; if (d->fd < 1) return 0; /* ts A60821 <<< debug: for tracing calls which might use open drive fds */ mmc_function_spy(NULL, "sg_release ----------- closing"); sg_close_drive(d); return 0; } /* @return -1= transport failed, give up drive 0= transport failed, do not retry 1= transport succeeded 2- transport failed, please retry */ static int evaluate_transport_success(struct burn_drive *d, struct command *c, FILE *fp, unsigned short host_status, unsigned short driver_status) { int ret, do_retry= 0, give_up_drive= 0, sev; char *msg = NULL, *host_problem, *driver_problem, *driver_sugg; BURN_ALLOC_MEM(msg, char, 161); if ((host_status == Libburn_sg_host_oK && (driver_status & 0xf7) == Libburn_sg_driver_oK) || c->error) {ret = 1; goto ex;} /* No transport problems */ /* See http://www.tldp.org/HOWTO/SCSI-Generic-HOWTO/x291.html */ switch(host_status) { case 0x00: host_problem = "SG_ERR_DID_OK (No error)"; break; case 0x01: host_problem = "SG_ERR_DID_NO_CONNECT (Could not connect before timeout period)"; give_up_drive= 1; break; case 0x02: host_problem = "SG_ERR_DID_BUS_BUSY (Bus stayed busy through time out period)"; break; case 0x03: host_problem = "SG_ERR_DID_TIME_OUT (Timed out for miscellaneous reasons)"; break; case 0x04: host_problem = "SG_ERR_DID_BAD_TARGET (Bad target, device not responding ?)"; give_up_drive= 1; break; case 0x05: host_problem = "SG_ERR_DID_ABORT (Told to abort)"; break; case 0x06: host_problem = "SG_ERR_DID_PARITY (Parity error)"; break; case 0x07: host_problem = "SG_ERR_DID_ERROR (Internal error detected in the host adapter)"; give_up_drive= 1; break; case 0x08: host_problem = "SG_ERR_DID_RESET (The SCSI bus or the device have been reset)"; give_up_drive= 1; break; case 0x09: host_problem = "SG_ERR_DID_BAD_INTR (Got an unexpected interrupt)"; break; case 0x0a: host_problem = "SG_ERR_DID_PASSTHROUGH (Force command past mid-layer)"; break; case 0x0b: host_problem = "SG_ERR_DID_SOFT_ERROR (The low level driver wants a retry)"; do_retry = 1; break; default: host_problem = "? (unknown host_status code)"; } if (host_status != Libburn_sg_host_oK) { sprintf(msg, "SCSI command %2.2Xh yielded host problem: ", (unsigned int) c->opcode[0]); sprintf(msg+strlen(msg), "0x%x %s", (unsigned int) host_status, host_problem); sev = LIBDAX_MSGS_SEV_FAILURE; if (do_retry && !give_up_drive) sev = LIBDAX_MSGS_SEV_DEBUG; libdax_msgs_submit(libdax_messenger, d->global_index, 0x000201a7, sev, LIBDAX_MSGS_PRIO_HIGH, msg, 0, 0); sprintf(msg, "--- SG_IO: host_status= 0x%x %s", (unsigned int) host_status, host_problem); scsi_log_message(d, fp, msg, 0); } switch (driver_status & 0x07) { case 0: driver_problem = "SG_ERR_DRIVER_OK"; break; case 1: driver_problem = "SG_ERR_DRIVER_BUSY"; break; case 2: driver_problem = "SG_ERR_DRIVER_SOFT"; break; case 3: driver_problem = "SG_ERR_DRIVER_MEDIA"; break; case 4: driver_problem = "SG_ERR_DRIVER_ERROR"; break; case 5: driver_problem = "SG_ERR_DRIVER_INVALID"; break; case 6: driver_problem = "SG_ERR_DRIVER_TIMEOUT"; break; case 7: driver_problem = "SG_ERR_DRIVER_HARD"; break; default: driver_problem = "(unknown driver_status code)"; } switch (driver_status & 0xf0) { case 0: driver_sugg = "(no suggestion)"; break; case 0x10: driver_sugg = "SG_ERR_SUGGEST_RETRY"; do_retry = 1; break; case 0x20: driver_sugg = "SG_ERR_SUGGEST_ABORT"; give_up_drive= 1; break; case 0x30: driver_sugg = "SG_ERR_SUGGEST_REMAP"; give_up_drive= 1; break; case 0x40: driver_sugg = "SG_ERR_SUGGEST_DIE"; give_up_drive= 1; break; case 0x80: driver_sugg = "SG_ERR_SUGGEST_SENSE"; break; default: driver_sugg = "(unknown driver_status suggestion)"; } if ((driver_status & 0xf7) != Libburn_sg_driver_oK) { sprintf(msg, "SCSI command %2.2Xh yielded driver problem: ", (unsigned int) c->opcode[0]); sprintf(msg+strlen(msg), "driver_status= 0x%x %s / %s", (unsigned int) driver_status, driver_problem, driver_sugg); sev = LIBDAX_MSGS_SEV_FAILURE; if (do_retry && !give_up_drive) sev = LIBDAX_MSGS_SEV_DEBUG; libdax_msgs_submit(libdax_messenger, d->global_index, 0x000201a8, sev, LIBDAX_MSGS_PRIO_HIGH, msg, 0, 0); sprintf(msg, "--- SG_IO: driver_status= 0x%x %s / %s", (unsigned int) driver_status, driver_problem, driver_sugg); scsi_log_message(d, fp, msg, 0); } if (! do_retry) c->error = 1; ret = give_up_drive ? -1 : do_retry ? 2 : 0; ex:; BURN_FREE_MEM(msg); return ret; } static void react_on_drive_loss(struct burn_drive *d, struct command *c, FILE *fp) { sg_close_drive(d); d->released = 1; d->busy = BURN_DRIVE_IDLE; d->cancel = 1; c->error = 1; libdax_msgs_submit(libdax_messenger, d->global_index, 0x000201a6, LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH, "Lost connection to drive", 0, 0); scsi_log_message(d, fp, "--- SG_IO: Gave up connection to drive", 0); } /** Sends a SCSI command to the drive, receives reply and evaluates wether the command succeeded or shall be retried or finally failed. Returned SCSI errors shall not lead to a return value indicating failure. The callers get notified by c->error. An SCSI failure which leads not to a retry shall be notified via scsi_notify_error(). @return: 1 success , <=0 failure */ int sg_issue_command(struct burn_drive *d, struct command *c) { int done = 0, no_c_page = 0, i, ret; int err; time_t start_time; sg_io_hdr_t s; /* ts A61030 */ static FILE *fp= NULL; char *msg = NULL; BURN_ALLOC_MEM(msg, char, 161); c->error = 0; memset(c->sense, 0, sizeof(c->sense)); /* <<< ts A60821 debug: for tracing calls which might use open drive fds */ sprintf(msg, "sg_issue_command d->fd= %d d->released= %d\n", d->fd, d->released); mmc_function_spy(NULL, msg); /* >>> ts B11110 : move this into scsi_log_cmd() together with the static fp */ /* ts A61030 */ if (burn_sg_log_scsi & 1) { if (fp == NULL) { fp= fopen("/tmp/libburn_sg_command_log", "a"); fprintf(fp, "\n-----------------------------------------\n"); } } /* ts A61010 : with no fd there is no chance to send an ioctl */ if (d->fd < 0) { c->error = 1; {ret = 0; goto ex;} } c->error = 0; memset(&s, 0, sizeof(sg_io_hdr_t)); if (burn_sg_log_scsi & 3) scsi_log_cmd(c,fp,0); s.interface_id = 'S'; #ifdef Libburn_sgio_as_growisofS /* ??? ts A91112 : does this speed up USB ? (from growisofs) --- did not help */ s.flags = SG_FLAG_DIRECT_IO; #endif /* Libburn_sgio_as_growisofS */ if (c->dir == TO_DRIVE) s.dxfer_direction = SG_DXFER_TO_DEV; else if (c->dir == FROM_DRIVE) s.dxfer_direction = SG_DXFER_FROM_DEV; else if (c->dir == NO_TRANSFER) { s.dxfer_direction = SG_DXFER_NONE; /* ts A61007 */ /* a ssert(!c->page); */ no_c_page = 1; } s.cmd_len = c->oplen; s.cmdp = c->opcode; s.mx_sb_len = 32; s.sbp = c->sense; if (c->timeout > 0) s.timeout = c->timeout; else s.timeout = Libburn_scsi_default_timeouT; if (c->page && !no_c_page) { s.dxferp = c->page->data; /* # def ine Libburn_debug_dxferP 1 */ #ifdef Libburn_debug_dxferP { char text[1024], *content; int i = c->page->bytes; if (c->dir == FROM_DRIVE) { for (i = 0; i < c->page->bytes && c->page->data[i] == 0; i++); content = (i < c->page->bytes) ? " (some nonzero)" : " (all zero)"; } else { i = c->page->bytes; content = ""; } sprintf(text, "dxferp before = %lx%s", (unsigned long) s.dxferp, content); scsi_log_text(text, fp, 0); } #endif if (c->dir == FROM_DRIVE) { /* ts A70519 : kernel 2.4 usb-storage seems to expect exact dxfer_len for data fetching commands. */ if (c->dxfer_len >= 0) s.dxfer_len = c->dxfer_len; else s.dxfer_len = BUFFER_SIZE; /* touch page so we can use valgrind */ memset(c->page->data, 0, BUFFER_SIZE); } else { /* ts A61010 */ /* a ssert(c->page->bytes > 0); */ if (c->page->bytes <= 0) { c->error = 1; {ret = 0; goto ex;} } s.dxfer_len = c->page->bytes; } } else { s.dxferp = NULL; s.dxfer_len = 0; } s.usr_ptr = c; start_time = time(NULL); for(i = 0; !done; i++) { memset(c->sense, 0, sizeof(c->sense)); c->start_time = burn_get_time(0); err = ioctl(d->fd, SG_IO, &s); c->end_time = burn_get_time(0); #ifdef Libburn_debug_dxferP if (c->page && !no_c_page) { char text[1024]; sprintf(text, "dxferp after = %lx", (unsigned long) s.dxferp); scsi_log_text(text, fp, 0); } #endif /* ts A61010 */ /* a ssert(err != -1); */ if (err == -1) { libdax_msgs_submit(libdax_messenger, d->global_index, 0x0002010c, LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH, "Failed to transfer command to drive", errno, 0); sprintf(msg, "--- SG_IO: return= -1 , "); sprintf(msg + strlen(msg), "errno= %d , ", errno); sprintf(msg + strlen(msg), "host_status= 0x%x , driver_status= 0x%x", (unsigned int) s.host_status, (unsigned int) s.driver_status); scsi_log_message(d, fp, msg, 0); react_on_drive_loss(d, c, fp); {ret = -1; goto ex;} } done = scsi_eval_cmd_outcome(d, c, fp, (unsigned char *) (s.sbp), s.sb_len_wr, start_time, s.timeout, i, 0); if (d->cancel) break; ret = evaluate_transport_success(d, c, fp, s.host_status, s.driver_status); if (ret == -1) react_on_drive_loss(d, c, fp); if (ret <= 0) {ret = -1; goto ex;} if (d->cancel) break; /* if ! done : loop for retry */; } ret = 1; ex:; BURN_FREE_MEM(msg); return ret; } /* ts B11001 : outsourced from non-static sg_obtain_scsi_adr() */ /** Tries to obtain SCSI address parameters. @return 1 is success , 0 is failure */ 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) { int fd, ret, l, open_mode = O_RDONLY; struct my_scsi_idlun { int x; int host_unique_id; }; struct my_scsi_idlun idlun; /* valgrind called idlun unitialized because it is blind for ioctl */ idlun.x = 0; idlun.host_unique_id = 0; l = strlen(linux_ata_device_family) - 2; if (l > 0 && strncmp(path, linux_ata_device_family, l) == 0 && path[7] >= 'a' && path[7] <= 'z' && path[8] == 0) return 0; /* on RIP 14 all hdx return SCSI adr 0,0,0,0 */ /* ts A70409 : DDLP-B */ /* >>> obtain single lock on path */ if(burn_sg_open_o_nonblock) open_mode |= O_NDELAY; if(burn_sg_open_o_excl) { /* O_EXCL | O_RDONLY does not work with /dev/sg* on SuSE 9.0 (kernel 2.4) and SuSE 9.3 (kernel 2.6) */ /* so skip it for now */; } if (fd_in >= 0) fd = fd_in; else fd = open(path, open_mode); if(fd < 0) return 0; sg_fcntl_lock(&fd, path, F_RDLCK, 0); if(fd < 0) return 0; #ifdef SCSI_IOCTL_GET_BUS_NUMBER /* Hearsay A61005 */ if (ioctl(fd, SCSI_IOCTL_GET_BUS_NUMBER, bus_no) == -1) *bus_no = -1; #endif /* http://www.tldp.org/HOWTO/SCSI-Generic-HOWTO/scsi_g_idlun.html */ ret = ioctl(fd, SCSI_IOCTL_GET_IDLUN, &idlun); if (fd_in < 0) sg_close_drive_fd(path, -1, &fd, 0); if (ret == -1) return(0); *host_no= (idlun.x>>24)&255; *channel_no= (idlun.x>>16)&255; *target_no= (idlun.x)&255; *lun_no= (idlun.x>>8)&255; #ifdef SCSI_IOCTL_GET_BUS_NUMBER if(*bus_no == -1) *bus_no = 1000 * (*host_no + 1) + *channel_no; #else *bus_no= *host_no; #endif return 1; } /* 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 */ /** Tells wether a text is a persistent address as listed by the enumeration functions. */ int sg_is_enumerable_adr(char *adr) { char *fname = NULL; int ret = 0, first = 1, fname_size = 4096; burn_drive_enumerator_t idx; BURN_ALLOC_MEM(fname, char, fname_size); while (1) { ret= sg_give_next_adr(&idx, fname, fname_size, first); if(ret <= 0) break; first = 0; if (strcmp(adr, fname) == 0) { sg_give_next_adr(&idx, fname, fname_size, -1); {ret = 1; goto ex;} } } ret = 0; ex:; if (first == 0) sg_give_next_adr(&idx, fname, fname_size, -1); BURN_FREE_MEM(fname); return ret; } /* ts B00115 */ /* Return 1 if the given path leads to a regular file or a device that can be seeked, read, and possibly written with 2 kB granularity. */ int burn_os_is_2k_seekrw(char *path, int flag) { struct stat stbuf; if (stat(path, &stbuf) == -1) return 0; if (S_ISREG(stbuf.st_mode)) return 1; if (S_ISBLK(stbuf.st_mode)) return 1; return 0; } /* ts A70909 */ /** Estimate the potential payload capacity of a file address. @param path The address of the file to be examined. If it does not exist yet, then the directory will be inquired. @param bytes The pointed value gets modified, but only if an estimation is possible. @return -2 = cannot perform necessary operations on file object -1 = neither path nor dirname of path exist 0 = could not estimate size capacity of file object 1 = estimation has been made, bytes was set */ int burn_os_stdio_capacity(char *path, off_t write_start, off_t *bytes) { struct stat stbuf; struct statvfs vfsbuf; char *testpath = NULL, *cpt; long blocks; int open_mode = O_RDONLY, fd, ret; off_t add_size = 0; BURN_ALLOC_MEM(testpath, char, 4096); testpath[0] = 0; if (stat(path, &stbuf) == -1) { strcpy(testpath, path); cpt = strrchr(testpath, '/'); if(cpt == NULL) strcpy(testpath, "."); else if(cpt == testpath) testpath[1] = 0; else *cpt = 0; if (stat(testpath, &stbuf) == -1) {ret = -1; goto ex;} } else if(S_ISBLK(stbuf.st_mode)) { fd = open(path, open_mode); if (fd == -1) {ret = -2; goto ex;} ret = ioctl(fd, BLKGETSIZE, &blocks); close(fd); if (ret == -1) {ret = -2; goto ex;} *bytes = ((off_t) blocks) * (off_t) 512; } else if(S_ISREG(stbuf.st_mode)) { add_size = burn_sparse_file_addsize(write_start, &stbuf); strcpy(testpath, path); } else {ret = 0; goto ex;} if (testpath[0]) { if (statvfs(testpath, &vfsbuf) == -1) {ret = -2; goto ex;} *bytes = add_size + ((off_t) vfsbuf.f_frsize) * (off_t) vfsbuf.f_bavail; } #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; ex:; BURN_FREE_MEM(testpath); return ret; } /* ts A91122 : an interface to open(O_DIRECT) or similar OS tricks. */ #ifdef PROT_READ #ifdef PROT_WRITE #ifdef MAP_SHARED #ifdef MAP_ANONYMOUS #ifdef MAP_FAILED #define Libburn_linux_do_mmaP 1 #endif #endif #endif #endif #endif #ifdef Libburn_read_o_direcT #ifdef O_DIRECT #define Libburn_linux_do_o_direcT 1 #endif #endif /* Libburn_read_o_direcT */ int burn_os_open_track_src(char *path, int open_flags, int flag) { int fd; #ifdef Libburn_linux_do_o_direcT libdax_msgs_submit(libdax_messenger, -1, 0x00000002, LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH, "Opening track source with O_DIRECT" , 0, 0); fd = open(path, open_flags | O_DIRECT); #else fd = open(path, open_flags); #endif return fd; } void *burn_os_alloc_buffer(size_t amount, int flag) { void *buf = NULL; #ifdef Libburn_linux_do_mmaP /* >>> check whether size is suitable */; libdax_msgs_submit(libdax_messenger, -1, 0x00000002, LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH, "Allocating buffer via mmap()" , 0, 0); buf = mmap(NULL, amount, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, (off_t) 0); if (buf == MAP_FAILED) buf = NULL; else memset(buf, 0, amount); #else buf = calloc(1, amount); #endif /* ! Libburn_linux_do_mmaP */ return buf; } int burn_os_free_buffer(void *buffer, size_t amount, int flag) { int ret = 0; if (buffer == NULL) return 0; #ifdef Libburn_linux_do_mmaP ret = munmap(buffer, amount); #else free(buffer); #endif return (ret == 0); } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������libburn-1.4.2/libburn/libburn.ver�������������������������������������������������������������������0000644�0001757�0001751�00000012011�12652644224�013716� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������LIBBURN4 { global: burn_abort; burn_abort_pacifier; burn_allow_drive_role_4; burn_allow_untested_profiles; burn_cdtext_from_session; burn_cdtext_from_packfile; burn_disc_add_session; burn_disc_available_space; burn_disc_close_damaged; burn_disc_create; burn_disc_erasable; burn_disc_erase; burn_disc_format; burn_disc_free; burn_disc_free_multi_caps; burn_disc_get_bd_spare_info; burn_disc_get_cd_info; burn_disc_get_format_descr; burn_disc_get_formats; burn_disc_get_incomplete_sessions; burn_disc_get_leadin_text; burn_disc_get_media_id; burn_disc_get_msc1; burn_disc_get_multi_caps; burn_disc_get_phys_format_info; burn_disc_get_profile; burn_disc_get_sectors; burn_disc_get_sessions; burn_disc_get_status; burn_disc_next_track_is_damaged; burn_disc_pretend_blank; burn_disc_pretend_full; burn_disc_pretend_full_uncond; burn_disc_read; burn_disc_read_atip; burn_disc_remove_session; burn_disc_track_lba_nwa; burn_disc_write; burn_drive_add_whitelist; burn_drive_cancel; burn_drive_clear_whitelist; burn_drive_convert_fs_adr; burn_drive_convert_scsi_adr; burn_drive_d_get_adr; burn_drive_equals_adr; burn_drive_extract_audio; burn_drive_extract_audio_track; burn_drive_free_speedlist; burn_drive_get_adr; burn_drive_get_all_profiles; burn_drive_get_best_speed; burn_drive_get_disc; burn_drive_get_drive_role; burn_drive_get_media_sno; burn_drive_get_min_write_speed; burn_drive_get_read_speed; burn_drive_get_serial_no; burn_drive_get_speedlist; burn_drive_get_start_end_lba; burn_drive_get_status; burn_drive_get_write_speed; burn_drive_grab; burn_drive_info_forget; burn_drive_info_free; burn_drive_is_enumerable_adr; burn_drive_leave_locked; burn_drive_obtain_scsi_adr; burn_drive_probe_cd_write_modes; burn_drive_re_assess; burn_drive_release; burn_drive_scan; burn_drive_scan_and_grab; burn_drive_set_buffer_waiting; burn_drive_set_speed; burn_drive_set_stream_recording; burn_drive_snooze; burn_drive_was_feat21_failure; burn_drive_wrote_well; burn_fd_source_new; burn_fifo_fill; burn_fifo_get_statistics; burn_fifo_inquire_status; burn_fifo_next_interval; burn_fifo_peek_data; burn_fifo_source_new; burn_file_source_new; burn_finish; burn_get_read_capacity; burn_guess_cd_manufacturer; burn_guess_manufacturer; burn_initialize; burn_is_aborting; burn_lba_to_msf; burn_list_sev_texts; burn_lookup_device_link; burn_make_input_sheet_v07t; burn_msf_to_lba; burn_msf_to_sectors; burn_msgs_obtain; burn_msgs_set_severities; burn_msgs_submit; burn_obtain_profile_name; burn_offst_source_new; burn_os_alloc_buffer; burn_os_free_buffer; burn_os_open_track_src; burn_precheck_write; burn_preset_device_open; burn_random_access_write; burn_read_audio; burn_read_data; burn_read_opts_free; burn_read_opts_new; burn_read_opts_read_subcodes_audio; burn_read_opts_read_subcodes_data; burn_read_opts_report_recovered_errors; burn_read_opts_set_c2errors; burn_read_opts_set_hardware_error_recovery; burn_read_opts_set_hardware_error_retries; burn_read_opts_set_raw; burn_read_opts_transfer_damaged_blocks; burn_scsi_transport_id; burn_sectors_to_msf; burn_session_add_track; burn_session_by_cue_file; burn_session_create; burn_session_dispose_cdtext; burn_session_free; burn_session_get_cdtext; burn_session_get_cdtext_par; burn_session_get_hidefirst; burn_session_get_leadout_entry; burn_session_get_sectors; burn_session_get_start_tno; burn_session_get_tracks; burn_session_hide_first_track; burn_session_input_sheet_v07t; burn_session_remove_track; burn_session_set_cdtext; burn_session_set_cdtext_par; burn_session_set_start_tno; burn_set_messenger; burn_set_scsi_logging; burn_set_signal_handling; burn_set_verbosity; burn_sev_to_text; burn_source_free; burn_structure_print_disc; burn_structure_print_session; burn_structure_print_track; burn_text_to_sev; burn_track_clear_indice; burn_track_clear_isrc; burn_track_create; burn_track_define_data; burn_track_dispose_cdtext; burn_track_free; burn_track_get_cdtext; burn_track_get_counters; burn_track_get_entry; burn_track_get_mode; burn_track_get_sectors; burn_track_set_byte_swap; burn_track_set_cdxa_conv; burn_track_set_cdtext; burn_track_set_default_size; burn_track_set_index; burn_track_set_isrc; burn_track_set_isrc_string; burn_track_set_postgap_size; burn_track_set_pregap_size; burn_track_set_size; burn_track_set_source; burn_version; burn_write_opts_auto_write_type; burn_write_opts_free; burn_write_opts_get_drive; burn_write_opts_new; burn_write_opts_set_dvd_obs; burn_write_opts_set_fail21h_sev; burn_write_opts_set_fillup; burn_write_opts_set_force; burn_write_opts_set_format; burn_write_opts_set_has_mediacatalog; burn_write_opts_set_leadin_text; burn_write_opts_set_mediacatalog; burn_write_opts_set_multi; burn_write_opts_set_obs_pad; burn_write_opts_set_perform_opc; burn_write_opts_set_simulate; burn_write_opts_set_start_byte; burn_write_opts_set_stdio_fsync; burn_write_opts_set_stream_recording; burn_write_opts_set_toc_entries; burn_write_opts_set_underrun_proof; burn_write_opts_set_write_type; libdax_audioxtr_destroy; libdax_audioxtr_detach_fd; libdax_audioxtr_get_id; libdax_audioxtr_get_size; libdax_audioxtr_new; libdax_audioxtr_read; local: *; }; �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������libburn-1.4.2/libburn/error.h�����������������������������������������������������������������������0000644�0001757�0001751�00000000231�12652644224�013046� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* -*- indent-tabs-mode; t; tab-width: 8; c-basic-offset: 8; -*- */ #ifndef __ERROR_H #define __ERROR_H #define BE_CANCELLED 1 #endif /* __ERROR_H */ �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������libburn-1.4.2/libburn/sg-dummy.c��������������������������������������������������������������������0000644�0001757�0001751�00000022753�12652644224�013467� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */ /* Copyright (c) 2009 - 2011 Thomas Schmitt <scdbackup@gmx.net> Provided under GPL version 2 or later. */ #ifdef HAVE_CONFIG_H #include "../config.h" #endif /* This is the main operating system dependent SCSI part of libburn. It implements the transport level aspects of SCSI control and command i/o. Present implementation: default dummy which enables libburn only to work with stdio: pseudo drive addresses. For real implementations see sg-linux.c, sg-freebsd.c, sg-libcdio.c */ #include <unistd.h> #include <stdio.h> #include <sys/types.h> #include <errno.h> #include <fcntl.h> #include <sys/stat.h> #include <string.h> #include <stdlib.h> #ifdef Libburn_os_has_statvfS #include <sys/statvfs.h> #endif /* Libburn_os_has_stavtfS */ /* ts B41126 : O_BINARY is needed for Cygwin but undefined elsewhere */ #ifndef O_BINARY #define O_BINARY 0 #endif #include "transport.h" #include "drive.h" #include "sg.h" #include "spc.h" #include "mmc.h" #include "sbc.h" #include "debug.h" #include "toc.h" #include "util.h" #include "init.h" #include "libdax_msgs.h" extern struct libdax_msgs *libdax_messenger; /** Returns the id string of the SCSI transport adapter and eventually needed operating system facilities. This call is usable even if sg_initialize() was not called yet. In that case a preliminary constant message might be issued if detailed info is not available yet. @param msg returns id string @param flag unused yet, submit 0 @return 1 = success, <=0 = failure */ int sg_id_string(char msg[1024], int flag) { strcpy(msg, "internal X/Open adapter sg-dummy"); return 1; } /** Performs global initialization of the SCSI transport adapter and eventually needed operating system facilities. Checks for compatibility supporting software components. @param msg returns ids and/or error messages of eventual helpers @param flag unused yet, submit 0 @return 1 = success, <=0 = failure */ int sg_initialize(char msg[1024], int flag) { return sg_id_string(msg, 0); } /** Performs global finalization of the SCSI transport adapter and eventually needed operating system facilities. Releases globally aquired resources. @param flag unused yet, submit 0 @return 1 = success, <=0 = failure */ int sg_shutdown(int flag) { return 1; } /** Finalizes BURN_OS_TRANSPORT_DRIVE_ELEMENTS, the components of struct burn_drive which are defined in os-*.h. This will be called when a burn_drive gets disposed. @param d the drive to be finalized @param flag unused yet, submit 0 @return 1 = success, <=0 = failure */ int sg_dispose_drive(struct burn_drive *d, int flag) { return 1; } /** Returns the next index number and the next enumerated drive address. The enumeration has to cover all available and accessible drives. It is allowed to return addresses of drives which are not available but under some (even exotic) circumstances could be available. It is on the other hand allowed, only to hand out addresses which can really be used right in the moment of this call. (This implementation chooses the former.) @param idx An opaque handle. Make no own theories about it. @param adr Takes the reply @param adr_size Gives maximum size of reply including final 0 @param initialize 1 = start new, 0 = continue, use no other values for now -1 = finish @return 1 = reply is a valid address , 0 = no further address available -1 = severe error (e.g. adr_size too small) */ int sg_give_next_adr(burn_drive_enumerator_t *idx, char adr[], int adr_size, int initialize) { return 0; } /** Brings all available, not-whitelist-banned, and accessible drives into libburn's list of drives. */ /* ts A61115: replacing call to sg-implementation internals from drive.c */ int scsi_enumerate_drives(void) { libdax_msgs_submit(libdax_messenger, -1, 0x0002016b, LIBDAX_MSGS_SEV_WARNING, LIBDAX_MSGS_PRIO_HIGH, "No MMC transport adapter is present. Running on sg-dummy.c.", 0, 0); return 1; } /** Tells wether libburn has the given drive in use or exclusively reserved. If it is "open" then libburn will eventually call sg_release() on it when it is time to give up usage and reservation. */ /** Published as burn_drive.drive_is_open() */ int sg_drive_is_open(struct burn_drive * d) { return 0; } /** Opens the drive for SCSI commands and - if burn activities are prone to external interference on your system - obtains an exclusive access lock on the drive. (Note: this is not physical tray locking.) A drive that has been opened with sg_grab() will eventually be handed over to sg_release() for closing and unreserving. */ int sg_grab(struct burn_drive *d) { libdax_msgs_submit(libdax_messenger, d->global_index, 0x0002016a, LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH, "No MMC transport adapter is present. Running on sg-dummy.c.", 0, 0); return 0; } /** Gives up the drive for SCSI commands and releases eventual access locks. (Note: this is not physical tray locking.) */ int sg_release(struct burn_drive *d) { return 0; } /** Sends a SCSI command to the drive, receives reply and evaluates wether the command succeeded or shall be retried or finally failed. Returned SCSI errors shall not lead to a return value indicating failure. The callers get notified by c->error. An SCSI failure which leads not to a retry shall be notified via scsi_notify_error(). The Libburn_log_sg_commandS facility might be of help when problems with a drive have to be examined. It shall stay disabled for normal use. @return: 1 success , <=0 failure */ int sg_issue_command(struct burn_drive *d, struct command *c) { libdax_msgs_submit(libdax_messenger, d->global_index, 0x0002016a, LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH, "No MMC transport adapter is present. Running on sg-dummy.c.", 0, 0); return -1; } /** Tries to obtain SCSI address parameters. @return 1 is success , 0 is failure */ int sg_obtain_scsi_adr(char *path, int *bus_no, int *host_no, int *channel_no, int *target_no, int *lun_no) { libdax_msgs_submit(libdax_messenger, -1, 0x0002016c, LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH, "No MMC transport adapter is present. Running on sg-dummy.c.", 0, 0); return 0; } /** Tells wether a text is a persistent address as listed by the enumeration functions. */ int sg_is_enumerable_adr(char *adr) { return(0); } /* Return 1 if the given path leads to a regular file or a device that can be seeked, read, and possibly written with 2 kB granularity. */ int burn_os_is_2k_seekrw(char *path, int flag) { struct stat stbuf; if (stat(path, &stbuf) == -1) return 0; if (S_ISREG(stbuf.st_mode)) return 1; if (S_ISBLK(stbuf.st_mode)) return 1; return 0; } /** Estimate the potential payload capacity of a file address. @param path The address of the file to be examined. If it does not exist yet, then the directory will be inquired. @param bytes The pointed value gets modified, but only if an estimation is possible. @return -2 = cannot perform necessary operations on file object -1 = neither path nor dirname of path exist 0 = could not estimate size capacity of file object 1 = estimation has been made, bytes was set */ int burn_os_stdio_capacity(char *path, off_t write_start, off_t *bytes) { struct stat stbuf; #ifdef Libburn_os_has_statvfS struct statvfs vfsbuf; #endif char *testpath = NULL, *cpt; off_t add_size = 0; int ret; BURN_ALLOC_MEM(testpath, char, 4096); testpath[0] = 0; if (stat(path, &stbuf) == -1) { strcpy(testpath, path); cpt = strrchr(testpath, '/'); if(cpt == NULL) strcpy(testpath, "."); else if(cpt == testpath) testpath[1] = 0; else *cpt = 0; if (stat(testpath, &stbuf) == -1) {ret = -1; goto ex;} #ifdef Libburn_if_this_was_linuX } else if(S_ISBLK(stbuf.st_mode)) { long blocks; blocks = *bytes / 512; fd = open(path, open_mode | O_BINARY); if (fd == -1) {ret = -2; goto ex;} ret = ioctl(fd, BLKGETSIZE, &blocks); close(fd); if (ret == -1) {ret = -2; goto ex;} *bytes = ((off_t) blocks) * (off_t) 512; #endif /* Libburn_if_this_was_linuX */ } else if(S_ISREG(stbuf.st_mode)) { add_size = burn_sparse_file_addsize(write_start, &stbuf); strcpy(testpath, path); } else {ret = 0; goto ex;} if (testpath[0]) { #ifdef Libburn_os_has_statvfS if (statvfs(testpath, &vfsbuf) == -1) {ret = -2; goto ex;} *bytes = add_size + ((off_t) vfsbuf.f_frsize) * (off_t) vfsbuf.f_bavail; #else /* Libburn_os_has_statvfS */ {ret = 0; goto ex;} #endif /* ! Libburn_os_has_stavtfS */ } ret = 1; ex:; BURN_FREE_MEM(testpath); return ret; } /* ts A91122 : an interface to open(O_DIRECT) or similar OS tricks. */ #ifdef Libburn_read_o_direcT /* No special O_DIRECT-like precautions are implemented here */ #endif /* Libburn_read_o_direcT */ int burn_os_open_track_src(char *path, int open_flags, int flag) { int fd; fd = open(path, open_flags | O_BINARY); return fd; } void *burn_os_alloc_buffer(size_t amount, int flag) { void *buf = NULL; buf = calloc(1, amount); return buf; } int burn_os_free_buffer(void *buffer, size_t amount, int flag) { if (buffer == NULL) return 0; free(buffer); return 1; } ���������������������libburn-1.4.2/libburn/transport.h�������������������������������������������������������������������0000644�0001757�0001751�00000034624�12652644224�013766� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */ /* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens Copyright (c) 2006 - 2015 Thomas Schmitt <scdbackup@gmx.net> Provided under GPL version 2 or later. */ #ifndef __TRANSPORT #define __TRANSPORT #include "libburn.h" #include "os.h" #include <pthread.h> /* sg data structures */ #include <sys/types.h> /* see os.h for name of particular os-*.h where this is defined */ #define BUFFER_SIZE BURN_OS_TRANSPORT_BUFFER_SIZE enum transfer_direction { TO_DRIVE, FROM_DRIVE, NO_TRANSFER }; /* end of sg data structures */ /* generic 'drive' data structures */ struct cue_sheet { int count; unsigned char *data; }; struct params { int speed; int retries; }; struct buffer { /* ts A61219: Added 4096 bytes reserve against possible buffer overflows. (Changed in sector.c buffer flush test from >= to > BUFFER_SIZE . This can at most cause a 1 sector overlap. Sometimes an offset of 16 byte is applied to the output data (in some RAW mode). ) burn_write_opts.cdxa_conversion can imply an offset of 8 bytes. */ unsigned char data[BUFFER_SIZE + 4096]; int sectors; int bytes; }; struct command { unsigned char opcode[16]; int oplen; int dir; int dxfer_len; unsigned char sense[128]; int error; int retry; struct buffer *page; int timeout; /* milliseconds */ double start_time; double end_time; }; struct burn_scsi_inquiry_data { char peripheral; /* bit0-4: device type should be 5 bit5-7: qualifier must be 0 */ char version; /* should be 3 (SPC-1) to 5 (SPC-3) (or higher ?) but is often 0. */ char vendor[9]; char product[17]; char revision[5]; int valid; }; struct scsi_mode_data { int p2a_valid; int buffer_size; int dvdram_read; int dvdram_write; int dvdr_read; int dvdr_write; int dvdrom_read; int cdrw_read; int cdrw_write; int cdr_read; int cdr_write; int simulate; int c2_pointers; int underrun_proof; int max_read_speed; int cur_read_speed; int max_write_speed; int cur_write_speed; /* ts A61021 */ int min_write_speed; /* ts A61225 : Results from ACh GET PERFORMANCE, Type 03h Speed values go into *_*_speed */ int min_end_lba; int max_end_lba; struct burn_speed_descriptor *speed_descriptors; int retry_page_length; int retry_page_valid; int write_page_length; int write_page_valid; }; /* ts A70112 : represents a single Formattable Capacity Descriptor as of mmc5r03c.pdf 6.24.3.3 . There can at most be 32 of them. */ struct burn_format_descr { /* format type: e.g 0x00 is "Full", 0x15 is "Quick" */ int type; /* the size in bytes derived from Number of Blocks */ off_t size; /* the Type Dependent Parameter (usually the write alignment size) */ unsigned int tdp; }; /* ts B40106 : represents a Feature Descriptor as of mmc5r03c.pdf 5.2.2 There can be many of them. Thus a linked list. */ struct burn_feature_descr { unsigned short feature_code; unsigned char flags; /* bit0= current bit1= persistent bit2-5= version */ unsigned char data_lenght; /* Additional bytes after the first 4 bytes of the descriptor */ unsigned char *data; struct burn_feature_descr *next; }; /** Gets initialized in enumerate_common() and burn_drive_register() */ struct burn_drive { /* ts A70902: 0=null-emulation 1=MMC drive , 2=stdio random read-write 3=stdio sequential write-only 4=stdio random read-only 5=stdio random write-only */ int drive_role; int bus_no; int host; int id; int channel; int lun; char *devname; /* ts A70302: mmc5r03c.pdf 5.3.2 Physical Interface Standard */ int phys_if_std; /* 1=SCSI, 2=ATAPI, 3,4,6=FireWire, 7=SATA, 8=USB */ char phys_if_name[80]; /* MMC-5 5.3.2 table 91 , e.g. "SCSI Family" */ /* see os.h for name of particular os-*.h where this is defined */ BURN_OS_TRANSPORT_DRIVE_ELEMENTS /* ts A60904 : ticket 62, contribution by elmom */ /** Tells the index in scanned burn_drive_info array. -1 if fallen victim to burn_drive_info_forget() */ int global_index; pthread_mutex_t access_lock; enum burn_disc_status status; int erasable; /* ts A61201 from 46h GET CONFIGURATION */ int current_profile; char current_profile_text[80]; int current_is_cd_profile; int current_is_supported_profile; /* ts A90603 */ int current_is_guessed_profile; /* ts A90815 */ unsigned char all_profiles[256]; int num_profiles; /* ts B40106 : All feature descriptors as read from drive */ struct burn_feature_descr *features; /* ts A70128 : MMC-to-MMC feature info from 46h for DVD-RW. Quite internal. Regard as opaque :) */ /* 1 = incremental recording available, 0 = not available */ int current_has_feat21h; /* Some drives announce feature 21h on fast-blanked DVD-RW although they cannot write them in Incremental mode. 0= does not look like the recent write run failed due to Incremental on fast blanked DVD-RW 1= it seems to have happened 2= it seems to have happened with write address 0 */ int was_feat21h_failure; /* Link Size item number 0 from feature 0021h descriptor */ int current_feat21h_link_size; /* Flags from feature 0023h for formatting BD mmc5r03c.pdf 5.3.13 Byte 4 BD-RE: bit0= Cert format 30h sub-type 10b bit1= QCert format 30h sub-type 11b bit2= Expand format 01h bit3= RENoSA format 31h Byte 8 BD-R: bit0= RRM format 32h sub-type 10b */ int current_feat23h_byte4; int current_feat23h_byte8; /* Flags from feature 002Fh feature descriptor mmc5r03c.pdf 5.3.25 : bit1= DVD-RW supported bit2= Test Write available bit3= DVD-R DL supported bit6= Buffer Under-run Free recording available (page 05h BUFE) Value -1 indicates that no 002Fh was current in the features list. */ int current_feat2fh_byte4; /* ts B51016 : Result from feature 108h : Drive Serial Number */ char *drive_serial_number; char drive_serial_number_len; /* ts B51016 : Result from command AB READ MEDIA SERIAL NUMBER */ char *media_serial_number; char media_serial_number_len; /* ts B10524 : whether the damage bit was set for the future track. bit0= damage bit , bit1= nwa valid bit */ int next_track_damaged; /* ts A70114 : whether a DVD-RW media holds an incomplete session (which could need closing after write) */ int needs_close_session; /* ts A71003 : whether a random write operation was done and no synchronize chache has happened yet */ int needs_sync_cache; /* ts A80412 : whether to use WRITE12 with Streaming bit set rather than WRITE10. Speeds up DVD-RAM. Might help with BD-RE */ int do_stream_recording; /* ts A90227 : the LBA where stream recording shall start. Writing to lower LBA will be done without streaming. */ int stream_recording_start; /* ts A61218 from 51h READ DISC INFORMATION */ int last_lead_in; int last_lead_out; int num_opc_tables; /* ts A91104: -1= not yet known */ int bg_format_status; /* 0=needs format start, 1=needs format restart*/ int disc_type; /* 0="CD-DA or CD-ROM", 0x10="CD-I", 0x20="CD-ROM XA" */ unsigned int disc_id; /* a "32 bit binary integer" */ char disc_bar_code[9]; int disc_app_code; int disc_info_valid; /* bit0= disc_type , bit1= disc_id , bit2= disc_bar_code , bit3= disc_app_code bit4= URU bit is set (= unrestricted use) bit5= Erasable bit was set in reply */ /* ts A70108 from 23h READ FORMAT CAPACITY mmc5r03c.pdf 6.24 */ int format_descr_type; /* 1=unformatted, 2=formatted, 3=unclear */ off_t format_curr_max_size; /* meaning depends on format_descr_type */ unsigned int format_curr_blsas; /* dito */ int best_format_type; off_t best_format_size; /* The complete list of format descriptors as read with 23h */ int num_format_descr; struct burn_format_descr format_descriptors[32]; volatile int released; /* ts A61106 */ /* 0= report errors 1= do not report errors 2= do not report errors which the libburn function indicates in member .had_particular_error 3= report errors with severity DEBUG */ int silent_on_scsi_error; /* ts B21023 */ /* bit0= 5 64 00 occured with READ10 in mmc_read_10() */ int had_particular_error; int stdio_fd; int nwa; /* next writeable address */ int alba; /* absolute lba */ int rlba; /* relative lba in section */ int start_lba; int end_lba; /* ts A70131 : from 51h READ DISC INFORMATION Number of Sessions (-1)*/ int complete_sessions; /* ts A90107 */ int state_of_last_session; #ifdef Libburn_disc_with_incomplete_sessioN /* ts B30112 */ int incomplete_sessions; #endif /* ts A70129 : from 51h READ DISC INFORMATION Last Track Number in Last Session */ 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) With CD this might change after particular write parameters have been set and nwa has been inquired. (e.g. by d->send_write_parameters() ; d->get_nwa()). */ off_t media_capacity_remaining; /* ts A70215 : if > 0 : first lba on media that is too high for write*/ int media_lba_limit; /* ts A81210 : Upper limit of readable data size, 0x7fffffff = unknown 0x7ffffff0 = 32 bit overflow, or unknown stdio size */ int media_read_capacity; /* ts B10314 : Next Writeable Adress for drive_role == 5 */ int role_5_nwa; int toc_temp; struct burn_disc *disc; /* disc structure */ int block_types[4]; struct buffer *buffer; struct burn_progress progress; /* To be used by mmc.c, sbc.c, spc.c for SCSI commands where the struct content surely does not have to persist while another command gets composed and executed. (Inherently, sending SCSI commands to the same drive cannot be thread-safe. But there are functions which send SCSI commands and also call other such functions. These shall use own allocated command structs and not this struct here.) */ struct command casual_command; /* ts A70711 : keeping an eye on the drive buffer */ off_t pessimistic_buffer_free; int pbf_altered; int wait_for_buffer_free; int nominal_write_speed; unsigned int wfb_min_usec; unsigned int wfb_max_usec; unsigned int wfb_timeout_sec; unsigned int wfb_min_percent; unsigned int wfb_max_percent; unsigned int pessimistic_writes; unsigned int waited_writes; unsigned int waited_tries; unsigned int waited_usec; volatile int cancel; volatile enum burn_drive_status busy; /* During write runs, this points to a copy of the applied struct burn_write_opts. Only read this underneath burn_disc_write_sync() which removes the copy when done. Especially do not read it from outside the write thread. */ struct burn_write_opts *write_opts; /* ts A70929 */ pid_t thread_pid; int thread_pid_valid; /* ts B00225 */ pthread_t thread_tid; /* transport functions */ int (*grab) (struct burn_drive *); int (*release) (struct burn_drive *); /* ts A61021 */ int (*drive_is_open) (struct burn_drive *); int (*issue_command) (struct burn_drive *, struct command *); /* lower level functions */ void (*erase) (struct burn_drive *, int); void (*getcaps) (struct burn_drive *); /* ts A61021 */ void (*read_atip) (struct burn_drive *); int (*write) (struct burn_drive *, int, struct buffer *); void (*read_toc) (struct burn_drive *); void (*lock) (struct burn_drive *); void (*unlock) (struct burn_drive *); void (*eject) (struct burn_drive *); void (*load) (struct burn_drive *); int (*start_unit) (struct burn_drive *); /* ts A90824 : Calming down noisy drives */ int (*stop_unit) (struct burn_drive *); int is_stopped; void (*read_disc_info) (struct burn_drive *); int (*read_cd) (struct burn_drive *, int start, int len, int sec_type, int main_ch, const struct burn_read_opts *, struct buffer *, int flag); void (*perform_opc) (struct burn_drive *); void (*set_speed) (struct burn_drive *, int, int); void (*send_parameters) (struct burn_drive *, const struct burn_read_opts *); void (*send_write_parameters) (struct burn_drive *, struct burn_session *, int tno, const struct burn_write_opts *); int (*send_cue_sheet) (struct burn_drive *, struct cue_sheet *); /* ts A70205 : Announce size of a DVD-R[W] DAO session. */ int (*reserve_track) (struct burn_drive *d, off_t size); void (*sync_cache) (struct burn_drive *); int (*get_erase_progress) (struct burn_drive *); int (*get_nwa) (struct burn_drive *, int trackno, int *lba, int *nwa); /* ts A70131 : obtain (possibly fake) TOC number and start lba of first track in last complete session */ int (*read_multi_session_c1)(struct burn_drive *d, int *trackno, int *start); /* ts A61009 : removed d in favor of o->drive */ /* void (*close_disc) (struct burn_drive * d, struct burn_write_opts * o); void (*close_session) (struct burn_drive * d, struct burn_write_opts * o); */ void (*close_disc) (struct burn_write_opts * o); void (*close_session) ( struct burn_write_opts * o); /* ts A61029 */ void (*close_track_session) ( struct burn_drive *d, int session, int track); int (*test_unit_ready) (struct burn_drive * d); void (*probe_write_modes) (struct burn_drive * d); struct params params; struct burn_scsi_inquiry_data *idata; struct scsi_mode_data *mdata; int toc_entries; struct burn_toc_entry *toc_entry; /* ts A61023 : get size and free space of drive buffer */ int (*read_buffer_capacity) (struct burn_drive *d); /* ts A61220 : format media (e.g. DVD+RW) */ int (*format_unit) (struct burn_drive *d, off_t size, int flag); /* ts A70108 */ /* mmc5r03c.pdf 6.24 : get list of available formats */ int (*read_format_capacities) (struct burn_drive *d, int top_wanted); /* ts A70812 */ /* mmc5r03c.pdf 6.15 : read data sectors (start and amount in LBA) */ int (*read_10) (struct burn_drive *d, int start, int amount, struct buffer *buf); }; /* end of generic 'drive' data structures */ /* ts A80422 : centralizing this setting for debugging purposes */ int burn_drive_set_media_capacity_remaining(struct burn_drive *d, off_t value); #endif /* __TRANSPORT */ ������������������������������������������������������������������������������������������������������������libburn-1.4.2/libburn/libdax_audioxtr.h�������������������������������������������������������������0000644�0001757�0001751�00000017056�12652644224�015114� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ /* libdax_audioxtr Audio track data extraction facility of libdax and libburn. Copyright (C) 2006 Thomas Schmitt <scdbackup@gmx.net>, provided under GPLv2+ */ #ifndef LIBDAX_AUDIOXTR_H_INCLUDED #define LIBDAX_AUDIOXTR_H_INCLUDED 1 /* Normally this public API is defined in <libburn/libburn.h> Macro LIBDAX_AUDIOXTR_H_PUBLIC enables the definition for programs which only include this file. */ #ifdef LIBDAX_AUDIOXTR_H_PUBLIC /* Public Macros */ /* Maximum size for address paths and fmt_info strings */ #define LIBDAX_AUDIOXTR_STRLEN 4096 /* Public Opaque Handles */ /** Extractor object encapsulating intermediate states of extraction. The clients of libdax_audioxtr shall only allocate pointers to this struct and get a storage object via libdax_audioxtr_new(). Appropriate initial value for the pointer is NULL. */ struct libdax_audioxtr; /* Public Functions */ /* Calls initiated from inside libdax/libburn */ /* Calls from applications (to be forwarded by libdax/libburn) */ /** Open an audio file, check wether suitable, create extractor object. @param xtr Opaque handle to extractor. Gets attached extractor object. @param path Address of the audio file to extract. "-" is stdin (but might be not suitable for all futurely supported formats). @param flag Bitfield for control purposes (unused yet, submit 0) @return >0 success 0 unsuitable format -1 severe error -2 path not found */ int libdax_audioxtr_new(struct libdax_audioxtr **xtr, char *path, int flag); /** Obtain identification parameters of opened audio source. @param xtr Opaque handle to extractor @param fmt Gets pointed to the audio file format id text: ".wav" , ".au" @param fmt_info Gets pointed to a format info text telling parameters @param num_channels e.g. 1=mono, 2=stereo, etc @param sample_rate e.g. 11025, 44100 @param bits_per_sample e.g. 8= 8 bits per sample, 16= 16 bits ... @param msb_first Byte order of samples: 0=Intel 1=Motorola @param flag Bitfield for control purposes (unused yet, submit 0) @return >0 success, <=0 failure */ int libdax_audioxtr_get_id(struct libdax_audioxtr *xtr, char **fmt, char **fmt_info, int *num_channels, int *sample_rate, int *bits_per_sample, int *msb_first, int flag); /** Obtain a prediction about the extracted size based on internal information of the formatted file. @param xtr Opaque handle to extractor @param size Gets filled with the predicted size @param flag Bitfield for control purposes (unused yet, submit 0) @return 1 prediction was possible , 0 no prediction could be made */ int libdax_audioxtr_get_size(struct libdax_audioxtr *o, off_t *size, int flag); /** Obtain next buffer full of extracted data in desired format (only raw audio for now). @param xtr Opaque handle to extractor @param buffer Gets filled with extracted data @param buffer_size Maximum number of bytes to be filled into buffer @param flag Bitfield for control purposes bit0= do not stop at predicted end of data @return >0 number of valid buffer bytes, 0 End of file -1 operating system reports error -2 usage error by application */ int libdax_audioxtr_read(struct libdax_audioxtr *xtr, char buffer[], int buffer_size, int flag); /** Try to obtain a file descriptor which will deliver extracted data to normal calls of read(2). This may fail because the format is unsuitable for that, but ".wav" is ok. If this call succeeds the xtr object will have forgotten its file descriptor and libdax_audioxtr_read() will return a usage error. One may use *fd after libdax_audioxtr_destroy() and will have to close it via close(2) when done with it. @param xtr Opaque handle to extractor @param fd Eventually returns the file descriptor number @param flag Bitfield for control purposes bit0= do not dup(2) and close(2) but hand out original fd @return 1 success, 0 cannot hand out fd , -1 severe error */ int libdax_audioxtr_detach_fd(struct libdax_audioxtr *o, int *fd, int flag); /** Clean up after extraction and destroy extractor object. @param xtr Opaque handle to extractor, *xtr is allowed to be NULL, *xtr is set to NULL by this function @param flag Bitfield for control purposes (unused yet, submit 0) @return 1 = destroyed object, 0 = was already destroyed */ int libdax_audioxtr_destroy(struct libdax_audioxtr **xtr, int flag); #endif /* LIBDAX_AUDIOXTR_H_PUBLIC */ #ifdef LIBDAX_AUDIOXTR________________ -- place documentation text here --- #endif /* LIBDAX_AUDIOXTR_________________ */ /* *Never* set this macro outside libdax_audioxtr.c ! The entrails of this facility are not to be seen by the other library components or the applications. */ #ifdef LIBDAX_AUDIOXTR_H_INTERNAL /* Internal Structures */ /** Extractor object encapsulating intermediate states of extraction */ struct libdax_audioxtr { /* Source of the encoded audio data */ char path[LIBDAX_AUDIOXTR_STRLEN]; /* File descriptor to path. Anything else than 0 must be lseek-able */ int fd; /* Format identifier. E.g. ".wav" */ char fmt[80]; /* Format parameter info text */ char fmt_info[LIBDAX_AUDIOXTR_STRLEN]; /* 1= mono, 2= stereo, etc. */ int num_channels; /* 8000, 44100, etc. */ int sample_rate; /* 8 bits = 8, 16 bits = 16, etc. */ int bits_per_sample; /* Byte order of samples: 0=Intel 1=Motorola */ int msb_first; /* Number of bytes to extract (0= unknown/unlimited) */ off_t data_size; /* Number of extracted data bytes */ off_t extract_count; /* Format dependent parameters */ /* MS WAVE Format */ /* info used: http://ccrma.stanford.edu/courses/422/projects/WaveFormat/ */ /* == NumSamples * NumChannels * BitsPerSample/8 This is the number of bytes in the data. */ unsigned wav_subchunk2_size; /* Sun Audio, .au */ /* info used: http://www.opengroup.org/public/pubs/external/auformat.html */ /* Number of bytes in non-payload header part */ unsigned au_data_location; /* Number of payload bytes or 0xffffffff */ unsigned au_data_size; }; /* Internal Functions */ /** Open the audio source pointed to by .path and evaluate suitability. @return -1 failure to open, 0 unsuitable format, 1 success */ static int libdax_audioxtr_open(struct libdax_audioxtr *o, int flag); /** Identify format and evaluate suitability. @return 0 unsuitable format, 1 format is suitable */ static int libdax_audioxtr_identify(struct libdax_audioxtr *o, int flag); /** Specialized identifier for .wav */ static int libdax_audioxtr_identify_wav(struct libdax_audioxtr *o, int flag); /** Specialized identifier for .au */ static int libdax_audioxtr_identify_au(struct libdax_audioxtr *o, int flag); /** Convert a byte string into a number (currently only little endian) @param flag Bitfield for control purposes bit0=msb_first @return The resulting number */ static unsigned libdax_audioxtr_to_int(struct libdax_audioxtr *o, unsigned char *bytes, int len, int flag); /** Prepare for reading of first buffer. @return 0 error, 1 success */ static int libdax_audioxtr_init_reading(struct libdax_audioxtr *o, int flag); #endif /* LIBDAX_AUDIOXTR_H_INTERNAL */ #endif /* ! LIBDAX_AUDIOXTR_H_INCLUDED */ ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������libburn-1.4.2/libburn/source.h����������������������������������������������������������������������0000644�0001757�0001751�00000000453�12652644224�013223� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */ #ifndef __SOURCE #define __SOURCE struct burn_source *burn_source_new(void); int burn_source_cancel(struct burn_source *src); int burn_source_read(struct burn_source *src, unsigned char *buffer, int size); #endif /*__SOURCE*/ ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������libburn-1.4.2/libburn/source.c����������������������������������������������������������������������0000644�0001757�0001751�00000002602�12652644224�013214� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */ /* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens Copyright (c) 2006 - 2010 Thomas Schmitt <scdbackup@gmx.net> Provided under GPL version 2 or later. */ #ifdef HAVE_CONFIG_H #include "../config.h" #endif #include <stdlib.h> #include <string.h> #include "libburn.h" #include "source.h" #include "structure.h" #include "init.h" void burn_source_free(struct burn_source *src) { if (--src->refcount < 1) { if (src->free_data) src->free_data(src); free(src); } } enum burn_source_status burn_track_set_source(struct burn_track *t, struct burn_source *s) { s->refcount++; t->source = s; /* ts A61031 */ t->open_ended = (s->get_size(s) <= 0); return BURN_SOURCE_OK; } struct burn_source *burn_source_new(void) { struct burn_source *out; /* ts A70825 , B11219 */ out = burn_alloc_mem(sizeof(struct burn_source), 1, 0); if (out == NULL) return NULL; out->refcount = 1; return out; } /* ts A71223 */ int burn_source_cancel(struct burn_source *src) { if(src->read == NULL) if(src->version > 0) if(src->cancel != NULL) src->cancel(src); return 1; } /* ts B00922 */ int burn_source_read(struct burn_source *src, unsigned char *buffer, int size) { int ret; if (src->read != NULL) ret = src->read(src, buffer, size); else ret = src->read_xt(src, buffer, size); return ret; } ������������������������������������������������������������������������������������������������������������������������������libburn-1.4.2/libburn/crc.h�������������������������������������������������������������������������0000644�0001757�0001751�00000001716�12652644224�012475� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */ /* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens Copyright (c) 2012 Thomas Schmitt <scdbackup@gmx.net> Provided under GPL version 2 or later. */ #ifndef BURN__CRC_H #define BURN__CRC_H #ifdef Xorriso_standalonE /* Source module crc.c of yet unclear ancestry is excluded from GNU xorriso */ /* ts B20219 : The functions have been re-implemented from scratch after studying texts about CRC computation and understanding the meaning of the underlying ECMA-130 specs. Nevertheless, there is no need to include them into xorriso because it does neither CD-TEXT nor raw CD writing. */ #ifndef Libburn_no_crc_C #define Libburn_no_crc_C 1 #endif #endif #ifndef Libburn_no_crc_C unsigned short crc_ccitt(unsigned char *, int len); unsigned int crc_32(unsigned char *, int len); #endif /* Libburn_no_crc_C */ #endif /* BURN__CRC_H */ ��������������������������������������������������libburn-1.4.2/libburn/sector.c����������������������������������������������������������������������0000644�0001757�0001751�00000054525�12652644224�013226� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */ /* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens Copyright (c) 2006 - 2015 Thomas Schmitt <scdbackup@gmx.net> Provided under GPL version 2 or later. */ #ifdef HAVE_CONFIG_H #include "../config.h" #endif #include <stdio.h> /* ts A61010 */ /* #include <a ssert.h> */ #include <unistd.h> #include <string.h> #include "error.h" #include "options.h" #include "transport.h" #include "libburn.h" #include "drive.h" #include "sector.h" #include "crc.h" #include "debug.h" #include "toc.h" #include "write.h" #include "libdax_msgs.h" extern struct libdax_msgs *libdax_messenger; #include "ecma130ab.h" #ifdef Libburn_log_in_and_out_streaM /* ts A61031 */ #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #endif /* Libburn_log_in_and_out_streaM */ /* ts B41126 : O_BINARY is needed for Cygwin but undefined elsewhere */ #ifndef O_BINARY #define O_BINARY 0 #endif /*static unsigned char isrc[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";*/ #define sector_common(X) d->alba++; d->rlba X; static void uncook_subs(unsigned char *dest, unsigned char *source) { int i, j, code; memset(dest, 0, 96); for (i = 0; i < 12; i++) { for (j = 0; j < 8; j++) { for (code = 0; code < 8; code++) { if (source[code * 12 + i] & 0x80) dest[j + i * 8] |= (1 << (7 - code)); source[code * 12 + i] <<= 1; } } } } /* @return >=0 : valid , <0 invalid */ int sector_get_outmode(enum burn_write_types write_type, enum burn_block_types block_type) { /* ts A61103 : extended SAO condition to TAO */ if (write_type == BURN_WRITE_SAO || write_type == BURN_WRITE_TAO) return 0; else switch (block_type) { case BURN_BLOCK_RAW0: return BURN_MODE_RAW; case BURN_BLOCK_RAW16: return BURN_MODE_RAW | BURN_SUBCODE_P16; case BURN_BLOCK_RAW96P: return BURN_MODE_RAW | BURN_SUBCODE_P96; case BURN_BLOCK_RAW96R: return BURN_MODE_RAW | BURN_SUBCODE_R96; case BURN_BLOCK_MODE1: return BURN_MODE1; default: return -1; } /* ts A61007 : now handled in burn_write_opts_set_write_type() */ /* a ssert(0); */ /* return BURN_MODE_UNIMPLEMENTED :) */ } /* 0 means "same as inmode" */ static int get_outmode(struct burn_write_opts *o) { /* ts A61007 */ return sector_get_outmode(o->write_type, o->block_type); /* -1 is prevented by check in burn_write_opts_set_write_type() */ /* a ssert(0); */ /* return BURN_MODE_UNIMPLEMENTED :) */ } static void get_bytes(struct burn_track *track, int count, unsigned char *data) { int valid, shortage, curr, i, tr; #ifdef Libburn_log_in_and_out_streaM /* ts A61031 */ static int tee_fd= -1; if(tee_fd==-1) tee_fd= open("/tmp/libburn_sg_readin", O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, S_IRUSR | S_IWUSR); #endif /* Libburn_log_in_and_out_streaM */ /* no track pointer means we're just generating 0s */ if (!track) { memset(data, 0, count); return; } /* first we use up any offset */ valid = track->offset - track->offsetcount; if (valid > count) valid = count; if (valid) { track->offsetcount += valid; memset(data, 0, valid); } shortage = count - valid; if (!shortage) goto ex; /* Next we use source data */ curr = valid; if (!track->eos) { if (track->source->read != NULL) valid = track->source->read(track->source, data + curr, count - curr); else valid = track->source->read_xt(track->source, data + curr, count - curr); } else valid = 0; if (valid <= 0) { /* ts A61031 : extended from (valid == -1) */ track->eos = 1; valid = 0; } track->sourcecount += valid; #ifdef Libburn_log_in_and_out_streaM /* ts A61031 */ if(tee_fd!=-1 && valid>0) { write(tee_fd, data + curr, valid); } #endif /* Libburn_log_in_and_out_streaM */ curr += valid; shortage = count - curr; if (!shortage) goto ex; /* Before going to the next track, we run through any tail */ valid = track->tail - track->tailcount; if (valid > count - curr) valid = count - curr; if (valid) { track->tailcount += valid; memset(data + curr, 0, valid); } curr += valid; shortage -= valid; if (!shortage) goto ex; /* ts A61031 - B10103 */ if (shortage >= count) track->track_data_done = 1; if (track->end_on_premature_eoi && shortage >= count && !track->open_ended) { char msg[80]; off_t missing, inp_block_size, track_blocks; inp_block_size = burn_sector_length(track->mode); track_blocks = burn_track_get_sectors_2(track, 1); missing = track_blocks * inp_block_size - track->sourcecount; sprintf(msg, "Premature end of input encountered. Missing: %.f bytes", (double) missing); libdax_msgs_submit(libdax_messenger, -1, 0x00020180, LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH, msg, 0,0); /* Memorize that premature end of input happened */ track->end_on_premature_eoi = 2; } if (track->open_ended || track->end_on_premature_eoi) goto ex; /* If we're still short, and there's a "next" pointer, we pull from that. if that depletes, we'll just fill with 0s. */ if (track->source->next) { struct burn_source *src; printf("pulling from next track\n"); src = track->source->next; valid = src->read(src, data + curr, shortage); if (valid > 0) { shortage -= valid; curr += valid; } } ex:; /* ts A61024 : general finalizing processing */ if(shortage) memset(data + curr, 0, shortage); /* this is old icculus.org */ if (track->swap_source_bytes == 1) { for (i = 1; i < count; i += 2) { tr = data[i]; data[i] = data[i-1]; data[i-1] = tr; } } } /* ts B20113 : outsourced from get_sector() */ int sector_write_buffer(struct burn_drive *d, struct burn_track *track, int flag) { int err, i; struct buffer *out; out = d->buffer; if (out->sectors <= 0) return 2; err = d->write(d, d->nwa, out); if (err == BE_CANCELLED) return 0; /* ts A61101 */ if(track != NULL) { track->writecount += out->bytes; track->written_sectors += out->sectors; /* Determine current index */ for (i = d->progress.index; i + 1 < track->indices; i++) { if (track->index[i + 1] > d->nwa + out->sectors) break; d->progress.index = i + 1; } } /* ts A61119 */ d->progress.buffered_bytes += out->bytes; d->nwa += out->sectors; out->bytes = 0; out->sectors = 0; return 1; } /* ts A61009 : seems to hand out sector start pointer in opts->drive->buffer and to count hand outs as well as reserved bytes */ /* ts A61101 : added parameter track for counting written bytes */ static unsigned char *get_sector(struct burn_write_opts *opts, struct burn_track *track, int inmode) { struct burn_drive *d = opts->drive; struct buffer *out = d->buffer; int outmode, seclen, write_ret; unsigned char *ret; outmode = get_outmode(opts); if (outmode == 0) outmode = inmode; /* ts A61009 : react on eventual failure of burn_sector_length() (should not happen if API tested properly). Ensures out->bytes >= out->sectors */ seclen = burn_sector_length(outmode); if (seclen <= 0) return NULL; seclen += burn_subcode_length(outmode); /* ts A61219 : opts->obs is eventually a 32k trigger for DVD */ /* (there is enough buffer size reserve for track->cdxa_conversion) */ if (out->bytes + seclen > BUFFER_SIZE || (opts->obs > 0 && out->bytes + seclen > opts->obs)) { write_ret = sector_write_buffer(d, track, 0); if (write_ret <= 0) return NULL; } ret = out->data + out->bytes; out->bytes += seclen; out->sectors++; return ret; } /* ts A61031 */ /* Revoke the counting of the most recent sector handed out by get_sector() */ static void unget_sector(struct burn_write_opts *opts, int inmode) { struct burn_drive *d = opts->drive; struct buffer *out = d->buffer; int outmode; int seclen; outmode = get_outmode(opts); if (outmode == 0) outmode = inmode; /* ts A61009 : react on eventual failure of burn_sector_length() (should not happen if API tested properly). Ensures out->bytes >= out->sectors */ seclen = burn_sector_length(outmode); if (seclen <= 0) return; seclen += burn_subcode_length(outmode); out->bytes -= seclen; out->sectors--; } /* either inmode == outmode, or outmode == raw. anything else is bad news */ /* ts A61010 : changed type to int in order to propagate said bad news */ /** @return 1 is ok, <= 0 is failure */ static int convert_data(struct burn_write_opts *o, struct burn_track *track, int inmode, unsigned char *data) { int outlen, inlen; int offset = -1; int outmode; outmode = get_outmode(o); if (outmode == 0) outmode = inmode; outlen = burn_sector_length(outmode); inlen = burn_sector_length(inmode); /* ts A61010 */ /* a ssert(outlen >= inlen); */ if (outlen < inlen || outlen < 0 || inlen < 0) return 0; if ((outmode & BURN_MODE_BITS) == (inmode & BURN_MODE_BITS)) { /* see MMC-5 4.2.3.8.5.3 Block Format for Mode 2 form 1 Data Table 24 Mode 2 Formed Sector Sub-header Format */ if (track != NULL) if (track->cdxa_conversion == 1) inlen += 8; get_bytes(track, inlen, data); if (track != NULL) if (track->cdxa_conversion == 1) memmove(data, data + 8, inlen - 8); return 1; } /* ts A61010 */ /* a ssert(outmode & BURN_MODE_RAW); */ if (!(outmode & BURN_MODE_RAW)) return 0; if (inmode & BURN_MODE1) offset = 16; if (inmode & BURN_MODE_RAW) offset = 0; if (inmode & BURN_AUDIO) offset = 0; /* ts A61010 */ /* a ssert(offset != -1); */ if (offset == -1) return 0; get_bytes(track, inlen, data + offset); return 1; } static void convert_subs(struct burn_write_opts *o, int inmode, unsigned char *subs, unsigned char *sector) { unsigned char *out; int outmode; outmode = get_outmode(o); if (outmode == 0) outmode = inmode; sector += burn_sector_length(outmode); /* XXX for sao with subs, we'd need something else... */ switch (o->block_type) { case BURN_BLOCK_RAW96R: uncook_subs(sector, subs); break; case BURN_BLOCK_RAW16: memcpy(sector, subs + 12, 12); out = sector + 12; out[0] = 0; out[1] = 0; out[2] = 0; /*XXX find a better way to deal with partially damaged P channels*/ if (subs[2] != 0) out[3] = 0x80; else out[3] = 0; out = sector + 10; out[0] = ~out[0]; out[1] = ~out[1]; break; /* ts A61119 : to silence compiler warnings */ default:; } } static void subcode_toc(struct burn_drive *d, int mode, unsigned char *data) { unsigned char *q; int track; int crc; int min, sec, frame; track = d->toc_temp / 3; memset(data, 0, 96); q = data + 12; burn_lba_to_msf(d->rlba, &min, &sec, &frame); /*XXX track numbers are BCD a0 - 1st track ctrl a1 - last track ctrl a2 - lout ctrl */ q[0] = (d->toc_entry[track].control << 4) + 1; q[1] = 0; if (d->toc_entry[track].point < 100) q[2] = dec_to_bcd(d->toc_entry[track].point); else q[2] = d->toc_entry[track].point; q[3] = dec_to_bcd(min); q[4] = dec_to_bcd(sec); q[5] = dec_to_bcd(frame); q[6] = 0; q[7] = dec_to_bcd(d->toc_entry[track].pmin); q[8] = dec_to_bcd(d->toc_entry[track].psec); q[9] = dec_to_bcd(d->toc_entry[track].pframe); #ifdef Libburn_no_crc_C crc = 0; /* dummy */ #else crc = crc_ccitt(q, 10); #endif q[10] = crc >> 8; q[11] = crc & 0xFF; d->toc_temp++; d->toc_temp %= (d->toc_entries * 3); } int sector_toc(struct burn_write_opts *o, int mode) { struct burn_drive *d = o->drive; unsigned char *data; unsigned char subs[96]; data = get_sector(o, NULL, mode); if (data == NULL) return 0; /* ts A61010 */ if (convert_data(o, NULL, mode, data) <= 0) return 0; subcode_toc(d, mode, subs); convert_subs(o, mode, subs, data); if (sector_headers(o, data, mode, 1) <= 0) return 0; sector_common(++) return 1; } int sector_pregap(struct burn_write_opts *o, unsigned char tno, unsigned char control, int mode) { struct burn_drive *d = o->drive; unsigned char *data; unsigned char subs[96]; data = get_sector(o, NULL, mode); if (data == NULL) return 0; /* ts A61010 */ if (convert_data(o, NULL, mode, data) <= 0) return 0; subcode_user(o, subs, tno, control, 0, NULL, 1); convert_subs(o, mode, subs, data); if (sector_headers(o, data, mode, 0) <= 0) return 0; sector_common(--) return 1; } int sector_postgap(struct burn_write_opts *o, unsigned char tno, unsigned char control, int mode) { struct burn_drive *d = o->drive; unsigned char subs[96]; unsigned char *data; data = get_sector(o, NULL, mode); if (data == NULL) return 0; /* ts A61010 */ if (convert_data(o, NULL, mode, data) <= 0) return 0; /* use last index in track */ subcode_user(o, subs, tno, control, 1, NULL, 1); convert_subs(o, mode, subs, data); if (sector_headers(o, data, mode, 0) <= 0) return 0; sector_common(++) return 1; } static void subcode_lout(struct burn_write_opts *o, unsigned char control, unsigned char *data) { struct burn_drive *d = o->drive; unsigned char *q; int crc; int rmin, min, rsec, sec, rframe, frame; memset(data, 0, 96); q = data + 12; burn_lba_to_msf(d->alba, &min, &sec, &frame); burn_lba_to_msf(d->rlba, &rmin, &rsec, &rframe); if (((rmin == 0) && (rsec == 0) && (rframe == 0)) || ((rsec >= 2) && !((rframe / 19) % 2))) memset(data, 0xFF, 12); q[0] = (control << 4) + 1; q[1] = 0xAA; q[2] = 0x01; q[3] = dec_to_bcd(rmin); q[4] = dec_to_bcd(rsec); q[5] = dec_to_bcd(rframe); q[6] = 0; q[7] = dec_to_bcd(min); q[8] = dec_to_bcd(sec); q[9] = dec_to_bcd(frame); #ifdef Libburn_no_crc_C crc = 0; /* dummy */ #else crc = crc_ccitt(q, 10); #endif q[10] = crc >> 8; q[11] = crc & 0xFF; } static char char_to_isrc(char c) { if (c >= '0' && c <= '9') return c - '0'; if (c >= 'A' && c <= 'Z') return 0x11 + (c - 'A'); if (c >= 'a' && c <= 'z') return 0x11 + (c - 'a'); /* ts A61008 : obsoleted by test in burn_track_set_isrc() */ /* a ssert(0); */ return 0; } void subcode_user(struct burn_write_opts *o, unsigned char *subcodes, unsigned char tno, unsigned char control, unsigned char indx, struct isrc *isrc, int psub) { struct burn_drive *d = o->drive; unsigned char *p, *q; int crc; int m, s, f, c, qmode; /* 1, 2 or 3 */ memset(subcodes, 0, 96); p = subcodes; if ((tno == 1) && (d->rlba == -150)) memset(p, 0xFF, 12); if (psub) memset(p, 0xFF, 12); q = subcodes + 12; qmode = 1; /* every 1 in 10 we can do something different */ if (d->rlba % 10 == 0) { /* each of these can occur 1 in 100 */ if ((d->rlba / 10) % 10 == 0) { if (o->has_mediacatalog) qmode = 2; } else if ((d->rlba / 10) % 10 == 1) { if (isrc && isrc->has_isrc) qmode = 3; } } /* ts A61010 : this cannot happen. Assert for fun ? */ /* a ssert(qmode == 1 || qmode == 2 || qmode == 3); */ switch (qmode) { case 1: q[1] = dec_to_bcd(tno); /* track number */ q[2] = dec_to_bcd(indx); /* index XXX read this shit from the track array */ burn_lba_to_msf(d->rlba, &m, &s, &f); q[3] = dec_to_bcd(m); /* rel min */ q[4] = dec_to_bcd(s); /* rel sec */ q[5] = dec_to_bcd(f); /* rel frame */ q[6] = 0; /* zero */ burn_lba_to_msf(d->alba, &m, &s, &f); q[7] = dec_to_bcd(m); /* abs min */ q[8] = dec_to_bcd(s); /* abs sec */ q[9] = dec_to_bcd(f); /* abs frame */ break; case 2: /* media catalog number */ q[1] = (o->mediacatalog[0] << 4) + o->mediacatalog[1]; q[2] = (o->mediacatalog[2] << 4) + o->mediacatalog[3]; q[3] = (o->mediacatalog[4] << 4) + o->mediacatalog[5]; q[4] = (o->mediacatalog[6] << 4) + o->mediacatalog[7]; q[5] = (o->mediacatalog[8] << 4) + o->mediacatalog[9]; q[6] = (o->mediacatalog[10] << 4) + o->mediacatalog[11]; q[7] = o->mediacatalog[12] << 4; q[8] = 0; burn_lba_to_msf(d->alba, &m, &s, &f); q[9] = dec_to_bcd(f); /* abs frame */ break; case 3: c = char_to_isrc(isrc->country[0]); /* top 6 bits of [1] is the first country code */ q[1] = c << 2; c = char_to_isrc(isrc->country[1]); /* bottom 2 bits of [1] is part of the second country code */ q[1] += (c >> 4); /* top 4 bits if [2] is the rest of the second country code */ q[2] = c << 4; c = char_to_isrc(isrc->owner[0]); /* bottom 4 bits of [2] is part of the first owner code */ q[2] += (c >> 2); /* top 2 bits of [3] is the rest of the first owner code */ q[3] = c << 6; c = char_to_isrc(isrc->owner[1]); /* bottom 6 bits of [3] is the entire second owner code */ q[3] += c; c = char_to_isrc(isrc->owner[2]); /* top 6 bits of [4] are the third owner code */ q[4] = c << 2; /* [5] is the year in 2 BCD numbers */ q[5] = dec_to_bcd(isrc->year % 100); /* [6] is the first 2 digits in the serial */ q[6] = dec_to_bcd(isrc->serial % 100); /* [7] is the next 2 digits in the serial */ q[7] = dec_to_bcd((isrc->serial / 100) % 100); /* the top 4 bits of [8] is the last serial digit, the rest is zeros */ q[8] = dec_to_bcd((isrc->serial / 10000) % 10) << 4; burn_lba_to_msf(d->alba, &m, &s, &f); q[9] = dec_to_bcd(f); /* abs frame */ break; } q[0] = (control << 4) + qmode; #ifdef Libburn_no_crc_C crc = 0; /* dummy */ #else crc = crc_ccitt(q, 10); #endif q[10] = crc >> 8; q[11] = crc & 0xff; } int sector_lout(struct burn_write_opts *o, unsigned char control, int mode) { struct burn_drive *d = o->drive; unsigned char subs[96]; unsigned char *data; data = get_sector(o, NULL, mode); if (!data) return 0; /* ts A61010 */ if (convert_data(o, NULL, mode, data) <= 0) return 0; subcode_lout(o, control, subs); convert_subs(o, mode, subs, data); if (sector_headers(o, data, mode, 0) <= 0) return 0; sector_common(++) return 1; } int sector_data(struct burn_write_opts *o, struct burn_track *t, int psub) { struct burn_drive *d = o->drive; unsigned char subs[96]; unsigned char *data; data = get_sector(o, t, t->mode); if (data == NULL) return 0; /* ts A61010 */ if (convert_data(o, t, t->mode, data) <= 0) return 0; /* ts A61031 */ if ((t->open_ended || t->end_on_premature_eoi) && t->track_data_done) { unget_sector(o, t->mode); return 2; } /* ts A61219 : allow track without .entry */ if (t->entry == NULL) ; else if (!t->source->read_sub) subcode_user(o, subs, t->entry->point, t->entry->control, 1, &t->isrc, psub); else if (!t->source->read_sub(t->source, subs, 96)) subcode_user(o, subs, t->entry->point, t->entry->control, 1, &t->isrc, psub); convert_subs(o, t->mode, subs, data); if (sector_headers(o, data, t->mode, 0) <= 0) return 0; sector_common(++) return 1; } int burn_msf_to_lba(int m, int s, int f) { if (m < 90) return (m * 60 + s) * 75 + f - 150; else return (m * 60 + s) * 75 + f - 450150; } void burn_lba_to_msf(int lba, int *m, int *s, int *f) { if (lba >= -150) { *m = (lba + 150) / (60 * 75); *s = (lba + 150 - *m * 60 * 75) / 75; *f = lba + 150 - *m * 60 * 75 - *s * 75; } else { *m = (lba + 450150) / (60 * 75); *s = (lba + 450150 - *m * 60 * 75) / 75; *f = lba + 450150 - *m * 60 * 75 - *s * 75; } } int dec_to_bcd(int d) { int top, bottom; top = d / 10; bottom = d - (top * 10); return (top << 4) + bottom; } int sector_headers_is_ok(struct burn_write_opts *o, int mode) { if (mode & BURN_AUDIO) /* no headers for "audio" */ return 1; if (o->write_type == BURN_WRITE_SAO) return 1; /* ts A61031 */ if (o->write_type == BURN_WRITE_TAO) return 1; if (mode & BURN_MODE1) return 2; return 0; } /* ts A90830 : changed return type to int @return 0= failure 1= success */ int sector_headers(struct burn_write_opts *o, unsigned char *out, int mode, int leadin) { #ifdef Libburn_ecma130ab_includeD struct burn_drive *d = o->drive; unsigned int crc; int min, sec, frame; int modebyte = -1; int ret; ret = sector_headers_is_ok(o, mode); if (ret != 2) return !!ret; modebyte = 1; out[0] = 0; memset(out + 1, 0xFF, 10); /* sync */ out[11] = 0; if (leadin) { burn_lba_to_msf(d->rlba, &min, &sec, &frame); out[12] = dec_to_bcd(min) + 0xA0; out[13] = dec_to_bcd(sec); out[14] = dec_to_bcd(frame); out[15] = modebyte; } else { burn_lba_to_msf(d->alba, &min, &sec, &frame); out[12] = dec_to_bcd(min); out[13] = dec_to_bcd(sec); out[14] = dec_to_bcd(frame); out[15] = modebyte; } if (mode & BURN_MODE1) { #ifdef Libburn_no_crc_C crc = 0; /* dummy */ #else crc = crc_32(out, 2064); #endif out[2064] = crc & 0xFF; crc >>= 8; out[2065] = crc & 0xFF; crc >>= 8; out[2066] = crc & 0xFF; crc >>= 8; out[2067] = crc & 0xFF; } if (mode & BURN_MODE1) { memset(out + 2068, 0, 8); burn_rspc_parity_p(out); burn_rspc_parity_q(out); } burn_ecma130_scramble(out); return 1; #else /* Libburn_ecma130ab_includeD */ int ret; ret = sector_headers_is_ok(o, mode); if (ret != 2) return (!! ret); /* ts A90830 : lec.c is copied from cdrdao. I have no idea yet how lec.c implements the Reed-Solomon encoding which is described in ECMA-130 for CD-ROM. So this got removed for now. */ libdax_msgs_submit(libdax_messenger, o->drive->global_index, 0x0002010a, LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH, "Raw CD write modes are not supported", 0, 0); return 0; #endif /* ! Libburn_ecma130ab_includeD */ } #if 0 void process_q(struct burn_drive *d, unsigned char *q) { unsigned char i[5]; int mode; mode = q[0] & 0xF; /* burn_print(12, "mode: %d : ", mode);*/ switch (mode) { case 1: /* burn_print(12, "tno = %d : ", q[1]); burn_print(12, "index = %d\n", q[2]); */ /* q[1] is the track number (starting at 1) q[2] is the index number (starting at 0) */ #warning this is totally bogus if (q[1] - 1 > 99) break; if (q[2] > d->toc->track[q[1] - 1].indices) { burn_print(12, "new index at %d\n", d->alba); d->toc->track[q[1] - 1].index[q[2]] = d->alba; d->toc->track[q[1] - 1].indices++; } break; case 2: /* XXX dont ignore these */ break; case 3: /* burn_print(12, "ISRC data in mode 3 q\n");*/ i[0] = isrc[(q[1] << 2) >> 2]; /* burn_print(12, "0x%x 0x%x 0x%x 0x%x 0x%x\n", q[1], q[2], q[3], q[4], q[5]); burn_print(12, "ISRC - %c%c%c%c%c\n", i[0], i[1], i[2], i[3], i[4]); */ break; default: /* ts A61009 : if reactivated then witout Assert */ a ssert(0); } } #endif /* this needs more info. subs in the data? control/adr? */ /* ts A61119 : One should not use inofficial compiler extensions. >>> Some day this function needs to be implemented. At least for now the result does not match the "mode" of cdrecord -toc. */ /* #warning sector_identify needs to be written */ int sector_identify(unsigned char *data) { /* burn_ecma130_scramble(data); check mode byte for 1 or 2 test parity to see if it's a valid sector if invalid, return BURN_MODE_AUDIO; else return mode byte (what about mode 2 formless? heh) */ return BURN_MODE1; } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������libburn-1.4.2/libburn/sbc.h�������������������������������������������������������������������������0000644�0001757�0001751�00000001043�12652644224�012466� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */ /* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens Copyright (c) 2006 - 2010 Thomas Schmitt <scdbackup@gmx.net> Provided under GPL version 2 or later. */ #ifndef __SBC #define __SBC struct burn_drive; void sbc_load(struct burn_drive *); void sbc_eject(struct burn_drive *); /* ts A61118 */ int sbc_start_unit(struct burn_drive *); /* ts A61021 : the sbc specific part of sg.c:enumerate_common() */ int sbc_setup_drive(struct burn_drive *d); #endif /* __SBC */ ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������libburn-1.4.2/libburn/debug.h�����������������������������������������������������������������������0000644�0001757�0001751�00000000276�12652644224�013014� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */ #ifndef BURN__DEBUG_H #define BURN__DEBUG_H void burn_print(int level, const char *a, ...); #endif /* BURN__DEBUG_H */ ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������libburn-1.4.2/libburn/structure.h�������������������������������������������������������������������0000644�0001757�0001751�00000011431�12652644224�013761� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ /* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens Copyright (c) 2006 - 2011 Thomas Schmitt <scdbackup@gmx.net> Provided under GPL version 2 or later. */ #ifndef BURN__STRUCTURE_H #define BURN__STRUCTURE_H struct isrc { int has_isrc; char country[2]; /* each must be 0-9, A-Z */ char owner[3]; /* each must be 0-9, A-Z */ unsigned char year; /* must be 0-99 */ unsigned int serial; /* must be 0-99999 */ }; /* ts B11206 */ #define Libburn_pack_type_basE 0x80 #define Libburn_pack_num_typeS 0x10 #define Libburn_pack_type_nameS \ "TITLE", "PERFORMER", "SONGWRITER", "COMPOSER", \ "ARRANGER", "MESSAGE", "DISCID", "GENRE", \ "TOC", "TOC2", "", "", \ "", "CLOSED", "UPC_ISRC", "BLOCKSIZE" struct burn_cdtext { unsigned char *(payload[Libburn_pack_num_typeS]); int length[Libburn_pack_num_typeS]; int flags; /* bit0 - bit15= double byte characters */ }; struct burn_track { int refcnt; struct burn_toc_entry *entry; unsigned char indices; /* lba address of the index. CD only. 0x7fffffff means undefined index. To be programmed relative to track source start before burning, but to hold absolute addresses after burning or reading. */ int index[100]; /** number of 0 bytes to write before data */ int offset; /** how much offset has been used */ int offsetcount; /** Number of zeros to write after data */ int tail; /** how much tail has been used */ int tailcount; /** 1 means Pad with zeros, 0 means start reading the next track */ int pad; /* ts A70213 : wether to expand this track to full available media */ int fill_up_media; /* ts A70218 : a track size to use if it is mandarory to have some */ off_t default_size; /** Data source */ struct burn_source *source; /** End of Source flag */ int eos; /* ts A61101 */ off_t sourcecount; off_t writecount; off_t written_sectors; /* ts A61031 */ /** Source is of undefined length */ int open_ended; /** End of open ended track flag : offset+payload+tail are delivered */ int track_data_done; /* ts B10103 */ /** End track writing on premature End-of-input if source is of defined length. 0= normal operation in case of eoi 1= be ready to end track writing on eoi 2= eoi was encountered with previously set value of 1 */ int end_on_premature_eoi; /** The audio/data mode for the entry. Derived from control and possibly from reading the track's first sector. */ int mode; /** The track contains interval one of a pregap */ int pregap1; /** The track contains interval two of a pregap */ int pregap2; /* ts B20110 */ /** The number of sectors in pre-gap 2, if .pregap2 is set */ int pregap2_size; /** The track contains a postgap */ int postgap; /* ts B20111 */ /** The number of sectors in post-gap, if .postgap is set */ int postgap_size; struct isrc isrc; /* ts A61024 */ /** Byte swapping on source data stream : 0=none , 1=pairwise */ int swap_source_bytes; /* ts A90910 : conversions from CD XA prepared input */ int cdxa_conversion; /* 0=none, 1=remove -xa1 headers (first 8 bytes)*/ /* ts B11206 */ struct burn_cdtext *cdtext[8]; }; struct burn_session { unsigned char firsttrack; unsigned char lasttrack; int hidefirst; unsigned char start_m; unsigned char start_s; unsigned char start_f; struct burn_toc_entry *leadout_entry; int tracks; struct burn_track **track; int refcnt; /* ts B11206 */ struct burn_cdtext *cdtext[8]; unsigned char cdtext_char_code[8]; unsigned char cdtext_copyright[8]; unsigned char cdtext_language[8]; /* ts B11226 */ unsigned char mediacatalog[14]; /* overrideable by burn_write_opts */ }; struct burn_disc { int sessions; struct burn_session **session; #ifdef Libburn_disc_with_incomplete_sessioN int incomplete_sessions; #endif int refcnt; }; int burn_track_get_shortage(struct burn_track *t); /* ts A61031 : might go to libburn.h */ int burn_track_is_open_ended(struct burn_track *t); int burn_track_is_data_done(struct burn_track *t); /* ts A70125 : sets overall sectors of a track: offset+payload+padding */ int burn_track_set_sectors(struct burn_track *t, int sectors); /* ts A70218 : sets the payload size alone */ int burn_track_set_size(struct burn_track *t, off_t size); /* ts A70213 */ int burn_track_set_fillup(struct burn_track *t, int fill_up_media); int burn_track_apply_fillup(struct burn_track *t, off_t max_size, int flag); /* ts A70218 */ off_t burn_track_get_default_size(struct burn_track *t); /* ts A80808 : Enhance CD toc to DVD toc */ int burn_disc_cd_toc_extensions(struct burn_drive *drive, int flag); /* ts B11206 */ struct burn_cdtext *burn_cdtext_create(void); void burn_cdtext_free(struct burn_cdtext **cdtext); /* ts B20119 */ /* @param flag bit0= do not add post-gap */ int burn_track_get_sectors_2(struct burn_track *t, int flag); #endif /* BURN__STRUCTURE_H */ ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������libburn-1.4.2/libburn/sg.h��������������������������������������������������������������������������0000644�0001757�0001751�00000005200�12652644224�012327� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */ /* Copyright (C) 2009 Thomas Schmitt <scdbackup@gmx.net>, provided under GPLv2+ */ #ifndef __SG #define __SG #include "os.h" /* see os.h for name of particular os-*.h where this is defined */ BURN_OS_DEFINE_DRIVE_ENUMERATOR_T struct burn_drive; struct command; /* ts A60922 ticket 33 */ int sg_give_next_adr(burn_drive_enumerator_t *enm_context, char adr[], int adr_size, int initialize); int sg_is_enumerable_adr(char *adr); int sg_obtain_scsi_adr(char *path, int *bus_no, int *host_no, int *channel_no, int *target_no, int *lun_no); int sg_grab(struct burn_drive *); int sg_release(struct burn_drive *); int sg_issue_command(struct burn_drive *, struct command *); /* ts A61115 : formerly sg_enumerate();ata_enumerate() */ int scsi_enumerate_drives(void); int sg_drive_is_open(struct burn_drive * d); int burn_os_is_2k_seekrw(char *path, int flag); int burn_os_stdio_capacity(char *path, off_t write_start, off_t *bytes); /* ts A91227 */ /** Returns the id string of the SCSI transport adapter and eventually needed operating system facilities. This call is usable even if sg_initialize() was not called yet. In that case a preliminary constant message might be issued if detailed info is not available yet. @param msg returns id string @param flag unused yet, submit 0 @return 1 = success, <=0 = failure */ int sg_id_string(char msg[1024], int flag); /* ts A91225 */ /** Performs global initialization of the SCSI transport adapter and eventually needed operating system facilities. Checks for compatibility supporting software components. @param msg returns ids and/or error messages of eventual helpers @param flag unused yet, submit 0 @return 1 = success, <=0 = failure */ int sg_initialize(char msg[1024], int flag); /* ts A91227 */ /** Performs global finalization of the SCSI transport adapter and eventually needed operating system facilities. Releases globally aquired resources. @param flag unused yet, submit 0 @return 1 = success, <=0 = failure */ int sg_shutdown(int flag); /* ts A91227 */ /** Finalizes BURN_OS_TRANSPORT_DRIVE_ELEMENTS, the components of struct burn_drive which are defined in os-*.h. The eventual initialization of those components was made underneath scsi_enumerate_drives(). This will be called when a burn_drive gets disposed. @param d the drive to be finalized @param flag unused yet, submit 0 @return 1 = success, <=0 = failure */ int sg_dispose_drive(struct burn_drive *d, int flag); #endif /* __SG */ ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������libburn-1.4.2/libburn/spc.c�������������������������������������������������������������������������0000644�0001757�0001751�00000150145�12652644224�012507� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */ /* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens Copyright (c) 2006 - 2014 Thomas Schmitt <scdbackup@gmx.net> Provided under GPL version 2 or later. */ /* scsi primary commands */ #ifdef HAVE_CONFIG_H #include "../config.h" #endif #include <unistd.h> #include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <sys/ioctl.h> #include <string.h> /* ts A61008 */ /* #include <a ssert.h> */ #include <stdlib.h> #include "libburn.h" #include "transport.h" #include "spc.h" #include "mmc.h" #include "sbc.h" #include "drive.h" #include "debug.h" #include "options.h" #include "init.h" #include "util.h" #include "libdax_msgs.h" extern struct libdax_msgs *libdax_messenger; /* ts A91111 : whether to log SCSI commands: bit0= log in /tmp/libburn_sg_command_log bit1= log to stderr bit2= flush every line */ extern int burn_sg_log_scsi; /* spc command set */ /* ts A70519 : allocation length byte 3+4 was 0,255 */ static unsigned char SPC_INQUIRY[] = { 0x12, 0, 0, 0, 36, 0 }; /*static char SPC_TEST[]={0,0,0,0,0,0};*/ static unsigned char SPC_PREVENT[] = { 0x1e, 0, 0, 0, 1, 0 }; static unsigned char SPC_ALLOW[] = { 0x1e, 0, 0, 0, 0, 0 }; static unsigned char SPC_MODE_SENSE[] = { 0x5a, 0, 0, 0, 0, 0, 0, 16, 0, 0 }; static unsigned char SPC_MODE_SELECT[] = { 0x55, 16, 0, 0, 0, 0, 0, 0, 0, 0 }; static unsigned char SPC_REQUEST_SENSE[] = { 0x03, 0, 0, 0, 18, 0 }; static unsigned char SPC_TEST_UNIT_READY[] = { 0x00, 0, 0, 0, 0, 0 }; #ifdef Libburn_enable_scsi_cmd_ABh static unsigned char SPC_READ_MEDIA_SERIAL_NUMBER[] = { 0xAB, 0x01, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; #endif /* ts A70519 : An initializer for the abstract SCSI command structure */ int scsi_init_command(struct command *c, unsigned char *opcode, int oplen) { if (oplen > 16) return 0; memset(c, 0, sizeof(struct command)); memcpy(c->opcode, opcode, oplen); c->oplen = oplen; c->dir = NO_TRANSFER; c->dxfer_len = -1; memset(c->sense, 0, sizeof(c->sense)); c->error = 0; c->retry = 0; c->page = NULL; c->timeout = Libburn_scsi_default_timeouT; return 1; } /* ts B00728 */ int spc_decode_sense(unsigned char *sense, int senselen, int *key, int *asc, int *ascq) { *key = *asc = *ascq = 0; if ((sense[0] & 0x7f) == 0x72 || (sense[0] & 0x7f) == 0x73) { if (senselen <= 0 || senselen > 1) *key = sense[1] & 0x0f; if (senselen <= 0 || senselen > 2) *asc = sense[2]; if (senselen <= 0 || senselen > 3) *ascq = sense[3]; return 1; } if (senselen <= 0 || senselen > 2) *key = sense[2] & 0x0f; if (senselen <= 0 || senselen > 12) *asc = sense[12]; if (senselen <= 0 || senselen > 13) *ascq = sense[13]; return 1; } int spc_test_unit_ready_r(struct burn_drive *d, int *key, int *asc, int *ascq, int *progress) { struct command *c; c = &(d->casual_command); if (mmc_function_spy(d, "test_unit_ready") <= 0) return 0; scsi_init_command(c, SPC_TEST_UNIT_READY,sizeof(SPC_TEST_UNIT_READY)); c->retry = 0; c->dir = NO_TRANSFER; d->issue_command(d, c); *key = *asc = *ascq = 0; *progress = -1; if (c->error) { spc_decode_sense(c->sense, 0, key, asc, ascq); if (c->sense[0] == 0x70 && ((c->sense[2] & 0x0f) == 0 || (c->sense[2] & 0x0f) == 2) && (c->sense[15] & 0x80)) *progress = (c->sense[16] << 8) + c->sense[17]; return (*key == 0); } return 1; } int spc_test_unit_ready(struct burn_drive *d) { int key, asc, ascq, progress; return spc_test_unit_ready_r(d, &key, &asc, &ascq, &progress); } /* ts A70315 */ /** @param flag bit0=do not wait 0.1 seconds before first test unit ready bit1=do not issue success message */ /** Wait until the drive state becomes clear or until max_usec elapsed */ int spc_wait_unit_attention(struct burn_drive *d, int max_sec, char *cmd_text, int flag) { int i, ret = 1, key = 0, asc = 0, ascq = 0, clueless_start = 0; static double tests_per_second = 2.0; int sleep_usecs, loop_limit, clueless_timeout, progress; char *msg = NULL; unsigned char sense[14]; 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)) usleep(sleep_usecs); for(i = !(flag & 1); i < loop_limit; i++) { ret = spc_test_unit_ready_r(d, &key, &asc, &ascq, &progress); if (ret > 0) /* ready */ break; if (key!=0x2 || asc!=0x4) { if (key == 0x2 && asc == 0x3A) { ret = 1; /* medium not present = ok */ /* <<< ts A70912 : My LG GSA-4082B on asynchronous load: first it reports no media 2,3A,00, then it reports not ready 2,04,00, further media inquiry retrieves wrong data if(i<=100) goto slumber; */ break; } if (key == 0x6 && asc == 0x28 && ascq == 0x00) /* media change notice = try again */ goto slumber; handle_error:; /* ts A90213 */ sprintf(msg, "Asynchronous SCSI error on %s: ", cmd_text); sense[0] = 0x70; /* Fixed format sense data */ sense[2] = key; sense[12] = asc; sense[13] = ascq; scsi_error_msg(d, sense, 14, msg + strlen(msg), &key, &asc, &ascq); libdax_msgs_submit(libdax_messenger, d->global_index, 0x0002014d, LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH, msg, 0, 0); d->cancel = 1; break; } else if (ascq == 0x00) { /* CAUSE NOT REPORTABLE */ /* Might be a clueless system adapter */ if (clueless_start == 0) clueless_start = i; if (i - clueless_start > clueless_timeout) { libdax_msgs_submit(libdax_messenger, d->global_index, 0x00000002, LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH, "Ended clueless NOT READY cycle", 0, 0); ret = 1; /* medium not present = ok */ break; } } else if (ascq == 0x02 || ascq == 0x03) goto handle_error; slumber:; usleep(sleep_usecs); } if (ret <= 0 || !(flag & 2)) { sprintf(msg, "Async %s %s after %d.%d seconds", cmd_text, (ret > 0 ? "succeeded" : "failed"), i / 10, i % 10); libdax_msgs_submit(libdax_messenger, d->global_index, 0x00020150, LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_LOW, msg, 0, 0); } if (i < max_sec * 10) {ret = (ret > 0); goto ex;} sprintf(msg, "Timeout (%d s) with asynchronous SCSI command %s\n", max_sec, cmd_text); libdax_msgs_submit(libdax_messenger, d->global_index, 0x0002014f, LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH, msg, 0, 0); ret = 0; ex:; BURN_FREE_MEM(msg); return ret; } void spc_request_sense(struct burn_drive *d, struct buffer *buf) { struct command *c; c = &(d->casual_command); if (mmc_function_spy(d, "request_sense") <= 0) return; scsi_init_command(c, SPC_REQUEST_SENSE, sizeof(SPC_REQUEST_SENSE)); c->retry = 0; c->dxfer_len= c->opcode[4]; c->retry = 0; c->page = buf; c->page->sectors = 0; c->page->bytes = 0; c->dir = FROM_DRIVE; d->issue_command(d, c); } static int spc_report_async_error(struct burn_drive *d, int key, int asc, int ascq, int flag) { char *msg = NULL; unsigned char sense[14]; int ret; BURN_ALLOC_MEM(msg, char, BURN_DRIVE_ADR_LEN + 160); sprintf(msg, "Asynchronous SCSI error : "); sense[0] = 0x70; /* Fixed format sense data */ sense[2] = key; sense[12] = asc; sense[13] = ascq; scsi_error_msg(d, sense, 14, msg + strlen(msg), &key, &asc, &ascq); libdax_msgs_submit(libdax_messenger, d->global_index, 0x000201a5, LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH, msg, 0, 0); ret = 1; ex:; BURN_FREE_MEM(msg); return ret; } /* @return -3 = other error reported -2 = drive is ready , -1 = not ready, but no progress reported , >= 0 progress indication between 0 and 65535 */ int spc_get_erase_progress(struct burn_drive *d) { struct buffer *b = NULL; int ret, key, asc, ascq, progress; if (mmc_function_spy(d, "get_erase_progress") <= 0) {ret = 0; goto ex;} /* ts B20104 : TEST UNIT READY seems to be more reliable than REQUEST SENSE. Nevertheless growisofs still uses the latter as fallback. */ ret = spc_test_unit_ready_r(d, &key, &asc, &ascq, &progress); if (ret > 0) {ret = -2; goto ex;} /* Check key, asc, ascq for errors other than "not yet ready" */ if (key != 0 && (key != 0x2 || asc != 0x04 || ascq == 0x02 || ascq ==0x03)) { spc_report_async_error(d, key, asc, ascq, 0); ret= -3; goto ex; } if (progress >= 0) {ret = progress; goto ex;} /* Fallback to request sense */ BURN_ALLOC_MEM(b, struct buffer, 1); spc_request_sense(d, b); /* Checking the preconditions as of SPC-3 4.5.2.4.4 and 4.5.3 */ ret = -1; if (b->data[0] == 0x70 && ((b->data[2] & 0x0f) == 0 || (b->data[2] & 0x0f) == 2) && (b->data[15] & 0x80)) ret = (b->data[16] << 8) | b->data[17]; ex:; BURN_FREE_MEM(b); return ret; } void spc_inquiry(struct burn_drive *d) { struct buffer *buf = NULL; struct burn_scsi_inquiry_data *id; struct command *c = NULL; if (mmc_function_spy(d, "inquiry") <= 0) return; BURN_ALLOC_MEM_VOID(buf, struct buffer, 1); BURN_ALLOC_MEM_VOID(c, struct command, 1); scsi_init_command(c, SPC_INQUIRY, sizeof(SPC_INQUIRY)); c->dxfer_len = (c->opcode[3] << 8) | c->opcode[4]; c->retry = 1; c->page = buf; c->page->bytes = 0; c->page->sectors = 0; c->dir = FROM_DRIVE; d->issue_command(d, c); id = (struct burn_scsi_inquiry_data *)d->idata; id->peripheral = 0x7f; /* SPC-3: incabable undefined peripheral type */ id->version = 0; /* SPC-3: no claim for conformance */ memset(id->vendor, 0, 9); memset(id->product, 0, 17); memset(id->revision, 0, 5); if (c->error) { id->valid = -1; goto ex; } id->peripheral = ((char *) c->page->data)[0]; id->version = ((char *) c->page->data)[2]; memcpy(id->vendor, c->page->data + 8, 8); memcpy(id->product, c->page->data + 16, 16); memcpy(id->revision, c->page->data + 32, 4); id->valid = 1; ex:; BURN_FREE_MEM(buf); BURN_FREE_MEM(c); return; } void spc_prevent(struct burn_drive *d) { struct command *c; c = &(d->casual_command); if (mmc_function_spy(d, "prevent") <= 0) return; scsi_init_command(c, SPC_PREVENT, sizeof(SPC_PREVENT)); c->retry = 1; c->dir = NO_TRANSFER; d->issue_command(d, c); #ifdef Libburn_pioneer_dvr_216d_get_evenT mmc_get_event(d); #endif } void spc_allow(struct burn_drive *d) { struct command *c; c = &(d->casual_command); if (mmc_function_spy(d, "allow") <= 0) return; scsi_init_command(c, SPC_ALLOW, sizeof(SPC_ALLOW)); c->retry = 1; c->dir = NO_TRANSFER; d->issue_command(d, c); } /* ts B40216 : Outsourced from spc_sense_caps_al(). To be called by spc_sense_caps() after spc_sense_caps_al() */ static int spc_try_get_performance(struct burn_drive *d, int flag) { int ret; struct burn_feature_descr *feature_descr; /* ts B40107 : Feature 0x107 announces availability of GET PERFORMANCE Its WSPD bit announces Type 3. Try this even if the feature is not current. */ ret = burn_drive_has_feature(d, 0x107, &feature_descr, 0); if (ret <= 0) return ret; if (feature_descr->data_lenght <= 0) return 1; if (feature_descr->data[0] & 2) /* WSPD */ ret = mmc_get_write_performance(d); /* Get read performance */ mmc_get_performance(d, 0x00, 0); return 1; } /* ts A70518 - A90603 : Do not call with *alloc_len < 10 */ /** @param flag bit0= do only inquire alloc_len @return 1=ok , <=0 error , 2=Block Descriptor Length > 0, retry with flag bit1 */ static int spc_sense_caps_al(struct burn_drive *d, int *alloc_len, int flag) { struct buffer *buf = NULL; struct scsi_mode_data *m; int page_length, num_write_speeds = 0, i, speed, ret; int old_alloc_len, was_error = 0, block_descr_len; unsigned char *page; struct command *c = NULL; struct burn_speed_descriptor *sd; char *msg = NULL; /* ts A61225 : 1 = report about post-MMC-1 speed descriptors */ static int speed_debug = 0; if (*alloc_len < 10) {ret = 0; goto ex;} BURN_ALLOC_MEM(msg, char, BURN_DRIVE_ADR_LEN + 160); BURN_ALLOC_MEM(buf, struct buffer, 1); BURN_ALLOC_MEM(c, struct command, 1); /* ts A90602 : Clearing mdata before command execution */ m = d->mdata; m->p2a_valid = 0; burn_mdata_free_subs(m); memset(buf, 0, sizeof(struct buffer)); scsi_init_command(c, SPC_MODE_SENSE, sizeof(SPC_MODE_SENSE)); c->dxfer_len = *alloc_len; c->opcode[7] = (c->dxfer_len >> 8) & 0xff; c->opcode[8] = c->dxfer_len & 0xff; c->retry = 1; c->opcode[2] = 0x2A; c->page = buf; c->page->bytes = 0; c->page->sectors = 0; c->dir = FROM_DRIVE; d->issue_command(d, c); if (c->error) { memset(buf, 0, sizeof(struct buffer)); m->p2a_valid = -1; was_error = 1; } /* ts B11103 : qemu SCSI CD-ROM has Block Descriptor Length > 0. The descriptors come between header and page. */ block_descr_len = c->page->data[6] * 256 + c->page->data[7]; if (block_descr_len + 8 + 2 > *alloc_len) { if (block_descr_len + 8 + 2 > BUFFER_SIZE || !(flag & 1)) { m->p2a_valid = -1; sprintf(msg, "MODE SENSE page 2A with oversized Block Descriptors: %s : %d", d->devname, block_descr_len); libdax_msgs_submit(libdax_messenger, d->global_index, 0x0002016e, LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_LOW, msg, 0, 0); {ret = 0; goto ex;} } *alloc_len = block_descr_len + 10; {ret = 2; goto ex;} } /* Skip over Mode Data Header and block descriptors */ page = c->page->data + 8 + block_descr_len; /* ts A61225 : 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, in MMC-3 6.3.11 there are at least 28 bytes plus a variable length set of speed descriptors. In MMC-5 E.11 it is declared "legacy". ts B11031 : qemu emulates an ATAPI DVD-ROM, which delivers only a page length of 18. This is now tolerated. */ /* ts A90603 : SPC-1 8.3.3 enumerates mode page format bytes from 0 to n and defines Page Length as (n-1). */ page_length = page[1]; old_alloc_len = *alloc_len; *alloc_len = page_length + 10 + block_descr_len; if (flag & 1) {ret = !was_error; goto ex;} if (page_length + 10 > old_alloc_len) page_length = old_alloc_len - 10; /* ts A90602 : page_length N asserts page[N+1]. (see SPC-1 8.3.3) */ /* ts B11031 : qemu drive has a page_length of 18 */ if (page_length < 18) { m->p2a_valid = -1; sprintf(msg, "MODE SENSE page 2A too short: %s : %d", d->devname, page_length); libdax_msgs_submit(libdax_messenger, d->global_index, 0x0002016e, LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_LOW, msg, 0, 0); {ret = 0; goto ex;} } m->buffer_size = page[12] * 256 + page[13]; m->dvdram_read = page[2] & 32; m->dvdram_write = page[3] & 32; m->dvdr_read = page[2] & 16; m->dvdr_write = page[3] & 16; m->dvdrom_read = page[2] & 8; m->simulate = page[3] & 4; m->cdrw_read = page[2] & 2; m->cdrw_write = page[3] & 2; m->cdr_read = page[2] & 1; m->cdr_write = page[3] & 1; m->c2_pointers = page[5] & 16; m->underrun_proof = page[4] & 128; /* ts A61021 : these fields are marked obsolete in MMC 3 */ m->max_read_speed = page[8] * 256 + page[9]; m->cur_read_speed = page[14] * 256 + page[15]; m->max_write_speed = m->cur_write_speed = 0; 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) */ m->min_write_speed = m->max_write_speed; /* ts A61225 : for ACh GET PERFORMANCE, Type 03h */ m->min_end_lba = 0x7fffffff; m->max_end_lba = 0; if (!was_error) m->p2a_valid = 1; /* ts A61225 : end of MMC-1 , begin of MMC-3 */ if (page_length < 30) /* no write speed descriptors ? */ goto no_speed_descriptors; m->cur_write_speed = page[28] * 256 + page[29]; if (speed_debug) fprintf(stderr, "LIBBURN_DEBUG: cur_write_speed = %d\n", m->cur_write_speed); num_write_speeds = page[30] * 256 + page[31]; m->max_write_speed = m->min_write_speed = m->cur_write_speed; if (32 + 4 * num_write_speeds > page_length + 2) { sprintf(msg, "Malformed capabilities page 2Ah received (len=%d, #speeds=%d)", page_length, num_write_speeds); libdax_msgs_submit(libdax_messenger, d->global_index, 0x0002013c, LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH, msg, 0, 0); {ret = 0; goto ex;} } for (i = 0; i < num_write_speeds; i++) { speed = page[32 + 4 * i + 2] * 256 + page[32 + 4 * i + 3]; if (speed_debug) fprintf(stderr, "LIBBURN_DEBUG: write speed #%d = %d kB/s (rc %d)\n", i, speed, page[32 + 4 * i + 1] & 7); /* ts A61226 */ ret = burn_speed_descriptor_new(&(d->mdata->speed_descriptors), NULL, d->mdata->speed_descriptors, 0); if (ret > 0) { sd = d->mdata->speed_descriptors; sd->source = 1; if (d->current_profile > 0) { sd->profile_loaded = d->current_profile; strcpy(sd->profile_name, d->current_profile_text); } sd->wrc = (( page[32 + 4 * i + 1] & 7 ) == 1 ); sd->write_speed = speed; } if (speed > m->max_write_speed) m->max_write_speed = speed; if (speed < m->min_write_speed) m->min_write_speed = speed; } if (speed_debug) fprintf(stderr, "LIBBURN_DEBUG: 5Ah,2Ah min_write_speed = %d , max_write_speed = %d\n", m->min_write_speed, m->max_write_speed); no_speed_descriptors:; ret = !was_error; ex: BURN_FREE_MEM(msg); BURN_FREE_MEM(buf); BURN_FREE_MEM(c); return ret; } void spc_sense_caps(struct burn_drive *d) { int alloc_len, start_len = 30, minimum_len = 28, ret; mmc_start_if_needed(d, 1); if (mmc_function_spy(d, "sense_caps") <= 0) return; mmc_get_configuration(d); /* first command execution to learn Allocation Length */ alloc_len = start_len; ret = spc_sense_caps_al(d, &alloc_len, 1); if (ret == 2) { /* ts B40205: Unexpectedly found Block Descriptors. Repeat with new alloc_len. */ ret = spc_sense_caps_al(d, &alloc_len, 1); if (ret == 2) goto try_get_performance; } /* 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 */ spc_sense_caps_al(d, &alloc_len, 0); try_get_performance:; spc_try_get_performance(d, 0); } void spc_sense_error_params(struct burn_drive *d) { struct buffer *buf = NULL; struct scsi_mode_data *m; int alloc_len = 12 ; unsigned char *page; struct command *c = NULL; mmc_start_if_needed(d, 1); if (mmc_function_spy(d, "sense_error_params") <= 0) goto ex; BURN_ALLOC_MEM_VOID(buf, struct buffer, 1); BURN_ALLOC_MEM_VOID(c, struct command, 1); scsi_init_command(c, SPC_MODE_SENSE, sizeof(SPC_MODE_SENSE)); c->dxfer_len = alloc_len; c->opcode[7] = (c->dxfer_len >> 8) & 0xff; c->opcode[8] = c->dxfer_len & 0xff; c->retry = 1; c->opcode[2] = 0x01; c->page = buf; c->page->bytes = 0; c->page->sectors = 0; c->dir = FROM_DRIVE; d->issue_command(d, c); m = d->mdata; page = c->page->data + 8; d->params.retries = page[3]; m->retry_page_length = page[1]; m->retry_page_valid = 1; ex:; BURN_FREE_MEM(buf); BURN_FREE_MEM(c); } void spc_select_error_params(struct burn_drive *d, const struct burn_read_opts *o) { struct buffer *buf = NULL; struct command *c = NULL; mmc_start_if_needed(d, 1); if (mmc_function_spy(d, "select_error_params") <= 0) goto ex; BURN_ALLOC_MEM_VOID(buf, struct buffer, 1); BURN_ALLOC_MEM_VOID(c, struct command, 1); scsi_init_command(c, SPC_MODE_SELECT, sizeof(SPC_MODE_SELECT)); c->retry = 1; if (d->mdata->retry_page_valid <= 0) d->mdata->retry_page_length = 0; c->opcode[8] = 8 + 2 + d->mdata->retry_page_length; c->page = buf; c->page->bytes = 0; c->page->sectors = 0; memset(c->page->data, 0, 8 + 2 + d->mdata->retry_page_length); c->page->bytes = 8 + 2 + d->mdata->retry_page_length; c->page->data[8] = 1; c->page->data[9] = d->mdata->retry_page_length; if (o->transfer_damaged_blocks) c->page->data[10] |= 32; if (o->report_recovered_errors) c->page->data[10] |= 4; if (!o->hardware_error_recovery) c->page->data[10] |= 1; c->page->data[11] = d->params.retries; c->dir = TO_DRIVE; d->issue_command(d, c); ex:; BURN_FREE_MEM(buf); BURN_FREE_MEM(c); } void spc_sense_write_params(struct burn_drive *d) { struct buffer *buf = NULL; struct scsi_mode_data *m; int dummy1, dummy2, alloc_len = 10; unsigned char *page; struct command *c = NULL; mmc_start_if_needed(d, 1); if (mmc_function_spy(d, "sense_write_params") <= 0) goto ex; BURN_ALLOC_MEM_VOID(buf, struct buffer, 1); BURN_ALLOC_MEM_VOID(c, struct command, 1); /* ts A61007 : Done in soft at only caller burn_drive_grab() */ /* a ssert(d->mdata->cdr_write || d->mdata->cdrw_write || d->mdata->dvdr_write || d->mdata->dvdram_write); */ scsi_init_command(c, SPC_MODE_SENSE, sizeof(SPC_MODE_SENSE)); c->dxfer_len = alloc_len; c->opcode[7] = (c->dxfer_len >> 8) & 0xff; c->opcode[8] = c->dxfer_len & 0xff; c->retry = 1; c->opcode[2] = 0x05; c->page = buf; c->page->bytes = 0; c->page->sectors = 0; c->dir = FROM_DRIVE; d->issue_command(d, c); /* ts A71128 : do not interpret reply if error */ m = d->mdata; if (!c->error) { page = c->page->data + 8; m->write_page_length = page[1]; if (m->write_page_length > 0) m->write_page_valid = 1; else m->write_page_length = 0x32; } mmc_read_disc_info(d); /* ts A70212 : try to setup d->media_capacity_remaining */ if (d->current_profile == 0x1a || d->current_profile == 0x13 || d->current_profile == 0x12 || d->current_profile == 0x43) d->read_format_capacities(d, -1); else if (d->status == BURN_DISC_BLANK || (d->current_is_cd_profile && d->status == BURN_DISC_APPENDABLE)) { 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() */ /* fprintf(stderr, "LIBBURN_DEBUG: media_capacity_remaining = %.f\n", (double) d->media_capacity_remaining); */ ex:; BURN_FREE_MEM(buf); BURN_FREE_MEM(c); } /* remark ts A61104 : Although command MODE SELECT is SPC, the content of the Write Parameters Mode Page (05h) is MMC (Table 108 in MMC-1). Thus the filling of the mode page is done by mmc_compose_mode_page_5(). */ void spc_select_write_params(struct burn_drive *d, struct burn_session *s, int tnum, const struct burn_write_opts *o) { struct buffer *buf = NULL; struct command *c = NULL; int alloc_len; mmc_start_if_needed(d, 1); if (mmc_function_spy(d, "select_write_params") <= 0) goto ex; BURN_ALLOC_MEM_VOID(buf, struct buffer, 1); BURN_ALLOC_MEM_VOID(c, struct command, 1); /* ts A61007 : All current callers are safe. */ /* a ssert(o->drive == d); */ /* <<< A61030 fprintf(stderr,"libburn_debug: write_type=%d multi=%d control=%d\n", o->write_type,o->multi,o->control); fprintf(stderr,"libburn_debug: block_type=%d spc_block_type=%d\n", o->block_type,spc_block_type(o->block_type)); */ alloc_len = 8 + 2 + d->mdata->write_page_length; memset(&(buf->data), 0, alloc_len); #ifdef Libburn_pioneer_dvr_216d_load_mode5 scsi_init_command(c, SPC_MODE_SENSE, sizeof(SPC_MODE_SENSE)); c->dxfer_len = alloc_len; c->opcode[7] = (alloc_len >> 8) & 0xff; c->opcode[8] = alloc_len & 0xff; c->retry = 1; c->opcode[2] = 0x05; c->page = buf; c->page->bytes = 0; c->page->sectors = 0; c->dir = FROM_DRIVE; d->issue_command(d, c); if (c->error) memset(&(buf->data), 0, 8 + 2 + d->mdata->write_page_length); #endif /* Libburn_pioneer_dvr_216d_load_mode5 */ scsi_init_command(c, SPC_MODE_SELECT, sizeof(SPC_MODE_SELECT)); c->retry = 1; c->opcode[7] = (alloc_len >> 8) & 0xff; c->opcode[8] = alloc_len & 0xff; c->page = buf; c->page->bytes = 0; c->page->sectors = 0; c->page->bytes = alloc_len; /* ts A61229 */ if (mmc_compose_mode_page_5(d, s, tnum, o, c->page->data + 8) <= 0) goto ex; c->dir = TO_DRIVE; d->issue_command(d, c); ex:; BURN_FREE_MEM(buf); BURN_FREE_MEM(c); } #ifdef Libburn_enable_scsi_cmd_ABh /* At least on Linux kernel 3.16 the command ABh causes EFAULT if not sent from the superuser. For a test it may be replaced by a dummy 28h READ12 on block 0. This causes no EFAULT although it sets the wrong dxfer_len 4 rather than 2048. So it is indeed a permission problem and not bad alignment. */ /* ts B51016 */ int spc_read_media_serial_number_al(struct burn_drive *d, int *alloc_len) { struct buffer *buf = NULL; struct command *c = NULL; unsigned char *data; int ret; if (*alloc_len < 4) {ret = 0; goto ex;} BURN_ALLOC_MEM(buf, struct buffer, 1); BURN_ALLOC_MEM(c, struct command, 1); if (mmc_function_spy(d, "spc_read_media_serial_number") <= 0) {ret = 0; goto ex;} /* #de fine Spc_read_media_serial_number_dummY yes */ #ifdef Spc_read_media_serial_number_dummY { static unsigned char MMC_READ_12[] = { 0x28, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }; scsi_init_command(c, MMC_READ_12, sizeof(MMC_READ_12)); c->dxfer_len = *alloc_len; } #else scsi_init_command(c, SPC_READ_MEDIA_SERIAL_NUMBER, sizeof(SPC_READ_MEDIA_SERIAL_NUMBER)); c->dxfer_len = *alloc_len; /* (Will not accept more than 32 KB anyway) */ c->opcode[8] = (c->dxfer_len >> 8) & 0xff; c->opcode[9] = c->dxfer_len & 0xff; #endif /* ! Spc_read_media_serial_number_dummY */ c->retry = 1; c->page = buf; memset(c->page->data, 0, *alloc_len); c->page->bytes = 0; c->page->sectors = 0; c->dir = FROM_DRIVE; d->issue_command(d, c); if (c->error) {ret = 0; goto ex;} data = c->page->data; #ifdef Spc_read_media_serial_number_dummY d->media_serial_number_len = 0; #else d->media_serial_number_len = (data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[7]; #endif if (*alloc_len >= d->media_serial_number_len + 4) { if (d->media_serial_number != NULL) BURN_FREE_MEM(d->media_serial_number); BURN_ALLOC_MEM(d->media_serial_number, char, d->media_serial_number_len + 1); if (d->media_serial_number_len > 0) memcpy(d->media_serial_number, data + 4, d->media_serial_number_len); d->media_serial_number[d->media_serial_number_len] = 0; } *alloc_len = d->media_serial_number_len + 4; ret = 1; ex:; BURN_FREE_MEM(c); BURN_FREE_MEM(buf); return ret; } int spc_read_media_serial_number(struct burn_drive *d) { int alloc_len = 4, ret; ret = spc_read_media_serial_number_al(d, &alloc_len); if (alloc_len > 4 && alloc_len <= 0x8000 && ret > 0) ret = spc_read_media_serial_number_al(d, &alloc_len); return ret; } #endif /* Libburn_enable_scsi_cmd_ABh */ void spc_getcaps(struct burn_drive *d) { if (mmc_function_spy(d, "getcaps") <= 0) return; burn_speed_descriptor_destroy(&(d->mdata->speed_descriptors), 1); spc_inquiry(d); spc_sense_caps(d); spc_sense_error_params(d); } /* don't check totally stupid modes (raw/raw0) some drives say they're ok, and they're not. */ void spc_probe_write_modes(struct burn_drive *d) { struct buffer *buf = NULL; int try_write_type = 1; int try_block_type = 0; int key, asc, ascq, useable_write_type = -1, useable_block_type = -1; int last_try = 0; struct command *c = NULL; mmc_start_if_needed(d, 1); if (mmc_function_spy(d, "spc_probe_write_modes") <= 0) goto ex; BURN_ALLOC_MEM_VOID(buf, struct buffer, 1); BURN_ALLOC_MEM_VOID(c, struct command, 1); /* ts A70213 : added pseudo try_write_type 4 to set a suitable mode */ while (try_write_type != 5) { /* ts A70213 */ if (try_write_type == 4) { /* Pseudo write type NONE . Set a useable write mode */ if (useable_write_type == -1) break; try_write_type = useable_write_type; try_block_type = useable_block_type; last_try= 1; } scsi_init_command(c, SPC_MODE_SELECT,sizeof(SPC_MODE_SELECT)); c->retry = 1; c->opcode[8] = 8 + 2 + 0x32; c->page = buf; memset(c->page->data, 0, 8 + 2 + 0x32); c->page->bytes = 8 + 2 + 0x32; c->page->data[8] = 5; c->page->data[9] = 0x32; c->page->data[10] = try_write_type; if (try_block_type > 4) c->page->data[11] = 4; else c->page->data[11] = 0; c->page->data[12] = try_block_type; c->page->data[23] = 150; c->dir = TO_DRIVE; d->silent_on_scsi_error = 1; d->issue_command(d, c); d->silent_on_scsi_error = 0; if (last_try) break; spc_decode_sense(c->sense, 0, &key, &asc, &ascq); if (key) /* try_block_type not supported */; else { /* try_write_type, try_block_type is supported mode */ if (try_write_type == 2) /* sao */ d->block_types[try_write_type] = BURN_BLOCK_SAO; else d->block_types[try_write_type] |= 1 << try_block_type; /* ts A70213 */ if ((useable_write_type < 0 && try_write_type > 0) || (try_write_type == 1 && try_block_type == 8)) { /* Packet is not supported yet. Prefer TAO MODE_1. */ useable_write_type = try_write_type; useable_block_type = try_block_type; } } switch (try_block_type) { case 0: case 1: case 2: try_block_type++; break; case 3: try_block_type = 8; break; case 8: case 9: case 10: case 11: case 12: try_block_type++; break; case 13: try_block_type = 0; try_write_type++; break; default: goto ex; } } ex:; BURN_FREE_MEM(buf); BURN_FREE_MEM(c); } /* ( ts A61229 : shouldn't this go to mmc.c too ?) */ /** @return -1 = error */ int spc_block_type(enum burn_block_types b) { switch (b) { case BURN_BLOCK_SAO: return 0; /* ignored bitz */ case BURN_BLOCK_RAW0: return 0; case BURN_BLOCK_RAW16: return 1; case BURN_BLOCK_RAW96P: return 2; case BURN_BLOCK_RAW96R: return 3; case BURN_BLOCK_MODE1: return 8; case BURN_BLOCK_MODE2R: return 9; case BURN_BLOCK_MODE2_PATHETIC: return 10; case BURN_BLOCK_MODE2_LAME: return 11; case BURN_BLOCK_MODE2_OBSCURE: return 12; case BURN_BLOCK_MODE2_OK: return 13; default: return -1; } /* ts A61007 : already prevented in burn_write_opts_set_write_type() */ /* a ssert(0); */; } /* ts A61021 : the spc specific part of sg.c:enumerate_common() */ int spc_setup_drive(struct burn_drive *d) { d->getcaps = spc_getcaps; d->lock = spc_prevent; d->unlock = spc_allow; d->read_disc_info = spc_sense_write_params; d->get_erase_progress = spc_get_erase_progress; d->test_unit_ready = spc_test_unit_ready; d->probe_write_modes = spc_probe_write_modes; d->send_parameters = spc_select_error_params; d->send_write_parameters = spc_select_write_params; return 1; } /* ts A61021 : the general SCSI specific part of sg.c:enumerate_common() @param flag Bitfiled for control purposes bit0= do not setup spc/sbc/mmc */ int burn_scsi_setup_drive(struct burn_drive *d, int bus_no, int host_no, int channel_no, int target_no, int lun_no, int flag) { int ret; /* ts A60923 */ d->bus_no = bus_no; d->host = host_no; d->id = target_no; d->channel = channel_no; d->lun = lun_no; /* ts A61106 */ d->silent_on_scsi_error = 0; /* ts B21023 */ d->had_particular_error = 0; d->idata = calloc(1, sizeof(struct burn_scsi_inquiry_data)); d->mdata = calloc(1, sizeof(struct scsi_mode_data)); /* ts A61007 : obsolete Assert in drive_getcaps() */ if (d->idata == NULL || d->mdata == NULL) { libdax_msgs_submit(libdax_messenger, -1, 0x00020108, LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH, "Could not allocate new drive object", 0, 0); return -1; } d->idata->valid = 0; d->mdata->p2a_valid = 0; d->mdata->max_read_speed = 0; d->mdata->cur_read_speed = 0; d->mdata->max_write_speed = 0; d->mdata->cur_write_speed = 0; d->mdata->speed_descriptors = NULL; d->mdata->write_page_length = 0x32; d->mdata->write_page_valid = 0; if (!(flag & 1)) { ret = spc_setup_drive(d); if (ret<=0) return ret; ret = sbc_setup_drive(d); if (ret<=0) return ret; ret = mmc_setup_drive(d); if (ret<=0) return ret; } return 1; } /* ts A61122 - A80829 */ enum response scsi_error_msg(struct burn_drive *d, unsigned char *sense, int senselen, char msg_data[161], int *key, int *asc, int *ascq) { int ret; char *msg; static char key_def[16][40] = { "(no specific error)", "Recovered error", "Drive not ready", "Medium error", "Drive error", "Illegal request", "Drive event", "Data protected", "Blank/Nonblank", "Vendor specific code", "Copy aborted", "Command aborted", "(obsolete error code)", "Volume overflow", "Miscompare", "(reserved error code)", }; msg= msg_data; *key= *asc= *ascq= -1; ret = spc_decode_sense(sense, senselen, key, asc, ascq); if (ret <= 0) *key= *asc= *ascq= -1; sprintf(msg, "[%X %2.2X %2.2X] ", *key, *asc, *ascq); msg= msg + strlen(msg); if (key_def[*key & 0xf][0] != '(') { sprintf(msg, "%s. ", key_def[*key & 0xf]); msg= msg + strlen(msg); } switch (*asc) { case 0x00: if (*key > 0 || *ascq > 0) break; /* Fall through to unknown error */ sprintf(msg, "(No error reported by SCSI transaction)"); return GO_ON; case 0x02: sprintf(msg, "Not ready"); goto return_retry; case 0x04: if (*ascq == 1) sprintf(msg, "Logical unit is in the process of becoming ready"); else sprintf(msg, "Logical unit is not ready"); goto return_retry; case 0x06: if (*ascq == 0) sprintf(msg, "No reference position found"); else break; goto return_fail; case 0x08: if (*ascq == 0) sprintf(msg, "Logical unit communication failure"); else if (*ascq == 1) sprintf(msg, "Logical unit communication timeout"); else if (*ascq == 2) sprintf(msg, "Logical unit communication parity error"); else if (*ascq == 3) sprintf(msg, "Logical unit communication crc error"); else break; goto return_retry; case 0x09: if (*ascq == 0) sprintf(msg, "Track following error"); else if (*ascq == 1) sprintf(msg, "Tracking servo failure"); else if (*ascq == 2) sprintf(msg, "Focus servo failure"); else if (*ascq == 3) sprintf(msg, "Spindle servo failure"); else if (*ascq == 4) sprintf(msg, "Head select fault"); else break; goto return_fail; case 0x0C: if (*ascq == 0) sprintf(msg, "Write error"); else if (*ascq == 1) sprintf(msg, "Write error, recovered with auto-allocation"); else if (*ascq == 2) sprintf(msg, "Write error, auto reallocation failed"); else if (*ascq == 7) sprintf(msg, "Write error, recovery needed"); else if (*ascq == 8) sprintf(msg, "Write error, recovery failed"); else if (*ascq == 9) sprintf(msg, "Write error, loss of streaming"); else if (*ascq == 0x0f) sprintf(msg, "Defects in error window"); else break; goto return_fail; case 0x11: if (*ascq == 0) sprintf(msg, "Unrecovered read error"); else if (*ascq == 1) sprintf(msg, "Read retries exhausted"); else if (*ascq == 2) sprintf(msg, "Error too long to correct"); else if (*ascq == 5) sprintf(msg, "L-EC uncorrectable error"); else if (*ascq == 6) sprintf(msg, "CIRC uncorrectable error"); else break; goto return_fail; case 0x15: if (*ascq == 0) sprintf(msg, "Random positioning error"); else if (*ascq == 1) sprintf(msg, "Mechanical positioning error"); else break; goto return_fail; case 0x1a: if (*ascq == 0) sprintf(msg, "Parameter list length error"); else break; goto return_fail; case 0x1b: if (*ascq == 0) sprintf(msg, "Synchronous data transfer error"); else break; goto return_fail; case 0x20: if (*ascq == 0) sprintf(msg, "Invalid command operation code"); else break; goto return_fail; case 0x21: if (*ascq == 0) sprintf(msg, "Lba out of range"); else if (*ascq == 1) sprintf(msg, "Invalid element address"); else if (*ascq == 2) sprintf(msg, "Invalid address for write"); else if (*ascq == 3) sprintf(msg, "Invalid write crossing layer jump"); else break; goto return_fail; case 0x24: if (*ascq == 0) sprintf(msg, "Invalid field in cdb"); else break; goto return_fail; case 0x26: if (*ascq == 0) sprintf(msg, "Invalid field in parameter list"); else if (*ascq == 1) sprintf(msg, "Parameter not supported"); else if (*ascq == 2) sprintf(msg, "Parameter value invalid"); else break; goto return_fail; case 0x27: sprintf(msg, "Write protected"); goto return_fail; case 0x28: if (*ascq == 0) sprintf(msg, "Medium may have changed"); else if (*ascq == 2) sprintf(msg, "Format layer may have changed"); else break; goto return_retry; case 0x29: if (*ascq == 0) sprintf(msg, "Power on, reset, or bus device reset occured"); else if (*ascq == 1) sprintf(msg, "Power on occured"); else if (*ascq == 2) sprintf(msg, "Bus reset occured"); else if (*ascq == 3) sprintf(msg, "Bus device reset function occured"); else if (*ascq == 4) sprintf(msg, "Device internal reset"); else break; goto return_retry; case 0x2c: if (*ascq == 0) sprintf(msg, "Command sequence error"); else break; goto return_fail; case 0x2e: if (*ascq == 0) sprintf(msg, "Insufficient time for operation"); else break; goto return_fail; case 0x30: if (*ascq == 0) sprintf(msg, "Incompatible medium installed"); else if (*ascq == 1) sprintf(msg, "Cannot read medium, unknown format"); else if (*ascq == 2) sprintf(msg, "Cannot read medium, incompatible format"); else if (*ascq == 4) sprintf(msg, "Cannot write medium, unknown format"); else if (*ascq == 5) sprintf(msg, "Cannot write medium, incompatible format"); else if (*ascq == 6) sprintf(msg, "Cannot format medium, incompatible medium"); else if (*ascq == 7) sprintf(msg, "Cleaning failure"); else break; goto return_fail; case 0x31: if (*ascq == 0) sprintf(msg, "Medium unformatted or format corrupted"); else if (*ascq == 1) sprintf(msg, "Format command failed"); else break; goto return_fail; case 0x32: if (*ascq == 0) sprintf(msg, "No defect spare location available"); else break; goto return_fail; case 0x3A: if (*ascq == 0) sprintf(msg, "Medium not present"); else if (*ascq == 1) sprintf(msg, "Medium not present, tray closed"); else if (*ascq == 2) sprintf(msg, "Medium not present, tray open"); else if (*ascq == 3) sprintf(msg, "Medium not present, loadable"); else break; d->status = BURN_DISC_EMPTY; goto return_fail; case 0x3E: if (*ascq == 1) sprintf(msg, "Logical unit failure"); else if (*ascq == 2) sprintf(msg, "Timeout on logical unit"); else break; goto return_fail; case 0x44: if (*ascq == 0) sprintf(msg, "Internal target failure"); else break; goto return_fail; case 0x51: if (*ascq == 0) sprintf(msg, "Erase failure"); else if (*ascq == 1) sprintf(msg, "Erase failure. Incomplete erase operation"); else break; goto return_fail; case 0x57: if (*ascq == 0) sprintf(msg, "Unable to recover Table-of-Content"); else break; goto return_fail; case 0x63: if (*ascq == 0) sprintf(msg, "End of user area encountered on this track"); else if (*ascq == 1) sprintf(msg, "Packet does not fit in available space"); else break; goto return_fail; case 0x64: if (*ascq == 0) sprintf(msg, "Illegal mode for this track"); else if (*ascq == 1) sprintf(msg, "Invalid packet size"); else break; goto return_fail; case 0x72: if (*ascq == 0) sprintf(msg, "Session fixation error"); else if (*ascq == 1) sprintf(msg, "Session fixation error writing lead-in"); else if (*ascq == 2) sprintf(msg, "Session fixation error writing lead-out"); else if (*ascq == 3) sprintf(msg, "Session fixation error, incomplete track in session"); else if (*ascq == 4) sprintf(msg, "Empty or partially written reserved track"); else if (*ascq == 5) sprintf(msg, "No more track reservations allowed"); else break; goto return_fail; case 0x73: if (*ascq == 0) sprintf(msg, "CD control error"); else if (*ascq == 1) sprintf(msg, "Power calibration area almost full"); else if (*ascq == 2) sprintf(msg, "Power calibration area is full"); else if (*ascq == 3) sprintf(msg, "Power calibration area error"); else if (*ascq == 4) sprintf(msg, "Program memory area update failure"); else if (*ascq == 5) sprintf(msg, "Program memory area is full"); else break; goto return_fail; } sprintf(msg_data, "See MMC specs: Sense Key %X \"%s\", ASC %2.2X ASCQ %2.2X", *key & 0xf, key_def[(*key) & 0xf], *asc, *ascq); goto return_fail; return_fail: strcat(msg, "."); if (*key == 1) return GO_ON; return FAIL; return_retry:; strcat(msg, "."); if (*key == 1) return GO_ON; return RETRY; } /* ts A61115 moved from sg-*.c */ /* ts A61122 made it frontend to scsi_error_msg() */ enum response scsi_error(struct burn_drive *d, unsigned char *sense, int senselen) { int key, asc, ascq, ret = 0; char *msg = NULL; enum response resp; BURN_ALLOC_MEM(msg, char, 160); resp = scsi_error_msg(d, sense, senselen, msg, &key, &asc, &ascq); ex:; if (ret == -1) resp = FAIL; BURN_FREE_MEM(msg); return resp; } static char *scsi_command_name(unsigned int c, int flag) { switch (c) { case 0x00: return "TEST UNIT READY"; case 0x03: return "REQUEST SENSE"; case 0x04: return "FORMAT UNIT"; case 0x1b: return "START/STOP UNIT"; case 0x12: return "INQUIRY"; case 0x1e: return "PREVENT/ALLOW MEDIA REMOVAL"; case 0x23: return "READ FORMAT CAPACITIES"; case 0x25: return "READ CAPACITY"; case 0x28: return "READ(10)"; case 0x2a: return "WRITE(10)"; case 0x35: return "SYNCHRONIZE CACHE"; case 0x43: return "READ TOC/PMA/ATIP"; case 0x46: return "GET CONFIGURATION"; case 0x4a: return "GET EVENT STATUS NOTIFICATION"; case 0x51: return "READ DISC INFORMATION"; case 0x52: return "READ TRACK INFORMATION"; case 0x53: return "RESERVE TRACK"; case 0x54: return "SEND OPC INFORMATION"; case 0x55: return "MODE SELECT"; case 0x5a: return "MODE SENSE"; case 0x5b: return "CLOSE TRACK/SESSION"; case 0x5c: return "READ BUFFER CAPACITY"; case 0x5d: return "SEND CUE SHEET"; case 0xa1: return "BLANK"; case 0xaa: return "WRITE(12)"; case 0xab: return "READ MEDIA SERIAL NUMBER"; case 0xac: return "GET PERFORMANCE"; case 0xad: return "READ DISC STRUCTURE"; case 0xb6: return "SET STREAMING"; case 0xb9: return "READ CD MSF"; case 0xbb: return "SET CD SPEED"; case 0xbe: return "READ CD"; #ifdef Libburn_develop_quality_scaN case 0xf3: return "NEC/OPTIARC REPORT ERROR RATE"; #endif /* Libburn_develop_quality_scaN */ } return "(NOT IN LIBBURN COMMAND LIST)"; } /* ts A61030 - A61115 */ /* @param flag bit0= do report conditions which are considered not an error bit1= report with severity FAILURE rather than DEBUG */ int scsi_notify_error(struct burn_drive *d, struct command *c, unsigned char *sense, int senselen, int flag) { int key= -1, asc= -1, ascq= -1, ret; char *msg = NULL, *scsi_msg = NULL; if (d->silent_on_scsi_error == 1 || d->silent_on_scsi_error == 2) {ret = 1; goto ex;} BURN_ALLOC_MEM(msg, char, 320); BURN_ALLOC_MEM(scsi_msg, char, 160); scsi_error_msg(d, sense, senselen, scsi_msg, &key, &asc, &ascq); if (!(flag & 1)) { /* SPC : TEST UNIT READY command */ if (c->opcode[0] == 0) {ret = 1; goto ex;} /* MMC : READ DISC INFORMATION command */ if (c->opcode[0] == 0x51) if (key == 0x2 && asc == 0x3A && ascq>=0 && ascq <= 0x02) /* MEDIUM NOT PRESENT */ {ret = 1; goto ex;} if (key == 0 && asc == 0 && ascq == 0) {ret = 1; goto ex;} } sprintf(msg, "SCSI error condition on command %2.2Xh %s: ", c->opcode[0], scsi_command_name((unsigned int) c->opcode[0], 0)); strcat(msg, scsi_msg); ret = libdax_msgs_submit(libdax_messenger, d->global_index, 0x0002010f, (flag & 2) && d->silent_on_scsi_error != 3 ? LIBDAX_MSGS_SEV_FAILURE : LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH, msg,0,0); ex:; BURN_FREE_MEM(msg); BURN_FREE_MEM(scsi_msg); return ret; } /* ts B11110 */ /* @param flag bit0= do not show eventual data payload sent to the drive (never with WRITE commands) */ int scsi_show_command(unsigned char *opcode, int oplen, int dir, unsigned char *data, int bytes, void *fp_in, int flag) { int i; FILE *fp = fp_in; fprintf(fp, "\n%s\n", scsi_command_name((unsigned int) opcode[0], 0)); for(i = 0; i < 16 && i < oplen; i++) fprintf(fp, "%2.2x ", opcode[i]); if (i > 0) fprintf(fp, "\n"); if (flag & 1) return 1; if (opcode[0] == 0x2A) { /* WRITE 10 */ if ((flag & 2) && oplen > 8) fprintf(fp, "%d -> %d\n", (opcode[7] << 8) | opcode[8], mmc_four_char_to_int(opcode + 2)); } else if (opcode[0] == 0xAA) { /* WRITE 12 */ if ((flag & 2) && oplen > 9) fprintf(fp, "%d -> %d\n", mmc_four_char_to_int(opcode + 6), mmc_four_char_to_int(opcode + 2)); } else if (dir == TO_DRIVE && !(flag & 1)) { fprintf(fp, "To drive: %db\n", bytes); for (i = 0; i < bytes; i++) fprintf(fp, "%2.2x%c", data[i], ((i % 20) == 19 ? '\n' : ' ')); if (i % 20) fprintf(fp, "\n"); } return 1; } /* ts A91106 */ /* @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; FILE *fp = fp_in; if (data_dir != FROM_DRIVE) return 2; if (opcode[0] == 0x28 || opcode[0] == 0x3C || opcode[0] == 0xA8 || opcode[0] == 0xB9 || opcode[0] == 0xBE) { /* READ commands */ /* >>> report amount of data */; return 2; } fprintf(fp, "From drive: %db\n", dxfer_len); for (i = 0; i < dxfer_len; i++) fprintf(fp, "%2.2x%c", data[i], ((i % 20) == 19 ? '\n' : ' ')); if (i % 20) fprintf(fp, "\n"); return 1; } /* 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 B40731 */ /* Arbitrary SCSI log message */ int scsi_log_text(char *text, void *fp_in, int flag) { FILE *fp = fp_in; if (fp != NULL && (fp == stderr || (burn_sg_log_scsi & 1))) { fprintf(fp, "%s\n", text); if (burn_sg_log_scsi & 4) fflush(fp); } if (fp == stderr || !(burn_sg_log_scsi & 2)) return 1; fprintf(stderr, "%s\n", text); return 1; } /* ts A91218 (former sg_log_cmd ts A70518) */ /** Logs command (before execution) */ int scsi_log_cmd(struct command *c, void *fp_in, int flag) { int ret, bytes = 0; unsigned char *data = NULL; if (c->page != NULL) { data = c->page->data; bytes = c->page->bytes; } ret = scsi_log_command(c->opcode, c->oplen, c->dir, data, bytes, fp_in, flag); return ret; } /* 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, double duration, int flag) { FILE *fp = fp_in; int key, asc, ascq, i, l; if (fp != NULL && (fp == stderr || (burn_sg_log_scsi & 1))) { if (flag & 1) { l = 18; if ((sense[0] & 0x7f) == 0x72 || (sense[0] & 0x7f) == 0x73) l = sense[7] + 7 + 1; /* SPC-3 4.5.2. */ if (l > sense_len) l = sense_len; fprintf(fp, "+++ sense data ="); for (i = 0 ; i < l; i++) fprintf(fp, " %2.2X", sense[i]); fprintf(fp, "\n"); spc_decode_sense(sense, 0, &key, &asc, &ascq); fprintf(fp, "+++ key=%X asc=%2.2Xh ascq=%2.2Xh\n", (unsigned int) key, (unsigned int) asc, (unsigned int) ascq); } else { scsi_show_command_reply(opcode, data_dir, data, dxfer_len, fp, 0); } if (!(flag & 2)) fprintf(fp, " %8.f us [ %.f ]\n", duration * 1.0e6, (burn_get_time(0) - lib_start_time) * 1.0e6); if (burn_sg_log_scsi & 4) fflush(fp); } if (fp == stderr || !(burn_sg_log_scsi & 2)) return 1; scsi_log_reply(opcode, data_dir, data, dxfer_len, stderr, sense, sense_len, duration, flag); 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 burn_drive *d, struct command *c, void *fp_in, unsigned char sense[18], int sense_len, 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, c->end_time - c->start_time, flag); return ret; } /* ts B31112 */ int scsi_log_message(struct burn_drive *d, void *fp_in, char * msg, int flag) { int ret; FILE *fp = fp_in; if (fp != NULL && (fp == stderr || (burn_sg_log_scsi & 1))) { fprintf(fp, "%s\n", msg); if (burn_sg_log_scsi & 4) fflush(fp); } if (fp == stderr || !(burn_sg_log_scsi & 2)) return 1; ret = scsi_log_message(d, stderr, msg, flag); return ret; } /* ts B00808 */ /* @param flag bit0 = do not retry bit1 = do not print duration @return 0 = not yet done , 1 = done , -1 = error */ int scsi_eval_cmd_outcome(struct burn_drive *d, struct command *c, void *fp, unsigned char *sense, int sense_len, time_t start_time, int timeout_ms, int loop_count, int flag) { enum response outcome; int done = -1, usleep_time; char *msg = NULL; if (burn_sg_log_scsi & 3) scsi_log_err(d, c, fp, sense, sense_len, (sense_len > 0) | (flag & 2)); if (sense_len <= 0) {done = 1; goto ex;} outcome = scsi_error(d, sense, sense_len); if (outcome == RETRY && c->retry && !(flag & 1)) { /* Calming down retries and breaking up endless cycle */ if (c->opcode[0] == 0x2A || c->opcode[0] == 0xAA) { /* WRITE(10) , WRITE(12) */ usleep_time = Libburn_scsi_write_retry_usleeP + loop_count * Libburn_scsi_write_retry_incR; if (usleep_time > Libburn_scsi_write_retry_umaX) usleep_time = Libburn_scsi_write_retry_umaX; } else { usleep_time = Libburn_scsi_retry_usleeP + loop_count * Libburn_scsi_retry_incR; if (usleep_time > Libburn_scsi_retry_umaX) usleep_time = Libburn_scsi_retry_umaX; } if (time(NULL) + usleep_time / 1000000 - start_time > timeout_ms / 1000 + 1) { done = -1; /* In case of alloc failure */ BURN_ALLOC_MEM_VOID(msg, char, 320); done = 1; sprintf(msg, "Timeout exceed (%d ms). Retry canceled.\n", timeout_ms); libdax_msgs_submit(libdax_messenger, d->global_index, 0x0002018a, LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH, msg, 0, 0); goto err_ex; } if (d->cancel) {done = 1; goto ex;} if (usleep_time > 0) usleep(usleep_time); if (d->cancel) {done = 1; goto ex;} if (burn_sg_log_scsi & 3) scsi_log_cmd(c, fp, 0); {done = 0; goto ex;} } else if (outcome == RETRY) { done = 1; } else if (outcome == GO_ON) { {done = 1; goto ex;} } else if (outcome == FAIL) { done = 1; } err_ex:; c->error = 1; scsi_notify_error(d, c, sense, sense_len, 0); ex:; BURN_FREE_MEM(msg); return done; } int spc_confirm_cd_drive(struct burn_drive *d, int flag) { char *msg = NULL; int ret; BURN_ALLOC_MEM(msg, char, strlen(d->devname) + 1024); spc_inquiry(d); if (d->idata->valid < 0) { sprintf(msg, "INQUIRY failed with drive '%s'", d->devname); libdax_msgs_submit(libdax_messenger, -1, 0x0002000a, LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH, msg, 0,0); ret = 0; goto ex; } if (d->idata->peripheral != 0x5) { sprintf(msg, "Does not identify itself as CD-ROM drive '%s'", d->devname); libdax_msgs_submit(libdax_messenger, -1, 0x0002000a, LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH, msg, 0,0); ret = 0; goto ex; } ret = 1; ex:; BURN_FREE_MEM(msg); return ret; } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������libburn-1.4.2/libburn/util.c������������������������������������������������������������������������0000644�0001757�0001751�00000030552�12652644224�012676� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ /* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens Copyright (c) 2006 - 2013 Thomas Schmitt <scdbackup@gmx.net> Provided under GPL version 2 or later. */ #ifdef HAVE_CONFIG_H #include "../config.h" #endif #include <string.h> /* ts A61008 */ /* #include <a ssert.h> */ #include <stdlib.h> #include <stdio.h> #include <time.h> #include <sys/time.h> #include <sys/types.h> #include <sys/stat.h> #include <unistd.h> /* ts A80914 : This is unneeded. Version info comes from libburn.h. #include "v ersion.h" */ #include "util.h" #include "libburn.h" void burn_version(int *major, int *minor, int *micro) { /* ts A80408 : switched from configure.ac versioning to libburn.h versioning */ *major = burn_header_version_major; *minor = burn_header_version_minor; *micro = burn_header_version_micro; } struct cd_mid_record { char *manufacturer; int m_li; int s_li; int f_li; char *other_brands; }; typedef struct cd_mid_record cd_mid_record_t; /* ts A90902 */ /** API @param flag Bitfield for control purposes, bit0= append "(aka %s)",other_brands to reply */ 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) { static cd_mid_record_t mid_list[]= { {"SKC", 96, 40, 0, ""}, {"Ritek Corp" , 96, 43, 30, ""}, {"TDK / Ritek" , 97, 10, 0, "TRAXDATA"}, {"TDK Corporation" , 97, 15, 0, ""}, {"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, ""}, {"Nan-Ya Plastics Corporation" , 97, 15, 30, "Hatron, MMore, Acer, LITEON"}, {"Delphi" , 97, 15, 50, ""}, {"Shenzhen SG&SAST" , 97, 16, 20, ""}, {"Moser Baer India Limited" , 97, 17, 0, "EMTEC, Intenso, YAKUMO, PLATINUM, Silver Circle"}, {"SKY media Manufacturing SA" , 97, 17, 10, ""}, {"Wing" , 97, 18, 10, ""}, {"DDT" , 97, 18, 20, ""}, {"Daxon Technology Inc. / Acer" , 97, 22, 60, "Maxmax, Diamond Data, BenQ, gold, SONY"}, {"Taiyo Yuden Company Limited" , 97, 24, 0, "Maxell, FUJIFILM, SONY"}, {"Sony Corporation" , 97, 24, 10, "LeadData, Imation"}, {"Computer Support Italcard s.r.l" , 97, 24, 20, ""}, {"Unitech Japan Inc." , 97, 24, 30, ""}, {"MPO, France" , 97, 25, 0, "TDK"}, {"Hitachi Maxell Ltd." , 97, 25, 20, ""}, {"Infodisc Technology Co,Ltd." , 97, 25, 30, "MEMOREX, SPEEDA, Lead data"}, {"Xcitec" , 97, 25, 60, ""}, {"Fornet International Pte Ltd" , 97, 26, 0, "COMPUSA, Cdhouse"}, {"Postech Corporation" , 97, 26, 10, "Mr.Platinum"}, {"SKC Co Ltd." , 97, 26, 20, "Infinite"}, {"Fuji Photo Film Co,Ltd." , 97, 26, 40, ""}, {"Lead Data Inc." , 97, 26, 50, "SONY, Gigastorage, MIRAGE"}, {"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, "Sony, Digital Storage, Csita"}, {"Plasmon Data Systems Ltd" , 97, 27, 10, "Ritek, TDK, EMTEC, ALPHAPET, MANIA"}, {"Princo Corporation" , 97, 27, 20, ""}, {"Pioneer" , 97, 27, 30, ""}, {"Eastman Kodak Company" , 97, 27, 40, ""}, {"Mitsui Chemicals Inc." , 97, 27, 50, "MAM-A, TDK"}, {"Ricoh Company Limited" , 97, 27, 60, "Ritek"}, {"Gigastorage Corporation" , 97, 28, 10, "MaxMax, Nan-Ya"}, {"Multi Media Masters&Machinary SA" , 97, 28, 20, "King, Mmirex"}, {"Ritek Corp" , 97, 31, 0, "TDK"}, {"Grand Advance Technology Sdn. Bhd." , 97, 31, 30, ""}, {"TDK Corporation" , 97, 32, 00, ""}, {"Prodisc Technology Inc." , 97, 32, 10, "Smartbuy, Mitsubishi, Digmaster, LG, Media Market"}, {"Mitsubishi Chemical Corporation" , 97, 34, 20, "YAMAHA, Verbatim"}, {"Mitsui Chemicals Inc." , 97, 48, 50, ""}, {"TDK Corporation" , 97, 49, 0, ""}, {"", 0, 0, 0, ""} }; int i, f_li_0; char buf[1024]; char *result = NULL; if (m_li == 0 && s_li == 2 && f_li == 0) { result = strdup("(no manufacturer code)"); return result; } f_li_0 = f_li - (f_li % 10); for (i = 0; mid_list[i].manufacturer[0]; i++) { if (m_li == mid_list[i].m_li && s_li == mid_list[i].s_li && (f_li_0 == mid_list[i].f_li || f_li == mid_list[i].f_li)) break; } if (mid_list[i].manufacturer[0] == 0) { sprintf(buf, "Unknown CD manufacturer. Please report code '%2.2dm%2.2ds%2.2df/%2.2dm%2.2ds%2.2df', the human readable brand, size, and speed to scdbackup@gmx.net.", m_li, s_li, f_li, m_lo, s_lo, f_lo); result = strdup(buf); return result; } /* Compose, allocate and copy result */ if ((flag & 1) && mid_list[i].other_brands[0]) { sprintf(buf, "%s (aka %s)", mid_list[i].manufacturer, mid_list[i].other_brands); result = strdup(buf); } else result = strdup(mid_list[i].manufacturer); return result; } /* ts A90904 */ struct dvd_mid_record { char *mc1; int mc1_sig_len; char *manufacturer; }; typedef struct dvd_mid_record dvd_mid_record_t; /* ts A90904 */ char *burn_guess_manufacturer(int prf, char *media_code1, char *media_code2, int flag) { int i, l = 0, m_li, s_li, f_li, m_lo, s_lo, f_lo; char buf[1024]; char *result = NULL, *cpt; /* Important Note: media_code1 and media_code2 are supposed to be encoded by burn_util_make_printable_word(). Especially: ' ' -> '_' , {"_%/" unprintables -> %XY) */ static dvd_mid_record_t mid_list[]= { {"AML", 8, "UML"}, {"BeAll", 5, "BeAll Developers, Inc."}, {"CMC", 3, "CMC Magnetics Corporation"}, {"DAXON", 5, "Daxon Technology Inc. / Acer"}, {"Daxon", 5, "Daxon Technology Inc. / Acer"}, {"FUJI", 4, "Fujifilm Holdings Corporation"}, {"INFODISC", 8, "New Star Digital Co., Ltd."}, {"INFOME", 6, "InfoMedia Inc."}, {"ISMMBD", 6, "Info Source Multi Media Ltd."}, {"JVC", 3, "JVC Limited"}, {"KIC01RG", 7, "AMC"}, {"LD", 8, "Lead Data Inc."}, {"LGE", 3, "LG Electronics"}, {"MAM", 8, "Mitsui Advanced Media, Inc. Europe"}, {"MAXELL", 6, "Hitachi Maxell Ltd."}, {"MBI", 3, "Moser Baer India Limited"}, {"MCC", 8, "Mitsubishi Chemical Corporation"}, {"MCI", 8, "Mitsui Chemicals Inc."}, {"MEI", 3, "Panasonic Corporation"}, {"MILLEN", 8, "Millenniata Inc."}, {"MKM", 3, "Mitsubishi Kagaku Media Co."}, {"MMC", 8, "Mitsubishi Kagaku Media Co."}, {"MXL", 8, "Hitachi Maxell Ltd."}, {"NANYA", 5, "Nan-Ya Plastics Corporation"}, {"NSD", 8, "NESA International Inc."}, {"OPTODISC", 8, "Optodisc Technology Corporation"}, {"OTCBDR", 8, "Optodisc Technology Corporation"}, {"PHILIP", 8, "Moser Baer India Limited"}, {"PHILIPS", 8, "Philips"}, {"PRINCO", 6, "Princo Corporation"}, {"PRODISC", 7, "Prodisc Technology Inc."}, {"Prodisc", 7, "Prodisc Technology Inc."}, {"PVC", 3, "Pioneer"}, {"RICOHJPN", 8, "Ricoh Company Limited"}, {"RITEK", 5, "Ritek Corp"}, {"SONY", 4, "Sony Corporation"}, {"TDK", 3, "TDK Corporation"}, {"TT", 8, "TDK Corporation"}, {"TY", 8, "Taiyo Yuden Company Limited"}, {"TYG", 3, "Taiyo Yuden Company Limited"}, {"UME", 3, "UmeDisc Limited"}, {"UTJR001", 7, "Unifino Inc."}, {"VERBAT", 5, "Mitsubishi Kagaku Media Co."}, {"YUDEN", 5, "Taiyo Yuden Company Limited"}, {"", 0, ""} }; if (media_code2 != NULL && (prf == -1 || prf == 0x09 || prf == 0x0A)) { if (strlen(media_code2) == 9 && media_code1[0] == '9' && media_code1[2] == 'm' && media_code1[5] == 's' && media_code1[8] == 'f' && strchr(media_code1, '%') == NULL) { sscanf(media_code1, "%dm%ds%df", &m_li, &s_li, &f_li); sscanf(media_code2, "%dm%ds%df", &m_lo, &s_lo, &f_lo); if (m_li >= 96 && m_li <= 97 && m_lo > 0) { result = burn_guess_cd_manufacturer( m_li, s_li, f_li, m_lo, s_lo, f_lo, 0); return result; } } } /* DVD-R do not keep manufacturer id apart from media id. Some manufacturers use a blank as separator which would now be '_'. */ cpt = strchr(media_code1, '_'); if (cpt != NULL && (prf == -1 || prf == 0x11 || prf == 0x13 || prf == 0x14 || prf == 0x15)) l = cpt - media_code1; for (i = 0; mid_list[i].mc1[0]; i++) { if (strncmp(mid_list[i].mc1, media_code1, mid_list[i].mc1_sig_len) == 0) break; if (l > 0) if (strncmp(mid_list[i].mc1, media_code1, l) == 0) break; } if (mid_list[i].mc1[0] == 0) { sprintf(buf, "Unknown DVD/BD manufacturer. Please report code '%s/%s', the human readable brand, size, and speed to scdbackup@gmx.net.", media_code1, media_code2); result = strdup(buf); return result; } result = strdup(mid_list[i].manufacturer); return result; } /* ts A90905 */ /* Make *text a single printable word */ /* IMPORTANT: text must be freeable memory ! @param flag bit0=escape '/' too bit1=(overrides bit0) do not escape " _/" */ int burn_util_make_printable_word(char **text, int flag) { int i, esc_add = 0, ret; char *wpt, *rpt, *new_text = NULL; if (flag & 2) flag &= ~1; for (i = 0; (*text)[i]; i++) { rpt = (*text) + i; if (*rpt < 32 || *rpt > 126 || *rpt == 96 || ((*rpt == '_' || *rpt == '%') && (!(flag & 2))) || (*rpt == '/' && (flag & 1))) esc_add += 2; } if (esc_add) { new_text = calloc(strlen(*text) + esc_add + 1, 1); if (new_text == NULL) { ret = -1; goto ex; } wpt = new_text; for (i = 0; (*text)[i]; i++) { rpt = (*text) + i; if (*rpt < 32 || *rpt > 126 || *rpt == 96 || ((*rpt == '_' || *rpt == '%') && (!(flag & 2))) || (*rpt == '/' && (flag & 1))) { sprintf(wpt, "%%%2.2X", (unsigned int) *((unsigned char *) rpt)); wpt+= 3; } else *(wpt++) = *rpt; } *wpt = 0; free(*text); *text = new_text; } if (!(flag & 2)) for (i = 0; (*text)[i]; i++) if ((*text)[i] == ' ') (*text)[i] = '_'; ret = 1; ex: return ret; } /* ts B11216 */ /** Read a line from fp and strip LF or CRLF */ char *burn_sfile_fgets(char *line, int maxl, FILE *fp) { int l; char *ret; ret = fgets(line, maxl, fp); if (ret == NULL) return NULL; l = strlen(line); if (l > 0) if (line[l - 1] == '\r') line[--l] = 0; if (l > 0) if (line[l - 1] == '\n') line[--l] = 0; if(l > 0) if(line[l - 1] == '\r') line[--l] = 0; return ret; } char *burn_printify(char *msg) { char *cpt; for (cpt = msg; *cpt != 0; cpt++) if (*cpt < 32 || *cpt > 126) *cpt = '#'; return msg; } /* ts B30521 */ void burn_int_to_lsb(int val, char *target) { unsigned char *buf; buf = (unsigned char *) target; buf[0] = val & 0xff; buf[1] = (val >> 8) & 0xff; buf[2] = (val >> 16) & 0xff; buf[3] = (val >> 24) & 0xff; } /* ts B30609 */ double burn_get_time(int flag) { int ret; struct timeval tv; #ifdef Libburn_use_clock_gettime_monotoniC #ifdef _POSIX_TIMERS #ifdef _POSIX_MONOTONIC_CLOCK /* Enable by export CFLAGS=-DLibburn_use_clock_gettime_monotoniC export LIBS=-lrt ./configure ... && make clean && make */ struct timespec tp; ret = clock_gettime(CLOCK_MONOTONIC, &tp); if (ret == 0) return ((double) tp.tv_sec) + ((double) tp.tv_nsec) * 1.0e-9; #endif /* _POSIX_MONOTONIC_CLOCK */ #endif /* _POSIX_TIMERS */ #endif /* Xorriso_use_clock_gettime_monotoniC */ ret = gettimeofday(&tv, NULL); if (ret == 0) return ((double) tv.tv_sec) + ((double) tv.tv_usec) * 1.0e-6; return (double) time(NULL); } /* ts B40609 */ off_t burn_sparse_file_addsize(off_t write_start, struct stat *stbuf) { off_t add_size; add_size = stbuf->st_blocks * (off_t) 512; if (add_size < stbuf->st_size) { /* Sparse file */ if (write_start < stbuf->st_size) { /* Might write into sparse gaps */ if (write_start > add_size) add_size = write_start; } else { /* Will not write into sparse area */ add_size = stbuf->st_size; } } return add_size; } ������������������������������������������������������������������������������������������������������������������������������������������������������libburn-1.4.2/libburn/options.c���������������������������������������������������������������������0000644�0001757�0001751�00000037451�12652644224�013421� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ /* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens Copyright (c) 2006 - 2012 Thomas Schmitt <scdbackup@gmx.net> Provided under GPL version 2 or later. */ #ifdef HAVE_CONFIG_H #include "../config.h" #endif #include "libburn.h" #include "options.h" #include "drive.h" #include "transport.h" #include "init.h" #include "write.h" /* ts A61007 */ /* #include <a ssert.h> */ #include <stdlib.h> #include <string.h> #include <stdio.h> #include "libdax_msgs.h" extern struct libdax_msgs *libdax_messenger; struct burn_write_opts *burn_write_opts_new(struct burn_drive *drive) { struct burn_write_opts *opts; opts = calloc(1, sizeof(struct burn_write_opts)); if (opts == NULL) { libdax_msgs_submit(libdax_messenger, -1, 0x00020111, LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH, "Could not allocate new auxiliary object", 0, 0); return NULL; } opts->drive = drive; opts->refcount = 1; opts->write_type = BURN_WRITE_TAO; opts->block_type = BURN_BLOCK_MODE1; opts->toc_entry = NULL; opts->toc_entries = 0; opts->simulate = 0; opts->underrun_proof = drive->mdata->p2a_valid > 0 && drive->mdata->underrun_proof; opts->perform_opc = 1; opts->obs = -1; #ifdef Libburn_dvd_always_obs_paD opts->obs_pad = 1; #else opts->obs_pad = 0; #endif opts->start_byte = -1; opts->fill_up_media = 0; opts->force_is_set = 0; opts->do_stream_recording = 0; opts->dvd_obs_override = 0; opts->stdio_fsync_size = Libburn_stdio_fsync_limiT; opts->text_packs = NULL; opts->num_text_packs = 0; opts->no_text_pack_crc_check = 0; opts->has_mediacatalog = 0; opts->format = BURN_CDROM; opts->multi = 0; opts->control = 0; return opts; } void burn_write_opts_free(struct burn_write_opts *opts) { if (--opts->refcount > 0) return; if (opts->text_packs != NULL) free(opts->text_packs); free(opts); } int burn_write_opts_clone(struct burn_write_opts *from, struct burn_write_opts **to, int flag) { if (*to != NULL) burn_write_opts_free(*to); if (from == NULL) return 1; *to = calloc(1, sizeof(struct burn_write_opts)); if (*to == NULL) { libdax_msgs_submit(libdax_messenger, -1, 0x00000003, LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH, "Out of virtual memory", 0, 0); return -1; } memcpy(*to, from, sizeof(struct burn_write_opts)); (*to)->refcount= 1; return 1; } struct burn_read_opts *burn_read_opts_new(struct burn_drive *drive) { struct burn_read_opts *opts; opts = calloc(1, sizeof(struct burn_read_opts)); opts->drive = drive; opts->refcount = 1; opts->raw = 0; opts->c2errors = 0; opts->subcodes_audio = 0; opts->subcodes_data = 0; opts->hardware_error_recovery = 0; opts->report_recovered_errors = 0; opts->transfer_damaged_blocks = 0; opts->hardware_error_retries = 3; opts->dap_bit = 0; return opts; } void burn_read_opts_free(struct burn_read_opts *opts) { if (--opts->refcount <= 0) free(opts); } int burn_write_opts_set_write_type(struct burn_write_opts *opts, enum burn_write_types write_type, int block_type) { int sector_get_outmode(enum burn_write_types write_type, enum burn_block_types block_type); int spc_block_type(enum burn_block_types b); /* ts A61007 */ if (! ( (write_type == BURN_WRITE_SAO && block_type == BURN_BLOCK_SAO) || (opts->drive->block_types[write_type] & block_type) ) ) { bad_combination:; libdax_msgs_submit(libdax_messenger, -1, 0x00020112, LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH, "Bad combination of write_type and block_type", 0, 0); return 0; } /* ts A61007 : obsoleting Assert in sector.c:get_outmode() */ if (sector_get_outmode(write_type, (enum burn_block_types) block_type) == -1) goto bad_combination; /* ts A61007 : obsoleting Assert in spc.c:spc_block_type() */ if (spc_block_type((enum burn_block_types) block_type) == -1) goto bad_combination; opts->write_type = write_type; opts->block_type = block_type; return 1; /* a ssert(0); */ } void burn_write_opts_set_toc_entries(struct burn_write_opts *opts, int count, struct burn_toc_entry *toc_entries) { opts->toc_entries = count; opts->toc_entry = calloc(count, sizeof(struct burn_toc_entry)); memcpy(opts->toc_entry, &toc_entries, sizeof(struct burn_toc_entry) * count); } void burn_write_opts_set_format(struct burn_write_opts *opts, int format) { opts->format = format; } int burn_write_opts_set_simulate(struct burn_write_opts *opts, int sim) { opts->simulate = !!sim; return 1; } int burn_write_opts_set_underrun_proof(struct burn_write_opts *opts, int underrun_proof) { if (opts->drive->mdata->p2a_valid <= 0 || opts->drive->mdata->underrun_proof) { opts->underrun_proof = underrun_proof; return 1; } return 0; } void burn_write_opts_set_perform_opc(struct burn_write_opts *opts, int opc) { opts->perform_opc = opc; } void burn_write_opts_set_has_mediacatalog(struct burn_write_opts *opts, int has_mediacatalog) { opts->has_mediacatalog = has_mediacatalog; } void burn_write_opts_set_mediacatalog(struct burn_write_opts *opts, unsigned char mediacatalog[13]) { memcpy(opts->mediacatalog, mediacatalog, 13); } /* ts A61106 */ void burn_write_opts_set_multi(struct burn_write_opts *opts, int multi) { opts->multi = !!multi; } /* ts B31024 */ /* API */ void burn_write_opts_set_fail21h_sev(struct burn_write_opts *opts, char *severity) { int ret, sevno; ret = libdax_msgs__text_to_sev(severity, &sevno, 0); if (ret <= 0) opts->feat21h_fail_sev = 0; else opts->feat21h_fail_sev = sevno; } /* ts B11204 */ /* @param flag bit0=do not verify checksums bit1= repair mismatching checksums bit2= repair checksums if they are 00 00 with each pack */ int burn_write_opts_set_leadin_text(struct burn_write_opts *opts, unsigned char *text_packs, int num_packs, int flag) { int ret; unsigned char *pack_buffer = NULL; if (num_packs > Libburn_leadin_cdtext_packs_maX ) { libdax_msgs_submit(libdax_messenger, opts->drive->global_index, 0x0002018b, LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH, "Too many CD-TEXT packs", 0, 0); ret= 0; goto ex; } if (num_packs > 0) BURN_ALLOC_MEM(pack_buffer, unsigned char, num_packs * 18); if (opts->text_packs != NULL) { free(opts->text_packs); opts->text_packs = NULL; } if (flag & 1) { opts->no_text_pack_crc_check = 1; } else { opts->no_text_pack_crc_check = 0; ret = burn_cdtext_crc_mismatches(text_packs, num_packs, (flag >> 1) & 3); if (ret > 0) { libdax_msgs_submit(libdax_messenger, -1, 0x0002018f, LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH, "CD-TEXT pack CRC mismatch", 0, 0); ret = 0; goto ex; } else if (ret < 0) { libdax_msgs_submit(libdax_messenger, -1, 0x00020190, LIBDAX_MSGS_SEV_WARNING, LIBDAX_MSGS_PRIO_HIGH, "CD-TEXT pack CRC mismatch had to be corrected", 0, 0); } } if (num_packs > 0) { memcpy(pack_buffer, text_packs, num_packs * 18); opts->text_packs = pack_buffer; pack_buffer = NULL; } opts->num_text_packs = num_packs; ret = 1; ex:; BURN_FREE_MEM(pack_buffer); return ret; } /* ts A61222 */ void burn_write_opts_set_start_byte(struct burn_write_opts *opts, off_t value) { opts->start_byte = value; } /* ts A70207 API */ /** @param flag Bitfield for control purposes: bit0= do not choose type but check the one that is already set bit1= do not issue error messages via burn_msgs queue */ enum burn_write_types burn_write_opts_auto_write_type( struct burn_write_opts *opts, struct burn_disc *disc, char reasons[BURN_REASONS_LEN], int flag) { struct burn_multi_caps *caps = NULL; struct burn_drive *d = opts->drive; struct burn_disc_mode_demands demands; enum burn_write_types wt; int ret, would_do_sao = 0; char *reason_pt; reasons[0] = 0; if (d->status != BURN_DISC_BLANK && d->status != BURN_DISC_APPENDABLE){ if (d->status == BURN_DISC_FULL) strcat(reasons, "MEDIA: closed or not recordable, "); else strcat(reasons,"MEDIA: no writeable media detected, "); if (!(flag & 3)) libdax_msgs_submit(libdax_messenger, d->global_index, 0x0002013a, LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH, "No suitable media detected", 0, 0); return BURN_WRITE_NONE; } ret = burn_disc_get_write_mode_demands(disc, opts, &demands, !!opts->fill_up_media); if (ret <= 0) { strcat(reasons, "cannot recognize job demands, "); {wt = BURN_WRITE_NONE; goto ex;} } if (demands.exotic_track && !d->current_is_cd_profile) { if (demands.audio) strcat(reasons, "audio track prohibited by non-CD, "); else strcat(reasons, "exotic track prohibited by non-CD, "); {wt = BURN_WRITE_NONE; goto ex;} } if ((flag & 1) && opts->write_type != BURN_WRITE_SAO) goto try_tao; reason_pt = reasons + strlen(reasons); strcat(reasons, "SAO: "); if (d->status != BURN_DISC_BLANK) { strcat(reasons, "write type SAO works only on blank media, "); goto try_tao; } burn_disc_free_multi_caps(&caps); ret = burn_disc_get_multi_caps(d, BURN_WRITE_SAO, &caps, 0); if (ret < 0) { no_caps:; strcat(reasons, "cannot inquire write mode capabilities, "); {wt = BURN_WRITE_NONE; goto ex;} } else if (ret == 0) { strcat(reasons, "no SAO offered by drive and media, "); goto no_sao; } if ((opts->multi || demands.multi_session) && !caps->multi_session) strcat(reasons, "multi session capability lacking, "); if (demands.will_append) strcat(reasons, "appended session capability lacking, "); if (demands.multi_track && !caps->multi_track) strcat(reasons, "multi track capability lacking, "); if (demands.unknown_track_size == 1 && (caps->might_do_sao == 1 || caps->might_do_sao == 3)) strcat(reasons, "track size unpredictable, "); if (demands.mixed_mode) strcat(reasons, "tracks of different modes mixed, "); if (demands.exotic_track && !d->current_is_cd_profile) strcat(reasons, "non-data track on non-cd, "); else if (d->current_is_cd_profile) if ((d->block_types[BURN_WRITE_TAO] & demands.block_types) != demands.block_types) strcat(reasons, "drive dislikes block type, "); if (d->current_is_cd_profile && opts->fill_up_media) strcat(reasons, "cd sao cannot do media fill up yet, "); if (strcmp(reason_pt, "SAO: ") != 0) goto no_sao; would_do_sao = 1; if (demands.unknown_track_size == 2 && (!(flag & 1)) && (caps->might_do_sao == 1 || caps->might_do_sao == 3)) { strcat(reasons, "would have to use default track sizes, "); goto no_sao; } else if (caps->might_do_sao >= 3 && !(flag & 1)) goto try_tao; do_sao:; if (caps->might_simulate == 0 && opts->simulate && !opts->force_is_set) goto no_simulate; if (!(flag & 1)) burn_write_opts_set_write_type( opts, BURN_WRITE_SAO, BURN_BLOCK_SAO); {wt = BURN_WRITE_SAO; goto ex;} no_sao:; try_tao:; if (opts->num_text_packs > 0) { strcat(reasons, "CD-TEXT: write type SAO required, "); {wt = BURN_WRITE_NONE; goto ex;} } if ((flag & 1) && opts->write_type != BURN_WRITE_TAO) goto try_raw; reason_pt = reasons + strlen(reasons); strcat(reasons, "TAO: "); burn_disc_free_multi_caps(&caps); ret = burn_disc_get_multi_caps(d, BURN_WRITE_TAO, &caps, 0); if (ret < 0) goto no_caps; if (ret == 0) { strcat(reasons, "no TAO offered by drive and media, "); goto no_tao; } if ((opts->multi || demands.multi_session) && !caps->multi_session) strcat(reasons, "multi session capability lacking, "); if (demands.multi_track && !caps->multi_track) strcat(reasons, "multi track capability lacking, "); if (demands.exotic_track && !d->current_is_cd_profile) strcat(reasons, "non-data track on non-cd, "); if (d->current_is_cd_profile && !opts->force_is_set) if ((d->block_types[BURN_WRITE_TAO] & demands.block_types) != demands.block_types) strcat(reasons, "drive dislikes block type, "); if (strcmp(reason_pt, "TAO: ") != 0) goto no_tao; /* ( TAO data/audio block size will be handled automatically ) */ if (caps->might_simulate == 0 && opts->simulate && !opts->force_is_set) goto no_simulate; if (!(flag & 1)) burn_write_opts_set_write_type( opts, BURN_WRITE_TAO, BURN_BLOCK_MODE1); {wt = BURN_WRITE_TAO; goto ex;} no_tao:; if (would_do_sao && !(flag & 1)) goto do_sao; if (!d->current_is_cd_profile) goto no_write_mode; try_raw:; if ((flag & 1) && opts->write_type != BURN_WRITE_RAW) goto no_write_mode; if (!(flag & 1)) /* For now: no automatic raw write modes */ goto no_write_mode; reason_pt = reasons + strlen(reasons); strcat(reasons, "RAW: "); if (!d->current_is_cd_profile) strcat(reasons, "write type RAW prohibited by non-cd, "); else if (d->status != BURN_DISC_BLANK) strcat(reasons, "write type RAW works only on blank media, "); else if ((d->block_types[BURN_WRITE_TAO] & demands.block_types) != demands.block_types) strcat(reasons, "drive dislikes block type, "); if (strcmp(reason_pt, "RAW: ") != 0) goto no_write_mode; if (!opts->force_is_set) goto no_simulate; /* For now: no setting of raw write modes */ {wt = BURN_WRITE_RAW; goto ex;} no_write_mode:; {wt = BURN_WRITE_NONE; goto ex;} no_simulate:; strcat(reasons, "simulation of write job not supported by drive and media, "); {wt = BURN_WRITE_NONE; goto ex;} ex:; burn_disc_free_multi_caps(&caps); if (wt == BURN_WRITE_NONE && !(flag & 3)) { libdax_msgs_submit(libdax_messenger, d->global_index, 0x0002012b, LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH, "Drive offers no suitable write mode with this job", 0, 0); } return wt; } /* ts A70213 : new API function */ void burn_write_opts_set_fillup(struct burn_write_opts *opts,int fill_up_media) { opts->fill_up_media = !!fill_up_media; return; } /* ts A70303: API */ void burn_write_opts_set_force(struct burn_write_opts *opts, int use_force) { opts->force_is_set = !!use_force; } /* ts A80412: API */ void burn_write_opts_set_stream_recording(struct burn_write_opts *opts, int value) { opts->do_stream_recording = value; } /* ts A91115: API */ void burn_write_opts_set_dvd_obs(struct burn_write_opts *opts, int obs) { if (obs != 0 && obs != 32 * 1024 && obs != 64 * 1024) return; opts->dvd_obs_override = obs; } /* ts B20406: API */ void burn_write_opts_set_obs_pad(struct burn_write_opts *opts, int pad) { opts->obs_pad = 2 * !!pad; } /* ts A91115: API */ void burn_write_opts_set_stdio_fsync(struct burn_write_opts *opts, int rythm) { if (rythm == -1) opts->stdio_fsync_size = -1; /* never */ else if (rythm == 0) opts->stdio_fsync_size = Libburn_stdio_fsync_limiT; else if (rythm == 1) opts->stdio_fsync_size = 0; /* only at end of writing */ else if (rythm >= 32) opts->stdio_fsync_size = rythm; } /* ts A70901: API */ struct burn_drive *burn_write_opts_get_drive(struct burn_write_opts *opts) { return opts->drive; } void burn_read_opts_set_raw(struct burn_read_opts *opts, int raw) { opts->raw = raw; } void burn_read_opts_set_c2errors(struct burn_read_opts *opts, int c2errors) { opts->c2errors = c2errors; } void burn_read_opts_read_subcodes_audio(struct burn_read_opts *opts, int subcodes_audio) { opts->subcodes_audio = subcodes_audio; } void burn_read_opts_read_subcodes_data(struct burn_read_opts *opts, int subcodes_data) { opts->subcodes_data = subcodes_data; } void burn_read_opts_set_hardware_error_recovery(struct burn_read_opts *opts, int hardware_error_recovery) { opts->hardware_error_recovery = hardware_error_recovery; } void burn_read_opts_report_recovered_errors(struct burn_read_opts *opts, int report_recovered_errors) { opts->report_recovered_errors = report_recovered_errors; } void burn_read_opts_transfer_damaged_blocks(struct burn_read_opts *opts, int transfer_damaged_blocks) { opts->transfer_damaged_blocks = transfer_damaged_blocks; } void burn_read_opts_set_hardware_error_retries(struct burn_read_opts *opts, unsigned char hardware_error_retries) { opts->hardware_error_retries = hardware_error_retries; } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������libburn-1.4.2/libburn/sg-freebsd.c������������������������������������������������������������������0000644�0001757�0001751�00000070537�12652644224�013751� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */ /* Copyright (c) 2006 - 2013 Thomas Schmitt <scdbackup@gmx.net> Provided under GPL version 2 or later and under FreeBSD license revised, i.e. without advertising clause. */ #ifdef HAVE_CONFIG_H #include "../config.h" #endif #include <errno.h> #include <unistd.h> #include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <sys/ioctl.h> #include <sys/file.h> #include <stdlib.h> #include <string.h> #include <sys/poll.h> #include <camlib.h> #include <cam/scsi/scsi_message.h> #include <cam/scsi/scsi_pass.h> #include <err.h> /* XXX */ /* ts A70909 */ #include <sys/statvfs.h> /* ts B00121 */ #include <sys/disk.h> /* DIOCGMEDIASIZE */ /* ts B00326 : For use of CAM_PASS_ERR_RECOVER with ahci */ #define Libburn_for_freebsd_ahcI yes /* ts B00327 : for debugging of cam_send_cdb() failures # define Libburn_ahci_verbouS yes */ /* ts B00327 : Apply CAM_PASS_ERR_RECOVER to drives even if not ahci # define libburn_ahci_style_for_alL yes */ #include "transport.h" #include "drive.h" #include "sg.h" #include "spc.h" #include "mmc.h" #include "sbc.h" #include "debug.h" #include "toc.h" #include "util.h" #include "init.h" #include "libdax_msgs.h" extern struct libdax_msgs *libdax_messenger; struct burn_drive_enumeration_state { int fd; union ccb ccb; unsigned int i; int skip_device; }; static void enumerate_common(char *fname, int bus_no, int host_no, int channel_no, int target_no, int lun_no); /* ts A51221 */ int burn_drive_is_banned(char *device_address); /* ts A60821 debug: for tracing calls which might use open drive fds or for catching SCSI usage of emulated drives. */ int mmc_function_spy(struct burn_drive *d, char * text); /* ts B00113 Whether to log SCSI commands: bit0= log in /tmp/libburn_sg_command_log bit1= log to stderr bit2= flush every line */ extern int burn_sg_log_scsi; /* ts B00114 */ /* Storage object is in libburn/init.c whether to strive for exclusive access to the drive */ extern int burn_sg_open_o_excl; /* ts A91227 */ /** Returns the id string of the SCSI transport adapter and eventually needed operating system facilities. This call is usable even if sg_initialize() was not called yet. In that case a preliminary constant message might be issued if detailed info is not available yet. @param msg returns id string @param flag unused yet, submit 0 @return 1 = success, <=0 = failure */ int sg_id_string(char msg[1024], int flag) { strcpy(msg, "internal FreeBSD CAM adapter sg-freebsd"); return 1; } /* ts A91227 */ /** Performs global initialization of the SCSI transport adapter and eventually needed operating system facilities. Checks for compatibility supporting software components. @param msg returns ids and/or error messages of eventual helpers @param flag unused yet, submit 0 @return 1 = success, <=0 = failure */ int sg_initialize(char msg[1024], int flag) { return sg_id_string(msg, 0); } /* ts A91227 */ /** Performs global finalization of the SCSI transport adapter and eventually needed operating system facilities. Releases globally aquired resources. @param flag unused yet, submit 0 @return 1 = success, <=0 = failure */ int sg_shutdown(int flag) { return 1; } /** Finalizes BURN_OS_TRANSPORT_DRIVE_ELEMENTS, the components of struct burn_drive which are defined in os-*.h. The eventual initialization of those components was made underneath scsi_enumerate_drives(). This will be called when a burn_drive gets disposed. @param d the drive to be finalized @param flag unused yet, submit 0 @return 1 = success, <=0 = failure */ int sg_dispose_drive(struct burn_drive *d, int flag) { return 1; } /* ts A61021 : Moved most code from scsi_enumerate_drives under sg_give_next_adr() */ /* Some helper functions for scsi_give_next_adr() */ static int sg_init_enumerator(burn_drive_enumerator_t *idx_) { struct burn_drive_enumeration_state *idx; int bufsize; idx = calloc(1, sizeof(*idx)); if (idx == NULL) { warnx("cannot allocate memory for enumerator"); return -1; } idx->skip_device = 0; if ((idx->fd = open(XPT_DEVICE, O_RDWR)) == -1) { warn("could not open %s", XPT_DEVICE); free(idx); idx = NULL; return -1; } memset(&(idx->ccb), 0, sizeof(union ccb)); idx->ccb.ccb_h.path_id = CAM_XPT_PATH_ID; idx->ccb.ccb_h.target_id = CAM_TARGET_WILDCARD; idx->ccb.ccb_h.target_lun = CAM_LUN_WILDCARD; idx->ccb.ccb_h.func_code = XPT_DEV_MATCH; bufsize = sizeof(struct dev_match_result) * 100; idx->ccb.cdm.match_buf_len = bufsize; idx->ccb.cdm.matches = (struct dev_match_result *) calloc(1, bufsize); if (idx->ccb.cdm.matches == NULL) { warnx("cannot allocate memory for matches"); close(idx->fd); free(idx); return -1; } idx->ccb.cdm.num_matches = 0; idx->i = idx->ccb.cdm.num_matches; /* to trigger buffer load */ /* * We fetch all nodes, since we display most of them in the default * case, and all in the verbose case. */ idx->ccb.cdm.num_patterns = 0; idx->ccb.cdm.pattern_buf_len = 0; *idx_ = idx; return 1; } static void sg_destroy_enumerator(burn_drive_enumerator_t *idx_) { struct burn_drive_enumeration_state *idx = *idx_; if(idx->fd != -1) close(idx->fd); free(idx->ccb.cdm.matches); free(idx); *idx_ = NULL; } static int sg_next_enumeration_buffer(burn_drive_enumerator_t *idx_) { struct burn_drive_enumeration_state *idx = *idx_; /* * We do the ioctl multiple times if necessary, in case there are * more than 100 nodes in the EDT. */ if (ioctl(idx->fd, CAMIOCOMMAND, &(idx->ccb)) == -1) { warn("error sending CAMIOCOMMAND ioctl"); return -1; } if ((idx->ccb.ccb_h.status != CAM_REQ_CMP) || ((idx->ccb.cdm.status != CAM_DEV_MATCH_LAST) && (idx->ccb.cdm.status != CAM_DEV_MATCH_MORE))) { warnx("got CAM error %#x, CDM error %d\n", idx->ccb.ccb_h.status, idx->ccb.cdm.status); return -1; } return 1; } /** Returns the next index object state and the next enumerated drive address. @param idx An opaque handle. Make no own theories about it. @param adr Takes the reply @param adr_size Gives maximum size of reply including final 0 @param initialize 1 = start new, 0 = continue, use no other values for now -1 = finish @return 1 = reply is a valid address , 0 = no further address available -1 = severe error (e.g. adr_size too small) */ int sg_give_next_adr(burn_drive_enumerator_t *idx_, char adr[], int adr_size, int initialize) { struct burn_drive_enumeration_state *idx; int ret; if (initialize == 1) { ret = sg_init_enumerator(idx_); if (ret<=0) return ret; } else if (initialize == -1) { sg_destroy_enumerator(idx_); return 0; } idx = *idx_; do { if (idx->i >= idx->ccb.cdm.num_matches) { ret = sg_next_enumeration_buffer(idx_); if (ret<=0) return -1; idx->i = 0; } else (idx->i)++; while (idx->i < idx->ccb.cdm.num_matches) { switch (idx->ccb.cdm.matches[idx->i].type) { case DEV_MATCH_BUS: break; case DEV_MATCH_DEVICE: { struct device_match_result* result; result = &(idx->ccb.cdm.matches[idx->i].result.device_result); if (result->flags & DEV_RESULT_UNCONFIGURED) idx->skip_device = 1; else idx->skip_device = 0; break; } case DEV_MATCH_PERIPH: { struct periph_match_result* result; result = &(idx->ccb.cdm.matches[idx->i].result.periph_result); /* ts B00112 : we really want only "cd" devices. if (idx->skip_device || strcmp(result->periph_name, "pass") == 0) break; */ if (idx->skip_device || strcmp(result->periph_name, "cd") != 0) break; ret = snprintf(adr, adr_size, "/dev/%s%d", result->periph_name, result->unit_number); if(ret >= adr_size) return -1; /* Found next enumerable address */ return 1; } default: /* fprintf(stderr, "unknown match type\n"); */ break; } (idx->i)++; } } while ((idx->ccb.ccb_h.status == CAM_REQ_CMP) && (idx->ccb.cdm.status == CAM_DEV_MATCH_MORE)); return 0; } int sg_is_enumerable_adr(char* adr) { burn_drive_enumerator_t idx; int ret; char buf[64]; ret = sg_init_enumerator(&idx); if (ret <= 0) return 0; while(1) { ret = sg_give_next_adr(&idx, buf, sizeof(buf), 0); if (ret <= 0) break; if (strcmp(adr, buf) == 0) { sg_destroy_enumerator(&idx); return 1; } } sg_destroy_enumerator(&idx); return (0); } /** Try to obtain SCSI address parameters. @return 1 is success , 0 is failure */ int sg_obtain_scsi_adr(char *path, int *bus_no, int *host_no, int *channel_no, int *target_no, int *lun_no) { burn_drive_enumerator_t idx; int ret; char buf[64]; struct periph_match_result* result; ret = sg_init_enumerator(&idx); if (ret <= 0) return 0; while(1) { ret = sg_give_next_adr(&idx, buf, sizeof(buf), 0); if (ret <= 0) break; if (strcmp(path, buf) == 0) { result = &(idx->ccb.cdm.matches[idx->i].result.periph_result); *bus_no = result->path_id; *host_no = result->path_id; *channel_no = 0; *target_no = result->target_id; *lun_no = result->target_lun; sg_destroy_enumerator(&idx); return 1; } } sg_destroy_enumerator(&idx); return (0); } int sg_close_drive(struct burn_drive * d) { if (d->cam != NULL) { cam_close_device(d->cam); d->cam = NULL; } if (d->lock_fd > 0) { close(d->lock_fd); d->lock_fd = -1; } return 0; } int sg_drive_is_open(struct burn_drive * d) { return (d->cam != NULL); } int scsi_enumerate_drives(void) { burn_drive_enumerator_t idx; int ret; char buf[64]; struct periph_match_result* result; ret = sg_init_enumerator(&idx); if (ret <= 0) return 0; while(1) { ret = sg_give_next_adr(&idx, buf, sizeof(buf), 0); if (ret <= 0) break; if (burn_drive_is_banned(buf)) continue; result = &idx->ccb.cdm.matches[idx->i].result.periph_result; enumerate_common(buf, result->path_id, result->path_id, 0, result->target_id, result->target_lun); } sg_destroy_enumerator(&idx); return 1; } #ifdef Scsi_freebsd_make_own_enumeratE /* ts A61021: The old version which mixes SCSI and operating system adapter */ static void enumerate_common(char *fname, int bus_no, int host_no, int channel_no, int target_no, int lun_no) { struct burn_drive *t; struct burn_drive out; /* Initialize pointers to managed memory */ out.devname = NULL; out.idata = NULL; out.mdata = NULL; /* ts A60923 */ out.bus_no = bus_no; out.host = host_no; out.id = target_no; out.channel = channel_no; out.lun = lun_no; out.devname = strdup(fname); if (out.devname == NULL) goto could_not_allocate; out.cam = NULL; out.lock_fd = -1; out.is_ahci = 0; out.start_lba= -2000000000; out.end_lba= -2000000000; out.read_atip = mmc_read_atip; out.grab = sg_grab; out.release = sg_release; out.drive_is_open= sg_drive_is_open; out.issue_command = sg_issue_command; out.getcaps = spc_getcaps; out.released = 1; out.status = BURN_DISC_UNREADY; out.eject = sbc_eject; out.load = sbc_load; out.lock = spc_prevent; out.unlock = spc_allow; out.read_disc_info = spc_sense_write_params; out.get_erase_progress = spc_get_erase_progress; out.test_unit_ready = spc_test_unit_ready; out.probe_write_modes = spc_probe_write_modes; out.read_toc = mmc_read_toc; out.write = mmc_write; out.erase = mmc_erase; out.read_cd = mmc_read_cd; out.perform_opc = mmc_perform_opc; out.set_speed = mmc_set_speed; out.send_parameters = spc_select_error_params; out.send_write_parameters = spc_select_write_params; out.send_cue_sheet = mmc_send_cue_sheet; out.sync_cache = mmc_sync_cache; out.get_nwa = mmc_get_nwa; out.close_disc = mmc_close_disc; out.close_session = mmc_close_session; out.close_track_session = mmc_close; out.read_buffer_capacity = mmc_read_buffer_capacity; out.idata = calloc(1, sizeof(struct burn_scsi_inquiry_data)); out.idata->valid = 0; out.mdata = calloc(1, sizeof(struct scsi_mode_data)); if (out.idata == NULL || out.mdata == NULL) { could_not_allocate:; libdax_msgs_submit(libdax_messenger, -1, 0x00020108, LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH, "Could not allocate new drive object", 0, 0); if (out.devname != NULL) free(out.devname); out.devname = NULL; if (out.idata != NULL) free(out.idata); out.idata = NULL; if (out.mdata != NULL) free(out.mdata); out.mdata = NULL; return; } out.mdata->p2a_valid = 0; memset(&out.params, 0, sizeof(struct params)); t = burn_drive_register(&out); /* ts A60821 <<< debug: for tracing calls which might use open drive fds */ mmc_function_spy(NULL, "enumerate_common : -------- doing grab"); /* try to get the drive info */ if (t->grab(t)) { t->getcaps(t); t->unlock(t); t->released = 1; } /* ts A60821 <<< debug: for tracing calls which might use open drive fds */ mmc_function_spy(NULL, "enumerate_common : ----- would release "); } #else /* Scsi_freebsd_make_own_enumeratE */ /* The new, more concise version of enumerate_common */ static void enumerate_common(char *fname, int bus_no, int host_no, int channel_no, int target_no, int lun_no) { int ret; struct burn_drive out; /* General libburn drive setup */ burn_setup_drive(&out, fname); /* This transport adapter uses SCSI-family commands and models (seems the adapter would know better than its boss, if ever) */ ret = burn_scsi_setup_drive(&out, bus_no, host_no, channel_no, target_no, lun_no, 0); if (ret<=0) return; /* Operating system adapter is CAM */ /* Adapter specific handles and data */ out.cam = NULL; out.lock_fd = -1; out.is_ahci = 0; /* Adapter specific functions */ out.grab = sg_grab; out.release = sg_release; out.drive_is_open = sg_drive_is_open; out.issue_command = sg_issue_command; /* Finally register drive and inquire drive information */ burn_drive_finish_enum(&out); } #endif /* ! Scsi_freebsd_make_own_enumeratE */ /* Lock the inode associated to dev_fd and the inode associated to devname. Return OS errno, number of pass device of dev_fd, locked fd to devname, error message. A return value of > 0 means success, <= 0 means failure. */ static int freebsd_dev_lock(int dev_fd, char *devname, int *os_errno, int *pass_dev_no, int *lock_fd, char msg[4096], int flag) { int lock_denied = 0, fd_stbuf_valid, name_stbuf_valid, i, pass_l = 100; int max_retry = 3, tries = 0; struct stat fd_stbuf, name_stbuf; char pass_name[16], *lock_name; *os_errno = 0; *pass_dev_no = -1; *lock_fd = -1; msg[0] = 0; fd_stbuf_valid = !fstat(dev_fd, &fd_stbuf); /* Try to find name of pass device by inode number */ lock_name = (char *) "effective device"; if(fd_stbuf_valid) { for (i = 0; i < pass_l; i++) { sprintf(pass_name, "/dev/pass%d", i); if (stat(pass_name, &name_stbuf) != -1) if(fd_stbuf.st_ino == name_stbuf.st_ino && fd_stbuf.st_dev == name_stbuf.st_dev) break; } if (i < pass_l) { lock_name = pass_name; *pass_dev_no = i; } } name_stbuf_valid = !stat(devname, &name_stbuf); for (tries= 0; tries <= max_retry; tries++) { lock_denied = flock(dev_fd, LOCK_EX | LOCK_NB); *os_errno = errno; if (lock_denied) { if (errno == EAGAIN && tries < max_retry) { /* <<< debugging fprintf(stderr, "\nlibcdio_DEBUG: EAGAIN pass, tries= %d\n", tries); */ usleep(2000000); continue; } sprintf(msg, "Device busy. flock(LOCK_EX) failed on %s of %s", strlen(lock_name) > 2000 || *pass_dev_no < 0 ? "pass device" : lock_name, strlen(devname) > 2000 ? "drive" : devname); return 0; } break; } /* fprintf(stderr, "libburn_DEBUG: flock obtained on %s of %s\n", lock_name, devname); */ /* Eventually lock the official device node too */ if (fd_stbuf_valid && name_stbuf_valid && (fd_stbuf.st_ino != name_stbuf.st_ino || fd_stbuf.st_dev != name_stbuf.st_dev)) { *lock_fd = open(devname, O_RDONLY); if (*lock_fd == 0) { close(*lock_fd); *lock_fd = -1; } if (*lock_fd > 0) { for (tries = 0; tries <= max_retry; tries++) { lock_denied = flock(*lock_fd, LOCK_EX | LOCK_NB); if (lock_denied) { if (errno == EAGAIN && tries < max_retry) { /* <<< debugging fprintf(stderr, "\nlibcdio_DEBUG: EAGAIN dev, tries= %d\n", tries); */ usleep(2000000); continue; } close(*lock_fd); *lock_fd = -1; sprintf(msg, "Device busy. flock(LOCK_EX) failed on %s", strlen(devname) > 4000 ? "drive" : devname); return 0; } break; } } /* fprintf(stderr, "libburn_DEBUG: flock obtained on %s\n", devname); */ } return 1; } static int sg_lock(struct burn_drive *d, int flag) { int ret, os_errno, pass_dev_no = -1, flock_fd = -1; char *msg = NULL; BURN_ALLOC_MEM(msg, char, 4096); ret = freebsd_dev_lock(d->cam->fd, d->devname, &os_errno, &pass_dev_no, &flock_fd, msg, 0); if (ret <= 0) { libdax_msgs_submit(libdax_messenger, d->global_index, 0x00020008, LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH, msg, os_errno, 0); sg_close_drive(d); {ret = 0; goto ex;} } if (d->lock_fd > 0) close(d->lock_fd); d->lock_fd = flock_fd; ret = 1; ex:; BURN_FREE_MEM(msg); return ret; } int sg_grab(struct burn_drive *d) { struct cam_device *cam; char path_string[80]; if (mmc_function_spy(d, "sg_grab") <= 0) return 0; if (burn_drive_is_open(d)) { d->released = 0; return 1; } cam = cam_open_device(d->devname, O_RDWR); if (cam == NULL) { libdax_msgs_submit(libdax_messenger, d->global_index, 0x00020003, LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH, "Could not grab drive", errno, 0); return 0; } d->cam = cam; if (burn_sg_open_o_excl & 63) if (sg_lock(d, 0) <= 0) return 0; fcntl(cam->fd, F_SETOWN, getpid()); cam_path_string(d->cam, path_string, sizeof(path_string)); #ifdef Libburn_ahci_verbouS fprintf(stderr, "libburn_EXPERIMENTAL: CAM path = %s\n", path_string); #endif if (strstr(path_string, ":ahcich") != NULL) d->is_ahci = 1; else d->is_ahci = -1; d->released = 0; return 1; } /* non zero return means you still have the drive and it's not in a state to be released? (is that even possible?) */ int sg_release(struct burn_drive *d) { if (mmc_function_spy(d, "sg_release") <= 0) return 0; if (d->cam == NULL) return 0; mmc_function_spy(NULL, "sg_release ----------- closing."); sg_close_drive(d); d->released = 1; return 0; } int sg_issue_command(struct burn_drive *d, struct command *c) { int done = 0, err, sense_len = 0, ret, ignore_error, i; int cam_pass_err_recover = 0, key, asc, ascq, timeout_ms; union ccb *ccb; static FILE *fp = NULL; time_t start_time; mmc_function_spy(NULL, "sg_issue_command"); c->error = 0; memset(c->sense, 0, sizeof(c->sense)); if (d->cam == NULL) return 0; if (burn_sg_log_scsi & 1) { if (fp == NULL) { fp= fopen("/tmp/libburn_sg_command_log", "a"); fprintf(fp, "\n-----------------------------------------\n"); } } if (burn_sg_log_scsi & 3) scsi_log_cmd(c,fp,0); c->error = 0; if (c->timeout > 0) timeout_ms = c->timeout; else timeout_ms = 200000; ccb = cam_getccb(d->cam); cam_fill_csio(&ccb->csio, 1, /* retries */ NULL, /* cbfncp */ CAM_DEV_QFRZDIS, /* flags */ MSG_SIMPLE_Q_TAG, /* tag_action */ NULL, /* data_ptr */ 0, /* dxfer_len */ sizeof (ccb->csio.sense_data), /* sense_len */ 0, /* cdb_len */ timeout_ms); /* timeout */ switch (c->dir) { case TO_DRIVE: ccb->csio.ccb_h.flags |= CAM_DIR_OUT; break; case FROM_DRIVE: ccb->csio.ccb_h.flags |= CAM_DIR_IN; break; case NO_TRANSFER: ccb->csio.ccb_h.flags |= CAM_DIR_NONE; break; } #ifdef Libburn_for_freebsd_ahcI /* ts B00325 : Advise by Alexander Motin */ /* Runs well on 8-STABLE (23 Mar 2003) But on 8-RELEASE cam_send_ccb() returns non-zero with errno 6 on eject. Long lasting TEST UNIT READY cycles break with errno 16. */ #ifdef Libburn_ahci_style_for_alL { #else if (d->is_ahci > 0) { #endif ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER; cam_pass_err_recover = 1; } #endif /* Libburn_for_freebsd_ahcI */ ccb->csio.cdb_len = c->oplen; memcpy(&ccb->csio.cdb_io.cdb_bytes, &c->opcode, c->oplen); if (c->page) { ccb->csio.data_ptr = c->page->data; if (c->dir == FROM_DRIVE) { /* ts A90430 : Ticket 148 , by jwehle : "On ... FreeBSD 6.4 which has a usb memory reader in addition to a ATAPI DVD burner sg_issue_command will hang while the SCSI bus is being scanned" */ if (c->dxfer_len >= 0) ccb->csio.dxfer_len = c->dxfer_len; else ccb->csio.dxfer_len = BUFFER_SIZE; /* touch page so we can use valgrind */ memset(c->page->data, 0, BUFFER_SIZE); } else { ccb->csio.dxfer_len = c->page->bytes; } } else { ccb->csio.data_ptr = NULL; ccb->csio.dxfer_len = 0; } start_time = time(NULL); for (i = 0; !done; i++) { memset(&ccb->csio.sense_data, 0, sizeof(ccb->csio.sense_data)); memset(c->sense, 0, sizeof(c->sense)); c->start_time = burn_get_time(0); err = cam_send_ccb(d->cam, ccb); c->end_time = burn_get_time(0); ignore_error = sense_len = 0; /* ts B00325 : CAM_AUTOSNS_VALID advised by Alexander Motin */ if (ccb->ccb_h.status & CAM_AUTOSNS_VALID) { /* ts B00110 */ /* Better curb sense_len */ sense_len = ccb->csio.sense_len; if (sense_len > (int) sizeof(c->sense)) sense_len = sizeof(c->sense); memcpy(c->sense, &ccb->csio.sense_data, sense_len); spc_decode_sense(c->sense, sense_len, &key, &asc, &ascq); if (sense_len >= 14 && cam_pass_err_recover && key) ignore_error = 1; } if (err == -1 && cam_pass_err_recover && ! ignore_error) { #ifdef Libburn_ahci_verbouS fprintf(stderr, "libburn_EXPERIMENTAL: errno = %d . cam_errbuf = '%s'\n", errno, cam_errbuf); #endif if (errno == ENXIO && c->opcode[0] != 0) { /* Operations on empty or ejected tray */ /* MEDIUM NOT PRESENT */ #ifdef Libburn_ahci_verbouS fprintf(stderr, "libburn_EXPERIMENTAL: Emulating [2,3A,00] MEDIUM NOT PRESENT\n"); #endif c->sense[0] = 0x70; /*Fixed format sense data*/ c->sense[2] = 0x02; c->sense[12] = 0x3A; c->sense[13] = 0x00; sense_len = 14; ignore_error = 1; } else if (c->opcode[0] == 0 && (errno == EBUSY || errno == ENXIO)) { /* Timeout of TEST UNIT READY loop */ /* Inquiries while tray is being loaded */ /*LOGICAL UNIT NOT READY,CAUSE NOT REPORTABLE*/ #ifdef Libburn_ahci_verbouS fprintf(stderr, "libburn_EXPERIMENTAL: Emulating [2,04,00] LOGICAL UNIT NOT READY,CAUSE NOT REPORTABLE\n"); #endif c->sense[0] = 0x70; /*Fixed format sense data*/ c->sense[2] = 0x02; c->sense[12] = 0x04; c->sense[13] = 0x00; sense_len = 14; ignore_error = 1; } else if (errno == EINVAL) { /* Inappropriate MODE SENSE */ /* INVALID FIELD IN CDB */ #ifdef Libburn_ahci_verbouS fprintf(stderr, "libburn_EXPERIMENTAL: Emulating [5,24,00] INVALID FIELD IN CDB\n"); #endif c->sense[0] = 0x70; /*Fixed format sense data*/ c->sense[2] = 0x05; c->sense[12] = 0x24; c->sense[13] = 0x00; sense_len = 14; ignore_error = 1; } } if (err == -1 && !ignore_error) { libdax_msgs_submit(libdax_messenger, d->global_index, 0x0002010c, LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH, "Failed to transfer command to drive", errno, 0); sg_close_drive(d); d->released = 1; d->busy = BURN_DRIVE_IDLE; c->error = 1; {ret = -1; goto ex;} } /* XXX */ if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { if (sense_len < 14) { /*LOGICAL UNIT NOT READY,CAUSE NOT REPORTABLE*/ #ifdef Libburn_ahci_verbouS fprintf(stderr, "libburn_EXPERIMENTAL: CAM_STATUS= %d .Emulating [2,04,00] LOGICAL UNIT NOT READY,CAUSE NOT REPORTABLE\n", (ccb->ccb_h.status & CAM_STATUS_MASK)); #endif c->sense[0] = 0x70; /*Fixed format sense data*/ c->sense[2] = 0x02; c->sense[12] = 0x04; c->sense[13] = 0x00; done = 1; } } done = scsi_eval_cmd_outcome(d, c, fp, c->sense, sense_len, start_time, timeout_ms, i, !!ignore_error); if (d->cancel) done = 1; } while (!done); ret = 1; ex:; cam_freeccb(ccb); return ret; } /* ts B00115 */ /* Return 1 if the given path leads to a regular file or a device that can be seeked, read and eventually written with 2 kB granularity. */ int burn_os_is_2k_seekrw(char *path, int flag) { struct stat stbuf; #ifdef Libburn_DIOCGMEDIASIZE_ISBLK int fd, ret; off_t add_size; #else char *spt; int i, e; #endif /* ! Libburn_DIOCGMEDIASIZE_ISBLK */ if (stat(path, &stbuf) == -1) return 0; if (S_ISREG(stbuf.st_mode)) return 1; if (!S_ISCHR(stbuf.st_mode)) return 0; #ifdef Libburn_DIOCGMEDIASIZE_ISBLK /* If it throws no error with DIOCGMEDIASIZE then it is a 'block device' */ fd = open(path, O_RDONLY); if (fd == -1) return 0; ret = ioctl(fd, DIOCGMEDIASIZE, &add_size); close(fd); return (ret != -1); #else /* Libburn_DIOCGMEDIASIZE_ISBLK */ spt = strrchr(path, '/'); if (spt == NULL) spt = path; else spt++; e = strlen(spt); for (i = strlen(spt) - 1; i > 0; i--) if (spt[i] >= '0' && spt[i] <= '9') e = i; if (strncmp(spt, "da", e) == 0) /* SCSI disk. E.g. USB stick. */ return 1; if (strncmp(spt, "cd", e) == 0) /* SCSI CD drive might be writeable. */ return 1; if (strncmp(spt, "ad", e) == 0) /* IDE hard drive */ return 1; if (strncmp(spt, "acd", e) == 0) /* IDE CD drive might be writeable */ return 1; if (strncmp(spt, "fd", e) == 0) /* Floppy disk */ return 1; if (strncmp(spt, "fla", e) == 0) /* Flash drive */ return 1; return 0; #endif /* ! Libburn_DIOCGMEDIASIZE_ISBLK */ } /* ts A70909 */ /** Estimate the potential payload capacity of a file address. @param path The address of the file to be examined. If it does not exist yet, then the directory will be inquired. @param bytes This value gets modified if an estimation is possible @return -2 = cannot perform necessary operations on file object -1 = neither path nor dirname of path exist 0 = could not estimate size capacity of file object 1 = estimation has been made, bytes was set */ int burn_os_stdio_capacity(char *path, off_t write_start, off_t *bytes) { struct stat stbuf; struct statvfs vfsbuf; char *testpath = NULL, *cpt; off_t add_size = 0; int fd, ret; BURN_ALLOC_MEM(testpath, char, 4096); testpath[0] = 0; if (stat(path, &stbuf) == -1) { strcpy(testpath, path); cpt = strrchr(testpath, '/'); if(cpt == NULL) strcpy(testpath, "."); else if(cpt == testpath) testpath[1] = 0; else *cpt = 0; if (stat(testpath, &stbuf) == -1) {ret = -1; goto ex;} #ifdef Libburn_if_this_was_linuX } else if(S_ISBLK(stbuf.st_mode)) { int open_mode = O_RDWR, fd, ret; long blocks; blocks = *bytes / 512; if(burn_sg_open_o_excl) open_mode |= O_EXCL; fd = open(path, open_mode); if (fd == -1) {ret = -2; goto ex;} ret = ioctl(fd, BLKGETSIZE, &blocks); close(fd); if (ret == -1) {ret = -2; goto ex;} *bytes = ((off_t) blocks) * (off_t) 512; #endif /* Libburn_if_this_was_linuX */ } else if(S_ISCHR(stbuf.st_mode)) { fd = open(path, O_RDONLY); if (fd == -1) {ret = -2; goto ex;} ret = ioctl(fd, DIOCGMEDIASIZE, &add_size); close(fd); if (ret == -1) {ret = -2; goto ex;} *bytes = add_size; } else if(S_ISREG(stbuf.st_mode)) { add_size = burn_sparse_file_addsize(write_start, &stbuf); strcpy(testpath, path); } else {ret = 0; goto ex;} if (testpath[0]) { if (statvfs(testpath, &vfsbuf) == -1) {ret = -2; goto ex;} *bytes = add_size + ((off_t) vfsbuf.f_frsize) * (off_t) vfsbuf.f_bavail; } ret = 1; ex: BURN_FREE_MEM(testpath); return ret; } /* ts A91122 : an interface to open(O_DIRECT) or similar OS tricks. */ #ifdef Libburn_read_o_direcT /* No special O_DIRECT-like precautions are implemented here */ #endif /* Libburn_read_o_direcT */ int burn_os_open_track_src(char *path, int open_flags, int flag) { int fd; fd = open(path, open_flags); return fd; } void *burn_os_alloc_buffer(size_t amount, int flag) { void *buf = NULL; buf = calloc(1, amount); return buf; } int burn_os_free_buffer(void *buffer, size_t amount, int flag) { if (buffer == NULL) return 0; free(buffer); return 1; } �����������������������������������������������������������������������������������������������������������������������������������������������������������������libburn-1.4.2/libburn/drive.h�����������������������������������������������������������������������0000644�0001757�0001751�00000012431�12652644224�013033� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */ /* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens Copyright (c) 2006 - 2014 Thomas Schmitt <scdbackup@gmx.net> Provided under GPL version 2 or later. */ #ifndef __DRIVE #define __DRIVE #include "libburn.h" #include "toc.h" #include "structure.h" #include <pthread.h> struct burn_drive; struct command; struct mempage; struct scsi_mode_data; struct burn_speed_descriptor; struct burn_feature_descr; #define LEAD_IN 1 #define GAP 2 #define USER_DATA 3 #define LEAD_OUT 4 #define SYNC 5 #define SESSION_LEADOUT_ENTRY(d,s) (d)->toc->session[(s)].leadout_entry #define CURRENT_SESSION_START(d) \ burn_msf_to_lba(d->toc->session[d->currsession].start_m, \ d->toc->session[d->currsession].start_s, \ d->toc->session[d->currsession].start_f) #define SESSION_END(d,s) \ TOC_ENTRY_PLBA((d)->toc, SESSION_LEADOUT_ENTRY((d), (s))) #define PREVIOUS_SESSION_END(d) \ TOC_ENTRY_PLBA((d)->toc, SESSION_LEADOUT_ENTRY((d), (d)->currsession-1)) #define LAST_SESSION_END(d) \ TOC_ENTRY_PLBA((d)->toc, \ SESSION_LEADOUT_ENTRY((d), (d)->toc->sessions-1)) struct burn_drive *burn_drive_register(struct burn_drive *); int burn_drive_unregister(struct burn_drive *d); unsigned int burn_drive_count(void); /* ts A61007 */ /* void burn_wait_all(void); */ /* @param flag bit0= demand freed drives (else released drives) */ int burn_drives_are_clear(int flag); int burn_sector_length_write(struct burn_drive *d); int burn_track_control(struct burn_drive *d, int); void burn_write_empty_sector(int fd); void burn_write_empty_subcode(int fd); void burn_drive_free(struct burn_drive *d); void burn_drive_free_all(void); /* @param flag bit0= reset global drive list */ int burn_drive_scan_sync(struct burn_drive_info *drives[], unsigned int *n_drives, int flag); void burn_disc_erase_sync(struct burn_drive *d, int fast); int burn_drive_get_block_types(struct burn_drive *d, enum burn_write_types write_type); int burn_drive_is_open(struct burn_drive *d); int burn_drive_is_occupied(struct burn_drive *d); int burn_drive_forget(struct burn_drive *d, int force); int burn_drive_convert_fs_adr_sub(char *path, char adr[], int *rec_count); /* ts A61021 : the unspecific part of sg.c:enumerate_common() */ int burn_setup_drive(struct burn_drive *d, char *fname); /* ts A61021 : after-setup activities from sg.c:enumerate_common() */ struct burn_drive *burn_drive_finish_enum(struct burn_drive *d); /* ts A61125 : media status aspects of burn_drive_grab() */ int burn_drive_inquire_media(struct burn_drive *d); /* ts A61125 : model aspects of burn_drive_release */ int burn_drive_mark_unready(struct burn_drive *d, int flag); /* ts A61226 */ int burn_speed_descriptor_new(struct burn_speed_descriptor **s, struct burn_speed_descriptor *prev, struct burn_speed_descriptor *next, int flag); /* ts A61226 */ /* @param flag bit0= destroy whole next-chain of descriptors */ int burn_speed_descriptor_destroy(struct burn_speed_descriptor **s, int flag); /* ts A61226 : free dynamically allocated sub data of struct scsi_mode_data */ int burn_mdata_free_subs(struct scsi_mode_data *m); /* ts A61230 */ void burn_disc_format_sync(struct burn_drive *d, off_t size, int flag); /* ts A70207 : evaluate write mode related peculiarities of a disc */ struct burn_disc_mode_demands { int multi_session; int multi_track; int unknown_track_size; /* 0=known, 1=unknown, 2=unknown+defaulted */ int mixed_mode; int audio; int exotic_track; int block_types; int will_append; /* because of media state or multi session disc */ }; int burn_disc_get_write_mode_demands(struct burn_disc *disc, struct burn_write_opts *opts, struct burn_disc_mode_demands *result, int flag); /* ts A70924 : convert a special stdio address into fd number. @return >0 is a valid fd , -1 indicates unsuitable address string. */ int burn_drive__fd_from_special_adr(char *adr); /* ts A70929 : Find the drive which is being worked on by pid , tid */ int burn_drive_find_by_thread_pid(struct burn_drive **d, pid_t pid, pthread_t tid); /* ts A51221 - A80731 : Whitelist inquiry functions */ int burn_drive_is_banned(char *device_address); int burn_drive_whitelist_count(void); char *burn_drive_whitelist_item(int idx, int flag); /* ts A80801 */ int burn_drive_is_listed(char *path, struct burn_drive **found, int flag); /* ts B00226 : Outsourced backend of burn_abort() @param elapsed to be subtracted from start time @param flag bit0= do not shutdown the library */ int burn_abort_5(int patience, int (*pacifier_func)(void *handle, int patience, int elapsed), void *handle, int elapsed, int flag); /* ts B10730 */ /* Send a default mode page 05 to CD and DVD-R-oids */ int burn_drive_send_default_page_05(struct burn_drive *d, int flag); /* ts B40106 */ int burn_feature_descr_new(struct burn_feature_descr **new, unsigned char *descr, int descr_len, int flag); /* ts B40106 */ int burn_feature_descr_free(struct burn_feature_descr **new, int flag); /* ts B40107 */ int burn_drive_has_feature(struct burn_drive *d, int feature_code, struct burn_feature_descr **descr, int flag); int burn_drive_grab_stdio(struct burn_drive *d, int flag); #endif /* __DRIVE */ ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������libburn-1.4.2/libburn/null.h������������������������������������������������������������������������0000644�0001757�0001751�00000000436�12652644224�012676� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */ #ifndef BURN__NULL_H #define BURN__NULL_H struct burn_source; int null_read(struct burn_source *source, unsigned char *buffer, int size); struct burn_source *burn_null_source_new(void); #endif /* LIBBURN__NULL_H */ ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������libburn-1.4.2/libburn/file.c������������������������������������������������������������������������0000644�0001757�0001751�00000065166�12652644224�012651� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */ /* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens Copyright (c) 2006 - 2014 Thomas Schmitt <scdbackup@gmx.net> Provided under GPL version 2 or later. */ #ifdef HAVE_CONFIG_H #include "../config.h" #endif #include <stdlib.h> #include <sys/types.h> #include <stdio.h> #include <errno.h> #include <string.h> #include <sys/stat.h> #include <unistd.h> #include <fcntl.h> #include <time.h> #include <pthread.h> /* ts B41126 : O_BINARY is needed for Cygwin but undefined elsewhere */ #ifndef O_BINARY #define O_BINARY 0 #endif #include "source.h" #include "libburn.h" #include "file.h" #include "async.h" #include "init.h" #include "util.h" #include "libdax_msgs.h" extern struct libdax_msgs *libdax_messenger; /* main channel data can be padded on read, but 0 padding the subs will make an unreadable disc */ /* This is a generic OS oriented function wrapper which compensates shortcommings of read() in respect to a guaranteed amount of return data. See man 2 read , paragraph "RETURN VALUE". */ static int read_full_buffer(int fd, unsigned char *buffer, int size) { int ret,summed_ret = 0; /* make safe against partial buffer returns */ while (1) { ret = read(fd, buffer + summed_ret, size - summed_ret); if (ret <= 0) break; summed_ret += ret; if (summed_ret >= size) break; } if (ret < 0) /* error encountered. abort immediately */ return ret; return summed_ret; } static int file_read(struct burn_source *source, unsigned char *buffer, int size) { struct burn_source_file *fs = source->data; return read_full_buffer(fs->datafd, buffer, size); } static int file_read_sub(struct burn_source *source, unsigned char *buffer, int size) { struct burn_source_file *fs = source->data; return read_full_buffer(fs->subfd, buffer, size); } static void file_free(struct burn_source *source) { struct burn_source_file *fs = source->data; close(fs->datafd); if (source->read_sub) close(fs->subfd); free(fs); } static off_t file_size(struct burn_source *source) { struct stat buf; struct burn_source_file *fs = source->data; if (fs->fixed_size > 0) return fs->fixed_size; if (fstat(fs->datafd, &buf) != 0) return (off_t) 0; if ((buf.st_mode & S_IFMT) != S_IFREG) return (off_t) 0; return (off_t) buf.st_size; } /* ts A70125 */ static int file_set_size(struct burn_source *source, off_t size) { struct burn_source_file *fs = source->data; fs->fixed_size = size; return 1; } struct burn_source *burn_file_source_new(const char *path, const char *subpath) { struct burn_source_file *fs; struct burn_source *src; int fd1 = -1, fd2 = -1; if (!path) return NULL; fd1 = open(path, O_RDONLY | O_BINARY); if (fd1 == -1) return NULL; if (subpath != NULL) { fd2 = open(subpath, O_RDONLY | O_BINARY); if (fd2 == -1) { close(fd1); return NULL; } } fs = calloc(1, sizeof(struct burn_source_file)); /* ts A70825 */ if (fs == NULL) { failure:; close(fd1); if (fd2 >= 0) close(fd2); return NULL; } fs->datafd = fd1; fs->subfd = fd2; /* ts A70125 */ fs->fixed_size = 0; src = burn_source_new(); /* ts A70825 */ if (src == NULL) { free((char *) fs); goto failure; } src->read = file_read; if (subpath) src->read_sub = file_read_sub; src->get_size = file_size; src->set_size = file_set_size; src->free_data = file_free; src->data = fs; return src; } /* ts A70126 : removed class burn_source_fd in favor of burn_source_file */ struct burn_source *burn_fd_source_new(int datafd, int subfd, off_t size) { struct burn_source_file *fs; struct burn_source *src; if (datafd == -1) return NULL; fs = burn_alloc_mem(sizeof(struct burn_source_file), 1, 0); if (fs == NULL) /* ts A70825 */ return NULL; fs->datafd = datafd; fs->subfd = subfd; fs->fixed_size = size; src = burn_source_new(); /* ts A70825 */ if (src == NULL) { free((char *) fs); return NULL; } src->read = file_read; if(subfd != -1) src->read_sub = file_read_sub; src->get_size = file_size; src->set_size = file_set_size; src->free_data = file_free; src->data = fs; return src; } /* ts A71003 */ /* ------------------------------ fifo --------------------------- */ /* The fifo mechanism consists of a burn_source proxy which is here, a thread management team which is located in async.c, and a synchronous shoveller which is here. */ static int fifo_sleep(int flag) { static unsigned long sleeptime = 50000; /* 50 ms */ usleep(sleeptime); return 0; } static int fifo_read(struct burn_source *source, unsigned char *buffer, int size) { struct burn_source_fifo *fs = source->data; int ret, todo, rpos, bufsize, diff, counted = 0; if (fs->end_of_consumption) { /* ??? msg: reading has been ended already */; return 0; } if (fs->is_started == 0) { ret = burn_fifo_start(source, 0); if (ret <= 0) { libdax_msgs_submit(libdax_messenger, -1, 0x00020152, LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH, "Cannot start fifo thread", 0, 0); fs->end_of_consumption = 1; return -1; } fs->is_started = 1; } if (size == 0) return 0; /* Reading from the ring buffer */ /* This needs no mutex because each volatile variable has one thread which may write and the other which only reads and is aware of volatility. The feeder of the ringbuffer is in burn_fifo_source_shoveller(). */ todo = size; bufsize = fs->chunksize * fs->chunks; while (todo > 0) { /* readpos is not volatile here , writepos is volatile */ rpos = fs->buf_readpos; while (rpos == fs->buf_writepos) { if (fs->end_of_input) break; if (fs->input_error) { if (todo < size) /* deliver partial buffer */ break; fs->end_of_consumption = 1; libdax_msgs_submit(libdax_messenger, -1, 0x00020154, LIBDAX_MSGS_SEV_NOTE, LIBDAX_MSGS_PRIO_HIGH, "Forwarded input error ends output", 0, 0); return -1; } if (!counted) fs->empty_counter++; counted = 1; fifo_sleep(0); } diff = fs->buf_writepos - rpos; /* read volatile only once */ if (diff == 0) break; if (diff > 0) /* diff bytes are available */; else /* at least (bufsize - rpos) bytes are available */ diff = bufsize - rpos; if (diff > todo) diff = todo; memcpy(buffer, fs->buf+(size-todo)+rpos, diff); fs->buf_readpos += diff; if (fs->buf_readpos >= bufsize) fs->buf_readpos = 0; todo -= diff; } if (size - todo <= 0) fs->end_of_consumption = 1; else fs->out_counter += size - todo; /* fprintf(stderr, "libburn_EXPERIMENTAL: read= %d , pos= %d , out_count= %.f\n", (size - todo), fs->buf_readpos, (double) fs->out_counter); */ fs->get_counter++; return (size - todo); } static off_t fifo_get_size(struct burn_source *source) { struct burn_source_fifo *fs = source->data; return fs->inp->get_size(fs->inp); } static int fifo_set_size(struct burn_source *source, off_t size) { struct burn_source_fifo *fs = source->data; return fs->inp->set_size(fs->inp, size); } static void fifo_free(struct burn_source *source) { struct burn_source_fifo *fs = source->data; burn_fifo_abort(fs, 0); if (fs->inp != NULL) burn_source_free(fs->inp); if (fs->buf != NULL) burn_os_free_buffer(fs->buf, ((size_t) fs->chunksize) * (size_t) fs->chunks, 0); free((char *) fs); } int burn_fifo_source_shoveller(struct burn_source *source, int flag) { struct burn_source_fifo *fs = source->data; int ret, bufsize, diff, wpos, rpos, trans_end, free_bytes, fill; int counted; char *bufpt; pthread_t thread_handle_storage; fs->thread_handle= &thread_handle_storage; *((pthread_t *) fs->thread_handle)= pthread_self(); fs->thread_pid = getpid(); fs->thread_is_valid = 1; bufsize = fs->chunksize * fs->chunks; while (!fs->end_of_consumption) { /* wait for enough buffer space available */ wpos = fs->buf_writepos; counted = 0; while (1) { rpos = fs->buf_readpos; diff = rpos - wpos; trans_end = 0; if (diff == 0) free_bytes = bufsize - 1; else if (diff > 0) free_bytes = diff - 1; else { free_bytes = (bufsize - wpos) + rpos - 1; if (bufsize - wpos < fs->inp_read_size) trans_end = 1; } if (free_bytes >= fs->inp_read_size) break; if (!counted) fs->full_counter++; counted = 1; fifo_sleep(0); } fill = bufsize - free_bytes - 1; if (fill < fs->total_min_fill) fs->total_min_fill = fill; if (fill < fs->interval_min_fill) fs->interval_min_fill = fill; /* prepare the receiving memory */ bufpt = fs->buf + wpos; if (trans_end) { bufpt = burn_os_alloc_buffer( (size_t) fs->inp_read_size, 0); if (bufpt == NULL) { libdax_msgs_submit(libdax_messenger, -1, 0x00000003, LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH, "Out of virtual memory", 0, 0); fs->input_error = ENOMEM; break; } } /* Obtain next chunk */ if (fs->inp->read != NULL) ret = fs->inp->read(fs->inp, (unsigned char *) bufpt, fs->inp_read_size); else ret = fs->inp->read_xt( fs->inp, (unsigned char *) bufpt, fs->inp_read_size); if (ret == 0) { /* >>> ??? ts B00326 */ /* >>> report EOF of fifo input and fs->in_counter */; break; /* EOF */ } else if (ret < 0) { libdax_msgs_submit(libdax_messenger, -1, 0x00020153, LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH, "Read error on fifo input", errno, 0); fs->input_error = errno; if(errno == 0) fs->input_error = EIO; break; } fs->in_counter += ret; fs->put_counter++; /* activate read chunk */ if (ret > fs->inp_read_size) /* beware of ill custom burn_source */ ret = fs->inp_read_size; if (trans_end) { /* copy to end of buffer */ memcpy(fs->buf + wpos, bufpt, bufsize - wpos); /* copy to start of buffer */ memcpy(fs->buf, bufpt + (bufsize - wpos), fs->inp_read_size - (bufsize - wpos)); burn_os_free_buffer(bufpt, (size_t) fs->inp_read_size, 0); if (ret >= bufsize - wpos) fs->buf_writepos = ret - (bufsize - wpos); else fs->buf_writepos += ret; } else if (fs->buf_writepos + ret == bufsize) fs->buf_writepos = 0; else fs->buf_writepos += ret; /* fprintf(stderr, "[%2.2d%%] ", (int) (100.0 - 100.0 * ((double) free_bytes) / (double) bufsize)); fprintf(stderr, "libburn_EXPERIMENTAL: writepos= %d ,in_count = %.f\n", fs->buf_writepos, (double) fs->in_counter); */ } if (!fs->end_of_consumption) fs->end_of_input = 1; /* wait for end of reading by consumer */; while (fs->buf_readpos != fs->buf_writepos && !fs->end_of_consumption) fifo_sleep(0); /* destroy ring buffer */; if (!fs->end_of_consumption) fs->end_of_consumption = 2; /* Claim stop of consumption */ /* This is not prone to race conditions because either the consumer indicated hangup by fs->end_of_consumption = 1 or the consumer set fs->buf_readpos to a value indicating the buffer is empty. So in both cases the consumer is aware that reading is futile or even fatal. */ if(fs->buf != NULL) burn_os_free_buffer(fs->buf, ((size_t) fs->chunksize) * (size_t) fs->chunks, 0); fs->buf = NULL; fs->thread_handle= NULL; fs->thread_is_valid = 0; return (fs->input_error == 0); } int burn_fifo_cancel(struct burn_source *source) { int ret; struct burn_source_fifo *fs = source->data; ret = burn_source_cancel(fs->inp); return ret; } /* @param flag bit0= allow larger read chunks */ struct burn_source *burn_fifo_source_new(struct burn_source *inp, int chunksize, int chunks, int flag) { struct burn_source_fifo *fs; struct burn_source *src; if (((double) chunksize) * ((double) chunks) > 1024.0*1024.0*1024.0) { libdax_msgs_submit(libdax_messenger, -1, 0x00020155, LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH, "Desired fifo buffer too large (> 1GB)", 0, 0); return NULL; } if (chunksize < 1 || chunks < 2) { libdax_msgs_submit(libdax_messenger, -1, 0x00020156, LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH, "Desired fifo buffer too small", 0, 0); return NULL; } fs = burn_alloc_mem(sizeof(struct burn_source_fifo), 1, 0); if (fs == NULL) return NULL; fs->is_started = 0; fs->thread_handle = NULL; fs->thread_pid = 0; fs->thread_is_valid = 0; fs->inp = NULL; /* set later */ if (flag & 1) fs->inp_read_size = 32 * 1024; else fs->inp_read_size = chunksize; fs->chunksize = chunksize; fs->chunks = chunks; fs->buf = NULL; fs->buf_writepos = fs->buf_readpos = 0; fs->end_of_input = 0; fs->input_error = 0; fs->end_of_consumption = 0; fs->in_counter = fs->out_counter = 0; fs->total_min_fill = fs->interval_min_fill = 0; fs->put_counter = fs->get_counter = 0; fs->empty_counter = fs->full_counter = 0; src = burn_source_new(); if (src == NULL) { free((char *) fs); return NULL; } src->read = NULL; src->read_sub = NULL; src->get_size = fifo_get_size; src->set_size = fifo_set_size; src->free_data = fifo_free; src->data = fs; src->version= 1; src->read_xt = fifo_read; src->cancel= burn_fifo_cancel; fs->inp = inp; inp->refcount++; /* make sure inp lives longer than src */ return src; } /* ts A71003 : API */ int burn_fifo_inquire_status(struct burn_source *source, int *size, int *free_bytes, char **status_text) { struct burn_source_fifo *fs = source->data; int ret = 0, diff, wpos, rpos; static char *(states[8]) = { "standby", "active", "ending", "failing", "unused", "abandoned", "ended", "aborted"}; *status_text = NULL; *size = 0; if (source->free_data != fifo_free) { libdax_msgs_submit(libdax_messenger, -1, 0x00020157, LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH, "burn_source is not a fifo object", 0, 0); return -1; } *size = fs->chunksize * fs->chunks; rpos = fs->buf_readpos; wpos = fs->buf_writepos; diff = rpos - wpos; if (diff == 0) *free_bytes = *size - 1; else if (diff > 0) *free_bytes = diff - 1; else *free_bytes = (*size - wpos) + rpos - 1; ret = 0; if (fs->end_of_consumption > 0) ret |= 4; if (fs->input_error) ret |= 3; else if (fs->end_of_input) ret |= 2; else if(fs->buf != NULL) ret |= 1; *status_text = states[ret]; return ret; } /* ts A91125 : API */ void burn_fifo_get_statistics(struct burn_source *source, int *total_min_fill, int *interval_min_fill, int *put_counter, int *get_counter, int *empty_counter, int *full_counter) { struct burn_source_fifo *fs = source->data; *total_min_fill = fs->total_min_fill; *interval_min_fill = fs->interval_min_fill; *put_counter = fs->put_counter; *get_counter = fs->get_counter; *empty_counter = fs->empty_counter; *full_counter = fs->full_counter; } /* ts A91125 : API */ void burn_fifo_next_interval(struct burn_source *source, int *interval_min_fill) { struct burn_source_fifo *fs = source->data; int size, free_bytes, ret; char *status_text; *interval_min_fill = fs->interval_min_fill; ret = burn_fifo_inquire_status(source, &size, &free_bytes, &status_text); if (ret < 0) return; fs->interval_min_fill = size - free_bytes - 1; } /* @param flag bit0= do not copy to buf but only wait until the fifo has read bufsize or input ended. The same happens if buf is NULL. bit1= fill to max fifo size */ int burn_fifo_fill_data(struct burn_source *source, char *buf, int bufsize, int flag) { int size, free_bytes, ret, wait_count= 0; char *status_text; struct burn_source_fifo *fs = source->data; if (buf == NULL) flag |= 1; /* Eventually start fifo thread by reading 0 bytes */ ret = fifo_read(source, (unsigned char *) NULL, 0); if (ret<0) {ret = 0; goto ex;} /* wait for at least bufsize bytes being ready */ while (1) { ret= burn_fifo_inquire_status(source, &size, &free_bytes, &status_text); if (flag & 2) { bufsize = size - (size % fs->inp_read_size) - fs->inp_read_size; if (bufsize <= 0) {ret = 0; goto ex;} } if (size - fs->inp_read_size < bufsize) { if (flag & 1) { bufsize = size - (size % fs->inp_read_size) - fs->inp_read_size; if (bufsize <= 0) {ret = 0; goto ex;} } else { libdax_msgs_submit(libdax_messenger, -1, 0x0002015c, LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH, "Fifo size too small for desired peek buffer", 0, 0); {ret = -1; goto ex;} } } if (fs->out_counter > 0 || (ret & 4) || fs->buf == NULL) { libdax_msgs_submit(libdax_messenger, -1, 0x0002015e, LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH, "Fifo is already under consumption when peeking is desired", 0, 0); {ret = -1; goto ex;} } if(size - free_bytes >= bufsize) { /* <<< fprintf(stderr, "libburn_DEBUG: after waiting cycle %d : fifo %s , %d bytes\n", wait_count, status_text, size - free_bytes); */ if(!(flag & 1)) memcpy(buf, fs->buf, bufsize); {ret = 1; goto ex;} } if (ret & 2) { /* input has ended, not enough data arrived */ if (flag & 1) {ret = 0; goto ex;} libdax_msgs_submit(libdax_messenger, -1, 0x0002015d, LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH, "Fifo input ended short of desired peek buffer size", 0, 0); {ret = 0; goto ex;} } if (free_bytes < fs->inp_read_size) { /* Usable fifo size filled, not enough data arrived */ if (flag & 1) {ret = 0; goto ex;} libdax_msgs_submit(libdax_messenger, -1, 0x00020174, LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH, "Fifo alignment does not allow desired read size", 0, 0); {ret = 0; goto ex;} } usleep(100000); wait_count++; /* <<< if(wait_count%10==0) fprintf(stderr, "libburn_DEBUG: waiting cycle %d : fifo %s , %d bytes\n", wait_count, status_text, size - free_bytes); */ } ret = 0; ex:; fs->total_min_fill = fs->interval_min_fill = fs->buf_writepos; return(ret); } /* ts A80713 : API */ int burn_fifo_peek_data(struct burn_source *source, char *buf, int bufsize, int flag) { return burn_fifo_fill_data(source, buf, bufsize, 0); } /* ts A91125 : API */ int burn_fifo_fill(struct burn_source *source, int bufsize, int flag) { return burn_fifo_fill_data(source, NULL, bufsize, 1 | ((flag & 1) << 1)); } /* ----------------------------- Offset source ----------------------------- */ /* ts B00922 */ static void offst_free(struct burn_source *source); /* @param flag bit0 = do not check for burn_source_offst, do not return NULL */ static struct burn_source_offst *offst_auth(struct burn_source *source, int flag) { if (source->free_data != offst_free && !(flag & 1)) { libdax_msgs_submit(libdax_messenger, -1, 0x0002017a, LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH, "Expected offset source object as parameter", 0, 0); return NULL; } return (struct burn_source_offst *) source->data; } static off_t offst_get_size(struct burn_source *source) { struct burn_source_offst *fs; if ((fs = offst_auth(source, 0)) == NULL) return (off_t) 0; return fs->nominal_size; } static int offst_set_size(struct burn_source *source, off_t size) { struct burn_source_offst *fs; if ((fs = offst_auth(source, 0)) == NULL) return 0; fs->nominal_size = size; if (fs->size <= 0 || fs->size_adjustable) fs->size = size; return 1; } static void offst_free(struct burn_source *source) { struct burn_source_offst *fs; if ((fs = offst_auth(source, 0)) == NULL) return; if (fs->prev != NULL) offst_auth(fs->prev, 1)->next = fs->next; if (fs->next != NULL) offst_auth(fs->next, 1)->prev = fs->prev; if (fs->inp != NULL) burn_source_free(fs->inp); /* i.e. decrement refcount */ free(source->data); } static int offst_read(struct burn_source *source, unsigned char *buffer, int size) { int ret, to_read, todo; struct burn_source_offst *fs; if ((fs = offst_auth(source, 0)) == NULL) return -1; /* Eventually skip bytes up to start position */; if (!fs->running) { if (fs->prev != NULL) fs->pos = offst_auth(fs->prev, 1)->pos; fs->running= 1; } if(fs->pos < fs->start) { todo = fs->start - fs->pos; while (todo > 0) { to_read = todo; if (to_read > size) to_read = size; ret = burn_source_read(fs->inp, buffer, to_read); if (ret <= 0) return ret; todo -= ret; fs->pos += ret; } } /* Produce EOF if source size is exhausted. burn_source delivers no incomplete sector buffers. */ if (fs->pos + size > fs->start + fs->size) return 0; /* Read payload */ ret = burn_source_read(fs->inp, buffer, size); if (ret > 0) fs->pos += ret; return ret; } static int offst_cancel(struct burn_source *source) { int ret; struct burn_source_offst *fs; if ((fs = offst_auth(source, 0)) == NULL) return -1; ret = burn_source_cancel(fs->inp); return ret; } struct burn_source *burn_offst_source_new( struct burn_source *inp, struct burn_source *prev, off_t start, off_t size, int flag) { struct burn_source *src; struct burn_source_offst *fs, *prev_fs = NULL; if (prev != NULL) if ((prev_fs = offst_auth(prev, 0)) == NULL) return NULL; /* Not type burn_source_offst */ fs = calloc(1, sizeof(struct burn_source_offst)); if (fs == NULL) return NULL; src = burn_source_new(); if (src == NULL) { free((char *) fs); return NULL; } src->read = NULL; src->read_sub = NULL; src->get_size = offst_get_size; src->set_size = offst_set_size; src->free_data = offst_free; src->data = fs; src->version= 1; src->read_xt = offst_read; src->cancel= offst_cancel; fs->inp = inp; fs->prev = prev; fs->next = NULL; if (prev != NULL) { if (prev_fs->next != NULL) { offst_auth(prev_fs->next, 1)->prev = src; fs->next = prev_fs->next; } prev_fs->next = src; if (prev_fs->start + prev_fs->size > start) { libdax_msgs_submit(libdax_messenger, -1, 0x00020179, LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH, "Offset source start address is before end of previous source", 0, 0); return NULL; } } fs->start = start; fs->size = size; fs->size_adjustable = !(flag & 1); fs->nominal_size = size; fs->running = 0; fs->pos = 0; inp->refcount++; /* make sure inp lives longer than src */ return src; } /* -------------------- WAVE file extractor ------------------- */ /* ts B30522 */ /* API @param flag Bitfield for control purposes: bit0= Report about progress by UPDATE message bit3= Enable DAP : "flaw obscuring mechanisms like audio data mute and interpolate" */ int burn_drive_extract_audio(struct burn_drive *drive, int start_sector, int sector_count, char *target_path, int flag) { int fd = -1, ret, todo, sector_no, val, min, sec, fr; int sectors_done= 0; off_t data_size, data_count = 0; time_t last_pacified = 0, now; char *msg = NULL, *buf = NULL; BURN_ALLOC_MEM(msg, char, 4096); BURN_ALLOC_MEM(buf, char, 24 * 2352); fd = open(target_path, O_WRONLY | O_CREAT | O_BINARY, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH); if (fd == -1) { sprintf(msg, "Cannot open disk file for writing: %.4000s", target_path); libdax_msgs_submit(libdax_messenger, -1, 0x000201a1, LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH, msg, errno, 0); ret = 0; goto ex; } /* WAV header */ strcpy(buf, "RIFF"); val = 4 + 8 + 16 + 8 + sector_count * 2352; /* ChunkSize */ burn_int_to_lsb(val, buf + 4); strcpy(buf + 8, "WAVE"); strcpy(buf + 12, "fmt "); burn_int_to_lsb(16, buf + 16); /* Subchunk1Size */ buf[20] = 1; /* AudioFormat */ buf[21] = 0; buf[22] = 2; /* NumChannels */ buf[23] = 0; burn_int_to_lsb(44100, buf + 24); /* SampleRate */ burn_int_to_lsb(176400, buf + 28); /* ByteRate */ buf[32] = 4; /* BlockAlign */ buf[33] = 0; buf[34] = 16; /* BitsPerSample */ buf[35] = 0; strcpy(buf + 36, "data"); burn_int_to_lsb(sector_count * 2352, buf + 40); /* Subchunk2Size */ ret = write(fd, buf, 44); if (ret == -1) goto write_error; /* Audio data */ todo = sector_count; sector_no = start_sector; while (todo > 0) { if (todo > 24) data_size = 24 * 2352; else data_size = todo * 2352; ret = burn_read_audio(drive, sector_no, buf, data_size, &data_count, flag & 8); if (ret <= 0) { sprintf(msg, "Failure to read audio sectors"); libdax_msgs_submit(libdax_messenger, -1, 0x000201a4, LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH, msg, 0, 0); goto ex; } ret = write(fd, buf, data_count); if (ret == -1) { write_error:; sprintf(msg, "Error while writing to disk file: %.4000s", target_path); libdax_msgs_submit(libdax_messenger, -1, 0x000201a2, LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH, msg, errno, 0); ret = 0; goto ex; } todo -= data_count / 2352; sectors_done += data_count / 2352; sector_no += data_count / 2352; if ((flag & 1) && (now = time(NULL)) - last_pacified >= 1) { last_pacified = now; burn_lba_to_msf(sectors_done, &min, &sec, &fr); sprintf(msg, "Minutes:seconds of audio data read: %2d:%2.2d (%6.2f MB)", min, sec, ((double) sectors_done) * 2352.0 / 1048576.0); libdax_msgs_submit(libdax_messenger, -1, 0x000201a3, LIBDAX_MSGS_SEV_UPDATE, LIBDAX_MSGS_PRIO_HIGH, msg, 0, 1); } } if ((flag & 1)) { burn_lba_to_msf(sectors_done, &min, &sec, &fr); sprintf(msg, "Minutes:seconds of audio data read: %2d:%2.2d (%6.2f MB)", min, sec, ((double) sectors_done) * 2352.0 / 1048576.0); libdax_msgs_submit(libdax_messenger, -1, 0x000201a3, LIBDAX_MSGS_SEV_UPDATE, LIBDAX_MSGS_PRIO_HIGH, msg, 0, 0); } ret = 1; ex:; BURN_FREE_MEM(buf); BURN_FREE_MEM(msg); if (fd != -1) close(fd); return ret; } /* ts B30522 */ /* API @param flag Bitfield for control purposes: bit0= Report about progress by UPDATE message bit3= Enable DAP : "flaw obscuring mechanisms like audio data mute and interpolate" */ int burn_drive_extract_audio_track(struct burn_drive *drive, struct burn_track *track, char *target_path, int flag) { int ret; struct burn_toc_entry toc_entry; burn_track_get_entry(track, &toc_entry); if (!(toc_entry.extensions_valid & 1)) { /* Can only happen if burn_disc_cd_toc_extensions() is skipped in mmc_read_toc_al(). */ libdax_msgs_submit(libdax_messenger, -1, 0x00000004, LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH, "Internal libburn error: Outdated burn_toc_entry format encountered", errno, 0); return -1; } ret = burn_drive_extract_audio(drive, toc_entry.start_lba, toc_entry.track_blocks, target_path, flag & (1 | 8)); return ret; } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������libburn-1.4.2/libburn/sbc.c�������������������������������������������������������������������������0000644�0001757�0001751�00000011061�12652644224�012462� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */ /* scsi block commands */ /* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens Copyright (c) 2006 - 2010 Thomas Schmitt <scdbackup@gmx.net> Provided under GPL version 2 or later. */ #ifdef HAVE_CONFIG_H #include "../config.h" #endif #include <string.h> #include <unistd.h> #include "transport.h" #include "sbc.h" #include "spc.h" #include "options.h" /* ts A70910 debug: for tracing calls which might use open drive fds or for catching SCSI usage of emulated drives. */ int mmc_function_spy(struct burn_drive *d, char * text); /* START STOP UNIT as of SBC-1 and SBC-2 0: Opcode 0x1B 1: bit0= Immed bit1-7= reserved 2: reserved 3: reserved 4: bit0= Start (else Stop unit) bit1= Load/Eject (according to Start resp. Stop) bit2-3= reserved bit4-7= Power Condition 0= Start Valid: process Start and Load/Eject bits 1= assume Active state 2= assume Idle state 3= assume Stanby state (5= SBC-1 only: assume Sleep state) 7= transfer control of power conditions to logical unit 10= force idle condition timer to 0 11= force standby condition timer to 0 All others are reserved. 5: Control (set to 0) */ static unsigned char SBC_LOAD[] = { 0x1b, 0, 0, 0, 3, 0 }; static unsigned char SBC_UNLOAD[] = { 0x1b, 0, 0, 0, 2, 0 }; static unsigned char SBC_START_UNIT[] = { 0x1b, 0, 0, 0, 1, 0 }; static unsigned char SBC_STOP_UNIT[] = { 0x1b, 0, 0, 0, 0, 0 }; void sbc_load(struct burn_drive *d) { struct command *c; c = &(d->casual_command); if (mmc_function_spy(d, "load") <= 0) return; scsi_init_command(c, SBC_LOAD, sizeof(SBC_LOAD)); c->retry = 1; /* ts A70921 : Had to revoke Immed because of LG GSA-4082B */ /* c->opcode[1] |= 1; / * ts A70918 : Immed */ c->dir = NO_TRANSFER; c->timeout = Libburn_mmc_load_timeouT; d->issue_command(d, c); if (c->error) return; /* ts A70923 : Needed regardless of Immed bit. Was once 1 minute, now 5 minutes for loading. If this does not suffice then other commands shall fail righteously. */ spc_wait_unit_attention(d, 300, "waiting after START UNIT (+ LOAD)",0); } void sbc_eject(struct burn_drive *d) { struct command *c; c = &(d->casual_command); if (mmc_function_spy(d, "eject") <= 0) return; scsi_init_command(c, SBC_UNLOAD, sizeof(SBC_UNLOAD)); /* c->opcode[1] |= 1; / * ts A70918 : Immed , ts B00109 : revoked */ c->page = NULL; c->dir = NO_TRANSFER; d->issue_command(d, c); /* ts A70918 : Wait long. A late eject could surprise or hurt user. ts B00109 : Asynchronous eject revoked, as one cannot reliably distinguish out from unready. if (c->error) return; spc_wait_unit_attention(d, 1800, "STOP UNIT (+ EJECT)", 0); */ } /* ts A91112 : Now with flag */ /* @param flag bit0= asynchronous waiting */ int sbc_start_unit_flag(struct burn_drive *d, int flag) { struct command *c; int ret; c = &(d->casual_command); if (mmc_function_spy(d, "start_unit") <= 0) return 0; scsi_init_command(c, SBC_START_UNIT, sizeof(SBC_START_UNIT)); c->retry = 1; c->opcode[1] |= (flag & 1); /* ts A70918 : Immed */ c->dir = NO_TRANSFER; d->issue_command(d, c); if (c->error) return 0; if (!(flag & 1)) return 1; /* ts A70918 : asynchronous */ ret = spc_wait_unit_attention(d, 1800, "START UNIT", 0); return ret; } int sbc_start_unit(struct burn_drive *d) { int ret; d->is_stopped = 0; /* no endless starting attempts */ /* Asynchronous, not to block controller by waiting */ ret = sbc_start_unit_flag(d, 1); if (ret <= 0) return ret; /* Synchronous to catch Pioneer DVR-216D which is ready too early. A pending START UNIT can prevent ejecting of the tray. */ ret = sbc_start_unit_flag(d, 0); return ret; } /* ts A90824 : Trying to reduce drive noise */ int sbc_stop_unit(struct burn_drive *d) { struct command *c; int ret; c = &(d->casual_command); if (mmc_function_spy(d, "stop_unit") <= 0) return 0; scsi_init_command(c, SBC_STOP_UNIT, sizeof(SBC_STOP_UNIT)); c->retry = 0; c->opcode[1] |= 1; /* Immed */ c->dir = NO_TRANSFER; d->issue_command(d, c); if (c->error) return 0; ret = spc_wait_unit_attention(d, 1800, "STOP UNIT", 0); d->is_stopped = 1; return ret; } /* ts A61021 : the sbc specific part of sg.c:enumerate_common() */ int sbc_setup_drive(struct burn_drive *d) { d->eject = sbc_eject; d->load = sbc_load; d->start_unit = sbc_start_unit; d->stop_unit = sbc_stop_unit; d->is_stopped = 0; return 1; } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������libburn-1.4.2/libburn/os.h��������������������������������������������������������������������������0000644�0001757�0001751�00000003460�12652644224�012345� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ /* os.h Operating system specific libburn definitions and declarations. The macros defined here are used by libburn modules in order to avoid own system dependent case distinctions. Copyright (C) 2009 - 2014 Thomas Schmitt <scdbackup@gmx.net>, provided under GPLv2+ */ #ifndef BURN_OS_H_INCLUDED #define BURN_OS_H_INCLUDED 1 /* Operating system case distinction */ /* <<< Until it is known whether this adapter would work on OpenBSD too */ #ifdef __NetBSD__ #define Libburn_use_sg_netbsD #endif #ifdef Libburn_use_sg_dummY /* --------- Any other system. With dummy MMC transport sg-dummy.c --------- */ #include "os-dummy.h" #else #ifdef Libburn_use_libcdiO /* -------------------------- X/Open with GNU libcdio ---------------------- */ #include "os-libcdio.h" #else #ifdef Libburn_use_sg_netbsD /* To become: # ifdef __NetBSD__ */ /* -------------------------- NetBSD with SCIOCCOMMAND --------------------- */ #include "os-netbsd.h" #else #ifdef __FreeBSD__ /* ----------------------------- FreeBSD with CAM -------------------------- */ #include "os-freebsd.h" #else #ifdef __FreeBSD_kernel__ /* ----------------------- FreeBSD with CAM under Debian ------------------- */ #include "os-freebsd.h" #else #ifdef __linux /* ------- Linux kernels 2.4 and 2.6 with GNU/Linux SCSI Generic (sg) ------ */ #include "os-linux.h" #else #ifdef __sun /* ------- Solaris (e.g. SunOS 5.11) with uscsi ------ */ #include "os-solaris.h" #else /* --------- Any other system. With dummy MMC transport sg-dummy.c --------- */ #include "os-dummy.h" #endif /* ! __sun*/ #endif /* ! __linux */ #endif /* ! __FreeBSD__kernel__ */ #endif /* ! __FreeBSD__ */ #endif /* ! Libburn_use_sg_netbsD */ #endif /* ! Libburn_use_libcdiO */ #endif /* ! Libburn_use_sg_dummY */ #endif /* ! BURN_OS_H_INCLUDED */ ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������libburn-1.4.2/libburn/libdax_msgs.h�����������������������������������������������������������������0000644�0001757�0001751�00000104652�12652644224�014225� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ /* libdax_msgs Message handling facility of libburn and libisofs. Copyright (C) 2006-2011 Thomas Schmitt <scdbackup@gmx.net>, provided under GPL version 2 or later. */ /* *Never* set this macro outside libdax_msgs.c ! The entrails of the message handling facility are not to be seen by the other library components or the applications. */ #ifdef LIBDAX_MSGS_H_INTERNAL #ifndef LIBDAX_MSGS_SINGLE_THREADED #include <pthread.h> #endif struct libdax_msgs_item { double timestamp; pid_t process_id; int origin; int severity; int priority; /* Apply for your developer's error code range at libburn-hackers@pykix.org Report introduced codes in the list below. */ int error_code; char *msg_text; int os_errno; struct libdax_msgs_item *prev,*next; }; struct libdax_msgs { int refcount; struct libdax_msgs_item *oldest; struct libdax_msgs_item *youngest; int count; int queue_severity; int print_severity; char print_id[81]; #ifndef LIBDAX_MSGS_SINGLE_THREADED pthread_mutex_t lock_mutex; #endif }; #endif /* LIBDAX_MSGS_H_INTERNAL */ #ifndef LIBDAX_MSGS_H_INCLUDED #define LIBDAX_MSGS_H_INCLUDED 1 #ifndef LIBDAX_MSGS_H_INTERNAL /* Architectural aspects */ /* libdax_msgs is designed to serve in libraries which want to offer their applications a way to control the output of library messages. It shall be incorporated by an owner, i.e. a software entity which encloses the code of the .c file. Owner of libdax_msgs is libburn. A fully compatible variant named libiso_msgs is owned by libisofs and can get generated by a script of the libburn project: libburn/libdax_msgs_to_xyz_msgs.sh . Reason: One cannot link two owners of the same variant together because both would offer the same functions to the linker. For that situation one has to create a compatible variant as it is done for libisofs. Compatible variants may get plugged together by call combinations like burn_set_messenger(iso_get_messenger()); A new variant would demand a _set_messenger() function if it has to work with libisofs. If only libburn is planned as link partner then a simple _get_messenger() does suffice. Take care to shutdown libburn before its provider of the *_msgs object gets shut down. */ /* Public Opaque Handles */ /** A pointer to this is a opaque handle to a message handling facility */ struct libdax_msgs; /** A pointer to this is a opaque handle to a single message item */ struct libdax_msgs_item; #endif /* ! LIBDAX_MSGS_H_INTERNAL */ /* Public Macros */ /* Registered Severities */ /* It is well advisable to let applications select severities via strings and forwarded functions libdax_msgs__text_to_sev(), libdax_msgs__sev_to_text(). These macros are for use by the owner of libdax_msgs. */ /** Use this to get messages of any severity. Do not use for submitting. */ #define LIBDAX_MSGS_SEV_ALL 0x00000000 /** Messages of this severity shall transport plain disk file paths whenever an event of severity SORRY or above is related with an individual disk file. No message text shall be added to the file path. The ERRFILE message shall be issued before the human readable message which carries the true event severity. That message should contain the file path so it can be found by strstr(message, path)!=NULL. The error code shall be the same as with the human readable message. */ #define LIBDAX_MSGS_SEV_ERRFILE 0x08000000 /** Debugging messages not to be visible to normal users by default */ #define LIBDAX_MSGS_SEV_DEBUG 0x10000000 /** Update of a progress report about long running actions */ #define LIBDAX_MSGS_SEV_UPDATE 0x20000000 /** Not so usual events which were gracefully handled */ #define LIBDAX_MSGS_SEV_NOTE 0x30000000 /** Possibilities to achieve a better result */ #define LIBDAX_MSGS_SEV_HINT 0x40000000 /** Warnings about problems which could not be handled optimally */ #define LIBDAX_MSGS_SEV_WARNING 0x50000000 /** Non-fatal error messages indicating that parts of an action failed but processing may go on if one accepts deviations from the desired result. SORRY may also be the severity for incidents which are severe enough for FAILURE but happen within already started irrevocable actions, like ISO image generation. A precondition for such a severity ease is that the action can be continued after the incident. See below MISHAP for what xorriso would need instead of this kind of SORRY and generates for itself in case of libisofs image generation. E.g.: A pattern yields no result. A speed setting cannot be made. A libisofs input file is inaccessible during image generation. After SORRY a function should try to go on if that makes any sense and if no threshold prescribes abort on SORRY. The function should nevertheless indicate some failure in its return value. It should - but it does not have to. */ #define LIBDAX_MSGS_SEV_SORRY 0x60000000 /** A FAILURE (see below) which can be tolerated during long lasting operations just because they cannot simply be stopped or revoked. xorriso converts libisofs SORRY messages issued during image generation into MISHAP messages in order to allow its evaluators to distinguish image generation problems from minor image composition problems. E.g.: A libisofs input file is inaccessible during image generation. After a MISHAP a function should behave like after SORRY. */ #define LIBDAX_MSGS_SEV_MISHAP 0x64000000 /** Non-fatal error indicating that an important part of an action failed and that only a new setup of preconditions will give hope for sufficient success. E.g.: No media is inserted in the output drive. No write mode can be found for inserted media. A libisofs input file is inaccessible during grafting. After FAILURE a function should end with a return value indicating failure. It is at the discretion of the function whether it ends immediately in any case or whether it tries to go on if the eventual threshold allows. */ #define LIBDAX_MSGS_SEV_FAILURE 0x68000000 /** An error message which puts the whole operation of the program in question E.g.: Not enough memory for essential temporary objects. Irregular errors from resources. Programming errors (soft assert). After FATAL a function should end very soon with a return value indicating severe failure. */ #define LIBDAX_MSGS_SEV_FATAL 0x70000000 /** A message from an abort handler which will finally finish libburn */ #define LIBDAX_MSGS_SEV_ABORT 0x71000000 /** A severity to exclude resp. discard any possible message. Do not use this severity for submitting. */ #define LIBDAX_MSGS_SEV_NEVER 0x7fffffff /* Registered Priorities */ /* Priorities are to be selected by the programmers and not by the user. */ #define LIBDAX_MSGS_PRIO_ZERO 0x00000000 #define LIBDAX_MSGS_PRIO_LOW 0x10000000 #define LIBDAX_MSGS_PRIO_MEDIUM 0x20000000 #define LIBDAX_MSGS_PRIO_HIGH 0x30000000 #define LIBDAX_MSGS_PRIO_TOP 0x7ffffffe /* Do not use this priority for submitting */ #define LIBDAX_MSGS_PRIO_NEVER 0x7fffffff /* Origin numbers of libburn drives may range from 0 to 1048575 */ #define LIBDAX_MSGS_ORIGIN_DRIVE_BASE 0 #define LIBDAX_MSGS_ORIGIN_DRIVE_TOP 0xfffff /* Origin numbers of libisofs images may range from 1048575 to 2097152 */ #define LIBDAX_MSGS_ORIGIN_IMAGE_BASE 0x100000 #define LIBDAX_MSGS_ORIGIN_IMAGE_TOP 0x1fffff /* Public Functions */ /* Calls initiated from inside the direct owner (e.g. from libburn) */ /** Create new empty message handling facility with queue and issue a first official reference to it. @param flag Bitfield for control purposes (unused yet, submit 0) @return >0 success, <=0 failure */ int libdax_msgs_new(struct libdax_msgs **m, int flag); /** Destroy a message handling facility and all its eventual messages. The submitted pointer gets set to NULL. Actually only the last destroy call of all offical references to the object will really dispose it. All others just decrement the reference counter. Call this function only with official reference pointers obtained by libdax_msgs_new() or libdax_msgs_refer(), and only once per such pointer. @param flag Bitfield for control purposes (unused yet, submit 0) @return 1 for success, 0 for pointer to NULL, -1 for fatal error */ int libdax_msgs_destroy(struct libdax_msgs **m, int flag); /** Create an official reference to an existing libdax_msgs object. The references keep the object alive at least until it is released by a matching number of destroy calls. So each reference MUST be revoked by exactly one call to libdax_msgs_destroy(). @param pt The pointer to be set and registered @param m A pointer to the existing object @param flag Bitfield for control purposes (unused yet, submit 0) @return 1 for success, 0 for failure */ int libdax_msgs_refer(struct libdax_msgs **pt, struct libdax_msgs *o, int flag); /** Submit a message to a message handling facility. @param origin program specific identification number of the originator of a message. E.g. drive number. Programs should have an own range of origin numbers. See above LIBDAX_MSGS_ORIGIN_*_BASE Use -1 if no number is known. @param error_code Unique error code. Use only registered codes. See below. The same unique error_code may be issued at different occasions but those should be equivalent out of the view of a libdax_msgs application. (E.g. "cannot open ATA drive" versus "cannot open SCSI drive" would be equivalent.) @param severity The LIBDAX_MSGS_SEV_* of the event. @param priority The LIBDAX_MSGS_PRIO_* number of the event. @param msg_text Printable and human readable message text. @param os_errno Eventual error code from operating system (0 if none) @param flag Bitfield for control purposes bit0= If direct output to stderr: CarriageReturn rather than LineFeed @return 1 on success, 0 on rejection, <0 for severe errors */ int libdax_msgs_submit(struct libdax_msgs *m, int origin, int error_code, int severity, int priority, char *msg_text, int os_errno, int flag); /* Calls from applications (to be forwarded by direct owner) */ /** Convert a registered severity number into a severity name @param flag Bitfield for control purposes: bit0= list all severity names in a blank separated string @return >0 success, <=0 failure */ int libdax_msgs__sev_to_text(int severity, char **severity_name, int flag); /** Convert a severity name into a severity number, @param flag Bitfield for control purposes (unused yet, submit 0) @return >0 success, <=0 failure */ int libdax_msgs__text_to_sev(char *severity_name, int *severity, int flag); /** Set minimum severity for messages to be queued (default LIBDAX_MSGS_SEV_ALL) and for messages to be printed directly to stderr (default LIBDAX_MSGS_SEV_NEVER). @param print_id A text of at most 80 characters to be printed before any eventually printed message (default is "libdax: "). @param flag Bitfield for control purposes (unused yet, submit 0) @return always 1 for now */ int libdax_msgs_set_severities(struct libdax_msgs *m, int queue_severity, int print_severity, char *print_id, int flag); /** Obtain a message item that has at least the given severity and priority. Usually all older messages of lower severity are discarded then. If no item of sufficient severity was found, all others are discarded from the queue. @param flag Bitfield for control purposes (unused yet, submit 0) @return 1 if a matching item was found, 0 if not, <0 for severe errors */ int libdax_msgs_obtain(struct libdax_msgs *m, struct libdax_msgs_item **item, int severity, int priority, int flag); /** Destroy a message item obtained by libdax_msgs_obtain(). The submitted pointer gets set to NULL. Caution: Copy eventually obtained msg_text before destroying the item, if you want to use it further. @param flag Bitfield for control purposes (unused yet, submit 0) @return 1 for success, 0 for pointer to NULL, <0 for severe errors */ int libdax_msgs_destroy_item(struct libdax_msgs *m, struct libdax_msgs_item **item, int flag); /** Obtain from a message item the three application oriented components as submitted with the originating call of libdax_msgs_submit(). Caution: msg_text becomes a pointer into item, not a copy. @param flag Bitfield for control purposes (unused yet, submit 0) @return 1 on success, 0 on invalid item, <0 for servere errors */ int libdax_msgs_item_get_msg(struct libdax_msgs_item *item, int *error_code, char **msg_text, int *os_errno, int flag); /** Obtain from a message item the submitter identification submitted with the originating call of libdax_msgs_submit(). @param flag Bitfield for control purposes (unused yet, submit 0) @return 1 on success, 0 on invalid item, <0 for servere errors */ int libdax_msgs_item_get_origin(struct libdax_msgs_item *item, double *timestamp, pid_t *process_id, int *origin, int flag); /** Obtain from a message item severity and priority as submitted with the originating call of libdax_msgs_submit(). @param flag Bitfield for control purposes (unused yet, submit 0) @return 1 on success, 0 on invalid item, <0 for servere errors */ int libdax_msgs_item_get_rank(struct libdax_msgs_item *item, int *severity, int *priority, int flag); #ifdef LIBDAX_MSGS_________________ /* Registered Error Codes */ Format: error_code (LIBDAX_MSGS_SEV_*,LIBDAX_MSGS_PRIO_*) = explanation If no severity or priority are fixely associated, use "(,)". ------------------------------------------------------------------------------ Range "libdax_msgs" : 0x00000000 to 0x0000ffff 0x00000000 (ALL,ZERO) = Initial setting in new libdax_msgs_item 0x00000001 (DEBUG,ZERO) = Test error message 0x00000002 (DEBUG,ZERO) = Debugging message 0x00000003 (FATAL,HIGH) = Out of virtual memory 0x00000004 (FATAL,HIGH) = Generic fatal error ------------------------------------------------------------------------------ Range "elmom" : 0x00010000 to 0x0001ffff ------------------------------------------------------------------------------ Range "scdbackup" : 0x00020000 to 0x0002ffff Acessing and defending drives: 0x00020001 (SORRY,LOW) = Cannot open busy device 0x00020002 (SORRY,HIGH) = Encountered error when closing drive 0x00020003 (SORRY,HIGH) = Could not grab drive 0x00020004 (NOTE,HIGH) = Opened O_EXCL scsi sibling 0x00020005 (SORRY,HIGH) = Failed to open device 0x00020006 (FATAL,HIGH) = Too many scsi siblings 0x00020007 (NOTE,HIGH) = Closed O_EXCL scsi siblings 0x00020008 (SORRY,HIGH) = Device busy. Failed to fcntl-lock 0x00020009 (SORRY,HIGH) = Neither stdio-path nor its directory exist 0x0002000a (FAILURE,HIGH) = Cannot accept '...' as SG_IO CDROM drive 0x0002000b (FAILURE,HIGH) = File object '...' not found 0x0002000c (FAILURE,HIGH) = Cannot start device file enumeration 0x0002000d (FAILURE,HIGH) = Cannot enumerate next device 0x0002000e (NOTE,HIGH) = Failed to open device during General library operations: 0x00020101 (WARNING,HIGH) = Cannot find given worker item 0x00020102 (SORRY,HIGH) = A drive operation is still going on 0x00020103 (WARNING,HIGH) = After scan a drive operation is still going on 0x00020104 (SORRY,HIGH) = NULL pointer caught 0x00020105 (SORRY,HIGH) = Drive is already released 0x00020106 (SORRY,HIGH) = Drive is busy on attempt to close 0x00020107 (WARNING,HIGH) = A drive is still busy on shutdown of library 0x00020108 (SORRY,HIGH) = Drive is not grabbed on disc status inquiry 0x00020108 (FATAL,HIGH) = Could not allocate new drive object 0x00020109 (FATAL,HIGH) = Library not running 0x0002010a (FATAL,HIGH) = Unsuitable track mode 0x0002010b (FATAL,HIGH) = Burn run failed 0x0002010c (FATAL,HIGH) = Failed to transfer command to drive 0x0002010d (DEBUG,HIGH) = Could not inquire TOC 0x0002010e (FATAL,HIGH) = Attempt to read ATIP from ungrabbed drive 0x0002010f (DEBUG,HIGH) = SCSI error condition on command 0x00020110 (FATAL,HIGH) = Persistent drive address too long 0x00020111 (FATAL,HIGH) = Could not allocate new auxiliary object 0x00020112 (SORRY,HIGH) = Bad combination of write_type and block_type 0x00020113 (FATAL,HIGH) = Drive capabilities not inquired yet 0x00020114 (SORRY,HIGH) = Attempt to set ISRC with bad data 0x00020115 (SORRY,HIGH) = Attempt to set track mode to unusable value 0x00020116 (FATAL,HIGH) = Track mode has unusable value 0x00020117 (FATAL,HIGH) = toc_entry of drive is already in use 0x00020118 (DEBUG,HIGH) = Closing track 0x00020119 (DEBUG,HIGH) = Closing session 0x0002011a (NOTE,HIGH) = Padding up track to minimum size 0x0002011b (FATAL,HIGH) = Attempt to read track info from ungrabbed drive 0x0002011c (FATAL,HIGH) = Attempt to read track info from busy drive 0x0002011d (FATAL,HIGH) = SCSI error on write 0x0002011e (SORRY,HIGH) = Unsuitable media detected 0x0002011f (SORRY,HIGH) = Burning is restricted to a single track 0x00020120 (NOTE,HIGH) = FORMAT UNIT ignored 0x00020121 (FATAL,HIGH) = Write preparation setup failed 0x00020122 (FAILURE,HIGH) = SCSI error on format_unit 0x00020123 (SORRY,HIGH) = DVD Media are unsuitable for desired track type 0x00020124 (SORRY,HIGH) = SCSI error on set_streaming 0x00020125 (SORRY,HIGH) = Write start address not supported 0x00020126 (SORRY,HIGH) = Write start address not properly aligned 0x00020127 (NOTE,HIGH) = Write start address is ... 0x00020128 (FATAL,HIGH) = Unsupported inquiry_type with mmc_get_performance 0x00020129 (SORRY,HIGH) = Will not format media type 0x0002012a (FATAL,HIGH) = Cannot inquire write mode capabilities 0x0002012b (FATAL,HIGH) = Drive offers no suitable write mode with this job 0x0002012c (SORRY,HIGH) = Too many logical tracks recorded 0x0002012d (FATAL,HIGH) = Exceeding range of permissible write addresses 0x0002012e (NOTE,HIGH) = Activated track default size 0x0002012f (SORRY,HIGH) = SAO is restricted to single fixed size session 0x00020130 (SORRY,HIGH) = Drive and media state unsuitable for blanking 0x00020131 (SORRY,HIGH) = No suitable formatting type offered by drive 0x00020132 (SORRY,HIGH) = Selected format is not suitable for libburn 0x00020133 (SORRY,HIGH) = Cannot mix data and audio in SAO mode 0x00020134 (NOTE,HIGH) = Defaulted TAO to DAO 0x00020135 (SORRY,HIGH) = Cannot perform TAO, job unsuitable for DAO 0x00020136 (SORRY,HIGH) = DAO burning restricted to single fixed size track 0x00020137 (HINT,HIGH) = TAO would be possible 0x00020138 (FATAL,HIGH) = Cannot reserve track 0x00020139 (SORRY,HIGH) = Write job parameters are unsuitable 0x0002013a (FATAL,HIGH) = No suitable media detected 0x0002013b (DEBUG,HIGH) = SCSI command indicates host or driver error 0x0002013c (SORRY,HIGH) = Malformed capabilities page 2Ah received 0x0002013d (DEBUG,LOW) = Waiting for free buffer space takes long time 0x0002013e (SORRY,HIGH) = Timeout with waiting for free buffer. Now disabled 0x0002013f (DEBUG,LOW) = Reporting total time spent with waiting for buffer 0x00020140 (FATAL,HIGH) = Drive is busy on attempt to write random access 0x00020141 (SORRY,HIGH) = Write data count not properly aligned 0x00020142 (FATAL,HIGH) = Drive is not grabbed on random access write 0x00020143 (SORRY,HIGH) = Read start address not properly aligned 0x00020144 (SORRY,HIGH) = SCSI error on read 0x00020145 (FATAL,HIGH) = Drive is busy on attempt to read data 0x00020146 (FATAL,HIGH) = Drive is a virtual placeholder 0x00020147 (SORRY,HIGH) = Cannot address start byte 0x00020148 (SORRY,HIGH) = Cannot write desired amount of data 0x00020149 (SORRY,HIGH) = Unsuitable filetype for pseudo-drive 0x0002014a (SORRY,HIGH) = Cannot read desired amount of data 0x0002014b (SORRY,HIGH) = Drive is already registered resp. scanned 0x0002014c (FATAL,HIGH) = Emulated drive caught in SCSI function 0x0002014d (SORRY,HIGH) = Asynchronous SCSI error 0x0002014f (SORRY,HIGH) = Timeout with asynchronous SCSI command 0x00020150 (DEBUG,LOW) = Reporting asynchronous waiting time 0x00020151 (FAILURE,HIGH) = Read attempt on write-only drive 0x00020152 (FATAL,HIGH) = Cannot start fifo thread 0x00020153 (SORRY,HIGH) = Read error on fifo input 0x00020154 (NOTE,HIGH) = Forwarded input error ends output 0x00020155 (SORRY,HIGH) = Desired fifo buffer too large 0x00020156 (SORRY,HIGH) = Desired fifo buffer too small 0x00020157 (FATAL,HIGH) = burn_source is not a fifo object 0x00020158 (DEBUG,LOW) = Reporting thread disposal precautions 0x00020159 (DEBUG,HIGH) = TOC Format 0 returns inconsistent data 0x0002015a (NOTE,HIGH) = Could not examine busy device 0x0002015b (HINT,HIGH) = Busy '...' seems to be a hard disk, as '...1' exists 0x0002015c (FAILURE,HIGH) = Fifo size too small for desired peek buffer 0x0002015d (FAILURE,HIGH) = Fifo input ended short of desired peek buffer size 0x0002015e (FATAL,HIGH) = Fifo is already under consumption when peeking 0x0002015f (MISHAP,HIGH) = Damaged CD table-of-content detected and truncated 0x00020160 (WARNING,HIGH) = Session without leadout encountered 0x00020161 (WARNING,HIGH) = Empty session deleted 0x00020162 (SORRY,HIGH) = BD-R not unformatted blank any more. Cannot format 0x00020163 (NOTE,HIGH) = Blank BD-R left unformatted for zero spare capacity 0x00020164 (SORRY,HIGH) = Drive does not format BD-RE without spares 0x00020165 (WARNING,HIGH) = Drive does not support fast formatting 0x00020166 (WARNING,HIGH) = Drive does not support full formatting 0x00020167 (SORRY,HIGH) = Drive does not support non-default formatting 0x00020168 (FAILURE,HIGH) = Media not properly formatted. Cannot write. 0x00020169 (WARNING,HIGH) = Last session on media is still open 0x0002016a (FAILURE,HIGH) = No MMC transport adapter is present 0x0002016b (WARNING,HIGH) = No MMC transport adapter is present 0x0002016c (DEBUG,HIGH) = No MMC transport adapter is present 0x0002016e (DEBUG,HIGH) = MODE SENSE page 2A too short 0x0002016f (DEBUG,HIGH) = Unable to grab scanned drive 0x00020170 (NOTE,HIGH) = Closing open session before writing new one 0x00020171 (NOTE,HIGH) = Closing BD-R with accidently open session 0x00020172 (SORRY,HIGH) = Read start address larger than number of readable blocks 0x00020173 (FAILURE,HIGH) = Drive tells NWA smaller than last written address 0x00020174 (SORRY,HIGH) = Fifo alignment does not allow desired read size 0x00020175 (FATAL,HIGH) = Supporting library is too old 0x00020176 (NOTE,HIGH) = Stream recording disabled because of small OS buffer 0x00020177 (ABORT,HIGH) = Urged drive worker threads to do emergency halt 0x00020178 (DEBUG,HIGH) = Write thread ended 0x00020179 (FAILURE,HIGH) = Offset source start address is before end of previous source 0x0002017a (FAILURE,HIGH) = Expected offset source object as parameter 0x0002017b (WARNING,HIGH) = Sequential BD-R media likely to soon fail writing 0x0002017c (FAILURE,HIGH) = No valid write type selected 0x0002017d (FATAL,HIGH) = Invalid file descriptor with stdio pseudo-drive 0x0002017e (FAILURE,HIGH) = Failed to close track, session, or disc 0x0002017f (FAILURE,HIGH) = Failed to synchronize drive cache 0x00020180 (FAILURE,HIGH) = Premature end of input encountered 0x00020181 (FAILURE,HIGH) = Pseudo-drive is a read-only file. Cannot write. 0x00020182 (FAILURE,HIGH) = Cannot truncate disk file for pseudo blanking 0x00020183 (WARNING,HIGH) = Failed to open device (a pseudo-drive) for reading 0x00020184 (WARNING,HIGH) = No Next-Writable-Address 0x00020185 (WARNING,HIGH) = Track damaged, not closed and not writable 0x00020186 (WARNING,HIGH) = Track damaged and not closed 0x00020187 (NOTE,HIGH) = Track not marked as damaged. No action taken. 0x00020188 (FAILURE,HIGH) = Cannot close damaged track on given media type 0x00020189 (FATAL,HIGH) = Drive is already grabbed by libburn 0x0002018a (SORRY,HIGH) = Timeout exceeded. Retry cancled. 0x0002018b (FAILURE,HIGH) = Too many CD-TEXT packs 0x0002018c (FAILURE,HIGH) = CD-TEXT pack type out of range 0x0002018d (FAILURE,HIGH) = CD-TEXT block number out of range 0x0002018e (FAILURE,HIGH) = Too many CD-TEXT packs in block 0x0002018f (FAILURE,HIGH) = CD-TEXT pack CRC mismatch 0x00020190 (WARNING,HIGH) = CD-TEXT pack CRC mismatch had to be corrected 0x00020191 (FAILURE,HIGH) = Unknown parameter in text input file 0x00020192 (FAILURE,HIGH) = Text input file sequence error 0x00020193 (FAILURE,HIGH) = Text input file readability problem 0x00020194 (FAILURE,HIGH) = Text input file syntax error or specs violation 0x00020195 (WARNING,HIGH) = Text input file warning 0x00020196 (FAILURE,HIGH) = Session has already defined tracks 0x00020197 (FAILURE,HIGH) = Unsupported text input file feature 0x00020198 (FAILURE,HIGH) = CD-TEXT pack file readability problem 0x00020199 (SORRY,HIGH) = Text input file reading aborted 0x0002019a (SORRY,HIGH) = Bad track index number 0x0002019b (SORRY,HIGH) = CD track number exceeds range of 1 to 99 0x0002019c (SORRY,HIGH) = Session has no defined tracks 0x0002019d (SORRY,HIGH) = Audio read size not properly aligned 0x0002019e (NOTE,HIGH) = Drive does not support media certification 0x0002019f (FAILURE,HIGH) = CD-TEXT binary pack array faulty 0x000201a0 (WARNING,HIGH) = Maximum number of CD-TEXT blocks exceeded 0x000201a1 (FAILURE,HIGH) = Cannot open disk file for writing 0x000201a2 (FAILURE,HIGH) = Error while writing to disk file 0x000201a3 (UPDATE,HIGH) = Progress message of burn_drive_extract_audio() 0x000201a4 (FAILURE,HIGH) = Failure to read audio sectors 0x000201a5 (FAILURE,HIGH) = Asynchronous SCSI error 0x000201a6 (FATAL,HIGH) = Lost connection to drive 0x000201a7 (FAILURE,HIGH) = SCSI command yielded host problem 0x000201a8 (FAILURE,HIGH) = SCSI command yielded driver problem 0x000201a9 (FAILURE,HIGH) = Implausible length from GET CONFIGURATION 0x000201aa (FAILURE,HIGH) = No CD-TEXT packs in file libdax_audioxtr: 0x00020200 (SORRY,HIGH) = Cannot open audio source file 0x00020201 (SORRY,HIGH) = Audio source file has unsuitable format 0x00020202 (SORRY,HIGH) = Failed to prepare reading of audio data ------------------------------------------------------------------------------ Range "vreixo" : 0x00030000 to 0x0003ffff 0x0003ffff (FAILURE,HIGH) = Operation canceled 0x0003fffe (FATAL,HIGH) = Unknown or unexpected fatal error 0x0003fffd (FAILURE,HIGH) = Unknown or unexpected error 0x0003fffc (FATAL,HIGH) = Internal programming error 0x0003fffb (FAILURE,HIGH) = NULL pointer where NULL not allowed 0x0003fffa (FATAL,HIGH) = Memory allocation error 0x0003fff9 (FATAL,HIGH) = Interrupted by a signal 0x0003fff8 (FAILURE,HIGH) = Invalid parameter value 0x0003fff7 (FATAL,HIGH) = Cannot create a needed thread 0x0003fff6 (FAILURE,HIGH) = Write error 0x0003fff5 (FAILURE,HIGH) = Buffer read error 0x0003ffc0 (FAILURE,HIGH) = Trying to add a node already added to another dir 0x0003ffbf (FAILURE,HIGH) = Node with same name already exist 0x0003ffbe (FAILURE,HIGH) = Trying to remove a node that was not added to dir 0x0003ffbd (FAILURE,HIGH) = A requested node does not exist 0x0003ffbc (FAILURE,HIGH) = Image already bootable 0x0003ffbb (FAILURE,HIGH) = Trying to use an invalid file as boot image 0x0003ff80 (FAILURE,HIGH) = Error on file operation 0x0003ff7f (FAILURE,HIGH) = Trying to open an already openned file 0x0003ff7e (FAILURE,HIGH) = Access to file is not allowed 0x0003ff7d (FAILURE,HIGH) = Incorrect path to file 0x0003ff7c (FAILURE,HIGH) = The file does not exist in the filesystem 0x0003ff7b (FAILURE,HIGH) = Trying to read or close a file not openned 0x0003ff7a (FAILURE,HIGH) = Directory used where no dir is expected 0x0003ff79 (FAILURE,HIGH) = File read error 0x0003ff78 (FAILURE,HIGH) = Not dir used where a dir is expected 0x0003ff77 (FAILURE,HIGH) = Not symlink used where a symlink is expected 0x0003ff76 (FAILURE,HIGH) = Cannot seek to specified location 0x0003ff75 (HINT,MEDIUM) = File not supported in ECMA-119 tree and ignored 0x0003ff74 (HINT,MEDIUM) = File bigger than supported by used standard 0x0003ff73 (MISHAP,HIGH) = File read error during image creation 0x0003ff72 (HINT,MEDIUM) = Cannot convert filename to requested charset 0x0003ff71 (SORRY,HIGH) = File cannot be added to the tree 0x0003ff70 (HINT,MEDIUM) = File path breaks specification constraints 0x0003ff00 (FAILURE,HIGH) = Charset conversion error 0x0003feff (FAILURE,HIGH) = Too much files to mangle 0x0003fec0 (FAILURE,HIGH) = Wrong or damaged Primary Volume Descriptor 0x0003febf (SORRY,HIGH) = Wrong or damaged RR entry 0x0003febe (SORRY,HIGH) = Unsupported RR feature 0x0003febd (FAILURE,HIGH) = Wrong or damaged ECMA-119 0x0003febc (FAILURE,HIGH) = Unsupported ECMA-119 feature 0x0003febb (SORRY,HIGH) = Wrong or damaged El-Torito catalog 0x0003feba (SORRY,HIGH) = Unsupported El-Torito feature 0x0003feb9 (SORRY,HIGH) = Cannot patch isolinux boot image 0x0003feb8 (SORRY,HIGH) = Unsupported SUSP feature 0x0003feb7 (WARNING,HIGH) = Error on a RR entry that can be ignored 0x0003feb6 (HINT,MEDIUM) = Error on a RR entry that can be ignored 0x0003feb5 (WARNING,HIGH) = Multiple ER SUSP entries found 0x0003feb4 (HINT,MEDIUM) = Unsupported volume descriptor found 0x0003feb3 (WARNING,HIGH) = El-Torito related warning 0x0003feb2 (MISHAP,HIGH) = Image write cancelled 0x0003feb1 (WARNING,HIGH) = El-Torito image is hidden Outdated codes which may not be re-used for other purposes than re-instating them, if ever: X 0x00031001 (SORRY,HIGH) = Cannot read file (ignored) X 0x00031002 (FATAL,HIGH) = Cannot read file (operation canceled) X 0x00031000 (FATAL,HIGH) = Unsupported ISO-9660 image X 0x00031001 (HINT,MEDIUM) = Unsupported Vol Desc that will be ignored X 0x00031002 (FATAL,HIGH) = Damaged ISO-9660 image X 0x00031003 (SORRY,HIGH) = Cannot read previous image file X 0x00030101 (HINT,MEDIUM) = Unsupported SUSP entry that will be ignored X 0x00030102 (SORRY,HIGH) = Wrong/damaged SUSP entry X 0x00030103 (WARNING,MEDIUM)= Multiple SUSP ER entries where found X 0x00030111 (SORRY,HIGH) = Unsupported RR feature X 0x00030112 (SORRY,HIGH) = Error in a Rock Ridge entry X 0x00030201 (HINT,MEDIUM) = Unsupported Boot Vol Desc that will be ignored X 0x00030202 (SORRY,HIGH) = Wrong El-Torito catalog X 0x00030203 (HINT,MEDIUM) = Unsupported El-Torito feature X 0x00030204 (SORRY,HIGH) = Invalid file to be an El-Torito image X 0x00030205 (WARNING,MEDIUM)= Cannot properly patch isolinux image X 0x00030206 (WARNING,MEDIUM)= Copying El-Torito from a previous image without X enought info about it X 0x00030301 (NOTE,MEDIUM) = Unsupported file type for Joliet tree ------------------------------------------------------------------------------ Range "application" : 0x00040000 to 0x0004ffff 0x00040000 (ABORT,HIGH) : Application supplied message 0x00040001 (FATAL,HIGH) : Application supplied message 0x00040002 (SORRY,HIGH) : Application supplied message 0x00040003 (WARNING,HIGH) : Application supplied message 0x00040004 (HINT,HIGH) : Application supplied message 0x00040005 (NOTE,HIGH) : Application supplied message 0x00040006 (UPDATE,HIGH) : Application supplied message 0x00040007 (DEBUG,HIGH) : Application supplied message 0x00040008 (*,HIGH) : Application supplied message ------------------------------------------------------------------------------ Range "libisofs-xorriso" : 0x00050000 to 0x0005ffff This is an alternative representation of libisofs.so.6 error codes in xorriso. If values returned by iso_error_get_code() do not fit into 0x30000 to 0x3ffff then they get truncated to 16 bit and mapped into this range. (This should never need to happen, of course.) ------------------------------------------------------------------------------ Range "libisoburn" : 0x00060000 to 0x00006ffff 0x00060000 (*,*) : Message which shall be attributed to libisoburn >>> the messages of libisoburn need to be registered individually ------------------------------------------------------------------------------ #endif /* LIBDAX_MSGS_________________ */ #ifdef LIBDAX_MSGS_H_INTERNAL /* Internal Functions */ /** Lock before doing side effect operations on m */ static int libdax_msgs_lock(struct libdax_msgs *m, int flag); /** Unlock after effect operations on m are done */ static int libdax_msgs_unlock(struct libdax_msgs *m, int flag); /** Create new empty message item. @param link Previous item in queue @param flag Bitfield for control purposes (unused yet, submit 0) @return >0 success, <=0 failure */ static int libdax_msgs_item_new(struct libdax_msgs_item **item, struct libdax_msgs_item *link, int flag); /** Destroy a message item obtained by libdax_msgs_obtain(). The submitted pointer gets set to NULL. @param flag Bitfield for control purposes (unused yet, submit 0) @return 1 for success, 0 for pointer to NULL */ static int libdax_msgs_item_destroy(struct libdax_msgs_item **item, int flag); #endif /* LIBDAX_MSGS_H_INTERNAL */ #endif /* ! LIBDAX_MSGS_H_INCLUDED */ ��������������������������������������������������������������������������������������libburn-1.4.2/libburn/async.c�����������������������������������������������������������������������0000644�0001757�0001751�00000046506�12652644224�013044� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */ /* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens Copyright (c) 2006 - 2014 Thomas Schmitt <scdbackup@gmx.net> Provided under GPL version 2 or later. */ /* ts A71019 */ /* Standard measure should be: Threads are created detached. According to the man pages they should then care for disposing themselves. >>> ??? It is yet unclear why the threads vanish from the process list even if joinable and even if never joined. To be activated after release of libburn-0.4.0 */ #define Libburn_create_detached_threadS 1 /* Alternative : Threads are created joinable. Threads get detached in remove_worker() and thus should dispose themselves. #define Libburn_detach_done_workeR 1 */ #ifdef HAVE_CONFIG_H #include "../config.h" #endif #include "libburn.h" #include "transport.h" #include "drive.h" #include "write.h" #include "options.h" #include "file.h" #include "async.h" #include "init.h" #include "back_hacks.h" #include <pthread.h> #include <sys/types.h> #include <unistd.h> #include <stdlib.h> #include <stdio.h> #include <string.h> #include <signal.h> /* #include <a ssert.h> */ #include "libdax_msgs.h" extern struct libdax_msgs *libdax_messenger; /* ts A80714 : introduced type codes for the worker list */ #define Burnworker_type_scaN 0 #define Burnworker_type_erasE 1 #define Burnworker_type_formaT 2 #define Burnworker_type_writE 3 #define Burnworker_type_fifO 4 #define SCAN_GOING() (workers != NULL && \ workers->w_type == Burnworker_type_scaN) typedef void *(*WorkerFunc) (void *); struct scan_opts { struct burn_drive_info **drives; unsigned int *n_drives; int done; }; struct erase_opts { struct burn_drive *drive; int fast; }; /* ts A61230 */ struct format_opts { struct burn_drive *drive; off_t size; int flag; }; struct write_opts { struct burn_drive *drive; struct burn_write_opts *opts; struct burn_disc *disc; }; struct fifo_opts { struct burn_source *source; int flag; }; union w_list_data { struct scan_opts scan; struct erase_opts erase; struct format_opts format; struct write_opts write; struct fifo_opts fifo; }; struct w_list { /* ts A80714 */ int w_type; /* see above define Burnworker_type_* */ struct burn_drive *drive; pthread_t thread; struct w_list *next; union w_list_data u; }; static struct w_list *workers = NULL; static struct w_list *find_worker(struct burn_drive *d) { struct w_list *a; for (a = workers; a; a = a->next) if (a->drive == d) return a; return NULL; } static void add_worker(int w_type, struct burn_drive *d, WorkerFunc f, union w_list_data *data) { struct w_list *a; struct w_list *tmp; pthread_attr_t *attr_pt = NULL; #ifdef Libburn_create_detached_threadS pthread_attr_t attr; #endif a = calloc(1, sizeof(struct w_list)); a->w_type = w_type; a->drive = d; a->u = *data; /* memcpy(&(a->u), data, sizeof(union w_list_data)); */ /* insert at front of the list */ a->next = workers; tmp = workers; workers = a; if (d != NULL) d->busy = BURN_DRIVE_SPAWNING; #ifdef Libburn_create_detached_threadS /* ts A71019 : Trying to start the threads detached to get rid of the zombies which do neither react on pthread_join() nor on pthread_detach(). */ pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); attr_pt= &attr; /* libdax_msgs_submit(libdax_messenger, -1, 0x00020158, LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_LOW, "add_worker(): Creating detached thread.", 0, 0); */ #endif if (pthread_create(&a->thread, attr_pt, f, a)) { free(a); workers = tmp; return; } } static void remove_worker(pthread_t th) { struct w_list *a, *l = NULL; for (a = workers; a; l = a, a = a->next) if (a->thread == th) { if (l) l->next = a->next; else workers = a->next; #ifdef Libburn_detach_done_workeR /* ts A71019 : burry dead puppy before forgetting it */ /* Alternative : threads get detached and thus should dispose themselves. */ pthread_detach(th); /* int ret; char msg[80]; ret = pthread_detach(th); sprintf(msg, "remove_workers(): pid= %lu pthread_detach(%lu)= %d", (unsigned long) getpid(), (unsigned long) th, ret); libdax_msgs_submit(libdax_messenger, -1, 0x00020158, LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_LOW, msg, 0, 0); */ #endif /* Libburn_detach_done_workeR */ free(a); break; } /* ts A61006 */ /* a ssert(a != NULL);/ * wasn't found.. this should not be possible */ if (a == NULL) libdax_msgs_submit(libdax_messenger, -1, 0x00020101, LIBDAX_MSGS_SEV_WARNING, LIBDAX_MSGS_PRIO_HIGH, "remove_worker() cannot find given worker item", 0, 0); } static void *scan_worker_func(struct w_list *w) { int ret; ret = burn_drive_scan_sync(w->u.scan.drives, w->u.scan.n_drives, 1); if (ret <= 0) w->u.scan.done = -1; else w->u.scan.done = 1; return NULL; } static void reset_progress(struct burn_drive *d, int sessions, int tracks, int indices, int sectors, int flag) { /* reset the progress indicator */ d->progress.session = 0; d->progress.sessions = sessions; d->progress.track = 0; d->progress.tracks = tracks; d->progress.index = 0; d->progress.indices = indices; d->progress.start_sector = 0; d->progress.sectors = sectors; d->progress.sector = 0; } int burn_drive_scan(struct burn_drive_info *drives[], unsigned int *n_drives) { union w_list_data o; int ret = 0; /* ts A61006 : moved up from burn_drive_scan_sync , former Assert */ if (!burn_running) { libdax_msgs_submit(libdax_messenger, -1, 0x00020109, LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH, "Library not running (on attempt to scan)", 0, 0); *drives = NULL; *n_drives = 0; return -1; } /* cant be anything working! */ /* ts A61006 */ /* a ssert(!(workers && workers->drive)); */ if (workers != NULL && workers->drive != NULL) { drive_is_active:; libdax_msgs_submit(libdax_messenger, -1, 0x00020102, LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH, "A drive operation is still going on (want to scan)", 0, 0); *drives = NULL; *n_drives = 0; return -1; } if (workers == NULL) { /* start it */ /* ts A61007 : test moved up from burn_drive_scan_sync() was burn_wait_all() */ /* ts A70907 : now demanding freed drives, not only released */ if (!burn_drives_are_clear(1)) goto drive_is_active; *drives = NULL; *n_drives = 0; o.scan.drives = drives; o.scan.n_drives = n_drives; o.scan.done = 0; add_worker(Burnworker_type_scaN, NULL, (WorkerFunc) scan_worker_func, &o); } else if (workers->u.scan.done) { /* its done */ ret = workers->u.scan.done; remove_worker(workers->thread); /* ts A61006 */ /* a ssert(workers == NULL); */ if (workers != NULL) { libdax_msgs_submit(libdax_messenger, -1, 0x00020101, LIBDAX_MSGS_SEV_WARNING, LIBDAX_MSGS_PRIO_HIGH, "After scan a drive operation is still going on", 0, 0); return -1; } } else { /* still going */ } return ret; } static void *erase_worker_func(struct w_list *w) { #define Libburn_protect_erase_threaD 1 #ifdef Libburn_protect_erase_threaD sigset_t sigset, oldset; /* Protect blank thread from being interrupted by external signals */ sigfillset(&sigset); sigdelset(&sigset, SIGSEGV); sigdelset(&sigset, SIGILL); pthread_sigmask(SIG_SETMASK, &sigset, &oldset); #endif /* Libburn_protect_erase_threaD */ burn_disc_erase_sync(w->u.erase.drive, w->u.erase.fast); remove_worker(pthread_self()); #ifdef Libburn_protect_erase_threaD /* (just in case it would not end with all signals blocked) */ pthread_sigmask(SIG_SETMASK, &oldset, NULL); #endif /* Libburn_protect_erase_threaD */ return NULL; } void burn_disc_erase(struct burn_drive *drive, int fast) { union w_list_data o; /* ts A61006 */ /* a ssert(drive); */ /* a ssert(!SCAN_GOING()); */ /* a ssert(!find_worker(drive)); */ if(drive == NULL) { libdax_msgs_submit(libdax_messenger, -1, 0x00020104, LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH, "NULL pointer caught in burn_disc_erase", 0, 0); return; } if ((SCAN_GOING()) || find_worker(drive) != NULL) { libdax_msgs_submit(libdax_messenger, drive->global_index, 0x00020102, LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH, "A drive operation is still going on (want to erase)", 0, 0); return; } reset_progress(drive, 1, 1, 1, 0x10000, 0); /* A70103 : will be set to 0 by burn_disc_erase_sync() */ drive->cancel = 1; /* ts A70103 moved up from burn_disc_erase_sync() */ /* ts A60825 : allow on parole to blank appendable CDs */ /* ts A70131 : allow blanking of overwriteable DVD-RW (profile 0x13) */ /* ts A70216 : allow blanking of CD-RW or DVD-RW in any regular state and of any kind of full media */ /* ts A70909 : the willingness to burn any BURN_DISC_FULL media is inappropriate. One would rather need a -force option Note: keep this in sync with mmc_read_disc_info() */ /* ts B10321 : Allowed role 5 to be blanked */ if ((drive->drive_role == 1 && drive->current_profile != 0x0a && drive->current_profile != 0x13 && drive->current_profile != 0x14 && drive->status != BURN_DISC_FULL) || (drive->status != BURN_DISC_FULL && drive->status != BURN_DISC_APPENDABLE && drive->status != BURN_DISC_BLANK) || (drive->drive_role != 1 && drive->drive_role != 5) ) { char msg[160]; sprintf(msg, "Drive and media state unsuitable for blanking. (role= %d , profile= 0x%x , status= %d)", drive->drive_role, (unsigned int) drive->current_profile, drive->status); libdax_msgs_submit(libdax_messenger, drive->global_index, 0x00020130, LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH, msg, 0, 0); return; } o.erase.drive = drive; o.erase.fast = fast; add_worker(Burnworker_type_erasE, drive, (WorkerFunc) erase_worker_func, &o); } /* ts A61230 */ static void *format_worker_func(struct w_list *w) { #define Libburn_protect_format_threaD 1 #ifdef Libburn_protect_format_threaD sigset_t sigset, oldset; /* Protect format thread from being interrupted by external signals */ sigfillset(&sigset); sigdelset(&sigset, SIGSEGV); sigdelset(&sigset, SIGILL); pthread_sigmask(SIG_SETMASK, &sigset, &oldset); #endif /* Libburn_protect_format_threaD */ burn_disc_format_sync(w->u.format.drive, w->u.format.size, w->u.format.flag); remove_worker(pthread_self()); #ifdef Libburn_protect_format_threaD /* (just in case it would not end with all signals blocked) */ pthread_sigmask(SIG_SETMASK, &oldset, NULL); #endif /* Libburn_protect_format_threaD */ return NULL; } /* ts A61230 */ void burn_disc_format(struct burn_drive *drive, off_t size, int flag) { union w_list_data o; int ok = 0, ret; char msg[40]; reset_progress(drive, 1, 1, 1, 0x10000, 0); if ((SCAN_GOING()) || find_worker(drive) != NULL) { libdax_msgs_submit(libdax_messenger, drive->global_index, 0x00020102, LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH, "A drive operation is still going on (want to format)", 0, 0); return; } if (drive->drive_role != 1) { libdax_msgs_submit(libdax_messenger, drive->global_index, 0x00020146, LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH, "Drive is a virtual placeholder", 0, 0); drive->cancel = 1; return; } if (flag & 128) /* application prescribed format type */ flag |= 16; /* enforce re-format */ if (drive->current_profile == 0x14) ok = 1; /* DVD-RW sequential */ else if (drive->current_profile == 0x13 && (flag & 16)) ok = 1; /* DVD-RW Restricted Overwrite with force bit */ else if (drive->current_profile == 0x1a) { ok = 1; /* DVD+RW */ size = 0; flag &= ~(2|8); /* no insisting in size 0, no expansion */ flag |= 4; /* format up to maximum size */ } else if (drive->current_profile == 0x12) { ok = 1; /* DVD-RAM */ } else if (drive->current_profile == 0x41) { /* BD-R SRM */ ok= 1; ret = drive->read_format_capacities(drive, 0x00); if (ret > 0 && drive->format_descr_type == BURN_FORMAT_IS_FORMATTED) ok = 0; if (drive->status != BURN_DISC_BLANK) ok = 0; if (!ok) { libdax_msgs_submit(libdax_messenger, drive->global_index, 0x00020162, LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH, "BD-R not unformatted blank any more. Cannot format.", 0, 0); drive->cancel = 1; return; } if (flag & 32) { libdax_msgs_submit(libdax_messenger, drive->global_index, 0x00020163, LIBDAX_MSGS_SEV_NOTE, LIBDAX_MSGS_PRIO_HIGH, "Blank BD-R left unformatted for zero spare capacity.", 0, 0); return; } } else if (drive->current_profile == 0x43) { ok = 1; /* BD-RE */ if ((flag & 32) && !(drive->current_feat23h_byte4 & 8)) { libdax_msgs_submit(libdax_messenger, drive->global_index, 0x00020164, LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH, "Drive does not format BD-RE without spares.", 0, 0); drive->cancel = 1; return; } } if (!ok) { sprintf(msg,"Will not format media type %4.4Xh", drive->current_profile); libdax_msgs_submit(libdax_messenger, drive->global_index, 0x00020129, LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH, msg, 0, 0); drive->cancel = 1; return; } o.format.drive = drive; o.format.size = size; o.format.flag = flag; add_worker(Burnworker_type_formaT, drive, (WorkerFunc) format_worker_func, &o); } static void *write_disc_worker_func(struct w_list *w) { struct burn_drive *d = w->u.write.drive; char msg[80]; #define Libburn_protect_write_threaD 1 #ifdef Libburn_protect_write_threaD sigset_t sigset, oldset; /* Protect write thread from being interrupted by external signals */ sigfillset(&sigset); sigdelset(&sigset, SIGSEGV); sigdelset(&sigset, SIGILL); pthread_sigmask(SIG_SETMASK, &sigset, &oldset); #endif /* Libburn_protect_write_threaD */ d->thread_pid = getpid(); d->thread_tid = pthread_self(); d->thread_pid_valid= 1; burn_disc_write_sync(w->u.write.opts, w->u.write.disc); d->thread_pid_valid= 0; d->thread_pid = 0; /* the options are refcounted, free out ref count which we added below */ burn_write_opts_free(w->u.write.opts); sprintf(msg, "Write thread on drive %d ended", d->global_index); libdax_msgs_submit(libdax_messenger, d->global_index, 0x00020178, LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH, msg, 0, 0); remove_worker(pthread_self()); d->busy = BURN_DRIVE_IDLE; #ifdef Libburn_protect_write_threaD /* (just in case it would not end with all signals blocked) */ pthread_sigmask(SIG_SETMASK, &oldset, NULL); #endif /* Libburn_protect_write_threaD */ return NULL; } void burn_disc_write(struct burn_write_opts *opts, struct burn_disc *disc) { union w_list_data o; char *reasons= NULL; struct burn_drive *d; int mvalid; d = opts->drive; /* ts A61006 */ /* a ssert(!SCAN_GOING()); */ /* a ssert(!find_worker(opts->drive)); */ if ((SCAN_GOING()) || find_worker(opts->drive) != NULL) { libdax_msgs_submit(libdax_messenger, d->global_index, 0x00020102, LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH, "A drive operation is still going on (want to write)", 0, 0); return; } reset_progress(d, disc->sessions, disc->session[0]->tracks, disc->session[0]->track[0]->indices, 0, 0); /* For the next lines any return indicates failure */ d->cancel = 1; /* ts A70203 : people have been warned in API specs */ if (opts->write_type == BURN_WRITE_NONE) { libdax_msgs_submit(libdax_messenger, d->global_index, 0x0002017c, LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH, "No valid write type selected", 0, 0); return; } if (d->drive_role == 0) { libdax_msgs_submit(libdax_messenger, d->global_index, 0x00020146, LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH, "Drive is a virtual placeholder (null-drive)", 0, 0); return; } if (d->drive_role == 4) { libdax_msgs_submit(libdax_messenger, d->global_index, 0x00020181, LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH, "Pseudo-drive is a read-only file. Cannot write.", 0, 0); return; } /* ts A61007 : obsolete Assert in spc_select_write_params() */ if (d->drive_role == 1) { mvalid = 0; if (d->mdata != NULL) mvalid = 1; if (!mvalid) { libdax_msgs_submit(libdax_messenger, d->global_index, 0x00020113, LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH, "Drive capabilities not inquired yet", 0, 0); return; } } /* ts A70219 : intended to replace all further tests here and many tests in burn_*_write_sync() */ BURN_ALLOC_MEM_VOID(reasons, char, BURN_REASONS_LEN + 80); strcpy(reasons, "Write job parameters are unsuitable:\n"); if (burn_precheck_write(opts, disc, reasons + strlen(reasons), 1) <= 0) { libdax_msgs_submit(libdax_messenger, d->global_index, 0x00020139, LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH, reasons, 0, 0); goto ex; } BURN_FREE_MEM(reasons); reasons= NULL; /* ts A90106 : early catching of unformatted BD-RE */ if (d->current_profile == 0x43) if (d->read_format_capacities(d, 0x00) > 0 && d->format_descr_type != BURN_FORMAT_IS_FORMATTED) { libdax_msgs_submit(libdax_messenger, d->global_index, 0x00020168, LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH, "Media not properly formatted. Cannot write.", 0, 0); return; } d->cancel = 0; /* End of the return = failure area */ o.write.drive = d; o.write.opts = opts; o.write.disc = disc; opts->refcount++; add_worker(Burnworker_type_writE, d, (WorkerFunc) write_disc_worker_func, &o); ex:; BURN_FREE_MEM(reasons); } static void *fifo_worker_func(struct w_list *w) { int old; #define Libburn_protect_fifo_threaD 1 #ifdef Libburn_protect_fifo_threaD sigset_t sigset, oldset; /* Protect fifo thread from being interrupted by external signals */ sigfillset(&sigset); sigdelset(&sigset, SIGSEGV); sigdelset(&sigset, SIGILL); pthread_sigmask(SIG_SETMASK, &sigset, &oldset); #endif /* Libburn_protect_fifo_threaD */ pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &old); pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &old); /* Note: Only burn_fifo_abort() shall cancel the fifo thread */ burn_fifo_source_shoveller(w->u.fifo.source, w->u.fifo.flag); remove_worker(pthread_self()); #ifdef Libburn_protect_fifo_threaD /* (just in case it would not end with all signals blocked) */ pthread_sigmask(SIG_SETMASK, &oldset, NULL); #endif /* Libburn_protect_fifo_threaD */ return NULL; } int burn_fifo_start(struct burn_source *source, int flag) { union w_list_data o; struct burn_source_fifo *fs = source->data; fs->is_started = -1; /* create and set up ring buffer */; fs->buf = burn_os_alloc_buffer( ((size_t) fs->chunksize) * (size_t) fs->chunks, 0); if (fs->buf == NULL) { /* >>> could not start ring buffer */; return -1; } o.fifo.source = source; o.fifo.flag = flag; add_worker(Burnworker_type_fifO, NULL, (WorkerFunc) fifo_worker_func, &o); fs->is_started = 1; return 1; } int burn_fifo_abort(struct burn_source_fifo *fs, int flag) { int ret; pthread_t pt; if (fs->thread_is_valid <= 0 || fs->thread_handle == NULL) return(2); #ifdef NIX libdax_msgs_submit(libdax_messenger, -1, 0x00000002, LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH, "Aborting running burn_source_fifo thread", 0, 0); #endif /* NIX */ pt= *((pthread_t *) fs->thread_handle); remove_worker(pt); ret = pthread_cancel(pt); return (ret == 0); } #ifdef Libburn_has_burn_async_join_alL /* ts A71019 : never used */ void burn_async_join_all(void) { void *ret; while (workers) pthread_join(workers->thread, &ret); } #endif /* Libburn_has_burn_async_join_alL */ ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������libburn-1.4.2/libburn/toc.c�������������������������������������������������������������������������0000644�0001757�0001751�00000007676�12652644224�012521� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */ /* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens Copyright (c) 2011 - 2011 Thomas Schmitt <scdbackup@gmx.net> Provided under GPL version 2 or later. */ #ifdef HAVE_CONFIG_H #include "../config.h" #endif /* ts A61008 */ /* #include <a ssert.h> */ #include <string.h> #include <stdio.h> #include <stdlib.h> #include "toc.h" #include "transport.h" #include "libburn.h" #include "sector.h" #include "options.h" #include "init.h" #if 0 static void write_clonecd2(volatile struct toc *toc, int f); static void write_clonecd2(volatile struct toc *toc, int f) { int i; /* header */ dprintf(f, "[CloneCD]\r\n"); dprintf(f, "Version=2\r\n"); dprintf(f, "\r\n"); /* disc data */ dprintf(f, "[Disc]\r\n"); dprintf(f, "TocEntries=%d\r\n", toc->toc_entries); dprintf(f, "Sessions=%d\r\n", toc->sessions); dprintf(f, "DataTracksScrambled=%d\r\n", toc->datatracksscrambled); dprintf(f, "CDTextLength=%d\r\n", toc->cdtextlength); dprintf(f, "\r\n"); /* session data */ for (i = 0; i < toc->sessions; ++i) { dprintf(f, "[Session %d]\r\n", i + 1); { int m; switch (toc->session[i].track[0]->mode) { case BURN_MODE_RAW_DATA: case BURN_MODE_AUDIO: m = 0; break; case BURN_MODE0: m = 1; break; case BURN_MODE1: case BURN_MODE2_FORMLESS: case BURN_MODE2_FORM1: case BURN_MODE2_FORM2: case BURN_MODE_UNINITIALIZED: /* ts A61008 : do this softly without Assert */ a ssert(0); /* unhandled! find out ccd's value for these modes! */ } dprintf(f, "PreGapMode=%d\r\n", m); } dprintf(f, "\r\n"); } for (i = 0; i < toc->toc_entries; ++i) { dprintf(f, "[Entry %d]\r\n", i); dprintf(f, "Session=%d\r\n", toc->toc_entry[i].session); dprintf(f, "Point=0x%02x\r\n", toc->toc_entry[i].point); dprintf(f, "ADR=0x%02x\r\n", toc->toc_entry[i].adr); dprintf(f, "Control=0x%02x\r\n", toc->toc_entry[i].control); dprintf(f, "TrackNo=%d\r\n", toc->toc_entry[i].tno); dprintf(f, "AMin=%d\r\n", toc->toc_entry[i].min); dprintf(f, "ASec=%d\r\n", toc->toc_entry[i].sec); dprintf(f, "AFrame=%d\r\n", toc->toc_entry[i].frame); dprintf(f, "ALBA=%d\r\n", burn_msf_to_lba(toc->toc_entry[i].min, toc->toc_entry[i].sec, toc->toc_entry[i].frame)); dprintf(f, "Zero=%d\r\n", toc->toc_entry[i].zero); dprintf(f, "PMin=%d\r\n", toc->toc_entry[i].pmin); dprintf(f, "PSec=%d\r\n", toc->toc_entry[i].psec); dprintf(f, "PFrame=%d\r\n", toc->toc_entry[i].pframe); dprintf(f, "PLBA=%d\r\n", burn_msf_to_lba(toc->toc_entry[i].pmin, toc->toc_entry[i].psec, toc->toc_entry[i].pframe)); dprintf(f, "\r\n"); } } #endif void toc_find_modes(struct burn_drive *d) { int i, j; struct buffer *mem = NULL; struct burn_toc_entry *e; /* ts A70519 : the code which needs this does not work with GNU/Linux 2.4 USB int lba; struct burn_read_opts o; o.raw = 1; o.c2errors = 0; o.subcodes_audio = 1; o.subcodes_data = 1; o.hardware_error_recovery = 1; o.report_recovered_errors = 0; o.transfer_damaged_blocks = 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 (j = 0; j < d->disc->session[i]->tracks; j++) { struct burn_track *t = d->disc->session[i]->track[j]; e = t->entry; /* XXX | in the subcodes if appropriate! */ if (e && !(e->control & 4)) { t->mode = BURN_AUDIO; } else { t->mode = BURN_MODE1; /* 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. if (!e) lba = 0; else lba = burn_msf_to_lba(e->pmin, e->psec, e->pframe); mem->sectors = 1; ts B21119 : Would now be d->read_cd() with with sectype = 0 , mainch = 0xf8 d->read_sectors(d, lba, mem.sectors, &o, mem); t->mode = sector_identify(mem->data); */ } } ex: BURN_FREE_MEM(mem); } ������������������������������������������������������������������libburn-1.4.2/libburn/os-libcdio.h������������������������������������������������������������������0000644�0001757�0001751�00000005673�12652644224�013760� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ /* os-libcdio.h Operating system specific libburn definitions and declarations. Included by os.h in case of compilation for Unknown X/Open-like systems with GNU libcdio MMC transport adapter sg-libcdio.c Copyright (C) 2009 - 2013 Thomas Schmitt <scdbackup@gmx.net> Provided under GPLv2+ */ /** List of all signals which shall be caught by signal handlers and trigger a graceful abort of libburn. (See man 7 signal.) */ /* Once as system defined macros */ #define BURN_OS_SIGNAL_MACRO_LIST \ SIGHUP, SIGINT, SIGQUIT, SIGILL, SIGABRT, \ SIGFPE, SIGSEGV, SIGPIPE, SIGALRM, SIGTERM, \ SIGUSR1, SIGUSR2, SIGXCPU /* Once as text 1:1 list of strings for messages and interpreters */ #define BURN_OS_SIGNAL_NAME_LIST \ "SIGHUP", "SIGINT", "SIGQUIT", "SIGILL", "SIGABRT", \ "SIGFPE", "SIGSEGV", "SIGPIPE", "SIGALRM", "SIGTERM", \ "SIGUSR1", "SIGUSR2", "SIGXCPU" /* The number of above list items */ #define BURN_OS_SIGNAL_COUNT 13 /** The list of all signals which shall surely not be caught. It depends on the particular signal whether it can be ignored or whether it will lead to sudden death of the process. Some signals are not POSIX, but nevertheless ought to be ignored if they are defined. */ #ifdef SIGWINCH #define BURN_OS_SIG_WINCH ,SIGWINCH #define BURN_OS_SIG_WINCH_CNT 1 #else #define BURN_OS_SIG_WINCH #define BURN_OS_SIG_WINCH_CNT 0 #endif #ifdef SIGURG #define BURN_OS_SIG_URG ,SIGURG #define BURN_OS_SIG_URG_CNT 1 #else #define BURN_OS_SIG_URG #define BURN_OS_SIG_URG_CNT 0 #endif /** The combined list of all signals which shall not be caught. */ #define BURN_OS_NON_SIGNAL_MACRO_LIST \ SIGKILL, SIGCHLD, SIGSTOP, SIGTSTP, SIGCONT, SIGTTIN, SIGTTOU \ BURN_OS_SIG_WINCH BURN_OS_SIG_URG /* The number of above list items */ #define BURN_OS_NON_SIGNAL_COUNT \ ( 7 + BURN_OS_SIG_WINCH_CNT + BURN_OS_SIG_URG_CNT ) /* The maximum size for a (SCSI) i/o transaction */ /* My Blu-ray burner LG GGW-H20 writes junk if stream recording is combined with buffer size 32 kB. So stream recording is allowed only with size 64k. Older BSD info says that 32 kB is maximum. But 64 kB seems to work well on 8-STABLE. It is by default only used with BD in streaming mode. So older systems should still be quite safe with this buffer max size. */ /* Important : MUST be at least 32768 ! */ #define BURN_OS_TRANSPORT_BUFFER_SIZE 65536 /* To hold the position of the most recently delivered address from device enumeration. */ struct burn_drive_enumerator_struct { char **ppsz_cd_drives; char **pos; }; #define BURN_OS_DEFINE_DRIVE_ENUMERATOR_T \ typedef struct burn_drive_enumerator_struct burn_drive_enumerator_t; /* The list of operating system dependent elements in struct burn_drive. Usually they are initialized in sg-*.c:enumerate_common(). */ #define BURN_OS_TRANSPORT_DRIVE_ELEMENTS \ void *p_cdio; /* actually a pointer to CdIo_t */ \ char libcdio_name[4096]; /* The drive path as used by libcdio */ \ ���������������������������������������������������������������������libburn-1.4.2/libburn/libdax_audioxtr.c�������������������������������������������������������������0000644�0001757�0001751�00000017767�12652644224�015120� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ /* libdax_audioxtr Audio track data extraction facility of libdax and libburn. Copyright (C) 2006 Thomas Schmitt <scdbackup@gmx.net>, provided under GPLv2+ */ #ifdef HAVE_CONFIG_H #include "../config.h" #endif #include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #include <string.h> #include <stdlib.h> #include <errno.h> /* ts B41126 : O_BINARY is needed for Cygwin but undefined elsewhere */ #ifndef O_BINARY #define O_BINARY 0 #endif #include "libdax_msgs.h" extern struct libdax_msgs *libdax_messenger; /* Only this single source module is entitled to do this */ #define LIBDAX_AUDIOXTR_H_INTERNAL 1 /* All clients of the extraction facility must do this or include libburn.h */ #define LIBDAX_AUDIOXTR_H_PUBLIC 1 #include "libdax_audioxtr.h" int libdax_audioxtr_new(struct libdax_audioxtr **xtr, char *path, int flag) { int ret= -1; struct libdax_audioxtr *o; o= *xtr= (struct libdax_audioxtr *) calloc(1, sizeof(struct libdax_audioxtr)); if(o==NULL) return(-1); strncpy(o->path,path,LIBDAX_AUDIOXTR_STRLEN-1); o->path[LIBDAX_AUDIOXTR_STRLEN-1]= 0; o->fd= -1; strcpy(o->fmt,"unidentified"); o->fmt_info[0]= 0; o->data_size= 0; o->extract_count= 0; o->num_channels= 0; o->sample_rate= 0; o->bits_per_sample= 0; o->msb_first= 0; o->wav_subchunk2_size= 0; o->au_data_location= 0; o->au_data_size= 0xffffffff; ret= libdax_audioxtr_open(o,0); if(ret<=0) {ret= -2*(ret<0); goto failure;} return(1); failure: libdax_audioxtr_destroy(xtr,0); return(ret); } int libdax_audioxtr_destroy(struct libdax_audioxtr **xtr, int flag) { struct libdax_audioxtr *o; o= *xtr; if(o==NULL) return(0); if(o->fd>=0 && strcmp(o->path,"-")!=0) close(o->fd); free((char *) o); *xtr= NULL; return(1); } static int libdax_audioxtr_open(struct libdax_audioxtr *o, int flag) { int ret; char msg[LIBDAX_AUDIOXTR_STRLEN+80]; if(strcmp(o->path,"-")==0) o->fd= 0; else o->fd= open(o->path, O_RDONLY | O_BINARY); if(o->fd<0) { sprintf(msg,"Cannot open audio source file : %s",o->path); libdax_msgs_submit(libdax_messenger,-1,0x00020200, LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH, msg, errno, 0); return(-1); } ret= libdax_audioxtr_identify(o,0); if(ret<=0) { sprintf(msg,"Audio source file has unsuitable format : %s",o->path); libdax_msgs_submit(libdax_messenger,-1,0x00020201, LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH, msg, 0, 0); return(0); } ret= libdax_audioxtr_init_reading(o,0); if(ret<=0) { sprintf(msg,"Failed to prepare reading of audio data : %s",o->path); libdax_msgs_submit(libdax_messenger,-1,0x00020202, LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH, msg, 0, 0); return(0); } return(1); } static int libdax_audioxtr_identify_wav(struct libdax_audioxtr *o, int flag) { int ret; char buf[45]; /* check wether this is a MS WAVE file .wav */ /* info used: http://ccrma.stanford.edu/courses/422/projects/WaveFormat/ */ if(o->fd!=0) { ret= lseek(o->fd,0,SEEK_SET); if(ret==-1) return(0); } ret= read(o->fd, buf, 44); if(ret<44) return(0); buf[44]= 0; /* as stopper for any string operations */ if(strncmp(buf,"RIFF",4)!=0) /* ChunkID */ return(0); if(strncmp(buf+8,"WAVE",4)!=0) /* Format */ return(0); if(strncmp(buf+12,"fmt ",4)!=0) /* Subchunk1ID */ return(0); if(buf[16]!=16 || buf[17]!=0 || buf[18]!=0 || buf[19]!=0) /* Subchunk1Size */ return(0); if(buf[20]!=1 || buf[21]!=0) /* AudioFormat must be 1 (Linear quantization) */ return(0); strcpy(o->fmt,".wav"); o->msb_first= 0; o->num_channels= libdax_audioxtr_to_int(o,(unsigned char *) buf+22,2,0); o->sample_rate= libdax_audioxtr_to_int(o,(unsigned char *) buf+24,4,0); o->bits_per_sample= libdax_audioxtr_to_int(o,(unsigned char *)buf+34,2,0); sprintf(o->fmt_info, ".wav , num_channels=%d , sample_rate=%d , bits_per_sample=%d", o->num_channels,o->sample_rate,o->bits_per_sample); o->wav_subchunk2_size= libdax_audioxtr_to_int(o,(unsigned char *)buf+40,4,0); o->data_size= o->wav_subchunk2_size; return(1); } static int libdax_audioxtr_identify_au(struct libdax_audioxtr *o, int flag) { int ret,encoding; char buf[24]; /* Check wether this is a Sun Audio, .au file */ /* info used: http://ccrma.stanford.edu/courses/422/projects/WaveFormat/ */ if(o->fd!=0) { ret= lseek(o->fd,0,SEEK_SET); if(ret==-1) return(0); } ret= read(o->fd, buf, 24); if(ret<24) return(0); if(strncmp(buf,".snd",4)!=0) return(0); strcpy(o->fmt,".au"); o->msb_first= 1; o->au_data_location= libdax_audioxtr_to_int(o,(unsigned char *)buf+4,4,1); o->au_data_size= libdax_audioxtr_to_int(o,(unsigned char *)buf+8,4,1); encoding= libdax_audioxtr_to_int(o,(unsigned char *)buf+12,4,1); if(encoding==2) o->bits_per_sample= 8; else if(encoding==3) o->bits_per_sample= 16; else if(encoding==4) o->bits_per_sample= 24; else if(encoding==5) o->bits_per_sample= 32; else o->bits_per_sample= -encoding; o->sample_rate= libdax_audioxtr_to_int(o,(unsigned char *)buf+16,4,1); o->num_channels= libdax_audioxtr_to_int(o,(unsigned char *)buf+20,4,1); if(o->au_data_size!=0xffffffff) o->data_size= o->au_data_size; else o->data_size= 0; sprintf(o->fmt_info, ".au , num_channels=%d , sample_rate=%d , bits_per_sample=%d", o->num_channels,o->sample_rate,o->bits_per_sample); return(o->bits_per_sample>0); /* Audio format must be linear PCM */ } static int libdax_audioxtr_identify(struct libdax_audioxtr *o, int flag) { int ret; ret= libdax_audioxtr_identify_wav(o, 0); if(ret!=0) return(ret); if(o->fd==0) /* cannot rewind stdin */ return(0); ret= libdax_audioxtr_identify_au(o, 0); if(ret!=0) return(ret); return(0); } /* @param flag bit0=msb_first */ static unsigned libdax_audioxtr_to_int(struct libdax_audioxtr *o, unsigned char *bytes, int len, int flag) { unsigned int ret= 0; int i; if(flag&1) for(i= 0; i<len; i++) ret= ret*256+bytes[i]; else for(i= len-1; i>=0; i--) ret= ret*256+bytes[i]; return(ret); } static int libdax_audioxtr_init_reading(struct libdax_audioxtr *o, int flag) { int ret; /* currently this only works for MS WAVE files .wav and Sun .au*/; if(o->fd==0) /* stdin: hope no read came after libdax_audioxtr_identify() */ return(1); o->extract_count= 0; if(strcmp(o->fmt,".wav")==0) ret= lseek(o->fd,44,SEEK_SET); else if(strcmp(o->fmt,".au")==0) ret= lseek(o->fd,o->au_data_location,SEEK_SET); else ret= -1; if(ret==-1) return(0); return(1); } int libdax_audioxtr_get_id(struct libdax_audioxtr *o, char **fmt, char **fmt_info, int *num_channels, int *sample_rate, int *bits_per_sample, int *msb_first, int flag) { *fmt= o->fmt; *fmt_info= o->fmt_info; *num_channels= o->num_channels; *sample_rate= o->sample_rate; *bits_per_sample= o->bits_per_sample; *msb_first= o->msb_first; return(1); } int libdax_audioxtr_get_size(struct libdax_audioxtr *o, off_t *size, int flag) { *size= o->data_size; return(1); } int libdax_audioxtr_read(struct libdax_audioxtr *o, char buffer[], int buffer_size, int flag) { int ret; if(buffer_size<=0 || o->fd<0) return(-2); if(o->data_size>0 && !(flag&1)) if(buffer_size > o->data_size - o->extract_count) buffer_size= o->data_size - o->extract_count; if(buffer_size<=0) return(0); ret= read(o->fd,buffer,buffer_size); if(ret>0) o->extract_count+= ret; return(ret); } int libdax_audioxtr_detach_fd(struct libdax_audioxtr *o, int *fd, int flag) { if(o->fd<0) return(-1); if(strcmp(o->fmt,".wav")!=0 && strcmp(o->fmt,".au")!=0) return(0); if(flag&1) { *fd= o->fd; } else { *fd= dup(o->fd); if(*fd>=0 && strcmp(o->path,"-")!=0) close(o->fd); } if(*fd>=0) { o->fd= -1; return(1); } return(-1); } ���������libburn-1.4.2/libburn/os-netbsd.h�������������������������������������������������������������������0000644�0001757�0001751�00000004270�12652644224�013622� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ /* os-netbsd.h Operating system specific libburn definitions and declarations. Included by os.h in case of compilation for NetBSD 6 with MMC transport adapter sg-netbsd.c >>> for OpenBSD too ? Copyright (C) 2010 - 2014 Thomas Schmitt <scdbackup@gmx.net> provided under GPLv2+ Derived 2014 from libburn/os-solaris.c */ /** List of all signals which shall be caught by signal handlers and trigger a graceful abort of libburn. (See man signal.h) */ /* Once as system defined macros */ #define BURN_OS_SIGNAL_MACRO_LIST \ SIGHUP, SIGINT, SIGQUIT, SIGILL, SIGTRAP, \ SIGABRT, SIGEMT, SIGFPE, SIGBUS, SIGSEGV, \ SIGSYS, SIGPIPE, SIGALRM, SIGTERM, SIGXCPU, \ SIGXFSZ, SIGVTALRM, SIGPROF, SIGUSR1, SIGUSR2 /* Once as text 1:1 list of strings for messages and interpreters */ #define BURN_OS_SIGNAL_NAME_LIST \ "SIGHUP", "SIGINT", "SIGQUIT", "SIGILL", "SIGTRAP", \ "SIGABRT", "SIGEMT", "SIGFPE", "SIGBUS", "SIGSEGV", \ "SIGSYS", "SIGPIPE", "SIGALRM", "SIGTERM", "SIGXCPU", \ "SIGXFSZ", "SIGVTALRM", "SIGPROF", "SIGUSR1", "SIGUSR2" /* The number of above list items */ #define BURN_OS_SIGNAL_COUNT 20 /** To list all signals which shall surely not be caught */ #define BURN_OS_NON_SIGNAL_MACRO_LIST \ SIGKILL, SIGURG, SIGSTOP, SIGTSTP, SIGCONT, \ SIGCHLD, SIGTTIN, SIGTTOU, SIGIO, SIGWINCH, \ SIGINFO, SIGPWR /* The number of above list items */ #define BURN_OS_NON_SIGNAL_COUNT 12 /* The maximum size for a (SCSI) i/o transaction */ /* Important : MUST be at least 32768 ! */ /* My Blu-ray burner LG GGW-H20 writes junk if stream recording is combined with buffer size 32 kB. So stream recording is allowed only with size 64k. */ /* >>> ??? Does it do 64 kB ? */ #define BURN_OS_TRANSPORT_BUFFER_SIZE 65536 /* To hold the position of the most recently delivered address from device enumeration. */ struct burn_drive_enumerator_struct { int cdno; }; #define BURN_OS_DEFINE_DRIVE_ENUMERATOR_T \ typedef struct burn_drive_enumerator_struct burn_drive_enumerator_t; /* The list of operating system dependent elements in struct burn_drive. Usually they are initialized in sg-*.c:enumerate_common(). */ #define BURN_OS_TRANSPORT_DRIVE_ELEMENTS \ int fd; ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������libburn-1.4.2/libburn/mmc.h�������������������������������������������������������������������������0000644�0001757�0001751�00000011502�12652644224�012474� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */ /* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens Copyright (c) 2006 - 2014 Thomas Schmitt <scdbackup@gmx.net> Provided under GPL version 2 or later. */ #ifndef __MMC #define __MMC struct burn_drive; struct burn_write_opts; struct command; struct buffer; struct cue_sheet; /* MMC commands */ void mmc_read(struct burn_drive *); /* ts A61009 : removed redundant parameter d in favor of o->drive */ /* void mmc_close_session(struct burn_drive *, struct burn_write_opts *); */ /* void mmc_close_disc(struct burn_drive *, struct burn_write_opts *); */ void mmc_close_session(struct burn_write_opts *o); void mmc_close_disc(struct burn_write_opts *o); void mmc_close(struct burn_drive *, int session, int track); void mmc_get_event(struct burn_drive *); int mmc_write(struct burn_drive *, int start, struct buffer *buf); void mmc_write_12(struct burn_drive *d, int start, struct buffer *buf); void mmc_sync_cache(struct burn_drive *); void mmc_load(struct burn_drive *); void mmc_eject(struct burn_drive *); void mmc_erase(struct burn_drive *, int); void mmc_read_toc(struct burn_drive *); void mmc_read_disc_info(struct burn_drive *); void mmc_read_atip(struct burn_drive *); int mmc_read_cd(struct burn_drive *d, int start, int len, int sec_type, int main_ch, const struct burn_read_opts *o, struct buffer *buf, int flag); void mmc_set_speed(struct burn_drive *, int, int); void mmc_read_lead_in(struct burn_drive *, struct buffer *); void mmc_perform_opc(struct burn_drive *); void mmc_get_configuration(struct burn_drive *); /* ts A61110 : added parameters trackno, lba, nwa. Redefined return value. @return 1=nwa is valid , 0=nwa is not valid , -1=error */ int mmc_get_nwa(struct burn_drive *d, int trackno, int *lba, int *nwa); /* ts B11228 : changed from void to int */ int mmc_send_cue_sheet(struct burn_drive *, struct cue_sheet *); /* ts A61023 : get size and free space of drive buffer */ int mmc_read_buffer_capacity(struct burn_drive *d); /* ts A61021 : the mmc specific part of sg.c:enumerate_common() */ int mmc_setup_drive(struct burn_drive *d); /* ts A61219 : learned much from dvd+rw-tools-7.0: plus_rw_format() and mmc5r03c.pdf, 6.5 FORMAT UNIT */ int mmc_format_unit(struct burn_drive *d, off_t size, int flag); /* ts A61225 : obtain write speed descriptors via ACh GET PERFORMANCE */ int mmc_get_write_performance(struct burn_drive *d); /* ts A61229 : outsourced from spc_select_write_params() */ /* Note: Page data is not zeroed here to allow preset defaults. Thus memset(pd, 0, 2 + d->mdata->write_page_length); is the eventual duty of the caller. */ int mmc_compose_mode_page_5(struct burn_drive *d, struct burn_session *s, int tno, const struct burn_write_opts *o, unsigned char *pd); /* ts A70201 */ int mmc_four_char_to_int(unsigned char *data); /* ts A70201 : Common track info fetcher for mmc_get_nwa() and mmc_fake_toc() */ int mmc_read_track_info(struct burn_drive *d, int trackno, struct buffer *buf, int alloc_len); /* ts A70812 : return 0 = ok , return BE_CANCELLED = error occured */ int mmc_read_10(struct burn_drive *d, int start, int amount, struct buffer *buf); /* ts A81210 : Determine the upper limit of readable data size */ int mmc_read_capacity(struct burn_drive *d); /* ts A61201 */ char *mmc_obtain_profile_name(int profile_number); /* mmc5r03c.pdf 4.3.4.4.1 d) "The maximum number of RZones is 2 302." */ #define BURN_MMC_FAKE_TOC_MAX_SIZE 2302 /* ts A90903 */ /* MMC backend of API call burn_get_media_product_id() */ int mmc_get_media_product_id(struct burn_drive *d, char **product_id, char **media_code1, char **media_code2, char **book_type, int flag); /* ts A60910 (estimated) */ int mmc_function_spy(struct burn_drive *d, char * text); /* ts A91118 */ int mmc_start_if_needed(struct burn_drive *d, int flag); /* ts B00924 */ int mmc_get_bd_spare_info(struct burn_drive *d, int *alloc_blocks, int *free_blocks, int flag); /* ts B10801 */ int mmc_get_phys_format_info(struct burn_drive *d, int *disk_category, char **book_name, int *part_version, int *num_layers, int *num_blocks, int flag); /* ts B11201 */ int mmc_get_leadin_text(struct burn_drive *d, unsigned char **text_packs, int *num_packs, int flag); /* ts B40107 */ int mmc_get_performance(struct burn_drive *d, int descr_type, int flag); #ifdef Libburn_develop_quality_scaN /* B21108 ts */ int mmc_nec_optiarc_f3(struct burn_drive *d, int sub_op, int start_lba, int rate_period, int *eba, int *error_rate1, int *error_rate2); #endif #endif /*__MMC*/ ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������libburn-1.4.2/libburn/os-linux.h��������������������������������������������������������������������0000644�0001757�0001751�00000005126�12652644224�013503� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ /* os-linux.h Operating system specific libburn definitions and declarations. Included by os.h in case of compilation for Linux kernels 2.4 and 2.6, GNU/Linux SCSI Generic (sg) Copyright (C) 2006 - 2013 Thomas Schmitt <scdbackup@gmx.net> Provided under GPL version 2 or later. */ /** List of all signals which shall be caught by signal handlers and trigger a graceful abort of libburn. (See man 7 signal.) */ /* Once as system defined macros */ #define BURN_OS_SIGNAL_MACRO_LIST \ SIGHUP, SIGINT, SIGQUIT, SIGILL, SIGABRT, \ SIGFPE, SIGSEGV, SIGPIPE, SIGALRM, SIGTERM, \ SIGUSR1, SIGUSR2, SIGXCPU, SIGBUS, SIGPOLL, \ SIGPROF, SIGSYS, SIGTRAP, SIGVTALRM, SIGXCPU, \ SIGXFSZ /* Once as text 1:1 list of strings for messages and interpreters */ #define BURN_OS_SIGNAL_NAME_LIST \ "SIGHUP", "SIGINT", "SIGQUIT", "SIGILL", "SIGABRT", \ "SIGFPE", "SIGSEGV", "SIGPIPE", "SIGALRM", "SIGTERM", \ "SIGUSR1", "SIGUSR2", "SIGXCPU", "SIGBUS", "SIGPOLL", \ "SIGPROF", "SIGSYS", "SIGTRAP", "SIGVTALRM", "SIGXCPU", \ "SIGXFSZ" /* The number of above list items */ #define BURN_OS_SIGNAL_COUNT 21 /** To list all signals which shall surely not be caught */ #define BURN_OS_NON_SIGNAL_MACRO_LIST \ SIGKILL, SIGCHLD, SIGSTOP, SIGTSTP, SIGCONT, SIGURG, SIGWINCH, SIGTTIN, SIGTTOU /* The number of above list items */ #define BURN_OS_NON_SIGNAL_COUNT 9 /* The maximum size for a (SCSI) i/o transaction */ /* Important : MUST be at least 32768 ! */ /* ts A70523 : >32k seems not good with kernel 2.4 USB drivers and audio #define BURN_OS_TRANSPORT_BUFFER_SIZE 32768 */ /* ts A80414 : curbed in write.c CD media to Libburn_cd_obS = 32 kiB re-enlarged transport to 64 kiB for BD-RE experiments */ #define BURN_OS_TRANSPORT_BUFFER_SIZE 65536 /* To hold the position of the most recently delivered address from device enumeration. */ struct burn_drive_enumerator_struct { int pos; int info_count; char **info_list; }; #define BURN_OS_DEFINE_DRIVE_ENUMERATOR_T \ typedef struct burn_drive_enumerator_struct burn_drive_enumerator_t; /* Parameters for sibling list. See sibling_fds, sibling_fnames */ #define BURN_OS_SG_MAX_SIBLINGS 5 #define BURN_OS_SG_MAX_NAMELEN 16 /* The list of operating system dependent elements in struct burn_drive. Usually they are initialized in sg-*.c:enumerate_common(). */ #define BURN_OS_TRANSPORT_DRIVE_ELEMENTS \ int fd; \ \ /* ts A60926 : trying to lock against growisofs /dev/srN, /dev/scdN */ \ int sibling_count; \ int sibling_fds[BURN_OS_SG_MAX_SIBLINGS]; \ /* ts A70409 : DDLP */ \ char sibling_fnames[BURN_OS_SG_MAX_SIBLINGS][BURN_OS_SG_MAX_NAMELEN]; ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������libburn-1.4.2/libburn/os-dummy.h��������������������������������������������������������������������0000644�0001757�0001751�00000004737�12652644224�013506� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ /* os-dummy.h Operating system specific libburn definitions and declarations. Included by os.h in case of compilation for Unknown POSIX like systems with the dummy MMC transport adapter sg-dummy.c Copyright (C) 2009 - 2013 Thomas Schmitt <scdbackup@gmx.net> Provided under GPLv2+ */ /** List of all signals which shall be caught by signal handlers and trigger a graceful abort of libburn. (See man 7 signal.) */ /* Once as system defined macros */ #define BURN_OS_SIGNAL_MACRO_LIST \ SIGHUP, SIGINT, SIGQUIT, SIGILL, SIGABRT, \ SIGFPE, SIGSEGV, SIGPIPE, SIGALRM, SIGTERM, \ SIGUSR1, SIGUSR2, SIGXCPU /* Once as text 1:1 list of strings for messages and interpreters */ #define BURN_OS_SIGNAL_NAME_LIST \ "SIGHUP", "SIGINT", "SIGQUIT", "SIGILL", "SIGABRT", \ "SIGFPE", "SIGSEGV", "SIGPIPE", "SIGALRM", "SIGTERM", \ "SIGUSR1", "SIGUSR2", "SIGXCPU" /* The number of above list items */ #define BURN_OS_SIGNAL_COUNT 13 /** The list of all signals which shall surely not be caught. It depends on the particular signal whether it can be ignored or whether it will lead to sudden death of the process. Some signals are not POSIX, but nevertheless ought to be ignored if they are defined. */ #ifdef SIGWINCH #define BURN_OS_SIG_WINCH ,SIGWINCH #define BURN_OS_SIG_WINCH_CNT 1 #else #define BURN_OS_SIG_WINCH #define BURN_OS_SIG_WINCH_CNT 0 #endif #ifdef SIGURG #define BURN_OS_SIG_URG ,SIGURG #define BURN_OS_SIG_URG_CNT 1 #else #define BURN_OS_SIG_URG #define BURN_OS_SIG_URG_CNT 0 #endif /** The combined list of all signals which shall not be caught. */ #define BURN_OS_NON_SIGNAL_MACRO_LIST \ SIGKILL, SIGCHLD, SIGSTOP, SIGTSTP, SIGCONT, SIGTTIN, SIGTTOU \ BURN_OS_SIG_WINCH BURN_OS_SIG_URG /* The number of above list items */ #define BURN_OS_NON_SIGNAL_COUNT \ ( 7 + BURN_OS_SIG_WINCH_CNT + BURN_OS_SIG_URG_CNT ) /* The maximum size for a (SCSI) i/o transaction */ /* Important : MUST be at least 32768 ! */ #define BURN_OS_TRANSPORT_BUFFER_SIZE 65536 /* To hold the position of the most recently delivered address from device enumeration. */ struct burn_drive_enumerator_struct { int pos; int info_count; char **info_list; }; #define BURN_OS_DEFINE_DRIVE_ENUMERATOR_T \ typedef struct burn_drive_enumerator_struct burn_drive_enumerator_t; /* The list of operating system dependent elements in struct burn_drive. Usually they are initialized in sg-*.c:enumerate_common(). */ #define BURN_OS_TRANSPORT_DRIVE_ELEMENTS \ int just_a_dummy; ���������������������������������libburn-1.4.2/aclocal.m4����������������������������������������������������������������������������0000644�0001757�0001751�00001300171�12652650101�011745� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# generated automatically by aclocal 1.14.1 -*- Autoconf -*- # Copyright (C) 1996-2013 Free Software Foundation, Inc. # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])]) m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.69],, [m4_warning([this file was generated for autoconf 2.69. You have another version of autoconf. It may work, but is not guaranteed to. If you have problems, you may need to regenerate the build system entirely. To do so, use the procedure documented by the package, typically 'autoreconf'.])]) # libtool.m4 - Configure libtool for the host system. -*-Autoconf-*- # # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, # 2006, 2007, 2008, 2009, 2010, 2011 Free Software # Foundation, Inc. # Written by Gordon Matzigkeit, 1996 # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. m4_define([_LT_COPYING], [dnl # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, # 2006, 2007, 2008, 2009, 2010, 2011 Free Software # Foundation, Inc. # Written by Gordon Matzigkeit, 1996 # # This file is part of GNU Libtool. # # GNU Libtool is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License as # published by the Free Software Foundation; either version 2 of # the License, or (at your option) any later version. # # As a special exception to the GNU General Public License, # if you distribute this file as part of a program or library that # is built using GNU Libtool, you may include this file under the # same distribution terms that you use for the rest of that program. # # GNU Libtool is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with GNU Libtool; see the file COPYING. If not, a copy # can be downloaded from http://www.gnu.org/licenses/gpl.html, or # obtained by writing to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ]) # serial 57 LT_INIT # LT_PREREQ(VERSION) # ------------------ # Complain and exit if this libtool version is less that VERSION. m4_defun([LT_PREREQ], [m4_if(m4_version_compare(m4_defn([LT_PACKAGE_VERSION]), [$1]), -1, [m4_default([$3], [m4_fatal([Libtool version $1 or higher is required], 63)])], [$2])]) # _LT_CHECK_BUILDDIR # ------------------ # Complain if the absolute build directory name contains unusual characters m4_defun([_LT_CHECK_BUILDDIR], [case `pwd` in *\ * | *\ *) AC_MSG_WARN([Libtool does not cope well with whitespace in `pwd`]) ;; esac ]) # LT_INIT([OPTIONS]) # ------------------ AC_DEFUN([LT_INIT], [AC_PREREQ([2.58])dnl We use AC_INCLUDES_DEFAULT AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl AC_BEFORE([$0], [LT_LANG])dnl AC_BEFORE([$0], [LT_OUTPUT])dnl AC_BEFORE([$0], [LTDL_INIT])dnl m4_require([_LT_CHECK_BUILDDIR])dnl dnl Autoconf doesn't catch unexpanded LT_ macros by default: m4_pattern_forbid([^_?LT_[A-Z_]+$])dnl m4_pattern_allow([^(_LT_EOF|LT_DLGLOBAL|LT_DLLAZY_OR_NOW|LT_MULTI_MODULE)$])dnl dnl aclocal doesn't pull ltoptions.m4, ltsugar.m4, or ltversion.m4 dnl unless we require an AC_DEFUNed macro: AC_REQUIRE([LTOPTIONS_VERSION])dnl AC_REQUIRE([LTSUGAR_VERSION])dnl AC_REQUIRE([LTVERSION_VERSION])dnl AC_REQUIRE([LTOBSOLETE_VERSION])dnl m4_require([_LT_PROG_LTMAIN])dnl _LT_SHELL_INIT([SHELL=${CONFIG_SHELL-/bin/sh}]) dnl Parse OPTIONS _LT_SET_OPTIONS([$0], [$1]) # This can be used to rebuild libtool when needed LIBTOOL_DEPS="$ltmain" # Always use our own libtool. LIBTOOL='$(SHELL) $(top_builddir)/libtool' AC_SUBST(LIBTOOL)dnl _LT_SETUP # Only expand once: m4_define([LT_INIT]) ])# LT_INIT # Old names: AU_ALIAS([AC_PROG_LIBTOOL], [LT_INIT]) AU_ALIAS([AM_PROG_LIBTOOL], [LT_INIT]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_PROG_LIBTOOL], []) dnl AC_DEFUN([AM_PROG_LIBTOOL], []) # _LT_CC_BASENAME(CC) # ------------------- # Calculate cc_basename. Skip known compiler wrappers and cross-prefix. m4_defun([_LT_CC_BASENAME], [for cc_temp in $1""; do case $cc_temp in compile | *[[\\/]]compile | ccache | *[[\\/]]ccache ) ;; distcc | *[[\\/]]distcc | purify | *[[\\/]]purify ) ;; \-*) ;; *) break;; esac done cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` ]) # _LT_FILEUTILS_DEFAULTS # ---------------------- # It is okay to use these file commands and assume they have been set # sensibly after `m4_require([_LT_FILEUTILS_DEFAULTS])'. m4_defun([_LT_FILEUTILS_DEFAULTS], [: ${CP="cp -f"} : ${MV="mv -f"} : ${RM="rm -f"} ])# _LT_FILEUTILS_DEFAULTS # _LT_SETUP # --------- m4_defun([_LT_SETUP], [AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_REQUIRE([AC_CANONICAL_BUILD])dnl AC_REQUIRE([_LT_PREPARE_SED_QUOTE_VARS])dnl AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])dnl _LT_DECL([], [PATH_SEPARATOR], [1], [The PATH separator for the build system])dnl dnl _LT_DECL([], [host_alias], [0], [The host system])dnl _LT_DECL([], [host], [0])dnl _LT_DECL([], [host_os], [0])dnl dnl _LT_DECL([], [build_alias], [0], [The build system])dnl _LT_DECL([], [build], [0])dnl _LT_DECL([], [build_os], [0])dnl dnl AC_REQUIRE([AC_PROG_CC])dnl AC_REQUIRE([LT_PATH_LD])dnl AC_REQUIRE([LT_PATH_NM])dnl dnl AC_REQUIRE([AC_PROG_LN_S])dnl test -z "$LN_S" && LN_S="ln -s" _LT_DECL([], [LN_S], [1], [Whether we need soft or hard links])dnl dnl AC_REQUIRE([LT_CMD_MAX_LEN])dnl _LT_DECL([objext], [ac_objext], [0], [Object file suffix (normally "o")])dnl _LT_DECL([], [exeext], [0], [Executable file suffix (normally "")])dnl dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_CHECK_SHELL_FEATURES])dnl m4_require([_LT_PATH_CONVERSION_FUNCTIONS])dnl m4_require([_LT_CMD_RELOAD])dnl m4_require([_LT_CHECK_MAGIC_METHOD])dnl m4_require([_LT_CHECK_SHAREDLIB_FROM_LINKLIB])dnl m4_require([_LT_CMD_OLD_ARCHIVE])dnl m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl m4_require([_LT_WITH_SYSROOT])dnl _LT_CONFIG_LIBTOOL_INIT([ # See if we are running on zsh, and set the options which allow our # commands through without removal of \ escapes INIT. if test -n "\${ZSH_VERSION+set}" ; then setopt NO_GLOB_SUBST fi ]) if test -n "${ZSH_VERSION+set}" ; then setopt NO_GLOB_SUBST fi _LT_CHECK_OBJDIR m4_require([_LT_TAG_COMPILER])dnl case $host_os in aix3*) # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. if test "X${COLLECT_NAMES+set}" != Xset; then COLLECT_NAMES= export COLLECT_NAMES fi ;; esac # Global variables: ofile=libtool can_build_shared=yes # All known linkers require a `.a' archive for static linking (except MSVC, # which needs '.lib'). libext=a with_gnu_ld="$lt_cv_prog_gnu_ld" old_CC="$CC" old_CFLAGS="$CFLAGS" # Set sane defaults for various variables test -z "$CC" && CC=cc test -z "$LTCC" && LTCC=$CC test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS test -z "$LD" && LD=ld test -z "$ac_objext" && ac_objext=o _LT_CC_BASENAME([$compiler]) # Only perform the check for file, if the check method requires it test -z "$MAGIC_CMD" && MAGIC_CMD=file case $deplibs_check_method in file_magic*) if test "$file_magic_cmd" = '$MAGIC_CMD'; then _LT_PATH_MAGIC fi ;; esac # Use C for the default configuration in the libtool script LT_SUPPORTED_TAG([CC]) _LT_LANG_C_CONFIG _LT_LANG_DEFAULT_CONFIG _LT_CONFIG_COMMANDS ])# _LT_SETUP # _LT_PREPARE_SED_QUOTE_VARS # -------------------------- # Define a few sed substitution that help us do robust quoting. m4_defun([_LT_PREPARE_SED_QUOTE_VARS], [# Backslashify metacharacters that are still active within # double-quoted strings. sed_quote_subst='s/\([["`$\\]]\)/\\\1/g' # Same as above, but do not quote variable references. double_quote_subst='s/\([["`\\]]\)/\\\1/g' # Sed substitution to delay expansion of an escaped shell variable in a # double_quote_subst'ed string. delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' # Sed substitution to delay expansion of an escaped single quote. delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' # Sed substitution to avoid accidental globbing in evaled expressions no_glob_subst='s/\*/\\\*/g' ]) # _LT_PROG_LTMAIN # --------------- # Note that this code is called both from `configure', and `config.status' # now that we use AC_CONFIG_COMMANDS to generate libtool. Notably, # `config.status' has no value for ac_aux_dir unless we are using Automake, # so we pass a copy along to make sure it has a sensible value anyway. m4_defun([_LT_PROG_LTMAIN], [m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([ltmain.sh])])dnl _LT_CONFIG_LIBTOOL_INIT([ac_aux_dir='$ac_aux_dir']) ltmain="$ac_aux_dir/ltmain.sh" ])# _LT_PROG_LTMAIN # So that we can recreate a full libtool script including additional # tags, we accumulate the chunks of code to send to AC_CONFIG_COMMANDS # in macros and then make a single call at the end using the `libtool' # label. # _LT_CONFIG_LIBTOOL_INIT([INIT-COMMANDS]) # ---------------------------------------- # Register INIT-COMMANDS to be passed to AC_CONFIG_COMMANDS later. m4_define([_LT_CONFIG_LIBTOOL_INIT], [m4_ifval([$1], [m4_append([_LT_OUTPUT_LIBTOOL_INIT], [$1 ])])]) # Initialize. m4_define([_LT_OUTPUT_LIBTOOL_INIT]) # _LT_CONFIG_LIBTOOL([COMMANDS]) # ------------------------------ # Register COMMANDS to be passed to AC_CONFIG_COMMANDS later. m4_define([_LT_CONFIG_LIBTOOL], [m4_ifval([$1], [m4_append([_LT_OUTPUT_LIBTOOL_COMMANDS], [$1 ])])]) # Initialize. m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS]) # _LT_CONFIG_SAVE_COMMANDS([COMMANDS], [INIT_COMMANDS]) # ----------------------------------------------------- m4_defun([_LT_CONFIG_SAVE_COMMANDS], [_LT_CONFIG_LIBTOOL([$1]) _LT_CONFIG_LIBTOOL_INIT([$2]) ]) # _LT_FORMAT_COMMENT([COMMENT]) # ----------------------------- # Add leading comment marks to the start of each line, and a trailing # full-stop to the whole comment if one is not present already. m4_define([_LT_FORMAT_COMMENT], [m4_ifval([$1], [ m4_bpatsubst([m4_bpatsubst([$1], [^ *], [# ])], [['`$\]], [\\\&])]m4_bmatch([$1], [[!?.]$], [], [.]) )]) # _LT_DECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION], [IS-TAGGED?]) # ------------------------------------------------------------------- # CONFIGNAME is the name given to the value in the libtool script. # VARNAME is the (base) name used in the configure script. # VALUE may be 0, 1 or 2 for a computed quote escaped value based on # VARNAME. Any other value will be used directly. m4_define([_LT_DECL], [lt_if_append_uniq([lt_decl_varnames], [$2], [, ], [lt_dict_add_subkey([lt_decl_dict], [$2], [libtool_name], [m4_ifval([$1], [$1], [$2])]) lt_dict_add_subkey([lt_decl_dict], [$2], [value], [$3]) m4_ifval([$4], [lt_dict_add_subkey([lt_decl_dict], [$2], [description], [$4])]) lt_dict_add_subkey([lt_decl_dict], [$2], [tagged?], [m4_ifval([$5], [yes], [no])])]) ]) # _LT_TAGDECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION]) # -------------------------------------------------------- m4_define([_LT_TAGDECL], [_LT_DECL([$1], [$2], [$3], [$4], [yes])]) # lt_decl_tag_varnames([SEPARATOR], [VARNAME1...]) # ------------------------------------------------ m4_define([lt_decl_tag_varnames], [_lt_decl_filter([tagged?], [yes], $@)]) # _lt_decl_filter(SUBKEY, VALUE, [SEPARATOR], [VARNAME1..]) # --------------------------------------------------------- m4_define([_lt_decl_filter], [m4_case([$#], [0], [m4_fatal([$0: too few arguments: $#])], [1], [m4_fatal([$0: too few arguments: $#: $1])], [2], [lt_dict_filter([lt_decl_dict], [$1], [$2], [], lt_decl_varnames)], [3], [lt_dict_filter([lt_decl_dict], [$1], [$2], [$3], lt_decl_varnames)], [lt_dict_filter([lt_decl_dict], $@)])[]dnl ]) # lt_decl_quote_varnames([SEPARATOR], [VARNAME1...]) # -------------------------------------------------- m4_define([lt_decl_quote_varnames], [_lt_decl_filter([value], [1], $@)]) # lt_decl_dquote_varnames([SEPARATOR], [VARNAME1...]) # --------------------------------------------------- m4_define([lt_decl_dquote_varnames], [_lt_decl_filter([value], [2], $@)]) # lt_decl_varnames_tagged([SEPARATOR], [VARNAME1...]) # --------------------------------------------------- m4_define([lt_decl_varnames_tagged], [m4_assert([$# <= 2])dnl _$0(m4_quote(m4_default([$1], [[, ]])), m4_ifval([$2], [[$2]], [m4_dquote(lt_decl_tag_varnames)]), m4_split(m4_normalize(m4_quote(_LT_TAGS)), [ ]))]) m4_define([_lt_decl_varnames_tagged], [m4_ifval([$3], [lt_combine([$1], [$2], [_], $3)])]) # lt_decl_all_varnames([SEPARATOR], [VARNAME1...]) # ------------------------------------------------ m4_define([lt_decl_all_varnames], [_$0(m4_quote(m4_default([$1], [[, ]])), m4_if([$2], [], m4_quote(lt_decl_varnames), m4_quote(m4_shift($@))))[]dnl ]) m4_define([_lt_decl_all_varnames], [lt_join($@, lt_decl_varnames_tagged([$1], lt_decl_tag_varnames([[, ]], m4_shift($@))))dnl ]) # _LT_CONFIG_STATUS_DECLARE([VARNAME]) # ------------------------------------ # Quote a variable value, and forward it to `config.status' so that its # declaration there will have the same value as in `configure'. VARNAME # must have a single quote delimited value for this to work. m4_define([_LT_CONFIG_STATUS_DECLARE], [$1='`$ECHO "$][$1" | $SED "$delay_single_quote_subst"`']) # _LT_CONFIG_STATUS_DECLARATIONS # ------------------------------ # We delimit libtool config variables with single quotes, so when # we write them to config.status, we have to be sure to quote all # embedded single quotes properly. In configure, this macro expands # each variable declared with _LT_DECL (and _LT_TAGDECL) into: # # <var>='`$ECHO "$<var>" | $SED "$delay_single_quote_subst"`' m4_defun([_LT_CONFIG_STATUS_DECLARATIONS], [m4_foreach([_lt_var], m4_quote(lt_decl_all_varnames), [m4_n([_LT_CONFIG_STATUS_DECLARE(_lt_var)])])]) # _LT_LIBTOOL_TAGS # ---------------- # Output comment and list of tags supported by the script m4_defun([_LT_LIBTOOL_TAGS], [_LT_FORMAT_COMMENT([The names of the tagged configurations supported by this script])dnl available_tags="_LT_TAGS"dnl ]) # _LT_LIBTOOL_DECLARE(VARNAME, [TAG]) # ----------------------------------- # Extract the dictionary values for VARNAME (optionally with TAG) and # expand to a commented shell variable setting: # # # Some comment about what VAR is for. # visible_name=$lt_internal_name m4_define([_LT_LIBTOOL_DECLARE], [_LT_FORMAT_COMMENT(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [description])))[]dnl m4_pushdef([_libtool_name], m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [libtool_name])))[]dnl m4_case(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [value])), [0], [_libtool_name=[$]$1], [1], [_libtool_name=$lt_[]$1], [2], [_libtool_name=$lt_[]$1], [_libtool_name=lt_dict_fetch([lt_decl_dict], [$1], [value])])[]dnl m4_ifval([$2], [_$2])[]m4_popdef([_libtool_name])[]dnl ]) # _LT_LIBTOOL_CONFIG_VARS # ----------------------- # Produce commented declarations of non-tagged libtool config variables # suitable for insertion in the LIBTOOL CONFIG section of the `libtool' # script. Tagged libtool config variables (even for the LIBTOOL CONFIG # section) are produced by _LT_LIBTOOL_TAG_VARS. m4_defun([_LT_LIBTOOL_CONFIG_VARS], [m4_foreach([_lt_var], m4_quote(_lt_decl_filter([tagged?], [no], [], lt_decl_varnames)), [m4_n([_LT_LIBTOOL_DECLARE(_lt_var)])])]) # _LT_LIBTOOL_TAG_VARS(TAG) # ------------------------- m4_define([_LT_LIBTOOL_TAG_VARS], [m4_foreach([_lt_var], m4_quote(lt_decl_tag_varnames), [m4_n([_LT_LIBTOOL_DECLARE(_lt_var, [$1])])])]) # _LT_TAGVAR(VARNAME, [TAGNAME]) # ------------------------------ m4_define([_LT_TAGVAR], [m4_ifval([$2], [$1_$2], [$1])]) # _LT_CONFIG_COMMANDS # ------------------- # Send accumulated output to $CONFIG_STATUS. Thanks to the lists of # variables for single and double quote escaping we saved from calls # to _LT_DECL, we can put quote escaped variables declarations # into `config.status', and then the shell code to quote escape them in # for loops in `config.status'. Finally, any additional code accumulated # from calls to _LT_CONFIG_LIBTOOL_INIT is expanded. m4_defun([_LT_CONFIG_COMMANDS], [AC_PROVIDE_IFELSE([LT_OUTPUT], dnl If the libtool generation code has been placed in $CONFIG_LT, dnl instead of duplicating it all over again into config.status, dnl then we will have config.status run $CONFIG_LT later, so it dnl needs to know what name is stored there: [AC_CONFIG_COMMANDS([libtool], [$SHELL $CONFIG_LT || AS_EXIT(1)], [CONFIG_LT='$CONFIG_LT'])], dnl If the libtool generation code is destined for config.status, dnl expand the accumulated commands and init code now: [AC_CONFIG_COMMANDS([libtool], [_LT_OUTPUT_LIBTOOL_COMMANDS], [_LT_OUTPUT_LIBTOOL_COMMANDS_INIT])]) ])#_LT_CONFIG_COMMANDS # Initialize. m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS_INIT], [ # The HP-UX ksh and POSIX shell print the target directory to stdout # if CDPATH is set. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH sed_quote_subst='$sed_quote_subst' double_quote_subst='$double_quote_subst' delay_variable_subst='$delay_variable_subst' _LT_CONFIG_STATUS_DECLARATIONS LTCC='$LTCC' LTCFLAGS='$LTCFLAGS' compiler='$compiler_DEFAULT' # A function that is used when there is no print builtin or printf. func_fallback_echo () { eval 'cat <<_LTECHO_EOF \$[]1 _LTECHO_EOF' } # Quote evaled strings. for var in lt_decl_all_varnames([[ \ ]], lt_decl_quote_varnames); do case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in *[[\\\\\\\`\\"\\\$]]*) eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" ;; *) eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" ;; esac done # Double-quote double-evaled strings. for var in lt_decl_all_varnames([[ \ ]], lt_decl_dquote_varnames); do case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in *[[\\\\\\\`\\"\\\$]]*) eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" ;; *) eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" ;; esac done _LT_OUTPUT_LIBTOOL_INIT ]) # _LT_GENERATED_FILE_INIT(FILE, [COMMENT]) # ------------------------------------ # Generate a child script FILE with all initialization necessary to # reuse the environment learned by the parent script, and make the # file executable. If COMMENT is supplied, it is inserted after the # `#!' sequence but before initialization text begins. After this # macro, additional text can be appended to FILE to form the body of # the child script. The macro ends with non-zero status if the # file could not be fully written (such as if the disk is full). m4_ifdef([AS_INIT_GENERATED], [m4_defun([_LT_GENERATED_FILE_INIT],[AS_INIT_GENERATED($@)])], [m4_defun([_LT_GENERATED_FILE_INIT], [m4_require([AS_PREPARE])]dnl [m4_pushdef([AS_MESSAGE_LOG_FD])]dnl [lt_write_fail=0 cat >$1 <<_ASEOF || lt_write_fail=1 #! $SHELL # Generated by $as_me. $2 SHELL=\${CONFIG_SHELL-$SHELL} export SHELL _ASEOF cat >>$1 <<\_ASEOF || lt_write_fail=1 AS_SHELL_SANITIZE _AS_PREPARE exec AS_MESSAGE_FD>&1 _ASEOF test $lt_write_fail = 0 && chmod +x $1[]dnl m4_popdef([AS_MESSAGE_LOG_FD])])])# _LT_GENERATED_FILE_INIT # LT_OUTPUT # --------- # This macro allows early generation of the libtool script (before # AC_OUTPUT is called), incase it is used in configure for compilation # tests. AC_DEFUN([LT_OUTPUT], [: ${CONFIG_LT=./config.lt} AC_MSG_NOTICE([creating $CONFIG_LT]) _LT_GENERATED_FILE_INIT(["$CONFIG_LT"], [# Run this file to recreate a libtool stub with the current configuration.]) cat >>"$CONFIG_LT" <<\_LTEOF lt_cl_silent=false exec AS_MESSAGE_LOG_FD>>config.log { echo AS_BOX([Running $as_me.]) } >&AS_MESSAGE_LOG_FD lt_cl_help="\ \`$as_me' creates a local libtool stub from the current configuration, for use in further configure time tests before the real libtool is generated. Usage: $[0] [[OPTIONS]] -h, --help print this help, then exit -V, --version print version number, then exit -q, --quiet do not print progress messages -d, --debug don't remove temporary files Report bugs to <bug-libtool@gnu.org>." lt_cl_version="\ m4_ifset([AC_PACKAGE_NAME], [AC_PACKAGE_NAME ])config.lt[]dnl m4_ifset([AC_PACKAGE_VERSION], [ AC_PACKAGE_VERSION]) configured by $[0], generated by m4_PACKAGE_STRING. Copyright (C) 2011 Free Software Foundation, Inc. This config.lt script is free software; the Free Software Foundation gives unlimited permision to copy, distribute and modify it." while test $[#] != 0 do case $[1] in --version | --v* | -V ) echo "$lt_cl_version"; exit 0 ;; --help | --h* | -h ) echo "$lt_cl_help"; exit 0 ;; --debug | --d* | -d ) debug=: ;; --quiet | --q* | --silent | --s* | -q ) lt_cl_silent=: ;; -*) AC_MSG_ERROR([unrecognized option: $[1] Try \`$[0] --help' for more information.]) ;; *) AC_MSG_ERROR([unrecognized argument: $[1] Try \`$[0] --help' for more information.]) ;; esac shift done if $lt_cl_silent; then exec AS_MESSAGE_FD>/dev/null fi _LTEOF cat >>"$CONFIG_LT" <<_LTEOF _LT_OUTPUT_LIBTOOL_COMMANDS_INIT _LTEOF cat >>"$CONFIG_LT" <<\_LTEOF AC_MSG_NOTICE([creating $ofile]) _LT_OUTPUT_LIBTOOL_COMMANDS AS_EXIT(0) _LTEOF chmod +x "$CONFIG_LT" # configure is writing to config.log, but config.lt does its own redirection, # appending to config.log, which fails on DOS, as config.log is still kept # open by configure. Here we exec the FD to /dev/null, effectively closing # config.log, so it can be properly (re)opened and appended to by config.lt. lt_cl_success=: test "$silent" = yes && lt_config_lt_args="$lt_config_lt_args --quiet" exec AS_MESSAGE_LOG_FD>/dev/null $SHELL "$CONFIG_LT" $lt_config_lt_args || lt_cl_success=false exec AS_MESSAGE_LOG_FD>>config.log $lt_cl_success || AS_EXIT(1) ])# LT_OUTPUT # _LT_CONFIG(TAG) # --------------- # If TAG is the built-in tag, create an initial libtool script with a # default configuration from the untagged config vars. Otherwise add code # to config.status for appending the configuration named by TAG from the # matching tagged config vars. m4_defun([_LT_CONFIG], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl _LT_CONFIG_SAVE_COMMANDS([ m4_define([_LT_TAG], m4_if([$1], [], [C], [$1]))dnl m4_if(_LT_TAG, [C], [ # See if we are running on zsh, and set the options which allow our # commands through without removal of \ escapes. if test -n "${ZSH_VERSION+set}" ; then setopt NO_GLOB_SUBST fi cfgfile="${ofile}T" trap "$RM \"$cfgfile\"; exit 1" 1 2 15 $RM "$cfgfile" cat <<_LT_EOF >> "$cfgfile" #! $SHELL # `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services. # Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION # Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: # NOTE: Changes made to this file will be lost: look at ltmain.sh. # _LT_COPYING _LT_LIBTOOL_TAGS # ### BEGIN LIBTOOL CONFIG _LT_LIBTOOL_CONFIG_VARS _LT_LIBTOOL_TAG_VARS # ### END LIBTOOL CONFIG _LT_EOF case $host_os in aix3*) cat <<\_LT_EOF >> "$cfgfile" # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. if test "X${COLLECT_NAMES+set}" != Xset; then COLLECT_NAMES= export COLLECT_NAMES fi _LT_EOF ;; esac _LT_PROG_LTMAIN # We use sed instead of cat because bash on DJGPP gets confused if # if finds mixed CR/LF and LF-only lines. Since sed operates in # text mode, it properly converts lines to CR/LF. This bash problem # is reportedly fixed, but why not run on old versions too? sed '$q' "$ltmain" >> "$cfgfile" \ || (rm -f "$cfgfile"; exit 1) _LT_PROG_REPLACE_SHELLFNS mv -f "$cfgfile" "$ofile" || (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") chmod +x "$ofile" ], [cat <<_LT_EOF >> "$ofile" dnl Unfortunately we have to use $1 here, since _LT_TAG is not expanded dnl in a comment (ie after a #). # ### BEGIN LIBTOOL TAG CONFIG: $1 _LT_LIBTOOL_TAG_VARS(_LT_TAG) # ### END LIBTOOL TAG CONFIG: $1 _LT_EOF ])dnl /m4_if ], [m4_if([$1], [], [ PACKAGE='$PACKAGE' VERSION='$VERSION' TIMESTAMP='$TIMESTAMP' RM='$RM' ofile='$ofile'], []) ])dnl /_LT_CONFIG_SAVE_COMMANDS ])# _LT_CONFIG # LT_SUPPORTED_TAG(TAG) # --------------------- # Trace this macro to discover what tags are supported by the libtool # --tag option, using: # autoconf --trace 'LT_SUPPORTED_TAG:$1' AC_DEFUN([LT_SUPPORTED_TAG], []) # C support is built-in for now m4_define([_LT_LANG_C_enabled], []) m4_define([_LT_TAGS], []) # LT_LANG(LANG) # ------------- # Enable libtool support for the given language if not already enabled. AC_DEFUN([LT_LANG], [AC_BEFORE([$0], [LT_OUTPUT])dnl m4_case([$1], [C], [_LT_LANG(C)], [C++], [_LT_LANG(CXX)], [Go], [_LT_LANG(GO)], [Java], [_LT_LANG(GCJ)], [Fortran 77], [_LT_LANG(F77)], [Fortran], [_LT_LANG(FC)], [Windows Resource], [_LT_LANG(RC)], [m4_ifdef([_LT_LANG_]$1[_CONFIG], [_LT_LANG($1)], [m4_fatal([$0: unsupported language: "$1"])])])dnl ])# LT_LANG # _LT_LANG(LANGNAME) # ------------------ m4_defun([_LT_LANG], [m4_ifdef([_LT_LANG_]$1[_enabled], [], [LT_SUPPORTED_TAG([$1])dnl m4_append([_LT_TAGS], [$1 ])dnl m4_define([_LT_LANG_]$1[_enabled], [])dnl _LT_LANG_$1_CONFIG($1)])dnl ])# _LT_LANG m4_ifndef([AC_PROG_GO], [ # NOTE: This macro has been submitted for inclusion into # # GNU Autoconf as AC_PROG_GO. When it is available in # # a released version of Autoconf we should remove this # # macro and use it instead. # m4_defun([AC_PROG_GO], [AC_LANG_PUSH(Go)dnl AC_ARG_VAR([GOC], [Go compiler command])dnl AC_ARG_VAR([GOFLAGS], [Go compiler flags])dnl _AC_ARG_VAR_LDFLAGS()dnl AC_CHECK_TOOL(GOC, gccgo) if test -z "$GOC"; then if test -n "$ac_tool_prefix"; then AC_CHECK_PROG(GOC, [${ac_tool_prefix}gccgo], [${ac_tool_prefix}gccgo]) fi fi if test -z "$GOC"; then AC_CHECK_PROG(GOC, gccgo, gccgo, false) fi ])#m4_defun ])#m4_ifndef # _LT_LANG_DEFAULT_CONFIG # ----------------------- m4_defun([_LT_LANG_DEFAULT_CONFIG], [AC_PROVIDE_IFELSE([AC_PROG_CXX], [LT_LANG(CXX)], [m4_define([AC_PROG_CXX], defn([AC_PROG_CXX])[LT_LANG(CXX)])]) AC_PROVIDE_IFELSE([AC_PROG_F77], [LT_LANG(F77)], [m4_define([AC_PROG_F77], defn([AC_PROG_F77])[LT_LANG(F77)])]) AC_PROVIDE_IFELSE([AC_PROG_FC], [LT_LANG(FC)], [m4_define([AC_PROG_FC], defn([AC_PROG_FC])[LT_LANG(FC)])]) dnl The call to [A][M_PROG_GCJ] is quoted like that to stop aclocal dnl pulling things in needlessly. AC_PROVIDE_IFELSE([AC_PROG_GCJ], [LT_LANG(GCJ)], [AC_PROVIDE_IFELSE([A][M_PROG_GCJ], [LT_LANG(GCJ)], [AC_PROVIDE_IFELSE([LT_PROG_GCJ], [LT_LANG(GCJ)], [m4_ifdef([AC_PROG_GCJ], [m4_define([AC_PROG_GCJ], defn([AC_PROG_GCJ])[LT_LANG(GCJ)])]) m4_ifdef([A][M_PROG_GCJ], [m4_define([A][M_PROG_GCJ], defn([A][M_PROG_GCJ])[LT_LANG(GCJ)])]) m4_ifdef([LT_PROG_GCJ], [m4_define([LT_PROG_GCJ], defn([LT_PROG_GCJ])[LT_LANG(GCJ)])])])])]) AC_PROVIDE_IFELSE([AC_PROG_GO], [LT_LANG(GO)], [m4_define([AC_PROG_GO], defn([AC_PROG_GO])[LT_LANG(GO)])]) AC_PROVIDE_IFELSE([LT_PROG_RC], [LT_LANG(RC)], [m4_define([LT_PROG_RC], defn([LT_PROG_RC])[LT_LANG(RC)])]) ])# _LT_LANG_DEFAULT_CONFIG # Obsolete macros: AU_DEFUN([AC_LIBTOOL_CXX], [LT_LANG(C++)]) AU_DEFUN([AC_LIBTOOL_F77], [LT_LANG(Fortran 77)]) AU_DEFUN([AC_LIBTOOL_FC], [LT_LANG(Fortran)]) AU_DEFUN([AC_LIBTOOL_GCJ], [LT_LANG(Java)]) AU_DEFUN([AC_LIBTOOL_RC], [LT_LANG(Windows Resource)]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_CXX], []) dnl AC_DEFUN([AC_LIBTOOL_F77], []) dnl AC_DEFUN([AC_LIBTOOL_FC], []) dnl AC_DEFUN([AC_LIBTOOL_GCJ], []) dnl AC_DEFUN([AC_LIBTOOL_RC], []) # _LT_TAG_COMPILER # ---------------- m4_defun([_LT_TAG_COMPILER], [AC_REQUIRE([AC_PROG_CC])dnl _LT_DECL([LTCC], [CC], [1], [A C compiler])dnl _LT_DECL([LTCFLAGS], [CFLAGS], [1], [LTCC compiler flags])dnl _LT_TAGDECL([CC], [compiler], [1], [A language specific compiler])dnl _LT_TAGDECL([with_gcc], [GCC], [0], [Is the compiler the GNU compiler?])dnl # If no C compiler was specified, use CC. LTCC=${LTCC-"$CC"} # If no C compiler flags were specified, use CFLAGS. LTCFLAGS=${LTCFLAGS-"$CFLAGS"} # Allow CC to be a program name with arguments. compiler=$CC ])# _LT_TAG_COMPILER # _LT_COMPILER_BOILERPLATE # ------------------------ # Check for compiler boilerplate output or warnings with # the simple compiler test code. m4_defun([_LT_COMPILER_BOILERPLATE], [m4_require([_LT_DECL_SED])dnl ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" >conftest.$ac_ext eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_compiler_boilerplate=`cat conftest.err` $RM conftest* ])# _LT_COMPILER_BOILERPLATE # _LT_LINKER_BOILERPLATE # ---------------------- # Check for linker boilerplate output or warnings with # the simple link test code. m4_defun([_LT_LINKER_BOILERPLATE], [m4_require([_LT_DECL_SED])dnl ac_outfile=conftest.$ac_objext echo "$lt_simple_link_test_code" >conftest.$ac_ext eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_linker_boilerplate=`cat conftest.err` $RM -r conftest* ])# _LT_LINKER_BOILERPLATE # _LT_REQUIRED_DARWIN_CHECKS # ------------------------- m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[ case $host_os in rhapsody* | darwin*) AC_CHECK_TOOL([DSYMUTIL], [dsymutil], [:]) AC_CHECK_TOOL([NMEDIT], [nmedit], [:]) AC_CHECK_TOOL([LIPO], [lipo], [:]) AC_CHECK_TOOL([OTOOL], [otool], [:]) AC_CHECK_TOOL([OTOOL64], [otool64], [:]) _LT_DECL([], [DSYMUTIL], [1], [Tool to manipulate archived DWARF debug symbol files on Mac OS X]) _LT_DECL([], [NMEDIT], [1], [Tool to change global to local symbols on Mac OS X]) _LT_DECL([], [LIPO], [1], [Tool to manipulate fat objects and archives on Mac OS X]) _LT_DECL([], [OTOOL], [1], [ldd/readelf like tool for Mach-O binaries on Mac OS X]) _LT_DECL([], [OTOOL64], [1], [ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4]) AC_CACHE_CHECK([for -single_module linker flag],[lt_cv_apple_cc_single_mod], [lt_cv_apple_cc_single_mod=no if test -z "${LT_MULTI_MODULE}"; then # By default we will add the -single_module flag. You can override # by either setting the environment variable LT_MULTI_MODULE # non-empty at configure time, or by adding -multi_module to the # link flags. rm -rf libconftest.dylib* echo "int foo(void){return 1;}" > conftest.c echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ -dynamiclib -Wl,-single_module conftest.c" >&AS_MESSAGE_LOG_FD $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ -dynamiclib -Wl,-single_module conftest.c 2>conftest.err _lt_result=$? # If there is a non-empty error log, and "single_module" # appears in it, assume the flag caused a linker warning if test -s conftest.err && $GREP single_module conftest.err; then cat conftest.err >&AS_MESSAGE_LOG_FD # Otherwise, if the output was created with a 0 exit code from # the compiler, it worked. elif test -f libconftest.dylib && test $_lt_result -eq 0; then lt_cv_apple_cc_single_mod=yes else cat conftest.err >&AS_MESSAGE_LOG_FD fi rm -rf libconftest.dylib* rm -f conftest.* fi]) AC_CACHE_CHECK([for -exported_symbols_list linker flag], [lt_cv_ld_exported_symbols_list], [lt_cv_ld_exported_symbols_list=no save_LDFLAGS=$LDFLAGS echo "_main" > conftest.sym LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], [lt_cv_ld_exported_symbols_list=yes], [lt_cv_ld_exported_symbols_list=no]) LDFLAGS="$save_LDFLAGS" ]) AC_CACHE_CHECK([for -force_load linker flag],[lt_cv_ld_force_load], [lt_cv_ld_force_load=no cat > conftest.c << _LT_EOF int forced_loaded() { return 2;} _LT_EOF echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&AS_MESSAGE_LOG_FD $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&AS_MESSAGE_LOG_FD echo "$AR cru libconftest.a conftest.o" >&AS_MESSAGE_LOG_FD $AR cru libconftest.a conftest.o 2>&AS_MESSAGE_LOG_FD echo "$RANLIB libconftest.a" >&AS_MESSAGE_LOG_FD $RANLIB libconftest.a 2>&AS_MESSAGE_LOG_FD cat > conftest.c << _LT_EOF int main() { return 0;} _LT_EOF echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&AS_MESSAGE_LOG_FD $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err _lt_result=$? if test -s conftest.err && $GREP force_load conftest.err; then cat conftest.err >&AS_MESSAGE_LOG_FD elif test -f conftest && test $_lt_result -eq 0 && $GREP forced_load conftest >/dev/null 2>&1 ; then lt_cv_ld_force_load=yes else cat conftest.err >&AS_MESSAGE_LOG_FD fi rm -f conftest.err libconftest.a conftest conftest.c rm -rf conftest.dSYM ]) case $host_os in rhapsody* | darwin1.[[012]]) _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;; darwin1.*) _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; darwin*) # darwin 5.x on # if running on 10.5 or later, the deployment target defaults # to the OS version, if on x86, and 10.4, the deployment # target defaults to 10.4. Don't you love it? case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in 10.0,*86*-darwin8*|10.0,*-darwin[[91]]*) _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; 10.[[012]]*) _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; 10.*) _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; esac ;; esac if test "$lt_cv_apple_cc_single_mod" = "yes"; then _lt_dar_single_mod='$single_module' fi if test "$lt_cv_ld_exported_symbols_list" = "yes"; then _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym' else _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}' fi if test "$DSYMUTIL" != ":" && test "$lt_cv_ld_force_load" = "no"; then _lt_dsymutil='~$DSYMUTIL $lib || :' else _lt_dsymutil= fi ;; esac ]) # _LT_DARWIN_LINKER_FEATURES([TAG]) # --------------------------------- # Checks for linker and compiler features on darwin m4_defun([_LT_DARWIN_LINKER_FEATURES], [ m4_require([_LT_REQUIRED_DARWIN_CHECKS]) _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_automatic, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported if test "$lt_cv_ld_force_load" = "yes"; then _LT_TAGVAR(whole_archive_flag_spec, $1)='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' m4_case([$1], [F77], [_LT_TAGVAR(compiler_needs_object, $1)=yes], [FC], [_LT_TAGVAR(compiler_needs_object, $1)=yes]) else _LT_TAGVAR(whole_archive_flag_spec, $1)='' fi _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(allow_undefined_flag, $1)="$_lt_dar_allow_undefined" case $cc_basename in ifort*) _lt_dar_can_shared=yes ;; *) _lt_dar_can_shared=$GCC ;; esac if test "$_lt_dar_can_shared" = "yes"; then output_verbose_link_cmd=func_echo_all _LT_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" _LT_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" _LT_TAGVAR(module_expsym_cmds, $1)="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" m4_if([$1], [CXX], [ if test "$lt_cv_apple_cc_single_mod" != "yes"; then _LT_TAGVAR(archive_cmds, $1)="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dsymutil}" _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dar_export_syms}${_lt_dsymutil}" fi ],[]) else _LT_TAGVAR(ld_shlibs, $1)=no fi ]) # _LT_SYS_MODULE_PATH_AIX([TAGNAME]) # ---------------------------------- # Links a minimal program and checks the executable # for the system default hardcoded library path. In most cases, # this is /usr/lib:/lib, but when the MPI compilers are used # the location of the communication and MPI libs are included too. # If we don't find anything, use the default library path according # to the aix ld manual. # Store the results from the different compilers for each TAGNAME. # Allow to override them for all tags through lt_cv_aix_libpath. m4_defun([_LT_SYS_MODULE_PATH_AIX], [m4_require([_LT_DECL_SED])dnl if test "${lt_cv_aix_libpath+set}" = set; then aix_libpath=$lt_cv_aix_libpath else AC_CACHE_VAL([_LT_TAGVAR([lt_cv_aix_libpath_], [$1])], [AC_LINK_IFELSE([AC_LANG_PROGRAM],[ lt_aix_libpath_sed='[ /Import File Strings/,/^$/ { /^0/ { s/^0 *\([^ ]*\) *$/\1/ p } }]' _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` # Check for a 64-bit object if we didn't find anything. if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` fi],[]) if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then _LT_TAGVAR([lt_cv_aix_libpath_], [$1])="/usr/lib:/lib" fi ]) aix_libpath=$_LT_TAGVAR([lt_cv_aix_libpath_], [$1]) fi ])# _LT_SYS_MODULE_PATH_AIX # _LT_SHELL_INIT(ARG) # ------------------- m4_define([_LT_SHELL_INIT], [m4_divert_text([M4SH-INIT], [$1 ])])# _LT_SHELL_INIT # _LT_PROG_ECHO_BACKSLASH # ----------------------- # Find how we can fake an echo command that does not interpret backslash. # In particular, with Autoconf 2.60 or later we add some code to the start # of the generated configure script which will find a shell with a builtin # printf (which we can use as an echo command). m4_defun([_LT_PROG_ECHO_BACKSLASH], [ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO AC_MSG_CHECKING([how to print strings]) # Test print first, because it will be a builtin if present. if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \ test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then ECHO='print -r --' elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then ECHO='printf %s\n' else # Use this function as a fallback that always works. func_fallback_echo () { eval 'cat <<_LTECHO_EOF $[]1 _LTECHO_EOF' } ECHO='func_fallback_echo' fi # func_echo_all arg... # Invoke $ECHO with all args, space-separated. func_echo_all () { $ECHO "$*" } case "$ECHO" in printf*) AC_MSG_RESULT([printf]) ;; print*) AC_MSG_RESULT([print -r]) ;; *) AC_MSG_RESULT([cat]) ;; esac m4_ifdef([_AS_DETECT_SUGGESTED], [_AS_DETECT_SUGGESTED([ test -n "${ZSH_VERSION+set}${BASH_VERSION+set}" || ( ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO PATH=/empty FPATH=/empty; export PATH FPATH test "X`printf %s $ECHO`" = "X$ECHO" \ || test "X`print -r -- $ECHO`" = "X$ECHO" )])]) _LT_DECL([], [SHELL], [1], [Shell to use when invoking shell scripts]) _LT_DECL([], [ECHO], [1], [An echo program that protects backslashes]) ])# _LT_PROG_ECHO_BACKSLASH # _LT_WITH_SYSROOT # ---------------- AC_DEFUN([_LT_WITH_SYSROOT], [AC_MSG_CHECKING([for sysroot]) AC_ARG_WITH([sysroot], [ --with-sysroot[=DIR] Search for dependent libraries within DIR (or the compiler's sysroot if not specified).], [], [with_sysroot=no]) dnl lt_sysroot will always be passed unquoted. We quote it here dnl in case the user passed a directory name. lt_sysroot= case ${with_sysroot} in #( yes) if test "$GCC" = yes; then lt_sysroot=`$CC --print-sysroot 2>/dev/null` fi ;; #( /*) lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"` ;; #( no|'') ;; #( *) AC_MSG_RESULT([${with_sysroot}]) AC_MSG_ERROR([The sysroot must be an absolute path.]) ;; esac AC_MSG_RESULT([${lt_sysroot:-no}]) _LT_DECL([], [lt_sysroot], [0], [The root where to search for ]dnl [dependent libraries, and in which our libraries should be installed.])]) # _LT_ENABLE_LOCK # --------------- m4_defun([_LT_ENABLE_LOCK], [AC_ARG_ENABLE([libtool-lock], [AS_HELP_STRING([--disable-libtool-lock], [avoid locking (might break parallel builds)])]) test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes # Some flags need to be propagated to the compiler or linker for good # libtool support. case $host in ia64-*-hpux*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then case `/usr/bin/file conftest.$ac_objext` in *ELF-32*) HPUX_IA64_MODE="32" ;; *ELF-64*) HPUX_IA64_MODE="64" ;; esac fi rm -rf conftest* ;; *-*-irix6*) # Find out which ABI we are using. echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then if test "$lt_cv_prog_gnu_ld" = yes; then case `/usr/bin/file conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -melf32bsmip" ;; *N32*) LD="${LD-ld} -melf32bmipn32" ;; *64-bit*) LD="${LD-ld} -melf64bmip" ;; esac else case `/usr/bin/file conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -32" ;; *N32*) LD="${LD-ld} -n32" ;; *64-bit*) LD="${LD-ld} -64" ;; esac fi fi rm -rf conftest* ;; x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then case `/usr/bin/file conftest.o` in *32-bit*) case $host in x86_64-*kfreebsd*-gnu) LD="${LD-ld} -m elf_i386_fbsd" ;; x86_64-*linux*) case `/usr/bin/file conftest.o` in *x86-64*) LD="${LD-ld} -m elf32_x86_64" ;; *) LD="${LD-ld} -m elf_i386" ;; esac ;; powerpc64le-*) LD="${LD-ld} -m elf32lppclinux" ;; powerpc64-*) LD="${LD-ld} -m elf32ppclinux" ;; s390x-*linux*) LD="${LD-ld} -m elf_s390" ;; sparc64-*linux*) LD="${LD-ld} -m elf32_sparc" ;; esac ;; *64-bit*) case $host in x86_64-*kfreebsd*-gnu) LD="${LD-ld} -m elf_x86_64_fbsd" ;; x86_64-*linux*) LD="${LD-ld} -m elf_x86_64" ;; powerpcle-*) LD="${LD-ld} -m elf64lppc" ;; powerpc-*) LD="${LD-ld} -m elf64ppc" ;; s390*-*linux*|s390*-*tpf*) LD="${LD-ld} -m elf64_s390" ;; sparc*-*linux*) LD="${LD-ld} -m elf64_sparc" ;; esac ;; esac fi rm -rf conftest* ;; *-*-sco3.2v5*) # On SCO OpenServer 5, we need -belf to get full-featured binaries. SAVE_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -belf" AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf, [AC_LANG_PUSH(C) AC_LINK_IFELSE([AC_LANG_PROGRAM([[]],[[]])],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no]) AC_LANG_POP]) if test x"$lt_cv_cc_needs_belf" != x"yes"; then # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf CFLAGS="$SAVE_CFLAGS" fi ;; *-*solaris*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then case `/usr/bin/file conftest.o` in *64-bit*) case $lt_cv_prog_gnu_ld in yes*) case $host in i?86-*-solaris*) LD="${LD-ld} -m elf_x86_64" ;; sparc*-*-solaris*) LD="${LD-ld} -m elf64_sparc" ;; esac # GNU ld 2.21 introduced _sol2 emulations. Use them if available. if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then LD="${LD-ld}_sol2" fi ;; *) if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then LD="${LD-ld} -64" fi ;; esac ;; esac fi rm -rf conftest* ;; esac need_locks="$enable_libtool_lock" ])# _LT_ENABLE_LOCK # _LT_PROG_AR # ----------- m4_defun([_LT_PROG_AR], [AC_CHECK_TOOLS(AR, [ar], false) : ${AR=ar} : ${AR_FLAGS=cru} _LT_DECL([], [AR], [1], [The archiver]) _LT_DECL([], [AR_FLAGS], [1], [Flags to create an archive]) AC_CACHE_CHECK([for archiver @FILE support], [lt_cv_ar_at_file], [lt_cv_ar_at_file=no AC_COMPILE_IFELSE([AC_LANG_PROGRAM], [echo conftest.$ac_objext > conftest.lst lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&AS_MESSAGE_LOG_FD' AC_TRY_EVAL([lt_ar_try]) if test "$ac_status" -eq 0; then # Ensure the archiver fails upon bogus file names. rm -f conftest.$ac_objext libconftest.a AC_TRY_EVAL([lt_ar_try]) if test "$ac_status" -ne 0; then lt_cv_ar_at_file=@ fi fi rm -f conftest.* libconftest.a ]) ]) if test "x$lt_cv_ar_at_file" = xno; then archiver_list_spec= else archiver_list_spec=$lt_cv_ar_at_file fi _LT_DECL([], [archiver_list_spec], [1], [How to feed a file listing to the archiver]) ])# _LT_PROG_AR # _LT_CMD_OLD_ARCHIVE # ------------------- m4_defun([_LT_CMD_OLD_ARCHIVE], [_LT_PROG_AR AC_CHECK_TOOL(STRIP, strip, :) test -z "$STRIP" && STRIP=: _LT_DECL([], [STRIP], [1], [A symbol stripping program]) AC_CHECK_TOOL(RANLIB, ranlib, :) test -z "$RANLIB" && RANLIB=: _LT_DECL([], [RANLIB], [1], [Commands used to install an old-style archive]) # Determine commands to create old-style static archives. old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' old_postinstall_cmds='chmod 644 $oldlib' old_postuninstall_cmds= if test -n "$RANLIB"; then case $host_os in openbsd*) old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib" ;; *) old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib" ;; esac old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib" fi case $host_os in darwin*) lock_old_archive_extraction=yes ;; *) lock_old_archive_extraction=no ;; esac _LT_DECL([], [old_postinstall_cmds], [2]) _LT_DECL([], [old_postuninstall_cmds], [2]) _LT_TAGDECL([], [old_archive_cmds], [2], [Commands used to build an old-style archive]) _LT_DECL([], [lock_old_archive_extraction], [0], [Whether to use a lock for old archive extraction]) ])# _LT_CMD_OLD_ARCHIVE # _LT_COMPILER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, # [OUTPUT-FILE], [ACTION-SUCCESS], [ACTION-FAILURE]) # ---------------------------------------------------------------- # Check whether the given compiler option works AC_DEFUN([_LT_COMPILER_OPTION], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_SED])dnl AC_CACHE_CHECK([$1], [$2], [$2=no m4_if([$4], , [ac_outfile=conftest.$ac_objext], [ac_outfile=$4]) echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="$3" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. # The option is referenced via a variable to avoid confusing sed. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&AS_MESSAGE_LOG_FD echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then $2=yes fi fi $RM conftest* ]) if test x"[$]$2" = xyes; then m4_if([$5], , :, [$5]) else m4_if([$6], , :, [$6]) fi ])# _LT_COMPILER_OPTION # Old name: AU_ALIAS([AC_LIBTOOL_COMPILER_OPTION], [_LT_COMPILER_OPTION]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_COMPILER_OPTION], []) # _LT_LINKER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, # [ACTION-SUCCESS], [ACTION-FAILURE]) # ---------------------------------------------------- # Check whether the given linker option works AC_DEFUN([_LT_LINKER_OPTION], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_SED])dnl AC_CACHE_CHECK([$1], [$2], [$2=no save_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS $3" echo "$lt_simple_link_test_code" > conftest.$ac_ext if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then # The linker can only warn and ignore the option if not recognized # So say no if there are warnings if test -s conftest.err; then # Append any errors to the config.log. cat conftest.err 1>&AS_MESSAGE_LOG_FD $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if diff conftest.exp conftest.er2 >/dev/null; then $2=yes fi else $2=yes fi fi $RM -r conftest* LDFLAGS="$save_LDFLAGS" ]) if test x"[$]$2" = xyes; then m4_if([$4], , :, [$4]) else m4_if([$5], , :, [$5]) fi ])# _LT_LINKER_OPTION # Old name: AU_ALIAS([AC_LIBTOOL_LINKER_OPTION], [_LT_LINKER_OPTION]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_LINKER_OPTION], []) # LT_CMD_MAX_LEN #--------------- AC_DEFUN([LT_CMD_MAX_LEN], [AC_REQUIRE([AC_CANONICAL_HOST])dnl # find the maximum length of command line arguments AC_MSG_CHECKING([the maximum length of command line arguments]) AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl i=0 teststring="ABCD" case $build_os in msdosdjgpp*) # On DJGPP, this test can blow up pretty badly due to problems in libc # (any single argument exceeding 2000 bytes causes a buffer overrun # during glob expansion). Even if it were fixed, the result of this # check would be larger than it should be. lt_cv_sys_max_cmd_len=12288; # 12K is about right ;; gnu*) # Under GNU Hurd, this test is not required because there is # no limit to the length of command line arguments. # Libtool will interpret -1 as no limit whatsoever lt_cv_sys_max_cmd_len=-1; ;; cygwin* | mingw* | cegcc*) # On Win9x/ME, this test blows up -- it succeeds, but takes # about 5 minutes as the teststring grows exponentially. # Worse, since 9x/ME are not pre-emptively multitasking, # you end up with a "frozen" computer, even though with patience # the test eventually succeeds (with a max line length of 256k). # Instead, let's just punt: use the minimum linelength reported by # all of the supported platforms: 8192 (on NT/2K/XP). lt_cv_sys_max_cmd_len=8192; ;; mint*) # On MiNT this can take a long time and run out of memory. lt_cv_sys_max_cmd_len=8192; ;; amigaos*) # On AmigaOS with pdksh, this test takes hours, literally. # So we just punt and use a minimum line length of 8192. lt_cv_sys_max_cmd_len=8192; ;; netbsd* | freebsd* | openbsd* | darwin* | dragonfly*) # This has been around since 386BSD, at least. Likely further. if test -x /sbin/sysctl; then lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` elif test -x /usr/sbin/sysctl; then lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` else lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs fi # And add a safety zone lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` ;; interix*) # We know the value 262144 and hardcode it with a safety zone (like BSD) lt_cv_sys_max_cmd_len=196608 ;; os2*) # The test takes a long time on OS/2. lt_cv_sys_max_cmd_len=8192 ;; osf*) # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not # nice to cause kernel panics so lets avoid the loop below. # First set a reasonable default. lt_cv_sys_max_cmd_len=16384 # if test -x /sbin/sysconfig; then case `/sbin/sysconfig -q proc exec_disable_arg_limit` in *1*) lt_cv_sys_max_cmd_len=-1 ;; esac fi ;; sco3.2v5*) lt_cv_sys_max_cmd_len=102400 ;; sysv5* | sco5v6* | sysv4.2uw2*) kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` if test -n "$kargmax"; then lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[[ ]]//'` else lt_cv_sys_max_cmd_len=32768 fi ;; *) lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` if test -n "$lt_cv_sys_max_cmd_len" && \ test undefined != "$lt_cv_sys_max_cmd_len"; then lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` else # Make teststring a little bigger before we do anything with it. # a 1K string should be a reasonable start. for i in 1 2 3 4 5 6 7 8 ; do teststring=$teststring$teststring done SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} # If test is not a shell built-in, we'll probably end up computing a # maximum length that is only half of the actual maximum length, but # we can't tell. while { test "X"`env echo "$teststring$teststring" 2>/dev/null` \ = "X$teststring$teststring"; } >/dev/null 2>&1 && test $i != 17 # 1/2 MB should be enough do i=`expr $i + 1` teststring=$teststring$teststring done # Only check the string length outside the loop. lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` teststring= # Add a significant safety factor because C++ compilers can tack on # massive amounts of additional arguments before passing them to the # linker. It appears as though 1/2 is a usable value. lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` fi ;; esac ]) if test -n $lt_cv_sys_max_cmd_len ; then AC_MSG_RESULT($lt_cv_sys_max_cmd_len) else AC_MSG_RESULT(none) fi max_cmd_len=$lt_cv_sys_max_cmd_len _LT_DECL([], [max_cmd_len], [0], [What is the maximum length of a command?]) ])# LT_CMD_MAX_LEN # Old name: AU_ALIAS([AC_LIBTOOL_SYS_MAX_CMD_LEN], [LT_CMD_MAX_LEN]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_SYS_MAX_CMD_LEN], []) # _LT_HEADER_DLFCN # ---------------- m4_defun([_LT_HEADER_DLFCN], [AC_CHECK_HEADERS([dlfcn.h], [], [], [AC_INCLUDES_DEFAULT])dnl ])# _LT_HEADER_DLFCN # _LT_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE, # ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING) # ---------------------------------------------------------------- m4_defun([_LT_TRY_DLOPEN_SELF], [m4_require([_LT_HEADER_DLFCN])dnl if test "$cross_compiling" = yes; then : [$4] else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF [#line $LINENO "configure" #include "confdefs.h" #if HAVE_DLFCN_H #include <dlfcn.h> #endif #include <stdio.h> #ifdef RTLD_GLOBAL # define LT_DLGLOBAL RTLD_GLOBAL #else # ifdef DL_GLOBAL # define LT_DLGLOBAL DL_GLOBAL # else # define LT_DLGLOBAL 0 # endif #endif /* We may have to define LT_DLLAZY_OR_NOW in the command line if we find out it does not work in some platform. */ #ifndef LT_DLLAZY_OR_NOW # ifdef RTLD_LAZY # define LT_DLLAZY_OR_NOW RTLD_LAZY # else # ifdef DL_LAZY # define LT_DLLAZY_OR_NOW DL_LAZY # else # ifdef RTLD_NOW # define LT_DLLAZY_OR_NOW RTLD_NOW # else # ifdef DL_NOW # define LT_DLLAZY_OR_NOW DL_NOW # else # define LT_DLLAZY_OR_NOW 0 # endif # endif # endif # endif #endif /* When -fvisbility=hidden is used, assume the code has been annotated correspondingly for the symbols needed. */ #if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) int fnord () __attribute__((visibility("default"))); #endif int fnord () { return 42; } int main () { void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); int status = $lt_dlunknown; if (self) { if (dlsym (self,"fnord")) status = $lt_dlno_uscore; else { if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; else puts (dlerror ()); } /* dlclose (self); */ } else puts (dlerror ()); return status; }] _LT_EOF if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext} 2>/dev/null; then (./conftest; exit; ) >&AS_MESSAGE_LOG_FD 2>/dev/null lt_status=$? case x$lt_status in x$lt_dlno_uscore) $1 ;; x$lt_dlneed_uscore) $2 ;; x$lt_dlunknown|x*) $3 ;; esac else : # compilation failed $3 fi fi rm -fr conftest* ])# _LT_TRY_DLOPEN_SELF # LT_SYS_DLOPEN_SELF # ------------------ AC_DEFUN([LT_SYS_DLOPEN_SELF], [m4_require([_LT_HEADER_DLFCN])dnl if test "x$enable_dlopen" != xyes; then enable_dlopen=unknown enable_dlopen_self=unknown enable_dlopen_self_static=unknown else lt_cv_dlopen=no lt_cv_dlopen_libs= case $host_os in beos*) lt_cv_dlopen="load_add_on" lt_cv_dlopen_libs= lt_cv_dlopen_self=yes ;; mingw* | pw32* | cegcc*) lt_cv_dlopen="LoadLibrary" lt_cv_dlopen_libs= ;; cygwin*) lt_cv_dlopen="dlopen" lt_cv_dlopen_libs= ;; darwin*) # if libdl is installed we need to link against it AC_CHECK_LIB([dl], [dlopen], [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"],[ lt_cv_dlopen="dyld" lt_cv_dlopen_libs= lt_cv_dlopen_self=yes ]) ;; *) AC_CHECK_FUNC([shl_load], [lt_cv_dlopen="shl_load"], [AC_CHECK_LIB([dld], [shl_load], [lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld"], [AC_CHECK_FUNC([dlopen], [lt_cv_dlopen="dlopen"], [AC_CHECK_LIB([dl], [dlopen], [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"], [AC_CHECK_LIB([svld], [dlopen], [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"], [AC_CHECK_LIB([dld], [dld_link], [lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld"]) ]) ]) ]) ]) ]) ;; esac if test "x$lt_cv_dlopen" != xno; then enable_dlopen=yes else enable_dlopen=no fi case $lt_cv_dlopen in dlopen) save_CPPFLAGS="$CPPFLAGS" test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" save_LDFLAGS="$LDFLAGS" wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" save_LIBS="$LIBS" LIBS="$lt_cv_dlopen_libs $LIBS" AC_CACHE_CHECK([whether a program can dlopen itself], lt_cv_dlopen_self, [dnl _LT_TRY_DLOPEN_SELF( lt_cv_dlopen_self=yes, lt_cv_dlopen_self=yes, lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross) ]) if test "x$lt_cv_dlopen_self" = xyes; then wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" AC_CACHE_CHECK([whether a statically linked program can dlopen itself], lt_cv_dlopen_self_static, [dnl _LT_TRY_DLOPEN_SELF( lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=no, lt_cv_dlopen_self_static=cross) ]) fi CPPFLAGS="$save_CPPFLAGS" LDFLAGS="$save_LDFLAGS" LIBS="$save_LIBS" ;; esac case $lt_cv_dlopen_self in yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; *) enable_dlopen_self=unknown ;; esac case $lt_cv_dlopen_self_static in yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; *) enable_dlopen_self_static=unknown ;; esac fi _LT_DECL([dlopen_support], [enable_dlopen], [0], [Whether dlopen is supported]) _LT_DECL([dlopen_self], [enable_dlopen_self], [0], [Whether dlopen of programs is supported]) _LT_DECL([dlopen_self_static], [enable_dlopen_self_static], [0], [Whether dlopen of statically linked programs is supported]) ])# LT_SYS_DLOPEN_SELF # Old name: AU_ALIAS([AC_LIBTOOL_DLOPEN_SELF], [LT_SYS_DLOPEN_SELF]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF], []) # _LT_COMPILER_C_O([TAGNAME]) # --------------------------- # Check to see if options -c and -o are simultaneously supported by compiler. # This macro does not hard code the compiler like AC_PROG_CC_C_O. m4_defun([_LT_COMPILER_C_O], [m4_require([_LT_DECL_SED])dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_TAG_COMPILER])dnl AC_CACHE_CHECK([if $compiler supports -c -o file.$ac_objext], [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)], [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=no $RM -r conftest 2>/dev/null mkdir conftest cd conftest mkdir out echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-o out/conftest2.$ac_objext" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&AS_MESSAGE_LOG_FD echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then _LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes fi fi chmod u+w . 2>&AS_MESSAGE_LOG_FD $RM conftest* # SGI C++ compiler will create directory out/ii_files/ for # template instantiation test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files $RM out/* && rmdir out cd .. $RM -r conftest $RM conftest* ]) _LT_TAGDECL([compiler_c_o], [lt_cv_prog_compiler_c_o], [1], [Does compiler simultaneously support -c and -o options?]) ])# _LT_COMPILER_C_O # _LT_COMPILER_FILE_LOCKS([TAGNAME]) # ---------------------------------- # Check to see if we can do hard links to lock some files if needed m4_defun([_LT_COMPILER_FILE_LOCKS], [m4_require([_LT_ENABLE_LOCK])dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl _LT_COMPILER_C_O([$1]) hard_links="nottested" if test "$_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)" = no && test "$need_locks" != no; then # do not overwrite the value of need_locks provided by the user AC_MSG_CHECKING([if we can lock with hard links]) hard_links=yes $RM conftest* ln conftest.a conftest.b 2>/dev/null && hard_links=no touch conftest.a ln conftest.a conftest.b 2>&5 || hard_links=no ln conftest.a conftest.b 2>/dev/null && hard_links=no AC_MSG_RESULT([$hard_links]) if test "$hard_links" = no; then AC_MSG_WARN([`$CC' does not support `-c -o', so `make -j' may be unsafe]) need_locks=warn fi else need_locks=no fi _LT_DECL([], [need_locks], [1], [Must we lock files when doing compilation?]) ])# _LT_COMPILER_FILE_LOCKS # _LT_CHECK_OBJDIR # ---------------- m4_defun([_LT_CHECK_OBJDIR], [AC_CACHE_CHECK([for objdir], [lt_cv_objdir], [rm -f .libs 2>/dev/null mkdir .libs 2>/dev/null if test -d .libs; then lt_cv_objdir=.libs else # MS-DOS does not allow filenames that begin with a dot. lt_cv_objdir=_libs fi rmdir .libs 2>/dev/null]) objdir=$lt_cv_objdir _LT_DECL([], [objdir], [0], [The name of the directory that contains temporary libtool files])dnl m4_pattern_allow([LT_OBJDIR])dnl AC_DEFINE_UNQUOTED(LT_OBJDIR, "$lt_cv_objdir/", [Define to the sub-directory in which libtool stores uninstalled libraries.]) ])# _LT_CHECK_OBJDIR # _LT_LINKER_HARDCODE_LIBPATH([TAGNAME]) # -------------------------------------- # Check hardcoding attributes. m4_defun([_LT_LINKER_HARDCODE_LIBPATH], [AC_MSG_CHECKING([how to hardcode library paths into programs]) _LT_TAGVAR(hardcode_action, $1)= if test -n "$_LT_TAGVAR(hardcode_libdir_flag_spec, $1)" || test -n "$_LT_TAGVAR(runpath_var, $1)" || test "X$_LT_TAGVAR(hardcode_automatic, $1)" = "Xyes" ; then # We can hardcode non-existent directories. if test "$_LT_TAGVAR(hardcode_direct, $1)" != no && # If the only mechanism to avoid hardcoding is shlibpath_var, we # have to relink, otherwise we might link with an installed library # when we should be linking with a yet-to-be-installed one ## test "$_LT_TAGVAR(hardcode_shlibpath_var, $1)" != no && test "$_LT_TAGVAR(hardcode_minus_L, $1)" != no; then # Linking always hardcodes the temporary library directory. _LT_TAGVAR(hardcode_action, $1)=relink else # We can link without hardcoding, and we can hardcode nonexisting dirs. _LT_TAGVAR(hardcode_action, $1)=immediate fi else # We cannot hardcode anything, or else we can only hardcode existing # directories. _LT_TAGVAR(hardcode_action, $1)=unsupported fi AC_MSG_RESULT([$_LT_TAGVAR(hardcode_action, $1)]) if test "$_LT_TAGVAR(hardcode_action, $1)" = relink || test "$_LT_TAGVAR(inherit_rpath, $1)" = yes; then # Fast installation is not supported enable_fast_install=no elif test "$shlibpath_overrides_runpath" = yes || test "$enable_shared" = no; then # Fast installation is not necessary enable_fast_install=needless fi _LT_TAGDECL([], [hardcode_action], [0], [How to hardcode a shared library path into an executable]) ])# _LT_LINKER_HARDCODE_LIBPATH # _LT_CMD_STRIPLIB # ---------------- m4_defun([_LT_CMD_STRIPLIB], [m4_require([_LT_DECL_EGREP]) striplib= old_striplib= AC_MSG_CHECKING([whether stripping libraries is possible]) if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" test -z "$striplib" && striplib="$STRIP --strip-unneeded" AC_MSG_RESULT([yes]) else # FIXME - insert some real tests, host_os isn't really good enough case $host_os in darwin*) if test -n "$STRIP" ; then striplib="$STRIP -x" old_striplib="$STRIP -S" AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) fi ;; *) AC_MSG_RESULT([no]) ;; esac fi _LT_DECL([], [old_striplib], [1], [Commands to strip libraries]) _LT_DECL([], [striplib], [1]) ])# _LT_CMD_STRIPLIB # _LT_SYS_DYNAMIC_LINKER([TAG]) # ----------------------------- # PORTME Fill in your ld.so characteristics m4_defun([_LT_SYS_DYNAMIC_LINKER], [AC_REQUIRE([AC_CANONICAL_HOST])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_OBJDUMP])dnl m4_require([_LT_DECL_SED])dnl m4_require([_LT_CHECK_SHELL_FEATURES])dnl AC_MSG_CHECKING([dynamic linker characteristics]) m4_if([$1], [], [ if test "$GCC" = yes; then case $host_os in darwin*) lt_awk_arg="/^libraries:/,/LR/" ;; *) lt_awk_arg="/^libraries:/" ;; esac case $host_os in mingw* | cegcc*) lt_sed_strip_eq="s,=\([[A-Za-z]]:\),\1,g" ;; *) lt_sed_strip_eq="s,=/,/,g" ;; esac lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq` case $lt_search_path_spec in *\;*) # if the path contains ";" then we assume it to be the separator # otherwise default to the standard path separator (i.e. ":") - it is # assumed that no part of a normal pathname contains ";" but that should # okay in the real world where ";" in dirpaths is itself problematic. lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'` ;; *) lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"` ;; esac # Ok, now we have the path, separated by spaces, we can step through it # and add multilib dir if necessary. lt_tmp_lt_search_path_spec= lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` for lt_sys_path in $lt_search_path_spec; do if test -d "$lt_sys_path/$lt_multi_os_dir"; then lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir" else test -d "$lt_sys_path" && \ lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" fi done lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk ' BEGIN {RS=" "; FS="/|\n";} { lt_foo=""; lt_count=0; for (lt_i = NF; lt_i > 0; lt_i--) { if ($lt_i != "" && $lt_i != ".") { if ($lt_i == "..") { lt_count++; } else { if (lt_count == 0) { lt_foo="/" $lt_i lt_foo; } else { lt_count--; } } } } if (lt_foo != "") { lt_freq[[lt_foo]]++; } if (lt_freq[[lt_foo]] == 1) { print lt_foo; } }'` # AWK program above erroneously prepends '/' to C:/dos/paths # for these hosts. case $host_os in mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ $SED 's,/\([[A-Za-z]]:\),\1,g'` ;; esac sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP` else sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" fi]) library_names_spec= libname_spec='lib$name' soname_spec= shrext_cmds=".so" postinstall_cmds= postuninstall_cmds= finish_cmds= finish_eval= shlibpath_var= shlibpath_overrides_runpath=unknown version_type=none dynamic_linker="$host_os ld.so" sys_lib_dlsearch_path_spec="/lib /usr/lib" need_lib_prefix=unknown hardcode_into_libs=no # when you set need_version to no, make sure it does not cause -set_version # flags to be left without arguments need_version=unknown case $host_os in aix3*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' shlibpath_var=LIBPATH # AIX 3 has no versioning support, so we append a major version to the name. soname_spec='${libname}${release}${shared_ext}$major' ;; aix[[4-9]]*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no hardcode_into_libs=yes if test "$host_cpu" = ia64; then # AIX 5 supports IA64 library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH else # With GCC up to 2.95.x, collect2 would create an import file # for dependence libraries. The import file would start with # the line `#! .'. This would cause the generated library to # depend on `.', always an invalid library. This was fixed in # development snapshots of GCC prior to 3.0. case $host_os in aix4 | aix4.[[01]] | aix4.[[01]].*) if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' echo ' yes ' echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then : else can_build_shared=no fi ;; esac # AIX (on Power*) has no versioning support, so currently we can not hardcode correct # soname into executable. Probably we can add versioning support to # collect2, so additional links can be useful in future. if test "$aix_use_runtimelinking" = yes; then # If using run time linking (on AIX 4.2 or later) use lib<name>.so # instead of lib<name>.a to let people know that these are not # typical AIX shared libraries. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' else # We preserve .a as extension for shared libraries through AIX4.2 # and later when we are not doing run time linking. library_names_spec='${libname}${release}.a $libname.a' soname_spec='${libname}${release}${shared_ext}$major' fi shlibpath_var=LIBPATH fi ;; amigaos*) case $host_cpu in powerpc) # Since July 2007 AmigaOS4 officially supports .so libraries. # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ;; m68k) library_names_spec='$libname.ixlibrary $libname.a' # Create ${libname}_ixlibrary.a entries in /sys/libs. finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' ;; esac ;; beos*) library_names_spec='${libname}${shared_ext}' dynamic_linker="$host_os ld.so" shlibpath_var=LIBRARY_PATH ;; bsdi[[45]]*) version_type=linux # correct to gnu/linux during the next big refactor need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" # the default ld.so.conf also contains /usr/contrib/lib and # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow # libtool to hard-code these into programs ;; cygwin* | mingw* | pw32* | cegcc*) version_type=windows shrext_cmds=".dll" need_version=no need_lib_prefix=no case $GCC,$cc_basename in yes,*) # gcc library_names_spec='$libname.dll.a' # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \${file}`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname~ chmod a+x \$dldir/$dlname~ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; fi' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' shlibpath_overrides_runpath=yes case $host_os in cygwin*) # Cygwin DLLs use 'cyg' prefix rather than 'lib' soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' m4_if([$1], [],[ sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api"]) ;; mingw* | cegcc*) # MinGW DLLs use traditional 'lib' prefix soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' ;; pw32*) # pw32 DLLs use 'pw' prefix rather than 'lib' library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' ;; esac dynamic_linker='Win32 ld.exe' ;; *,cl*) # Native MSVC libname_spec='$name' soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' library_names_spec='${libname}.dll.lib' case $build_os in mingw*) sys_lib_search_path_spec= lt_save_ifs=$IFS IFS=';' for lt_path in $LIB do IFS=$lt_save_ifs # Let DOS variable expansion print the short 8.3 style file name. lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" done IFS=$lt_save_ifs # Convert to MSYS style. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([[a-zA-Z]]\\):| /\\1|g' -e 's|^ ||'` ;; cygwin*) # Convert to unix form, then to dos form, then back to unix form # but this time dos style (no spaces!) so that the unix form looks # like /cygdrive/c/PROGRA~1:/cygdr... sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` ;; *) sys_lib_search_path_spec="$LIB" if $ECHO "$sys_lib_search_path_spec" | [$GREP ';[c-zC-Z]:/' >/dev/null]; then # It is most probably a Windows format PATH. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` else sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` fi # FIXME: find the short name or the path components, as spaces are # common. (e.g. "Program Files" -> "PROGRA~1") ;; esac # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \${file}`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' shlibpath_overrides_runpath=yes dynamic_linker='Win32 link.exe' ;; *) # Assume MSVC wrapper library_names_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext} $libname.lib' dynamic_linker='Win32 ld.exe' ;; esac # FIXME: first we should search . and the directory the executable is in shlibpath_var=PATH ;; darwin* | rhapsody*) dynamic_linker="$host_os dyld" version_type=darwin need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext' soname_spec='${libname}${release}${major}$shared_ext' shlibpath_overrides_runpath=yes shlibpath_var=DYLD_LIBRARY_PATH shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' m4_if([$1], [],[ sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib"]) sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' ;; dgux*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH ;; freebsd* | dragonfly*) # DragonFly does not have aout. When/if they implement a new # versioning mechanism, adjust this. if test -x /usr/bin/objformat; then objformat=`/usr/bin/objformat` else case $host_os in freebsd[[23]].*) objformat=aout ;; *) objformat=elf ;; esac fi version_type=freebsd-$objformat case $version_type in freebsd-elf*) library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' need_version=no need_lib_prefix=no ;; freebsd-*) library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' need_version=yes ;; esac shlibpath_var=LD_LIBRARY_PATH case $host_os in freebsd2.*) shlibpath_overrides_runpath=yes ;; freebsd3.[[01]]* | freebsdelf3.[[01]]*) shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; freebsd3.[[2-9]]* | freebsdelf3.[[2-9]]* | \ freebsd4.[[0-5]] | freebsdelf4.[[0-5]] | freebsd4.1.1 | freebsdelf4.1.1) shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; *) # from 4.6 on, and DragonFly shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; esac ;; haiku*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no dynamic_linker="$host_os runtime_loader" library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LIBRARY_PATH shlibpath_overrides_runpath=yes sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' hardcode_into_libs=yes ;; hpux9* | hpux10* | hpux11*) # Give a soname corresponding to the major version so that dld.sl refuses to # link against other versions. version_type=sunos need_lib_prefix=no need_version=no case $host_cpu in ia64*) shrext_cmds='.so' hardcode_into_libs=yes dynamic_linker="$host_os dld.so" shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' if test "X$HPUX_IA64_MODE" = X32; then sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" else sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" fi sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; hppa*64*) shrext_cmds='.sl' hardcode_into_libs=yes dynamic_linker="$host_os dld.sl" shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; *) shrext_cmds='.sl' dynamic_linker="$host_os dld.sl" shlibpath_var=SHLIB_PATH shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' ;; esac # HP-UX runs *really* slowly unless shared libraries are mode 555, ... postinstall_cmds='chmod 555 $lib' # or fails outright, so override atomically: install_override_mode=555 ;; interix[[3-9]]*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; irix5* | irix6* | nonstopux*) case $host_os in nonstopux*) version_type=nonstopux ;; *) if test "$lt_cv_prog_gnu_ld" = yes; then version_type=linux # correct to gnu/linux during the next big refactor else version_type=irix fi ;; esac need_lib_prefix=no need_version=no soname_spec='${libname}${release}${shared_ext}$major' library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' case $host_os in irix5* | nonstopux*) libsuff= shlibsuff= ;; *) case $LD in # libtool.m4 will add one of these switches to LD *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") libsuff= shlibsuff= libmagic=32-bit;; *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") libsuff=32 shlibsuff=N32 libmagic=N32;; *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") libsuff=64 shlibsuff=64 libmagic=64-bit;; *) libsuff= shlibsuff= libmagic=never-match;; esac ;; esac shlibpath_var=LD_LIBRARY${shlibsuff}_PATH shlibpath_overrides_runpath=no sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" hardcode_into_libs=yes ;; # No shared lib support for Linux oldld, aout, or coff. linux*oldld* | linux*aout* | linux*coff*) dynamic_linker=no ;; # This must be glibc/ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no # Some binutils ld are patched to set DT_RUNPATH AC_CACHE_VAL([lt_cv_shlibpath_overrides_runpath], [lt_cv_shlibpath_overrides_runpath=no save_LDFLAGS=$LDFLAGS save_libdir=$libdir eval "libdir=/foo; wl=\"$_LT_TAGVAR(lt_prog_compiler_wl, $1)\"; \ LDFLAGS=\"\$LDFLAGS $_LT_TAGVAR(hardcode_libdir_flag_spec, $1)\"" AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], [AS_IF([ ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null], [lt_cv_shlibpath_overrides_runpath=yes])]) LDFLAGS=$save_LDFLAGS libdir=$save_libdir ]) shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath # This implies no fast_install, which is unacceptable. # Some rework will be needed to allow for fast_install # before this can be enabled. hardcode_into_libs=yes # Append ld.so.conf contents to the search path if test -f /etc/ld.so.conf; then lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" fi # We used to test for /lib/ld.so.1 and disable shared libraries on # powerpc, because MkLinux only supported shared libraries with the # GNU dynamic linker. Since this was broken with cross compilers, # most powerpc-linux boxes support dynamic linking these days and # people can always --disable-shared, the test was removed, and we # assume the GNU/Linux dynamic linker is in use. dynamic_linker='GNU/Linux ld.so' ;; netbsdelf*-gnu) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='NetBSD ld.elf_so' ;; netbsd*) # ts B51007 : changed version_type for lt_main.sh from "sunos" to "netbsd" version_type=netbsd need_lib_prefix=no need_version=no if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' dynamic_linker='NetBSD (a.out) ld.so' else library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' dynamic_linker='NetBSD ld.elf_so' fi shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; newsos6) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes ;; *nto* | *qnx*) version_type=qnx need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='ldqnx.so' ;; openbsd*) version_type=sunos sys_lib_dlsearch_path_spec="/usr/lib" need_lib_prefix=no # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. case $host_os in openbsd3.3 | openbsd3.3.*) need_version=yes ;; *) need_version=no ;; esac library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' shlibpath_var=LD_LIBRARY_PATH if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then case $host_os in openbsd2.[[89]] | openbsd2.[[89]].*) shlibpath_overrides_runpath=no ;; *) shlibpath_overrides_runpath=yes ;; esac else shlibpath_overrides_runpath=yes fi ;; os2*) libname_spec='$name' shrext_cmds=".dll" need_lib_prefix=no library_names_spec='$libname${shared_ext} $libname.a' dynamic_linker='OS/2 ld.exe' shlibpath_var=LIBPATH ;; osf3* | osf4* | osf5*) version_type=osf need_lib_prefix=no need_version=no soname_spec='${libname}${release}${shared_ext}$major' library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" ;; rdos*) dynamic_linker=no ;; solaris*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes # ldd complains unless libraries are executable postinstall_cmds='chmod +x $lib' ;; sunos4*) version_type=sunos library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes if test "$with_gnu_ld" = yes; then need_lib_prefix=no fi need_version=yes ;; sysv4 | sysv4.3*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH case $host_vendor in sni) shlibpath_overrides_runpath=no need_lib_prefix=no runpath_var=LD_RUN_PATH ;; siemens) need_lib_prefix=no ;; motorola) need_lib_prefix=no need_version=no shlibpath_overrides_runpath=no sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' ;; esac ;; sysv4*MP*) if test -d /usr/nec ;then version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' soname_spec='$libname${shared_ext}.$major' shlibpath_var=LD_LIBRARY_PATH fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) version_type=freebsd-elf need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes if test "$with_gnu_ld" = yes; then sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' else sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' case $host_os in sco3.2v5*) sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" ;; esac fi sys_lib_dlsearch_path_spec='/usr/lib' ;; tpf*) # TPF is a cross-target only. Preferred cross-host = GNU/Linux. version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; uts4*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH ;; *) dynamic_linker=no ;; esac AC_MSG_RESULT([$dynamic_linker]) test "$dynamic_linker" = no && can_build_shared=no variables_saved_for_relink="PATH $shlibpath_var $runpath_var" if test "$GCC" = yes; then variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" fi if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec" fi if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec" fi _LT_DECL([], [variables_saved_for_relink], [1], [Variables whose values should be saved in libtool wrapper scripts and restored at link time]) _LT_DECL([], [need_lib_prefix], [0], [Do we need the "lib" prefix for modules?]) _LT_DECL([], [need_version], [0], [Do we need a version for libraries?]) _LT_DECL([], [version_type], [0], [Library versioning type]) _LT_DECL([], [runpath_var], [0], [Shared library runtime path variable]) _LT_DECL([], [shlibpath_var], [0],[Shared library path variable]) _LT_DECL([], [shlibpath_overrides_runpath], [0], [Is shlibpath searched before the hard-coded library search path?]) _LT_DECL([], [libname_spec], [1], [Format of library name prefix]) _LT_DECL([], [library_names_spec], [1], [[List of archive names. First name is the real one, the rest are links. The last name is the one that the linker finds with -lNAME]]) _LT_DECL([], [soname_spec], [1], [[The coded name of the library, if different from the real name]]) _LT_DECL([], [install_override_mode], [1], [Permission mode override for installation of shared libraries]) _LT_DECL([], [postinstall_cmds], [2], [Command to use after installation of a shared archive]) _LT_DECL([], [postuninstall_cmds], [2], [Command to use after uninstallation of a shared archive]) _LT_DECL([], [finish_cmds], [2], [Commands used to finish a libtool library installation in a directory]) _LT_DECL([], [finish_eval], [1], [[As "finish_cmds", except a single script fragment to be evaled but not shown]]) _LT_DECL([], [hardcode_into_libs], [0], [Whether we should hardcode library paths into libraries]) _LT_DECL([], [sys_lib_search_path_spec], [2], [Compile-time system search path for libraries]) _LT_DECL([], [sys_lib_dlsearch_path_spec], [2], [Run-time system search path for libraries]) ])# _LT_SYS_DYNAMIC_LINKER # _LT_PATH_TOOL_PREFIX(TOOL) # -------------------------- # find a file program which can recognize shared library AC_DEFUN([_LT_PATH_TOOL_PREFIX], [m4_require([_LT_DECL_EGREP])dnl AC_MSG_CHECKING([for $1]) AC_CACHE_VAL(lt_cv_path_MAGIC_CMD, [case $MAGIC_CMD in [[\\/*] | ?:[\\/]*]) lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. ;; *) lt_save_MAGIC_CMD="$MAGIC_CMD" lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR dnl $ac_dummy forces splitting on constant user-supplied paths. dnl POSIX.2 word splitting is done only on the output of word expansions, dnl not every word. This closes a longstanding sh security hole. ac_dummy="m4_if([$2], , $PATH, [$2])" for ac_dir in $ac_dummy; do IFS="$lt_save_ifs" test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$1; then lt_cv_path_MAGIC_CMD="$ac_dir/$1" if test -n "$file_magic_test_file"; then case $deplibs_check_method in "file_magic "*) file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` MAGIC_CMD="$lt_cv_path_MAGIC_CMD" if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | $EGREP "$file_magic_regex" > /dev/null; then : else cat <<_LT_EOF 1>&2 *** Warning: the command libtool uses to detect shared libraries, *** $file_magic_cmd, produces output that libtool cannot recognize. *** The result is that libtool may fail to recognize shared libraries *** as such. This will affect the creation of libtool libraries that *** depend on shared libraries, but programs linked with such libtool *** libraries will work regardless of this problem. Nevertheless, you *** may want to report the problem to your system manager and/or to *** bug-libtool@gnu.org _LT_EOF fi ;; esac fi break fi done IFS="$lt_save_ifs" MAGIC_CMD="$lt_save_MAGIC_CMD" ;; esac]) MAGIC_CMD="$lt_cv_path_MAGIC_CMD" if test -n "$MAGIC_CMD"; then AC_MSG_RESULT($MAGIC_CMD) else AC_MSG_RESULT(no) fi _LT_DECL([], [MAGIC_CMD], [0], [Used to examine libraries when file_magic_cmd begins with "file"])dnl ])# _LT_PATH_TOOL_PREFIX # Old name: AU_ALIAS([AC_PATH_TOOL_PREFIX], [_LT_PATH_TOOL_PREFIX]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_PATH_TOOL_PREFIX], []) # _LT_PATH_MAGIC # -------------- # find a file program which can recognize a shared library m4_defun([_LT_PATH_MAGIC], [_LT_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin$PATH_SEPARATOR$PATH) if test -z "$lt_cv_path_MAGIC_CMD"; then if test -n "$ac_tool_prefix"; then _LT_PATH_TOOL_PREFIX(file, /usr/bin$PATH_SEPARATOR$PATH) else MAGIC_CMD=: fi fi ])# _LT_PATH_MAGIC # LT_PATH_LD # ---------- # find the pathname to the GNU or non-GNU linker AC_DEFUN([LT_PATH_LD], [AC_REQUIRE([AC_PROG_CC])dnl AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_REQUIRE([AC_CANONICAL_BUILD])dnl m4_require([_LT_DECL_SED])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_PROG_ECHO_BACKSLASH])dnl AC_ARG_WITH([gnu-ld], [AS_HELP_STRING([--with-gnu-ld], [assume the C compiler uses GNU ld @<:@default=no@:>@])], [test "$withval" = no || with_gnu_ld=yes], [with_gnu_ld=no])dnl ac_prog=ld if test "$GCC" = yes; then # Check if gcc -print-prog-name=ld gives a path. AC_MSG_CHECKING([for ld used by $CC]) case $host in *-*-mingw*) # gcc leaves a trailing carriage return which upsets mingw ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; *) ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; esac case $ac_prog in # Accept absolute paths. [[\\/]]* | ?:[[\\/]]*) re_direlt='/[[^/]][[^/]]*/\.\./' # Canonicalize the pathname of ld ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` done test -z "$LD" && LD="$ac_prog" ;; "") # If it fails, then pretend we aren't using GCC. ac_prog=ld ;; *) # If it is relative, then search for the first ld in PATH. with_gnu_ld=unknown ;; esac elif test "$with_gnu_ld" = yes; then AC_MSG_CHECKING([for GNU ld]) else AC_MSG_CHECKING([for non-GNU ld]) fi AC_CACHE_VAL(lt_cv_path_LD, [if test -z "$LD"; then lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR for ac_dir in $PATH; do IFS="$lt_save_ifs" test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then lt_cv_path_LD="$ac_dir/$ac_prog" # Check to see if the program is GNU ld. I'd rather use --version, # but apparently some variants of GNU ld only accept -v. # Break only if it was the GNU/non-GNU ld that we prefer. case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in *GNU* | *'with BFD'*) test "$with_gnu_ld" != no && break ;; *) test "$with_gnu_ld" != yes && break ;; esac fi done IFS="$lt_save_ifs" else lt_cv_path_LD="$LD" # Let the user override the test with a path. fi]) LD="$lt_cv_path_LD" if test -n "$LD"; then AC_MSG_RESULT($LD) else AC_MSG_RESULT(no) fi test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in \$PATH]) _LT_PATH_LD_GNU AC_SUBST([LD]) _LT_TAGDECL([], [LD], [1], [The linker used to build libraries]) ])# LT_PATH_LD # Old names: AU_ALIAS([AM_PROG_LD], [LT_PATH_LD]) AU_ALIAS([AC_PROG_LD], [LT_PATH_LD]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AM_PROG_LD], []) dnl AC_DEFUN([AC_PROG_LD], []) # _LT_PATH_LD_GNU #- -------------- m4_defun([_LT_PATH_LD_GNU], [AC_CACHE_CHECK([if the linker ($LD) is GNU ld], lt_cv_prog_gnu_ld, [# I'd rather use --version here, but apparently some GNU lds only accept -v. case `$LD -v 2>&1 </dev/null` in *GNU* | *'with BFD'*) lt_cv_prog_gnu_ld=yes ;; *) lt_cv_prog_gnu_ld=no ;; esac]) with_gnu_ld=$lt_cv_prog_gnu_ld ])# _LT_PATH_LD_GNU # _LT_CMD_RELOAD # -------------- # find reload flag for linker # -- PORTME Some linkers may need a different reload flag. m4_defun([_LT_CMD_RELOAD], [AC_CACHE_CHECK([for $LD option to reload object files], lt_cv_ld_reload_flag, [lt_cv_ld_reload_flag='-r']) reload_flag=$lt_cv_ld_reload_flag case $reload_flag in "" | " "*) ;; *) reload_flag=" $reload_flag" ;; esac reload_cmds='$LD$reload_flag -o $output$reload_objs' case $host_os in cygwin* | mingw* | pw32* | cegcc*) if test "$GCC" != yes; then reload_cmds=false fi ;; darwin*) if test "$GCC" = yes; then reload_cmds='$LTCC $LTCFLAGS -nostdlib ${wl}-r -o $output$reload_objs' else reload_cmds='$LD$reload_flag -o $output$reload_objs' fi ;; esac _LT_TAGDECL([], [reload_flag], [1], [How to create reloadable object files])dnl _LT_TAGDECL([], [reload_cmds], [2])dnl ])# _LT_CMD_RELOAD # _LT_CHECK_MAGIC_METHOD # ---------------------- # how to check for library dependencies # -- PORTME fill in with the dynamic library characteristics m4_defun([_LT_CHECK_MAGIC_METHOD], [m4_require([_LT_DECL_EGREP]) m4_require([_LT_DECL_OBJDUMP]) AC_CACHE_CHECK([how to recognize dependent libraries], lt_cv_deplibs_check_method, [lt_cv_file_magic_cmd='$MAGIC_CMD' lt_cv_file_magic_test_file= lt_cv_deplibs_check_method='unknown' # Need to set the preceding variable on all platforms that support # interlibrary dependencies. # 'none' -- dependencies not supported. # `unknown' -- same as none, but documents that we really don't know. # 'pass_all' -- all dependencies passed with no checks. # 'test_compile' -- check by making test program. # 'file_magic [[regex]]' -- check by looking for files in library path # which responds to the $file_magic_cmd with a given extended regex. # If you have `file' or equivalent on your system and you're not sure # whether `pass_all' will *always* work, you probably want this one. case $host_os in aix[[4-9]]*) lt_cv_deplibs_check_method=pass_all ;; beos*) lt_cv_deplibs_check_method=pass_all ;; bsdi[[45]]*) lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib)' lt_cv_file_magic_cmd='/usr/bin/file -L' lt_cv_file_magic_test_file=/shlib/libc.so ;; cygwin*) # func_win32_libid is a shell function defined in ltmain.sh lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' lt_cv_file_magic_cmd='func_win32_libid' ;; mingw* | pw32*) # Base MSYS/MinGW do not provide the 'file' command needed by # func_win32_libid shell function, so use a weaker test based on 'objdump', # unless we find 'file', for example because we are cross-compiling. # func_win32_libid assumes BSD nm, so disallow it if using MS dumpbin. if ( test "$lt_cv_nm_interface" = "BSD nm" && file / ) >/dev/null 2>&1; then lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' lt_cv_file_magic_cmd='func_win32_libid' else # Keep this pattern in sync with the one in func_win32_libid. lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' lt_cv_file_magic_cmd='$OBJDUMP -f' fi ;; cegcc*) # use the weaker test based on 'objdump'. See mingw*. lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' lt_cv_file_magic_cmd='$OBJDUMP -f' ;; darwin* | rhapsody*) lt_cv_deplibs_check_method=pass_all ;; freebsd* | dragonfly*) if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then case $host_cpu in i*86 ) # Not sure whether the presence of OpenBSD here was a mistake. # Let's accept both of them until this is cleared up. lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[[3-9]]86 (compact )?demand paged shared library' lt_cv_file_magic_cmd=/usr/bin/file lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` ;; esac else lt_cv_deplibs_check_method=pass_all fi ;; haiku*) lt_cv_deplibs_check_method=pass_all ;; hpux10.20* | hpux11*) lt_cv_file_magic_cmd=/usr/bin/file case $host_cpu in ia64*) lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|ELF-[[0-9]][[0-9]]) shared object file - IA64' lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so ;; hppa*64*) [lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]'] lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl ;; *) lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|PA-RISC[[0-9]]\.[[0-9]]) shared library' lt_cv_file_magic_test_file=/usr/lib/libc.sl ;; esac ;; interix[[3-9]]*) # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|\.a)$' ;; irix5* | irix6* | nonstopux*) case $LD in *-32|*"-32 ") libmagic=32-bit;; *-n32|*"-n32 ") libmagic=N32;; *-64|*"-64 ") libmagic=64-bit;; *) libmagic=never-match;; esac lt_cv_deplibs_check_method=pass_all ;; # This must be glibc/ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) lt_cv_deplibs_check_method=pass_all ;; netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' else lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|_pic\.a)$' fi ;; newos6*) lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (executable|dynamic lib)' lt_cv_file_magic_cmd=/usr/bin/file lt_cv_file_magic_test_file=/usr/lib/libnls.so ;; *nto* | *qnx*) lt_cv_deplibs_check_method=pass_all ;; openbsd*) if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|\.so|_pic\.a)$' else lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' fi ;; osf3* | osf4* | osf5*) lt_cv_deplibs_check_method=pass_all ;; rdos*) lt_cv_deplibs_check_method=pass_all ;; solaris*) lt_cv_deplibs_check_method=pass_all ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) lt_cv_deplibs_check_method=pass_all ;; sysv4 | sysv4.3*) case $host_vendor in motorola) lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib) M[[0-9]][[0-9]]* Version [[0-9]]' lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` ;; ncr) lt_cv_deplibs_check_method=pass_all ;; sequent) lt_cv_file_magic_cmd='/bin/file' lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )' ;; sni) lt_cv_file_magic_cmd='/bin/file' lt_cv_deplibs_check_method="file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB dynamic lib" lt_cv_file_magic_test_file=/lib/libc.so ;; siemens) lt_cv_deplibs_check_method=pass_all ;; pc) lt_cv_deplibs_check_method=pass_all ;; esac ;; tpf*) lt_cv_deplibs_check_method=pass_all ;; esac ]) file_magic_glob= want_nocaseglob=no if test "$build" = "$host"; then case $host_os in mingw* | pw32*) if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then want_nocaseglob=yes else file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[[\1]]\/[[\1]]\/g;/g"` fi ;; esac fi file_magic_cmd=$lt_cv_file_magic_cmd deplibs_check_method=$lt_cv_deplibs_check_method test -z "$deplibs_check_method" && deplibs_check_method=unknown _LT_DECL([], [deplibs_check_method], [1], [Method to check whether dependent libraries are shared objects]) _LT_DECL([], [file_magic_cmd], [1], [Command to use when deplibs_check_method = "file_magic"]) _LT_DECL([], [file_magic_glob], [1], [How to find potential files when deplibs_check_method = "file_magic"]) _LT_DECL([], [want_nocaseglob], [1], [Find potential files using nocaseglob when deplibs_check_method = "file_magic"]) ])# _LT_CHECK_MAGIC_METHOD # LT_PATH_NM # ---------- # find the pathname to a BSD- or MS-compatible name lister AC_DEFUN([LT_PATH_NM], [AC_REQUIRE([AC_PROG_CC])dnl AC_CACHE_CHECK([for BSD- or MS-compatible name lister (nm)], lt_cv_path_NM, [if test -n "$NM"; then # Let the user override the test. lt_cv_path_NM="$NM" else lt_nm_to_check="${ac_tool_prefix}nm" if test -n "$ac_tool_prefix" && test "$build" = "$host"; then lt_nm_to_check="$lt_nm_to_check nm" fi for lt_tmp_nm in $lt_nm_to_check; do lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do IFS="$lt_save_ifs" test -z "$ac_dir" && ac_dir=. tmp_nm="$ac_dir/$lt_tmp_nm" if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then # Check to see if the nm accepts a BSD-compat flag. # Adding the `sed 1q' prevents false positives on HP-UX, which says: # nm: unknown option "B" ignored # Tru64's nm complains that /dev/null is an invalid object file case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in */dev/null* | *'Invalid file or object type'*) lt_cv_path_NM="$tmp_nm -B" break ;; *) case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in */dev/null*) lt_cv_path_NM="$tmp_nm -p" break ;; *) lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but continue # so that we can try to find one that supports BSD flags ;; esac ;; esac fi done IFS="$lt_save_ifs" done : ${lt_cv_path_NM=no} fi]) if test "$lt_cv_path_NM" != "no"; then NM="$lt_cv_path_NM" else # Didn't find any BSD compatible name lister, look for dumpbin. if test -n "$DUMPBIN"; then : # Let the user override the test. else AC_CHECK_TOOLS(DUMPBIN, [dumpbin "link -dump"], :) case `$DUMPBIN -symbols /dev/null 2>&1 | sed '1q'` in *COFF*) DUMPBIN="$DUMPBIN -symbols" ;; *) DUMPBIN=: ;; esac fi AC_SUBST([DUMPBIN]) if test "$DUMPBIN" != ":"; then NM="$DUMPBIN" fi fi test -z "$NM" && NM=nm AC_SUBST([NM]) _LT_DECL([], [NM], [1], [A BSD- or MS-compatible name lister])dnl AC_CACHE_CHECK([the name lister ($NM) interface], [lt_cv_nm_interface], [lt_cv_nm_interface="BSD nm" echo "int some_variable = 0;" > conftest.$ac_ext (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&AS_MESSAGE_LOG_FD) (eval "$ac_compile" 2>conftest.err) cat conftest.err >&AS_MESSAGE_LOG_FD (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&AS_MESSAGE_LOG_FD) (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) cat conftest.err >&AS_MESSAGE_LOG_FD (eval echo "\"\$as_me:$LINENO: output\"" >&AS_MESSAGE_LOG_FD) cat conftest.out >&AS_MESSAGE_LOG_FD if $GREP 'External.*some_variable' conftest.out > /dev/null; then lt_cv_nm_interface="MS dumpbin" fi rm -f conftest*]) ])# LT_PATH_NM # Old names: AU_ALIAS([AM_PROG_NM], [LT_PATH_NM]) AU_ALIAS([AC_PROG_NM], [LT_PATH_NM]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AM_PROG_NM], []) dnl AC_DEFUN([AC_PROG_NM], []) # _LT_CHECK_SHAREDLIB_FROM_LINKLIB # -------------------------------- # how to determine the name of the shared library # associated with a specific link library. # -- PORTME fill in with the dynamic library characteristics m4_defun([_LT_CHECK_SHAREDLIB_FROM_LINKLIB], [m4_require([_LT_DECL_EGREP]) m4_require([_LT_DECL_OBJDUMP]) m4_require([_LT_DECL_DLLTOOL]) AC_CACHE_CHECK([how to associate runtime and link libraries], lt_cv_sharedlib_from_linklib_cmd, [lt_cv_sharedlib_from_linklib_cmd='unknown' case $host_os in cygwin* | mingw* | pw32* | cegcc*) # two different shell functions defined in ltmain.sh # decide which to use based on capabilities of $DLLTOOL case `$DLLTOOL --help 2>&1` in *--identify-strict*) lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib ;; *) lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback ;; esac ;; *) # fallback: assume linklib IS sharedlib lt_cv_sharedlib_from_linklib_cmd="$ECHO" ;; esac ]) sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO _LT_DECL([], [sharedlib_from_linklib_cmd], [1], [Command to associate shared and link libraries]) ])# _LT_CHECK_SHAREDLIB_FROM_LINKLIB # _LT_PATH_MANIFEST_TOOL # ---------------------- # locate the manifest tool m4_defun([_LT_PATH_MANIFEST_TOOL], [AC_CHECK_TOOL(MANIFEST_TOOL, mt, :) test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt AC_CACHE_CHECK([if $MANIFEST_TOOL is a manifest tool], [lt_cv_path_mainfest_tool], [lt_cv_path_mainfest_tool=no echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&AS_MESSAGE_LOG_FD $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out cat conftest.err >&AS_MESSAGE_LOG_FD if $GREP 'Manifest Tool' conftest.out > /dev/null; then lt_cv_path_mainfest_tool=yes fi rm -f conftest*]) if test "x$lt_cv_path_mainfest_tool" != xyes; then MANIFEST_TOOL=: fi _LT_DECL([], [MANIFEST_TOOL], [1], [Manifest tool])dnl ])# _LT_PATH_MANIFEST_TOOL # LT_LIB_M # -------- # check for math library AC_DEFUN([LT_LIB_M], [AC_REQUIRE([AC_CANONICAL_HOST])dnl LIBM= case $host in *-*-beos* | *-*-cegcc* | *-*-cygwin* | *-*-haiku* | *-*-pw32* | *-*-darwin*) # These system don't have libm, or don't need it ;; *-ncr-sysv4.3*) AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM="-lmw") AC_CHECK_LIB(m, cos, LIBM="$LIBM -lm") ;; *) AC_CHECK_LIB(m, cos, LIBM="-lm") ;; esac AC_SUBST([LIBM]) ])# LT_LIB_M # Old name: AU_ALIAS([AC_CHECK_LIBM], [LT_LIB_M]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_CHECK_LIBM], []) # _LT_COMPILER_NO_RTTI([TAGNAME]) # ------------------------------- m4_defun([_LT_COMPILER_NO_RTTI], [m4_require([_LT_TAG_COMPILER])dnl _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= if test "$GCC" = yes; then case $cc_basename in nvcc*) _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -Xcompiler -fno-builtin' ;; *) _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' ;; esac _LT_COMPILER_OPTION([if $compiler supports -fno-rtti -fno-exceptions], lt_cv_prog_compiler_rtti_exceptions, [-fno-rtti -fno-exceptions], [], [_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)="$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) -fno-rtti -fno-exceptions"]) fi _LT_TAGDECL([no_builtin_flag], [lt_prog_compiler_no_builtin_flag], [1], [Compiler flag to turn off builtin functions]) ])# _LT_COMPILER_NO_RTTI # _LT_CMD_GLOBAL_SYMBOLS # ---------------------- m4_defun([_LT_CMD_GLOBAL_SYMBOLS], [AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_REQUIRE([AC_PROG_CC])dnl AC_REQUIRE([AC_PROG_AWK])dnl AC_REQUIRE([LT_PATH_NM])dnl AC_REQUIRE([LT_PATH_LD])dnl m4_require([_LT_DECL_SED])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_TAG_COMPILER])dnl # Check for command to grab the raw symbol name followed by C symbol from nm. AC_MSG_CHECKING([command to parse $NM output from $compiler object]) AC_CACHE_VAL([lt_cv_sys_global_symbol_pipe], [ # These are sane defaults that work on at least a few old systems. # [They come from Ultrix. What could be older than Ultrix?!! ;)] # Character class describing NM global symbol codes. symcode='[[BCDEGRST]]' # Regexp to match symbols that can be accessed directly from C. sympat='\([[_A-Za-z]][[_A-Za-z0-9]]*\)' # Define system-specific variables. case $host_os in aix*) symcode='[[BCDT]]' ;; cygwin* | mingw* | pw32* | cegcc*) symcode='[[ABCDGISTW]]' ;; hpux*) if test "$host_cpu" = ia64; then symcode='[[ABCDEGRST]]' fi ;; irix* | nonstopux*) symcode='[[BCDEGRST]]' ;; osf*) symcode='[[BCDEGQRST]]' ;; solaris*) symcode='[[BDRT]]' ;; sco3.2v5*) symcode='[[DT]]' ;; sysv4.2uw2*) symcode='[[DT]]' ;; sysv5* | sco5v6* | unixware* | OpenUNIX*) symcode='[[ABDT]]' ;; sysv4) symcode='[[DFNSTU]]' ;; esac # If we're using GNU nm, then use its standard symbol codes. case `$NM -V 2>&1` in *GNU* | *'with BFD'*) symcode='[[ABCDGIRSTW]]' ;; esac # Transform an extracted symbol line into a proper C declaration. # Some systems (esp. on ia64) link data and code symbols differently, # so use this general approach. lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" # Transform an extracted symbol line into symbol name and symbol address lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\)[[ ]]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (void *) \&\2},/p'" lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([[^ ]]*\)[[ ]]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \(lib[[^ ]]*\)$/ {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"lib\2\", (void *) \&\2},/p'" # Handle CRLF in mingw tool chain opt_cr= case $build_os in mingw*) opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp ;; esac # Try without a prefix underscore, then with it. for ac_symprfx in "" "_"; do # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. symxfrm="\\1 $ac_symprfx\\2 \\2" # Write the raw and C identifiers. if test "$lt_cv_nm_interface" = "MS dumpbin"; then # Fake it for dumpbin and say T for any non-static function # and D for any global variable. # Also find C++ and __fastcall symbols from MSVC++, # which start with @ or ?. lt_cv_sys_global_symbol_pipe="$AWK ['"\ " {last_section=section; section=\$ 3};"\ " /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\ " /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ " \$ 0!~/External *\|/{next};"\ " / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ " {if(hide[section]) next};"\ " {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\ " {split(\$ 0, a, /\||\r/); split(a[2], s)};"\ " s[1]~/^[@?]/{print s[1], s[1]; next};"\ " s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\ " ' prfx=^$ac_symprfx]" else lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[ ]]\($symcode$symcode*\)[[ ]][[ ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" fi lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'" # Check to see that the pipe works correctly. pipe_works=no rm -f conftest* cat > conftest.$ac_ext <<_LT_EOF #ifdef __cplusplus extern "C" { #endif char nm_test_var; void nm_test_func(void); void nm_test_func(void){} #ifdef __cplusplus } #endif int main(){nm_test_var='a';nm_test_func();return(0);} _LT_EOF if AC_TRY_EVAL(ac_compile); then # Now try to grab the symbols. nlist=conftest.nm if AC_TRY_EVAL(NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) && test -s "$nlist"; then # Try sorting and uniquifying the output. if sort "$nlist" | uniq > "$nlist"T; then mv -f "$nlist"T "$nlist" else rm -f "$nlist"T fi # Make sure that we snagged all the symbols we need. if $GREP ' nm_test_var$' "$nlist" >/dev/null; then if $GREP ' nm_test_func$' "$nlist" >/dev/null; then cat <<_LT_EOF > conftest.$ac_ext /* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ #if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE) /* DATA imports from DLLs on WIN32 con't be const, because runtime relocations are performed -- see ld's documentation on pseudo-relocs. */ # define LT@&t@_DLSYM_CONST #elif defined(__osf__) /* This system does not cope well with relocations in const data. */ # define LT@&t@_DLSYM_CONST #else # define LT@&t@_DLSYM_CONST const #endif #ifdef __cplusplus extern "C" { #endif _LT_EOF # Now generate the symbol file. eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' cat <<_LT_EOF >> conftest.$ac_ext /* The mapping between symbol names and symbols. */ LT@&t@_DLSYM_CONST struct { const char *name; void *address; } lt__PROGRAM__LTX_preloaded_symbols[[]] = { { "@PROGRAM@", (void *) 0 }, _LT_EOF $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext cat <<\_LT_EOF >> conftest.$ac_ext {0, (void *) 0} }; /* This works around a problem in FreeBSD linker */ #ifdef FREEBSD_WORKAROUND static const void *lt_preloaded_setup() { return lt__PROGRAM__LTX_preloaded_symbols; } #endif #ifdef __cplusplus } #endif _LT_EOF # Now try linking the two files. mv conftest.$ac_objext conftstm.$ac_objext lt_globsym_save_LIBS=$LIBS lt_globsym_save_CFLAGS=$CFLAGS LIBS="conftstm.$ac_objext" CFLAGS="$CFLAGS$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)" if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext}; then pipe_works=yes fi LIBS=$lt_globsym_save_LIBS CFLAGS=$lt_globsym_save_CFLAGS else echo "cannot find nm_test_func in $nlist" >&AS_MESSAGE_LOG_FD fi else echo "cannot find nm_test_var in $nlist" >&AS_MESSAGE_LOG_FD fi else echo "cannot run $lt_cv_sys_global_symbol_pipe" >&AS_MESSAGE_LOG_FD fi else echo "$progname: failed program was:" >&AS_MESSAGE_LOG_FD cat conftest.$ac_ext >&5 fi rm -rf conftest* conftst* # Do not use the global_symbol_pipe unless it works. if test "$pipe_works" = yes; then break else lt_cv_sys_global_symbol_pipe= fi done ]) if test -z "$lt_cv_sys_global_symbol_pipe"; then lt_cv_sys_global_symbol_to_cdecl= fi if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then AC_MSG_RESULT(failed) else AC_MSG_RESULT(ok) fi # Response file support. if test "$lt_cv_nm_interface" = "MS dumpbin"; then nm_file_list_spec='@' elif $NM --help 2>/dev/null | grep '[[@]]FILE' >/dev/null; then nm_file_list_spec='@' fi _LT_DECL([global_symbol_pipe], [lt_cv_sys_global_symbol_pipe], [1], [Take the output of nm and produce a listing of raw symbols and C names]) _LT_DECL([global_symbol_to_cdecl], [lt_cv_sys_global_symbol_to_cdecl], [1], [Transform the output of nm in a proper C declaration]) _LT_DECL([global_symbol_to_c_name_address], [lt_cv_sys_global_symbol_to_c_name_address], [1], [Transform the output of nm in a C name address pair]) _LT_DECL([global_symbol_to_c_name_address_lib_prefix], [lt_cv_sys_global_symbol_to_c_name_address_lib_prefix], [1], [Transform the output of nm in a C name address pair when lib prefix is needed]) _LT_DECL([], [nm_file_list_spec], [1], [Specify filename containing input files for $NM]) ]) # _LT_CMD_GLOBAL_SYMBOLS # _LT_COMPILER_PIC([TAGNAME]) # --------------------------- m4_defun([_LT_COMPILER_PIC], [m4_require([_LT_TAG_COMPILER])dnl _LT_TAGVAR(lt_prog_compiler_wl, $1)= _LT_TAGVAR(lt_prog_compiler_pic, $1)= _LT_TAGVAR(lt_prog_compiler_static, $1)= m4_if([$1], [CXX], [ # C++ specific cases for pic, static, wl, etc. if test "$GXX" = yes; then _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' case $host_os in aix*) # All AIX code is PIC. if test "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; m68k) # FIXME: we need at least 68020 code to build shared libraries, but # adding the `-m68020' flag to GCC prevents building anything better, # like `-m68040'. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' ;; esac ;; beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) # PIC is the default for these OSes. ;; mingw* | cygwin* | os2* | pw32* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). # Although the cygwin gcc ignores -fPIC, still need this for old-style # (--disable-auto-import) libraries m4_if([$1], [GCJ], [], [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' ;; *djgpp*) # DJGPP does not support shared libraries at all _LT_TAGVAR(lt_prog_compiler_pic, $1)= ;; haiku*) # PIC is the default for Haiku. # The "-static" flag exists, but is broken. _LT_TAGVAR(lt_prog_compiler_static, $1)= ;; interix[[3-9]]*) # Interix 3.x gcc -fpic/-fPIC options generate broken code. # Instead, we relocate shared libraries at runtime. ;; sysv4*MP*) if test -d /usr/nec; then _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic fi ;; hpux*) # PIC is the default for 64-bit PA HP-UX, but not for 32-bit # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag # sets the default TLS model and affects inlining. case $host_cpu in hppa*64*) ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; esac ;; *qnx* | *nto*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; esac else case $host_os in aix[[4-9]]*) # All AIX code is PIC. if test "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' else _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' fi ;; chorus*) case $cc_basename in cxch68*) # Green Hills C++ Compiler # _LT_TAGVAR(lt_prog_compiler_static, $1)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a" ;; esac ;; mingw* | cygwin* | os2* | pw32* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). m4_if([$1], [GCJ], [], [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) ;; dgux*) case $cc_basename in ec++*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' ;; ghcx*) # Green Hills C++ Compiler _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' ;; *) ;; esac ;; freebsd* | dragonfly*) # FreeBSD uses GNU C++ ;; hpux9* | hpux10* | hpux11*) case $cc_basename in CC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' if test "$host_cpu" != ia64; then _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' fi ;; aCC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' case $host_cpu in hppa*64*|ia64*) # +Z the default ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' ;; esac ;; *) ;; esac ;; interix*) # This is c89, which is MS Visual C++ (no shared libs) # Anyone wants to do a port? ;; irix5* | irix6* | nonstopux*) case $cc_basename in CC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' # CC pic flag -KPIC is the default. ;; *) ;; esac ;; linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) case $cc_basename in KCC*) # KAI C++ Compiler _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; ecpc* ) # old Intel C++ for x86_64 which still supported -KPIC. _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; icpc* ) # Intel C++, used to be incompatible with GCC. # ICC 10 doesn't accept -KPIC any more. _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; pgCC* | pgcpp*) # Portland Group C++ compiler _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; cxx*) # Compaq C++ # Make sure the PIC flag is empty. It appears that all Alpha # Linux and Compaq Tru64 Unix objects are PIC. _LT_TAGVAR(lt_prog_compiler_pic, $1)= _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; xlc* | xlC* | bgxl[[cC]]* | mpixl[[cC]]*) # IBM XL 8.0, 9.0 on PPC and BlueGene _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' ;; *) case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C++ 5.9 _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' ;; esac ;; esac ;; lynxos*) ;; m88k*) ;; mvs*) case $cc_basename in cxx*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-W c,exportall' ;; *) ;; esac ;; netbsd* | netbsdelf*-gnu) ;; *qnx* | *nto*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' ;; osf3* | osf4* | osf5*) case $cc_basename in KCC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' ;; RCC*) # Rational C++ 2.4.1 _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' ;; cxx*) # Digital/Compaq C++ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # Make sure the PIC flag is empty. It appears that all Alpha # Linux and Compaq Tru64 Unix objects are PIC. _LT_TAGVAR(lt_prog_compiler_pic, $1)= _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; *) ;; esac ;; psos*) ;; solaris*) case $cc_basename in CC* | sunCC*) # Sun C++ 4.2, 5.x and Centerline C++ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' ;; gcx*) # Green Hills C++ Compiler _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' ;; *) ;; esac ;; sunos4*) case $cc_basename in CC*) # Sun C++ 4.x _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; lcc*) # Lucid _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' ;; *) ;; esac ;; sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) case $cc_basename in CC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; esac ;; tandem*) case $cc_basename in NCC*) # NonStop-UX NCC 3.20 _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' ;; *) ;; esac ;; vxworks*) ;; *) _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no ;; esac fi ], [ if test "$GCC" = yes; then _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' case $host_os in aix*) # All AIX code is PIC. if test "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; m68k) # FIXME: we need at least 68020 code to build shared libraries, but # adding the `-m68020' flag to GCC prevents building anything better, # like `-m68040'. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' ;; esac ;; beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) # PIC is the default for these OSes. ;; mingw* | cygwin* | pw32* | os2* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). # Although the cygwin gcc ignores -fPIC, still need this for old-style # (--disable-auto-import) libraries m4_if([$1], [GCJ], [], [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' ;; haiku*) # PIC is the default for Haiku. # The "-static" flag exists, but is broken. _LT_TAGVAR(lt_prog_compiler_static, $1)= ;; hpux*) # PIC is the default for 64-bit PA HP-UX, but not for 32-bit # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag # sets the default TLS model and affects inlining. case $host_cpu in hppa*64*) # +Z the default ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; esac ;; interix[[3-9]]*) # Interix 3.x gcc -fpic/-fPIC options generate broken code. # Instead, we relocate shared libraries at runtime. ;; msdosdjgpp*) # Just because we use GCC doesn't mean we suddenly get shared libraries # on systems that don't support them. _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no enable_shared=no ;; *nto* | *qnx*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' ;; sysv4*MP*) if test -d /usr/nec; then _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic fi ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; esac case $cc_basename in nvcc*) # Cuda Compiler Driver 2.2 _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Xlinker ' if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then _LT_TAGVAR(lt_prog_compiler_pic, $1)="-Xcompiler $_LT_TAGVAR(lt_prog_compiler_pic, $1)" fi ;; esac else # PORTME Check for flag to pass linker flags through the system compiler. case $host_os in aix*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' if test "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' else _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' fi ;; mingw* | cygwin* | pw32* | os2* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). m4_if([$1], [GCJ], [], [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) ;; hpux9* | hpux10* | hpux11*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but # not for PA HP-UX. case $host_cpu in hppa*64*|ia64*) # +Z the default ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' ;; esac # Is there a better lt_prog_compiler_static that works with the bundled CC? _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' ;; irix5* | irix6* | nonstopux*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # PIC (with -KPIC) is the default. _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) case $cc_basename in # old Intel for x86_64 which still supported -KPIC. ecc*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; # icc used to be incompatible with GCC. # ICC 10 doesn't accept -KPIC any more. icc* | ifort*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; # Lahey Fortran 8.1. lf95*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='--shared' _LT_TAGVAR(lt_prog_compiler_static, $1)='--static' ;; nagfor*) # NAG Fortran compiler _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,-Wl,,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) # Portland Group compilers (*not* the Pentium gcc compiler, # which looks to be a dead project) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; ccc*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # All Alpha code is PIC. _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; xl* | bgxl* | bgf* | mpixl*) # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' ;; *) case `$CC -V 2>&1 | sed 5q` in *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [[1-7]].* | *Sun*Fortran*\ 8.[[0-3]]*) # Sun Fortran 8.3 passes all unrecognized flags to the linker _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='' ;; *Sun\ F* | *Sun*Fortran*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' ;; *Sun\ C*) # Sun C 5.9 _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' ;; *Intel*\ [[CF]]*Compiler*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; *Portland\ Group*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; esac ;; esac ;; newsos6) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; *nto* | *qnx*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' ;; osf3* | osf4* | osf5*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # All OSF/1 code is PIC. _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; rdos*) _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; solaris*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' case $cc_basename in f77* | f90* | f95* | sunf77* | sunf90* | sunf95*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ';; *) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,';; esac ;; sunos4*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; sysv4 | sysv4.2uw2* | sysv4.3*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; sysv4*MP*) if test -d /usr/nec ;then _LT_TAGVAR(lt_prog_compiler_pic, $1)='-Kconform_pic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' fi ;; sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; unicos*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no ;; uts4*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; *) _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no ;; esac fi ]) case $host_os in # For platforms which do not support PIC, -DPIC is meaningless: *djgpp*) _LT_TAGVAR(lt_prog_compiler_pic, $1)= ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)="$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])" ;; esac AC_CACHE_CHECK([for $compiler option to produce PIC], [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)], [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_prog_compiler_pic, $1)]) _LT_TAGVAR(lt_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_cv_prog_compiler_pic, $1) # # Check to make sure the PIC flag actually works. # if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then _LT_COMPILER_OPTION([if $compiler PIC flag $_LT_TAGVAR(lt_prog_compiler_pic, $1) works], [_LT_TAGVAR(lt_cv_prog_compiler_pic_works, $1)], [$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])], [], [case $_LT_TAGVAR(lt_prog_compiler_pic, $1) in "" | " "*) ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)=" $_LT_TAGVAR(lt_prog_compiler_pic, $1)" ;; esac], [_LT_TAGVAR(lt_prog_compiler_pic, $1)= _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no]) fi _LT_TAGDECL([pic_flag], [lt_prog_compiler_pic], [1], [Additional compiler flags for building library objects]) _LT_TAGDECL([wl], [lt_prog_compiler_wl], [1], [How to pass a linker flag through the compiler]) # # Check to make sure the static flag actually works. # wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) eval lt_tmp_static_flag=\"$_LT_TAGVAR(lt_prog_compiler_static, $1)\" _LT_LINKER_OPTION([if $compiler static flag $lt_tmp_static_flag works], _LT_TAGVAR(lt_cv_prog_compiler_static_works, $1), $lt_tmp_static_flag, [], [_LT_TAGVAR(lt_prog_compiler_static, $1)=]) _LT_TAGDECL([link_static_flag], [lt_prog_compiler_static], [1], [Compiler flag to prevent dynamic linking]) ])# _LT_COMPILER_PIC # _LT_LINKER_SHLIBS([TAGNAME]) # ---------------------------- # See if the linker supports building shared libraries. m4_defun([_LT_LINKER_SHLIBS], [AC_REQUIRE([LT_PATH_LD])dnl AC_REQUIRE([LT_PATH_NM])dnl m4_require([_LT_PATH_MANIFEST_TOOL])dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_DECL_SED])dnl m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl m4_require([_LT_TAG_COMPILER])dnl AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) m4_if([$1], [CXX], [ _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] case $host_os in aix[[4-9]]*) # If we're using GNU nm, then we don't want the "-C" option. # -C means demangle to AIX nm, but means don't demangle with GNU nm # Also, AIX nm treats weak defined symbols like other global defined # symbols, whereas GNU nm marks them as "W". if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' else _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' fi ;; pw32*) _LT_TAGVAR(export_symbols_cmds, $1)="$ltdll_cmds" ;; cygwin* | mingw* | cegcc*) case $cc_basename in cl*) _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' ;; *) _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols' _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'] ;; esac ;; linux* | k*bsd*-gnu | gnu*) _LT_TAGVAR(link_all_deplibs, $1)=no ;; *) _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' ;; esac ], [ runpath_var= _LT_TAGVAR(allow_undefined_flag, $1)= _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(archive_cmds, $1)= _LT_TAGVAR(archive_expsym_cmds, $1)= _LT_TAGVAR(compiler_needs_object, $1)=no _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' _LT_TAGVAR(hardcode_automatic, $1)=no _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(hardcode_libdir_separator, $1)= _LT_TAGVAR(hardcode_minus_L, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported _LT_TAGVAR(inherit_rpath, $1)=no _LT_TAGVAR(link_all_deplibs, $1)=unknown _LT_TAGVAR(module_cmds, $1)= _LT_TAGVAR(module_expsym_cmds, $1)= _LT_TAGVAR(old_archive_from_new_cmds, $1)= _LT_TAGVAR(old_archive_from_expsyms_cmds, $1)= _LT_TAGVAR(thread_safe_flag_spec, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= # include_expsyms should be a list of space-separated symbols to be *always* # included in the symbol list _LT_TAGVAR(include_expsyms, $1)= # exclude_expsyms can be an extended regexp of symbols to exclude # it will be wrapped by ` (' and `)$', so one must not match beginning or # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', # as well as any symbol that contains `d'. _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out # platforms (ab)use it in PIC code, but their linkers get confused if # the symbol is explicitly referenced. Since portable code cannot # rely on this symbol name, it's probably fine to never include it in # preloaded symbol tables. # Exclude shared library initialization/finalization symbols. dnl Note also adjust exclude_expsyms for C++ above. extract_expsyms_cmds= case $host_os in cygwin* | mingw* | pw32* | cegcc*) # FIXME: the MSVC++ port hasn't been tested in a loooong time # When not using gcc, we currently assume that we are using # Microsoft Visual C++. if test "$GCC" != yes; then with_gnu_ld=no fi ;; interix*) # we just hope/assume this is gcc and not c89 (= MSVC++) with_gnu_ld=yes ;; openbsd*) with_gnu_ld=no ;; linux* | k*bsd*-gnu | gnu*) _LT_TAGVAR(link_all_deplibs, $1)=no ;; esac _LT_TAGVAR(ld_shlibs, $1)=yes # On some targets, GNU ld is compatible enough with the native linker # that we're better off using the native interface for both. lt_use_gnu_ld_interface=no if test "$with_gnu_ld" = yes; then case $host_os in aix*) # The AIX port of GNU ld has always aspired to compatibility # with the native linker. However, as the warning in the GNU ld # block says, versions before 2.19.5* couldn't really create working # shared libraries, regardless of the interface used. case `$LD -v 2>&1` in *\ \(GNU\ Binutils\)\ 2.19.5*) ;; *\ \(GNU\ Binutils\)\ 2.[[2-9]]*) ;; *\ \(GNU\ Binutils\)\ [[3-9]]*) ;; *) lt_use_gnu_ld_interface=yes ;; esac ;; *) lt_use_gnu_ld_interface=yes ;; esac fi if test "$lt_use_gnu_ld_interface" = yes; then # If archive_cmds runs LD, not CC, wlarc should be empty wlarc='${wl}' # Set some defaults for GNU ld with shared library support. These # are reset later if shared libraries are not supported. Putting them # here allows them to be overridden if necessary. runpath_var=LD_RUN_PATH _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' # ancient GNU ld didn't support --whole-archive et. al. if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' else _LT_TAGVAR(whole_archive_flag_spec, $1)= fi supports_anon_versioning=no case `$LD -v 2>&1` in *GNU\ gold*) supports_anon_versioning=yes ;; *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11 *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... *\ 2.11.*) ;; # other 2.11 versions *) supports_anon_versioning=yes ;; esac # See if GNU ld supports shared libraries. case $host_os in aix[[3-9]]*) # On AIX/PPC, the GNU linker is very broken if test "$host_cpu" != ia64; then _LT_TAGVAR(ld_shlibs, $1)=no cat <<_LT_EOF 1>&2 *** Warning: the GNU linker, at least up to release 2.19, is reported *** to be unable to reliably create shared libraries on AIX. *** Therefore, libtool is disabling shared libraries support. If you *** really care for shared libraries, you may want to install binutils *** 2.20 or above, or modify your PATH so that a non-GNU linker is found. *** You will then need to restart the configuration process. _LT_EOF fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='' ;; m68k) _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_minus_L, $1)=yes ;; esac ;; beos*) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(allow_undefined_flag, $1)=unsupported # Joseph Beckenbach <jrb3@best.com> says some releases of gcc # support --undefined. This deserves some investigation. FIXME _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; cygwin* | mingw* | pw32* | cegcc*) # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, # as there is no search path for DLLs. _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-all-symbols' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols' _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'] if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' # If the export-symbols file already is a .def file (1st line # is EXPORTS), use it as is; otherwise, prepend... _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then cp $export_symbols $output_objdir/$soname.def; else echo EXPORTS > $output_objdir/$soname.def; cat $export_symbols >> $output_objdir/$soname.def; fi~ $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; haiku*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(link_all_deplibs, $1)=yes ;; interix[[3-9]]*) _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. # Instead, shared libraries are loaded at an image base (0x10000000 by # default) and relocated if they conflict, which is a slow very memory # consuming and fragmenting process. To avoid this, we pick a random, # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link # time. Moving up from 0x10000000 also allows more sbrk(2) space. _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ;; gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) tmp_diet=no if test "$host_os" = linux-dietlibc; then case $cc_basename in diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) esac fi if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ && test "$tmp_diet" = no then tmp_addflag=' $pic_flag' tmp_sharedflag='-shared' case $cc_basename,$host_cpu in pgcc*) # Portland Group C compiler _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' tmp_addflag=' $pic_flag' ;; pgf77* | pgf90* | pgf95* | pgfortran*) # Portland Group f77 and f90 compilers _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' tmp_addflag=' $pic_flag -Mnomain' ;; ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 tmp_addflag=' -i_dynamic' ;; efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 tmp_addflag=' -i_dynamic -nofor_main' ;; ifc* | ifort*) # Intel Fortran compiler tmp_addflag=' -nofor_main' ;; lf95*) # Lahey Fortran 8.1 _LT_TAGVAR(whole_archive_flag_spec, $1)= tmp_sharedflag='--shared' ;; xl[[cC]]* | bgxl[[cC]]* | mpixl[[cC]]*) # IBM XL C 8.0 on PPC (deal with xlf below) tmp_sharedflag='-qmkshrobj' tmp_addflag= ;; nvcc*) # Cuda Compiler Driver 2.2 _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' _LT_TAGVAR(compiler_needs_object, $1)=yes ;; esac case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C 5.9 _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' _LT_TAGVAR(compiler_needs_object, $1)=yes tmp_sharedflag='-G' ;; *Sun\ F*) # Sun Fortran 8.3 tmp_sharedflag='-G' ;; esac _LT_TAGVAR(archive_cmds, $1)='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' if test "x$supports_anon_versioning" = xyes; then _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' fi case $cc_basename in xlf* | bgf* | bgxlf* | mpixlf*) # IBM XL Fortran 10.1 on PPC cannot create shared libs itself _LT_TAGVAR(whole_archive_flag_spec, $1)='--whole-archive$convenience --no-whole-archive' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib' if test "x$supports_anon_versioning" = xyes; then _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' fi ;; esac else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' wlarc= else _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' fi ;; solaris*) if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then _LT_TAGVAR(ld_shlibs, $1)=no cat <<_LT_EOF 1>&2 *** Warning: The releases 2.8.* of the GNU linker cannot reliably *** create shared libraries on Solaris systems. Therefore, libtool *** is disabling shared libraries support. We urge you to upgrade GNU *** binutils to release 2.9.1 or newer. Another option is to modify *** your PATH or compiler configuration so that the native linker is *** used, and then restart. _LT_EOF elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) case `$LD -v 2>&1` in *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.1[[0-5]].*) _LT_TAGVAR(ld_shlibs, $1)=no cat <<_LT_EOF 1>&2 *** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not *** reliably create shared libraries on SCO systems. Therefore, libtool *** is disabling shared libraries support. We urge you to upgrade GNU *** binutils to release 2.16.91.0.3 or newer. Another option is to modify *** your PATH or compiler configuration so that the native linker is *** used, and then restart. _LT_EOF ;; *) # For security reasons, it is highly recommended that you always # use absolute paths for naming shared libraries, and exclude the # DT_RUNPATH tag from executables and libraries. But doing so # requires that you compile everything twice, which is a pain. if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; sunos4*) _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' wlarc= _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac if test "$_LT_TAGVAR(ld_shlibs, $1)" = no; then runpath_var= _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= fi else # PORTME fill in a description of your system's linker (not GNU ld) case $host_os in aix3*) _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=yes _LT_TAGVAR(archive_expsym_cmds, $1)='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' # Note: this linker hardcodes the directories in LIBPATH if there # are no directories specified by -L. _LT_TAGVAR(hardcode_minus_L, $1)=yes if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then # Neither direct hardcoding nor static linking is supported with a # broken collect2. _LT_TAGVAR(hardcode_direct, $1)=unsupported fi ;; aix[[4-9]]*) if test "$host_cpu" = ia64; then # On IA64, the linker does run time linking by default, so we don't # have to do anything special. aix_use_runtimelinking=no exp_sym_flag='-Bexport' no_entry_flag="" else # If we're using GNU nm, then we don't want the "-C" option. # -C means demangle to AIX nm, but means don't demangle with GNU nm # Also, AIX nm treats weak defined symbols like other global # defined symbols, whereas GNU nm marks them as "W". if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' else _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' fi aix_use_runtimelinking=no # Test if we are trying to use run time linking or normal # AIX style linking. If -brtl is somewhere in LDFLAGS, we # need to do runtime linking. case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) for ld_flag in $LDFLAGS; do if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then aix_use_runtimelinking=yes break fi done ;; esac exp_sym_flag='-bexport' no_entry_flag='-bnoentry' fi # When large executables or shared objects are built, AIX ld can # have problems creating the table of contents. If linking a library # or program results in "error TOC overflow" add -mminimal-toc to # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. _LT_TAGVAR(archive_cmds, $1)='' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(file_list_spec, $1)='${wl}-f,' if test "$GCC" = yes; then case $host_os in aix4.[[012]]|aix4.[[012]].*) # We only want to do this on AIX 4.2 and lower, the check # below for broken collect2 doesn't work under 4.3+ collect2name=`${CC} -print-prog-name=collect2` if test -f "$collect2name" && strings "$collect2name" | $GREP resolve_lib_name >/dev/null then # We have reworked collect2 : else # We have old collect2 _LT_TAGVAR(hardcode_direct, $1)=unsupported # It fails to find uninstalled libraries when the uninstalled # path is not listed in the libpath. Setting hardcode_minus_L # to unsupported forces relinking _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)= fi ;; esac shared_flag='-shared' if test "$aix_use_runtimelinking" = yes; then shared_flag="$shared_flag "'${wl}-G' fi _LT_TAGVAR(link_all_deplibs, $1)=no else # not using gcc if test "$host_cpu" = ia64; then # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release # chokes on -Wl,-G. The following line is correct: shared_flag='-G' else if test "$aix_use_runtimelinking" = yes; then shared_flag='${wl}-G' else shared_flag='${wl}-bM:SRE' fi fi fi _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall' # It seems that -bexpall does not export symbols beginning with # underscore (_), so it is better to generate a list of symbols to export. _LT_TAGVAR(always_export_symbols, $1)=yes if test "$aix_use_runtimelinking" = yes; then # Warning - without using the other runtime loading flags (-brtl), # -berok will link without error, but may produce a broken library. _LT_TAGVAR(allow_undefined_flag, $1)='-berok' # Determine the default libpath from the value encoded in an # empty executable. _LT_SYS_MODULE_PATH_AIX([$1]) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" else if test "$host_cpu" = ia64; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib' _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" else # Determine the default libpath from the value encoded in an # empty executable. _LT_SYS_MODULE_PATH_AIX([$1]) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" # Warning - without using the other run time loading flags, # -berok will link without error, but may produce a broken library. _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok' _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok' if test "$with_gnu_ld" = yes; then # We only use this code for GNU lds that support --whole-archive. _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive' else # Exported symbols can be pulled into shared objects from archives _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' fi _LT_TAGVAR(archive_cmds_need_lc, $1)=yes # This is similar to how AIX traditionally builds its shared libraries. _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' fi fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='' ;; m68k) _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_minus_L, $1)=yes ;; esac ;; bsdi[[45]]*) _LT_TAGVAR(export_dynamic_flag_spec, $1)=-rdynamic ;; cygwin* | mingw* | pw32* | cegcc*) # When not using gcc, we currently assume that we are using # Microsoft Visual C++. # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. case $cc_basename in cl*) # Native MSVC _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=yes _LT_TAGVAR(file_list_spec, $1)='@' # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=".dll" # FIXME: Setting linknames here is a bad hack. _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames=' _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then sed -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp; else sed -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp; fi~ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ linknames=' # The linker will not automatically build a static lib if we build a DLL. # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1,DATA/'\'' | $SED -e '\''/^[[AITW]][[ ]]/s/.*[[ ]]//'\'' | sort | uniq > $export_symbols' # Don't use ranlib _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib' _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~ lt_tool_outputfile="@TOOL_OUTPUT@"~ case $lt_outputfile in *.exe|*.EXE) ;; *) lt_outputfile="$lt_outputfile.exe" lt_tool_outputfile="$lt_tool_outputfile.exe" ;; esac~ if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; $RM "$lt_outputfile.manifest"; fi' ;; *) # Assume MSVC wrapper _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=".dll" # FIXME: Setting linknames here is a bad hack. _LT_TAGVAR(archive_cmds, $1)='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames=' # The linker will automatically build a .lib file if we build a DLL. _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' # FIXME: Should let the user specify the lib program. _LT_TAGVAR(old_archive_cmds, $1)='lib -OUT:$oldlib$oldobjs$old_deplibs' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes ;; esac ;; darwin* | rhapsody*) _LT_DARWIN_LINKER_FEATURES($1) ;; dgux*) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor # support. Future versions do this automatically, but an explicit c++rt0.o # does not break anything, and helps significantly (at the cost of a little # extra space). freebsd2.2*) _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; # Unfortunately, older versions of FreeBSD 2 do not have this feature. freebsd2.*) _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; # FreeBSD 3 and greater uses gcc -shared to do shared libraries. freebsd* | dragonfly*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; hpux9*) if test "$GCC" = yes; then _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' else _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(hardcode_direct, $1)=yes # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' ;; hpux10*) if test "$GCC" = yes && test "$with_gnu_ld" = no; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' else _LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' fi if test "$with_gnu_ld" = no; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. _LT_TAGVAR(hardcode_minus_L, $1)=yes fi ;; hpux11*) if test "$GCC" = yes && test "$with_gnu_ld" = no; then case $host_cpu in hppa*64*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' ;; esac else case $host_cpu in hppa*64*) _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) m4_if($1, [], [ # Older versions of the 11.00 compiler do not understand -b yet # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does) _LT_LINKER_OPTION([if $CC understands -b], _LT_TAGVAR(lt_cv_prog_compiler__b, $1), [-b], [_LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'], [_LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'])], [_LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags']) ;; esac fi if test "$with_gnu_ld" = no; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: case $host_cpu in hppa*64*|ia64*) _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *) _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. _LT_TAGVAR(hardcode_minus_L, $1)=yes ;; esac fi ;; irix5* | irix6* | nonstopux*) if test "$GCC" = yes; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' # Try to use the -exported_symbol ld option, if it does not # work, assume that -exports_file does not work either and # implicitly export all symbols. # This should be the same for all languages, so no per-tag cache variable. AC_CACHE_CHECK([whether the $host_os linker accepts -exported_symbol], [lt_cv_irix_exported_symbol], [save_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null" AC_LINK_IFELSE( [AC_LANG_SOURCE( [AC_LANG_CASE([C], [[int foo (void) { return 0; }]], [C++], [[int foo (void) { return 0; }]], [Fortran 77], [[ subroutine foo end]], [Fortran], [[ subroutine foo end]])])], [lt_cv_irix_exported_symbol=yes], [lt_cv_irix_exported_symbol=no]) LDFLAGS="$save_LDFLAGS"]) if test "$lt_cv_irix_exported_symbol" = yes; then _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib' fi else _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib' fi _LT_TAGVAR(archive_cmds_need_lc, $1)='no' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(inherit_rpath, $1)=yes _LT_TAGVAR(link_all_deplibs, $1)=yes ;; netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out else _LT_TAGVAR(archive_cmds, $1)='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; newsos6) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *nto* | *qnx*) ;; openbsd*) if test -f /usr/libexec/ld.so; then _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=yes if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' else case $host_os in openbsd[[01]].* | openbsd2.[[0-7]] | openbsd2.[[0-7]].*) _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' ;; esac fi else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; os2*) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~echo DATA >> $output_objdir/$libname.def~echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' _LT_TAGVAR(old_archive_from_new_cmds, $1)='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' ;; osf3*) if test "$GCC" = yes; then _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' else _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' fi _LT_TAGVAR(archive_cmds_need_lc, $1)='no' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: ;; osf4* | osf5*) # as osf3* with the addition of -msym flag if test "$GCC" = yes; then _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $pic_flag $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' else _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp' # Both c and cxx compiler support -rpath directly _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' fi _LT_TAGVAR(archive_cmds_need_lc, $1)='no' _LT_TAGVAR(hardcode_libdir_separator, $1)=: ;; solaris*) _LT_TAGVAR(no_undefined_flag, $1)=' -z defs' if test "$GCC" = yes; then wlarc='${wl}' _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' else case `$CC -V 2>&1` in *"Compilers 5.0"*) wlarc='' _LT_TAGVAR(archive_cmds, $1)='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' ;; *) wlarc='${wl}' _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' ;; esac fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no case $host_os in solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; *) # The compiler driver will combine and reorder linker options, # but understands `-z linker_flag'. GCC discards it without `$wl', # but is careful enough not to reorder. # Supported since Solaris 2.6 (maybe 2.5.1?) if test "$GCC" = yes; then _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' else _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' fi ;; esac _LT_TAGVAR(link_all_deplibs, $1)=yes ;; sunos4*) if test "x$host_vendor" = xsequent; then # Use $CC to link under sequent, because it throws in some extra .o # files that make .init and .fini sections work. _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' else _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; sysv4) case $host_vendor in sni) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_direct, $1)=yes # is this really true??? ;; siemens) ## LD is ld it makes a PLAMLIB ## CC just makes a GrossModule. _LT_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(reload_cmds, $1)='$CC -r -o $output$reload_objs' _LT_TAGVAR(hardcode_direct, $1)=no ;; motorola) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_direct, $1)=no #Motorola manual says yes, but my tests say they lie ;; esac runpath_var='LD_RUN_PATH' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; sysv4.3*) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(export_dynamic_flag_spec, $1)='-Bexport' ;; sysv4*MP*) if test -d /usr/nec; then _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no runpath_var=LD_RUN_PATH hardcode_runpath_var=yes _LT_TAGVAR(ld_shlibs, $1)=yes fi ;; sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no runpath_var='LD_RUN_PATH' if test "$GCC" = yes; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; sysv5* | sco3.2v5* | sco5v6*) # Note: We can NOT use -z defs as we might desire, because we do not # link with -lc, and that would cause any symbols used from libc to # always be unresolved, which means just about no library would # ever link correctly. If we're not using GNU ld we use -z text # though, which does catch some bad symbols but isn't as heavy-handed # as -z defs. _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' _LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport' runpath_var='LD_RUN_PATH' if test "$GCC" = yes; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; uts4*) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *) _LT_TAGVAR(ld_shlibs, $1)=no ;; esac if test x$host_vendor = xsni; then case $host in sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Blargedynsym' ;; esac fi fi ]) AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no _LT_TAGVAR(with_gnu_ld, $1)=$with_gnu_ld _LT_DECL([], [libext], [0], [Old archive suffix (normally "a")])dnl _LT_DECL([], [shrext_cmds], [1], [Shared library suffix (normally ".so")])dnl _LT_DECL([], [extract_expsyms_cmds], [2], [The commands to extract the exported symbol list from a shared archive]) # # Do we need to explicitly link libc? # case "x$_LT_TAGVAR(archive_cmds_need_lc, $1)" in x|xyes) # Assume -lc should be added _LT_TAGVAR(archive_cmds_need_lc, $1)=yes if test "$enable_shared" = yes && test "$GCC" = yes; then case $_LT_TAGVAR(archive_cmds, $1) in *'~'*) # FIXME: we may have to deal with multi-command sequences. ;; '$CC '*) # Test whether the compiler implicitly links with -lc since on some # systems, -lgcc has to come before -lc. If gcc already passes -lc # to ld, don't add -lc before -lgcc. AC_CACHE_CHECK([whether -lc should be explicitly linked in], [lt_cv_]_LT_TAGVAR(archive_cmds_need_lc, $1), [$RM conftest* echo "$lt_simple_compile_test_code" > conftest.$ac_ext if AC_TRY_EVAL(ac_compile) 2>conftest.err; then soname=conftest lib=conftest libobjs=conftest.$ac_objext deplibs= wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) pic_flag=$_LT_TAGVAR(lt_prog_compiler_pic, $1) compiler_flags=-v linker_flags=-v verstring= output_objdir=. libname=conftest lt_save_allow_undefined_flag=$_LT_TAGVAR(allow_undefined_flag, $1) _LT_TAGVAR(allow_undefined_flag, $1)= if AC_TRY_EVAL(_LT_TAGVAR(archive_cmds, $1) 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) then lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=no else lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=yes fi _LT_TAGVAR(allow_undefined_flag, $1)=$lt_save_allow_undefined_flag else cat conftest.err 1>&5 fi $RM conftest* ]) _LT_TAGVAR(archive_cmds_need_lc, $1)=$lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1) ;; esac fi ;; esac _LT_TAGDECL([build_libtool_need_lc], [archive_cmds_need_lc], [0], [Whether or not to add -lc for building shared libraries]) _LT_TAGDECL([allow_libtool_libs_with_static_runtimes], [enable_shared_with_static_runtimes], [0], [Whether or not to disallow shared libs when runtime libs are static]) _LT_TAGDECL([], [export_dynamic_flag_spec], [1], [Compiler flag to allow reflexive dlopens]) _LT_TAGDECL([], [whole_archive_flag_spec], [1], [Compiler flag to generate shared objects directly from archives]) _LT_TAGDECL([], [compiler_needs_object], [1], [Whether the compiler copes with passing no objects directly]) _LT_TAGDECL([], [old_archive_from_new_cmds], [2], [Create an old-style archive from a shared archive]) _LT_TAGDECL([], [old_archive_from_expsyms_cmds], [2], [Create a temporary old-style archive to link instead of a shared archive]) _LT_TAGDECL([], [archive_cmds], [2], [Commands used to build a shared archive]) _LT_TAGDECL([], [archive_expsym_cmds], [2]) _LT_TAGDECL([], [module_cmds], [2], [Commands used to build a loadable module if different from building a shared archive.]) _LT_TAGDECL([], [module_expsym_cmds], [2]) _LT_TAGDECL([], [with_gnu_ld], [1], [Whether we are building with GNU ld or not]) _LT_TAGDECL([], [allow_undefined_flag], [1], [Flag that allows shared libraries with undefined symbols to be built]) _LT_TAGDECL([], [no_undefined_flag], [1], [Flag that enforces no undefined symbols]) _LT_TAGDECL([], [hardcode_libdir_flag_spec], [1], [Flag to hardcode $libdir into a binary during linking. This must work even if $libdir does not exist]) _LT_TAGDECL([], [hardcode_libdir_separator], [1], [Whether we need a single "-rpath" flag with a separated argument]) _LT_TAGDECL([], [hardcode_direct], [0], [Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the resulting binary]) _LT_TAGDECL([], [hardcode_direct_absolute], [0], [Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the resulting binary and the resulting library dependency is "absolute", i.e impossible to change by setting ${shlibpath_var} if the library is relocated]) _LT_TAGDECL([], [hardcode_minus_L], [0], [Set to "yes" if using the -LDIR flag during linking hardcodes DIR into the resulting binary]) _LT_TAGDECL([], [hardcode_shlibpath_var], [0], [Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into the resulting binary]) _LT_TAGDECL([], [hardcode_automatic], [0], [Set to "yes" if building a shared library automatically hardcodes DIR into the library and all subsequent libraries and executables linked against it]) _LT_TAGDECL([], [inherit_rpath], [0], [Set to yes if linker adds runtime paths of dependent libraries to runtime path list]) _LT_TAGDECL([], [link_all_deplibs], [0], [Whether libtool must link a program against all its dependency libraries]) _LT_TAGDECL([], [always_export_symbols], [0], [Set to "yes" if exported symbols are required]) _LT_TAGDECL([], [export_symbols_cmds], [2], [The commands to list exported symbols]) _LT_TAGDECL([], [exclude_expsyms], [1], [Symbols that should not be listed in the preloaded symbols]) _LT_TAGDECL([], [include_expsyms], [1], [Symbols that must always be exported]) _LT_TAGDECL([], [prelink_cmds], [2], [Commands necessary for linking programs (against libraries) with templates]) _LT_TAGDECL([], [postlink_cmds], [2], [Commands necessary for finishing linking programs]) _LT_TAGDECL([], [file_list_spec], [1], [Specify filename containing input files]) dnl FIXME: Not yet implemented dnl _LT_TAGDECL([], [thread_safe_flag_spec], [1], dnl [Compiler flag to generate thread safe objects]) ])# _LT_LINKER_SHLIBS # _LT_LANG_C_CONFIG([TAG]) # ------------------------ # Ensure that the configuration variables for a C compiler are suitably # defined. These variables are subsequently used by _LT_CONFIG to write # the compiler configuration to `libtool'. m4_defun([_LT_LANG_C_CONFIG], [m4_require([_LT_DECL_EGREP])dnl lt_save_CC="$CC" AC_LANG_PUSH(C) # Source file extension for C test sources. ac_ext=c # Object file extension for compiled C test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # Code to be used in simple compile tests lt_simple_compile_test_code="int some_variable = 0;" # Code to be used in simple link tests lt_simple_link_test_code='int main(){return(0);}' _LT_TAG_COMPILER # Save the default compiler, since it gets overwritten when the other # tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. compiler_DEFAULT=$CC # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE if test -n "$compiler"; then _LT_COMPILER_NO_RTTI($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_SYS_DYNAMIC_LINKER($1) _LT_LINKER_HARDCODE_LIBPATH($1) LT_SYS_DLOPEN_SELF _LT_CMD_STRIPLIB # Report which library types will actually be built AC_MSG_CHECKING([if libtool supports shared libraries]) AC_MSG_RESULT([$can_build_shared]) AC_MSG_CHECKING([whether to build shared libraries]) test "$can_build_shared" = "no" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. case $host_os in aix3*) test "$enable_shared" = yes && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix[[4-9]]*) if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then test "$enable_shared" = yes && enable_static=no fi ;; esac AC_MSG_RESULT([$enable_shared]) AC_MSG_CHECKING([whether to build static libraries]) # Make sure either enable_shared or enable_static is yes. test "$enable_shared" = yes || enable_static=yes AC_MSG_RESULT([$enable_static]) _LT_CONFIG($1) fi AC_LANG_POP CC="$lt_save_CC" ])# _LT_LANG_C_CONFIG # _LT_LANG_CXX_CONFIG([TAG]) # -------------------------- # Ensure that the configuration variables for a C++ compiler are suitably # defined. These variables are subsequently used by _LT_CONFIG to write # the compiler configuration to `libtool'. m4_defun([_LT_LANG_CXX_CONFIG], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_PATH_MANIFEST_TOOL])dnl if test -n "$CXX" && ( test "X$CXX" != "Xno" && ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) || (test "X$CXX" != "Xg++"))) ; then AC_PROG_CXXCPP else _lt_caught_CXX_error=yes fi AC_LANG_PUSH(C++) _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(allow_undefined_flag, $1)= _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(archive_expsym_cmds, $1)= _LT_TAGVAR(compiler_needs_object, $1)=no _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(hardcode_libdir_separator, $1)= _LT_TAGVAR(hardcode_minus_L, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported _LT_TAGVAR(hardcode_automatic, $1)=no _LT_TAGVAR(inherit_rpath, $1)=no _LT_TAGVAR(module_cmds, $1)= _LT_TAGVAR(module_expsym_cmds, $1)= _LT_TAGVAR(link_all_deplibs, $1)=unknown _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(reload_flag, $1)=$reload_flag _LT_TAGVAR(reload_cmds, $1)=$reload_cmds _LT_TAGVAR(no_undefined_flag, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no # Source file extension for C++ test sources. ac_ext=cpp # Object file extension for compiled C++ test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # No sense in running all these tests if we already determined that # the CXX compiler isn't working. Some variables (like enable_shared) # are currently assumed to apply to all compilers on this platform, # and will be corrupted by setting them based on a non-working compiler. if test "$_lt_caught_CXX_error" != yes; then # Code to be used in simple compile tests lt_simple_compile_test_code="int some_variable = 0;" # Code to be used in simple link tests lt_simple_link_test_code='int main(int, char *[[]]) { return(0); }' # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_CFLAGS=$CFLAGS lt_save_LD=$LD lt_save_GCC=$GCC GCC=$GXX lt_save_with_gnu_ld=$with_gnu_ld lt_save_path_LD=$lt_cv_path_LD if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx else $as_unset lt_cv_prog_gnu_ld fi if test -n "${lt_cv_path_LDCXX+set}"; then lt_cv_path_LD=$lt_cv_path_LDCXX else $as_unset lt_cv_path_LD fi test -z "${LDCXX+set}" || LD=$LDCXX CC=${CXX-"c++"} CFLAGS=$CXXFLAGS compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_CC_BASENAME([$compiler]) if test -n "$compiler"; then # We don't want -fno-exception when compiling C++ code, so set the # no_builtin_flag separately if test "$GXX" = yes; then _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' else _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= fi if test "$GXX" = yes; then # Set up default GNU C++ configuration LT_PATH_LD # Check if GNU C++ uses GNU ld as the underlying linker, since the # archiving commands below assume that GNU ld is being used. if test "$with_gnu_ld" = yes; then _LT_TAGVAR(archive_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' # If archive_cmds runs LD, not CC, wlarc should be empty # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to # investigate it a little bit more. (MM) wlarc='${wl}' # ancient GNU ld didn't support --whole-archive et. al. if eval "`$CC -print-prog-name=ld` --help 2>&1" | $GREP 'no-whole-archive' > /dev/null; then _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' else _LT_TAGVAR(whole_archive_flag_spec, $1)= fi else with_gnu_ld=no wlarc= # A generic and very simple default shared library creation # command for GNU C++ for the case where it uses the native # linker, instead of GNU ld. If possible, this setting should # overridden to take advantage of the native linker features on # the platform it is being used on. _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' fi # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' else GXX=no with_gnu_ld=no wlarc= fi # PORTME: fill in a description of your system's C++ link characteristics AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) _LT_TAGVAR(ld_shlibs, $1)=yes case $host_os in aix3*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; aix[[4-9]]*) if test "$host_cpu" = ia64; then # On IA64, the linker does run time linking by default, so we don't # have to do anything special. aix_use_runtimelinking=no exp_sym_flag='-Bexport' no_entry_flag="" else aix_use_runtimelinking=no # Test if we are trying to use run time linking or normal # AIX style linking. If -brtl is somewhere in LDFLAGS, we # need to do runtime linking. case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) for ld_flag in $LDFLAGS; do case $ld_flag in *-brtl*) aix_use_runtimelinking=yes break ;; esac done ;; esac exp_sym_flag='-bexport' no_entry_flag='-bnoentry' fi # When large executables or shared objects are built, AIX ld can # have problems creating the table of contents. If linking a library # or program results in "error TOC overflow" add -mminimal-toc to # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. _LT_TAGVAR(archive_cmds, $1)='' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(file_list_spec, $1)='${wl}-f,' if test "$GXX" = yes; then case $host_os in aix4.[[012]]|aix4.[[012]].*) # We only want to do this on AIX 4.2 and lower, the check # below for broken collect2 doesn't work under 4.3+ collect2name=`${CC} -print-prog-name=collect2` if test -f "$collect2name" && strings "$collect2name" | $GREP resolve_lib_name >/dev/null then # We have reworked collect2 : else # We have old collect2 _LT_TAGVAR(hardcode_direct, $1)=unsupported # It fails to find uninstalled libraries when the uninstalled # path is not listed in the libpath. Setting hardcode_minus_L # to unsupported forces relinking _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)= fi esac shared_flag='-shared' if test "$aix_use_runtimelinking" = yes; then shared_flag="$shared_flag "'${wl}-G' fi else # not using gcc if test "$host_cpu" = ia64; then # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release # chokes on -Wl,-G. The following line is correct: shared_flag='-G' else if test "$aix_use_runtimelinking" = yes; then shared_flag='${wl}-G' else shared_flag='${wl}-bM:SRE' fi fi fi _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall' # It seems that -bexpall does not export symbols beginning with # underscore (_), so it is better to generate a list of symbols to # export. _LT_TAGVAR(always_export_symbols, $1)=yes if test "$aix_use_runtimelinking" = yes; then # Warning - without using the other runtime loading flags (-brtl), # -berok will link without error, but may produce a broken library. _LT_TAGVAR(allow_undefined_flag, $1)='-berok' # Determine the default libpath from the value encoded in an empty # executable. _LT_SYS_MODULE_PATH_AIX([$1]) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" else if test "$host_cpu" = ia64; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib' _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" else # Determine the default libpath from the value encoded in an # empty executable. _LT_SYS_MODULE_PATH_AIX([$1]) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" # Warning - without using the other run time loading flags, # -berok will link without error, but may produce a broken library. _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok' _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok' if test "$with_gnu_ld" = yes; then # We only use this code for GNU lds that support --whole-archive. _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive' else # Exported symbols can be pulled into shared objects from archives _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' fi _LT_TAGVAR(archive_cmds_need_lc, $1)=yes # This is similar to how AIX traditionally builds its shared # libraries. _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' fi fi ;; beos*) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(allow_undefined_flag, $1)=unsupported # Joseph Beckenbach <jrb3@best.com> says some releases of gcc # support --undefined. This deserves some investigation. FIXME _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; chorus*) case $cc_basename in *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; cygwin* | mingw* | pw32* | cegcc*) case $GXX,$cc_basename in ,cl* | no,cl*) # Native MSVC # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=yes _LT_TAGVAR(file_list_spec, $1)='@' # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=".dll" # FIXME: Setting linknames here is a bad hack. _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames=' _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then $SED -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp; else $SED -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp; fi~ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ linknames=' # The linker will not automatically build a static lib if we build a DLL. # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes # Don't use ranlib _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib' _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~ lt_tool_outputfile="@TOOL_OUTPUT@"~ case $lt_outputfile in *.exe|*.EXE) ;; *) lt_outputfile="$lt_outputfile.exe" lt_tool_outputfile="$lt_tool_outputfile.exe" ;; esac~ func_to_tool_file "$lt_outputfile"~ if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; $RM "$lt_outputfile.manifest"; fi' ;; *) # g++ # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, # as there is no search path for DLLs. _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-all-symbols' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' # If the export-symbols file already is a .def file (1st line # is EXPORTS), use it as is; otherwise, prepend... _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then cp $export_symbols $output_objdir/$soname.def; else echo EXPORTS > $output_objdir/$soname.def; cat $export_symbols >> $output_objdir/$soname.def; fi~ $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; darwin* | rhapsody*) _LT_DARWIN_LINKER_FEATURES($1) ;; dgux*) case $cc_basename in ec++*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; ghcx*) # Green Hills C++ Compiler # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; freebsd2.*) # C++ shared libraries reported to be fairly broken before # switch to ELF _LT_TAGVAR(ld_shlibs, $1)=no ;; freebsd-elf*) _LT_TAGVAR(archive_cmds_need_lc, $1)=no ;; freebsd* | dragonfly*) # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF # conventions _LT_TAGVAR(ld_shlibs, $1)=yes ;; haiku*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(link_all_deplibs, $1)=yes ;; hpux9*) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, # but as the default # location of the library. case $cc_basename in CC*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; aCC*) _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) if test "$GXX" = yes; then _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' else # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; hpux10*|hpux11*) if test $with_gnu_ld = no; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: case $host_cpu in hppa*64*|ia64*) ;; *) _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' ;; esac fi case $host_cpu in hppa*64*|ia64*) _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *) _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, # but as the default # location of the library. ;; esac case $cc_basename in CC*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; aCC*) case $host_cpu in hppa*64*) _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; ia64*) _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; esac # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) if test "$GXX" = yes; then if test $with_gnu_ld = no; then case $host_cpu in hppa*64*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; ia64*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; esac fi else # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; interix[[3-9]]*) _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. # Instead, shared libraries are loaded at an image base (0x10000000 by # default) and relocated if they conflict, which is a slow very memory # consuming and fragmenting process. To avoid this, we pick a random, # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link # time. Moving up from 0x10000000 also allows more sbrk(2) space. _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ;; irix5* | irix6*) case $cc_basename in CC*) # SGI C++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' # Archives containing C++ object files must be created using # "CC -ar", where "CC" is the IRIX C++ compiler. This is # necessary to make sure instantiated templates are included # in the archive. _LT_TAGVAR(old_archive_cmds, $1)='$CC -ar -WR,-u -o $oldlib $oldobjs' ;; *) if test "$GXX" = yes; then if test "$with_gnu_ld" = no; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' else _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` -o $lib' fi fi _LT_TAGVAR(link_all_deplibs, $1)=yes ;; esac _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(inherit_rpath, $1)=yes ;; linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) case $cc_basename in KCC*) # Kuck and Associates, Inc. (KAI) C++ Compiler # KCC will only create a shared library if the output file # ends with ".so" (or ".sl" for HP-UX), so rename the library # to its proper name (with version) after linking. _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' # Archives containing C++ object files must be created using # "CC -Bstatic", where "CC" is the KAI C++ compiler. _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ;; icpc* | ecpc* ) # Intel C++ with_gnu_ld=yes # version 8.0 and above of icpc choke on multiply defined symbols # if we add $predep_objects and $postdep_objects, however 7.1 and # earlier do not add the objects themselves. case `$CC -V 2>&1` in *"Version 7."*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' ;; *) # Version 8.0 or newer tmp_idyn= case $host_cpu in ia64*) tmp_idyn=' -i_dynamic';; esac _LT_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' ;; esac _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive' ;; pgCC* | pgcpp*) # Portland Group C++ compiler case `$CC -V` in *pgCC\ [[1-5]].* | *pgcpp\ [[1-5]].*) _LT_TAGVAR(prelink_cmds, $1)='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~ compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"' _LT_TAGVAR(old_archive_cmds, $1)='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~ $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~ $RANLIB $oldlib' _LT_TAGVAR(archive_cmds, $1)='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' ;; *) # Version 6 and above use weak symbols _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' ;; esac _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' ;; cxx*) # Compaq C++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib ${wl}-retain-symbols-file $wl$export_symbols' runpath_var=LD_RUN_PATH _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed' ;; xl* | mpixl* | bgxl*) # IBM XL 8.0 on PPC, with GNU ld _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' _LT_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' if test "x$supports_anon_versioning" = xyes; then _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' fi ;; *) case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C++ 5.9 _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file ${wl}$export_symbols' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' _LT_TAGVAR(compiler_needs_object, $1)=yes # Not sure whether something based on # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 # would be better. output_verbose_link_cmd='func_echo_all' # Archives containing C++ object files must be created using # "CC -xar", where "CC" is the Sun C++ compiler. This is # necessary to make sure instantiated templates are included # in the archive. _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' ;; esac ;; esac ;; lynxos*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; m88k*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; mvs*) case $cc_basename in cxx*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; netbsd*) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' wlarc= _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no fi # Workaround some broken pre-1.5 toolchains output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"' ;; *nto* | *qnx*) _LT_TAGVAR(ld_shlibs, $1)=yes ;; openbsd2*) # C++ shared libraries are fairly broken _LT_TAGVAR(ld_shlibs, $1)=no ;; openbsd*) if test -f /usr/libexec/ld.so; then _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' fi output_verbose_link_cmd=func_echo_all else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; osf3* | osf4* | osf5*) case $cc_basename in KCC*) # Kuck and Associates, Inc. (KAI) C++ Compiler # KCC will only create a shared library if the output file # ends with ".so" (or ".sl" for HP-UX), so rename the library # to its proper name (with version) after linking. _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: # Archives containing C++ object files must be created using # the KAI C++ compiler. case $host in osf3*) _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ;; *) _LT_TAGVAR(old_archive_cmds, $1)='$CC -o $oldlib $oldobjs' ;; esac ;; RCC*) # Rational C++ 2.4.1 # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; cxx*) case $host in osf3*) _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && func_echo_all "${wl}-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' ;; *) _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~ echo "-hidden">> $lib.exp~ $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname ${wl}-input ${wl}$lib.exp `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~ $RM $lib.exp' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' ;; esac _LT_TAGVAR(hardcode_libdir_separator, $1)=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) if test "$GXX" = yes && test "$with_gnu_ld" = no; then _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' case $host in osf3*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' ;; esac _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' else # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; psos*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; sunos4*) case $cc_basename in CC*) # Sun C++ 4.x # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; lcc*) # Lucid # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; solaris*) case $cc_basename in CC* | sunCC*) # Sun C++ 4.2, 5.x and Centerline C++ _LT_TAGVAR(archive_cmds_need_lc,$1)=yes _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G${allow_undefined_flag} ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no case $host_os in solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; *) # The compiler driver will combine and reorder linker options, # but understands `-z linker_flag'. # Supported since Solaris 2.6 (maybe 2.5.1?) _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' ;; esac _LT_TAGVAR(link_all_deplibs, $1)=yes output_verbose_link_cmd='func_echo_all' # Archives containing C++ object files must be created using # "CC -xar", where "CC" is the Sun C++ compiler. This is # necessary to make sure instantiated templates are included # in the archive. _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' ;; gcx*) # Green Hills C++ Compiler _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' # The C++ compiler must be used to create the archive. _LT_TAGVAR(old_archive_cmds, $1)='$CC $LDFLAGS -archive -o $oldlib $oldobjs' ;; *) # GNU C++ compiler with Solaris linker if test "$GXX" = yes && test "$with_gnu_ld" = no; then _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-z ${wl}defs' if $CC --version | $GREP -v '^2\.7' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -shared $pic_flag -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' else # g++ 2.7 appears to require `-G' NOT `-shared' on this # platform. _LT_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $wl$libdir' case $host_os in solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; *) _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' ;; esac fi ;; esac ;; sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no runpath_var='LD_RUN_PATH' case $cc_basename in CC*) _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; esac ;; sysv5* | sco3.2v5* | sco5v6*) # Note: We can NOT use -z defs as we might desire, because we do not # link with -lc, and that would cause any symbols used from libc to # always be unresolved, which means just about no library would # ever link correctly. If we're not using GNU ld we use -z text # though, which does catch some bad symbols but isn't as heavy-handed # as -z defs. _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' _LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport' runpath_var='LD_RUN_PATH' case $cc_basename in CC*) _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(old_archive_cmds, $1)='$CC -Tprelink_objects $oldobjs~ '"$_LT_TAGVAR(old_archive_cmds, $1)" _LT_TAGVAR(reload_cmds, $1)='$CC -Tprelink_objects $reload_objs~ '"$_LT_TAGVAR(reload_cmds, $1)" ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; esac ;; tandem*) case $cc_basename in NCC*) # NonStop-UX NCC 3.20 # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; vxworks*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no _LT_TAGVAR(GCC, $1)="$GXX" _LT_TAGVAR(LD, $1)="$LD" ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... _LT_SYS_HIDDEN_LIBDEPS($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_SYS_DYNAMIC_LINKER($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi # test -n "$compiler" CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS LDCXX=$LD LD=$lt_save_LD GCC=$lt_save_GCC with_gnu_ld=$lt_save_with_gnu_ld lt_cv_path_LDCXX=$lt_cv_path_LD lt_cv_path_LD=$lt_save_path_LD lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld fi # test "$_lt_caught_CXX_error" != yes AC_LANG_POP ])# _LT_LANG_CXX_CONFIG # _LT_FUNC_STRIPNAME_CNF # ---------------------- # func_stripname_cnf prefix suffix name # strip PREFIX and SUFFIX off of NAME. # PREFIX and SUFFIX must not contain globbing or regex special # characters, hashes, percent signs, but SUFFIX may contain a leading # dot (in which case that matches only a dot). # # This function is identical to the (non-XSI) version of func_stripname, # except this one can be used by m4 code that may be executed by configure, # rather than the libtool script. m4_defun([_LT_FUNC_STRIPNAME_CNF],[dnl AC_REQUIRE([_LT_DECL_SED]) AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH]) func_stripname_cnf () { case ${2} in .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;; *) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;; esac } # func_stripname_cnf ])# _LT_FUNC_STRIPNAME_CNF # _LT_SYS_HIDDEN_LIBDEPS([TAGNAME]) # --------------------------------- # Figure out "hidden" library dependencies from verbose # compiler output when linking a shared library. # Parse the compiler output and extract the necessary # objects, libraries and library flags. m4_defun([_LT_SYS_HIDDEN_LIBDEPS], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl AC_REQUIRE([_LT_FUNC_STRIPNAME_CNF])dnl # Dependencies to place before and after the object being linked: _LT_TAGVAR(predep_objects, $1)= _LT_TAGVAR(postdep_objects, $1)= _LT_TAGVAR(predeps, $1)= _LT_TAGVAR(postdeps, $1)= _LT_TAGVAR(compiler_lib_search_path, $1)= dnl we can't use the lt_simple_compile_test_code here, dnl because it contains code intended for an executable, dnl not a library. It's possible we should let each dnl tag define a new lt_????_link_test_code variable, dnl but it's only used here... m4_if([$1], [], [cat > conftest.$ac_ext <<_LT_EOF int a; void foo (void) { a = 0; } _LT_EOF ], [$1], [CXX], [cat > conftest.$ac_ext <<_LT_EOF class Foo { public: Foo (void) { a = 0; } private: int a; }; _LT_EOF ], [$1], [F77], [cat > conftest.$ac_ext <<_LT_EOF subroutine foo implicit none integer*4 a a=0 return end _LT_EOF ], [$1], [FC], [cat > conftest.$ac_ext <<_LT_EOF subroutine foo implicit none integer a a=0 return end _LT_EOF ], [$1], [GCJ], [cat > conftest.$ac_ext <<_LT_EOF public class foo { private int a; public void bar (void) { a = 0; } }; _LT_EOF ], [$1], [GO], [cat > conftest.$ac_ext <<_LT_EOF package foo func foo() { } _LT_EOF ]) _lt_libdeps_save_CFLAGS=$CFLAGS case "$CC $CFLAGS " in #( *\ -flto*\ *) CFLAGS="$CFLAGS -fno-lto" ;; *\ -fwhopr*\ *) CFLAGS="$CFLAGS -fno-whopr" ;; *\ -fuse-linker-plugin*\ *) CFLAGS="$CFLAGS -fno-use-linker-plugin" ;; esac dnl Parse the compiler output and extract the necessary dnl objects, libraries and library flags. if AC_TRY_EVAL(ac_compile); then # Parse the compiler output and extract the necessary # objects, libraries and library flags. # Sentinel used to keep track of whether or not we are before # the conftest object file. pre_test_object_deps_done=no for p in `eval "$output_verbose_link_cmd"`; do case ${prev}${p} in -L* | -R* | -l*) # Some compilers place space between "-{L,R}" and the path. # Remove the space. if test $p = "-L" || test $p = "-R"; then prev=$p continue fi # Expand the sysroot to ease extracting the directories later. if test -z "$prev"; then case $p in -L*) func_stripname_cnf '-L' '' "$p"; prev=-L; p=$func_stripname_result ;; -R*) func_stripname_cnf '-R' '' "$p"; prev=-R; p=$func_stripname_result ;; -l*) func_stripname_cnf '-l' '' "$p"; prev=-l; p=$func_stripname_result ;; esac fi case $p in =*) func_stripname_cnf '=' '' "$p"; p=$lt_sysroot$func_stripname_result ;; esac if test "$pre_test_object_deps_done" = no; then case ${prev} in -L | -R) # Internal compiler library paths should come after those # provided the user. The postdeps already come after the # user supplied libs so there is no need to process them. if test -z "$_LT_TAGVAR(compiler_lib_search_path, $1)"; then _LT_TAGVAR(compiler_lib_search_path, $1)="${prev}${p}" else _LT_TAGVAR(compiler_lib_search_path, $1)="${_LT_TAGVAR(compiler_lib_search_path, $1)} ${prev}${p}" fi ;; # The "-l" case would never come before the object being # linked, so don't bother handling this case. esac else if test -z "$_LT_TAGVAR(postdeps, $1)"; then _LT_TAGVAR(postdeps, $1)="${prev}${p}" else _LT_TAGVAR(postdeps, $1)="${_LT_TAGVAR(postdeps, $1)} ${prev}${p}" fi fi prev= ;; *.lto.$objext) ;; # Ignore GCC LTO objects *.$objext) # This assumes that the test object file only shows up # once in the compiler output. if test "$p" = "conftest.$objext"; then pre_test_object_deps_done=yes continue fi if test "$pre_test_object_deps_done" = no; then if test -z "$_LT_TAGVAR(predep_objects, $1)"; then _LT_TAGVAR(predep_objects, $1)="$p" else _LT_TAGVAR(predep_objects, $1)="$_LT_TAGVAR(predep_objects, $1) $p" fi else if test -z "$_LT_TAGVAR(postdep_objects, $1)"; then _LT_TAGVAR(postdep_objects, $1)="$p" else _LT_TAGVAR(postdep_objects, $1)="$_LT_TAGVAR(postdep_objects, $1) $p" fi fi ;; *) ;; # Ignore the rest. esac done # Clean up. rm -f a.out a.exe else echo "libtool.m4: error: problem compiling $1 test program" fi $RM -f confest.$objext CFLAGS=$_lt_libdeps_save_CFLAGS # PORTME: override above test on systems where it is broken m4_if([$1], [CXX], [case $host_os in interix[[3-9]]*) # Interix 3.5 installs completely hosed .la files for C++, so rather than # hack all around it, let's just trust "g++" to DTRT. _LT_TAGVAR(predep_objects,$1)= _LT_TAGVAR(postdep_objects,$1)= _LT_TAGVAR(postdeps,$1)= ;; linux*) case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C++ 5.9 # The more standards-conforming stlport4 library is # incompatible with the Cstd library. Avoid specifying # it if it's in CXXFLAGS. Ignore libCrun as # -library=stlport4 depends on it. case " $CXX $CXXFLAGS " in *" -library=stlport4 "*) solaris_use_stlport4=yes ;; esac if test "$solaris_use_stlport4" != yes; then _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun' fi ;; esac ;; solaris*) case $cc_basename in CC* | sunCC*) # The more standards-conforming stlport4 library is # incompatible with the Cstd library. Avoid specifying # it if it's in CXXFLAGS. Ignore libCrun as # -library=stlport4 depends on it. case " $CXX $CXXFLAGS " in *" -library=stlport4 "*) solaris_use_stlport4=yes ;; esac # Adding this requires a known-good setup of shared libraries for # Sun compiler versions before 5.6, else PIC objects from an old # archive will be linked into the output, leading to subtle bugs. if test "$solaris_use_stlport4" != yes; then _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun' fi ;; esac ;; esac ]) case " $_LT_TAGVAR(postdeps, $1) " in *" -lc "*) _LT_TAGVAR(archive_cmds_need_lc, $1)=no ;; esac _LT_TAGVAR(compiler_lib_search_dirs, $1)= if test -n "${_LT_TAGVAR(compiler_lib_search_path, $1)}"; then _LT_TAGVAR(compiler_lib_search_dirs, $1)=`echo " ${_LT_TAGVAR(compiler_lib_search_path, $1)}" | ${SED} -e 's! -L! !g' -e 's!^ !!'` fi _LT_TAGDECL([], [compiler_lib_search_dirs], [1], [The directories searched by this compiler when creating a shared library]) _LT_TAGDECL([], [predep_objects], [1], [Dependencies to place before and after the objects being linked to create a shared library]) _LT_TAGDECL([], [postdep_objects], [1]) _LT_TAGDECL([], [predeps], [1]) _LT_TAGDECL([], [postdeps], [1]) _LT_TAGDECL([], [compiler_lib_search_path], [1], [The library search path used internally by the compiler when linking a shared library]) ])# _LT_SYS_HIDDEN_LIBDEPS # _LT_LANG_F77_CONFIG([TAG]) # -------------------------- # Ensure that the configuration variables for a Fortran 77 compiler are # suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to `libtool'. m4_defun([_LT_LANG_F77_CONFIG], [AC_LANG_PUSH(Fortran 77) if test -z "$F77" || test "X$F77" = "Xno"; then _lt_disable_F77=yes fi _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(allow_undefined_flag, $1)= _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(archive_expsym_cmds, $1)= _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(hardcode_libdir_separator, $1)= _LT_TAGVAR(hardcode_minus_L, $1)=no _LT_TAGVAR(hardcode_automatic, $1)=no _LT_TAGVAR(inherit_rpath, $1)=no _LT_TAGVAR(module_cmds, $1)= _LT_TAGVAR(module_expsym_cmds, $1)= _LT_TAGVAR(link_all_deplibs, $1)=unknown _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(reload_flag, $1)=$reload_flag _LT_TAGVAR(reload_cmds, $1)=$reload_cmds _LT_TAGVAR(no_undefined_flag, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no # Source file extension for f77 test sources. ac_ext=f # Object file extension for compiled f77 test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # No sense in running all these tests if we already determined that # the F77 compiler isn't working. Some variables (like enable_shared) # are currently assumed to apply to all compilers on this platform, # and will be corrupted by setting them based on a non-working compiler. if test "$_lt_disable_F77" != yes; then # Code to be used in simple compile tests lt_simple_compile_test_code="\ subroutine t return end " # Code to be used in simple link tests lt_simple_link_test_code="\ program t end " # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC="$CC" lt_save_GCC=$GCC lt_save_CFLAGS=$CFLAGS CC=${F77-"f77"} CFLAGS=$FFLAGS compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_CC_BASENAME([$compiler]) GCC=$G77 if test -n "$compiler"; then AC_MSG_CHECKING([if libtool supports shared libraries]) AC_MSG_RESULT([$can_build_shared]) AC_MSG_CHECKING([whether to build shared libraries]) test "$can_build_shared" = "no" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. case $host_os in aix3*) test "$enable_shared" = yes && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix[[4-9]]*) if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then test "$enable_shared" = yes && enable_static=no fi ;; esac AC_MSG_RESULT([$enable_shared]) AC_MSG_CHECKING([whether to build static libraries]) # Make sure either enable_shared or enable_static is yes. test "$enable_shared" = yes || enable_static=yes AC_MSG_RESULT([$enable_static]) _LT_TAGVAR(GCC, $1)="$G77" _LT_TAGVAR(LD, $1)="$LD" ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_SYS_DYNAMIC_LINKER($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi # test -n "$compiler" GCC=$lt_save_GCC CC="$lt_save_CC" CFLAGS="$lt_save_CFLAGS" fi # test "$_lt_disable_F77" != yes AC_LANG_POP ])# _LT_LANG_F77_CONFIG # _LT_LANG_FC_CONFIG([TAG]) # ------------------------- # Ensure that the configuration variables for a Fortran compiler are # suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to `libtool'. m4_defun([_LT_LANG_FC_CONFIG], [AC_LANG_PUSH(Fortran) if test -z "$FC" || test "X$FC" = "Xno"; then _lt_disable_FC=yes fi _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(allow_undefined_flag, $1)= _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(archive_expsym_cmds, $1)= _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(hardcode_libdir_separator, $1)= _LT_TAGVAR(hardcode_minus_L, $1)=no _LT_TAGVAR(hardcode_automatic, $1)=no _LT_TAGVAR(inherit_rpath, $1)=no _LT_TAGVAR(module_cmds, $1)= _LT_TAGVAR(module_expsym_cmds, $1)= _LT_TAGVAR(link_all_deplibs, $1)=unknown _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(reload_flag, $1)=$reload_flag _LT_TAGVAR(reload_cmds, $1)=$reload_cmds _LT_TAGVAR(no_undefined_flag, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no # Source file extension for fc test sources. ac_ext=${ac_fc_srcext-f} # Object file extension for compiled fc test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # No sense in running all these tests if we already determined that # the FC compiler isn't working. Some variables (like enable_shared) # are currently assumed to apply to all compilers on this platform, # and will be corrupted by setting them based on a non-working compiler. if test "$_lt_disable_FC" != yes; then # Code to be used in simple compile tests lt_simple_compile_test_code="\ subroutine t return end " # Code to be used in simple link tests lt_simple_link_test_code="\ program t end " # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC="$CC" lt_save_GCC=$GCC lt_save_CFLAGS=$CFLAGS CC=${FC-"f95"} CFLAGS=$FCFLAGS compiler=$CC GCC=$ac_cv_fc_compiler_gnu _LT_TAGVAR(compiler, $1)=$CC _LT_CC_BASENAME([$compiler]) if test -n "$compiler"; then AC_MSG_CHECKING([if libtool supports shared libraries]) AC_MSG_RESULT([$can_build_shared]) AC_MSG_CHECKING([whether to build shared libraries]) test "$can_build_shared" = "no" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. case $host_os in aix3*) test "$enable_shared" = yes && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix[[4-9]]*) if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then test "$enable_shared" = yes && enable_static=no fi ;; esac AC_MSG_RESULT([$enable_shared]) AC_MSG_CHECKING([whether to build static libraries]) # Make sure either enable_shared or enable_static is yes. test "$enable_shared" = yes || enable_static=yes AC_MSG_RESULT([$enable_static]) _LT_TAGVAR(GCC, $1)="$ac_cv_fc_compiler_gnu" _LT_TAGVAR(LD, $1)="$LD" ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... _LT_SYS_HIDDEN_LIBDEPS($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_SYS_DYNAMIC_LINKER($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi # test -n "$compiler" GCC=$lt_save_GCC CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS fi # test "$_lt_disable_FC" != yes AC_LANG_POP ])# _LT_LANG_FC_CONFIG # _LT_LANG_GCJ_CONFIG([TAG]) # -------------------------- # Ensure that the configuration variables for the GNU Java Compiler compiler # are suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to `libtool'. m4_defun([_LT_LANG_GCJ_CONFIG], [AC_REQUIRE([LT_PROG_GCJ])dnl AC_LANG_SAVE # Source file extension for Java test sources. ac_ext=java # Object file extension for compiled Java test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # Code to be used in simple compile tests lt_simple_compile_test_code="class foo {}" # Code to be used in simple link tests lt_simple_link_test_code='public class conftest { public static void main(String[[]] argv) {}; }' # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_CFLAGS=$CFLAGS lt_save_GCC=$GCC GCC=yes CC=${GCJ-"gcj"} CFLAGS=$GCJFLAGS compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_TAGVAR(LD, $1)="$LD" _LT_CC_BASENAME([$compiler]) # GCJ did not exist at the time GCC didn't implicitly link libc in. _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(reload_flag, $1)=$reload_flag _LT_TAGVAR(reload_cmds, $1)=$reload_cmds if test -n "$compiler"; then _LT_COMPILER_NO_RTTI($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi AC_LANG_RESTORE GCC=$lt_save_GCC CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS ])# _LT_LANG_GCJ_CONFIG # _LT_LANG_GO_CONFIG([TAG]) # -------------------------- # Ensure that the configuration variables for the GNU Go compiler # are suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to `libtool'. m4_defun([_LT_LANG_GO_CONFIG], [AC_REQUIRE([LT_PROG_GO])dnl AC_LANG_SAVE # Source file extension for Go test sources. ac_ext=go # Object file extension for compiled Go test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # Code to be used in simple compile tests lt_simple_compile_test_code="package main; func main() { }" # Code to be used in simple link tests lt_simple_link_test_code='package main; func main() { }' # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_CFLAGS=$CFLAGS lt_save_GCC=$GCC GCC=yes CC=${GOC-"gccgo"} CFLAGS=$GOFLAGS compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_TAGVAR(LD, $1)="$LD" _LT_CC_BASENAME([$compiler]) # Go did not exist at the time GCC didn't implicitly link libc in. _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(reload_flag, $1)=$reload_flag _LT_TAGVAR(reload_cmds, $1)=$reload_cmds if test -n "$compiler"; then _LT_COMPILER_NO_RTTI($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi AC_LANG_RESTORE GCC=$lt_save_GCC CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS ])# _LT_LANG_GO_CONFIG # _LT_LANG_RC_CONFIG([TAG]) # ------------------------- # Ensure that the configuration variables for the Windows resource compiler # are suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to `libtool'. m4_defun([_LT_LANG_RC_CONFIG], [AC_REQUIRE([LT_PROG_RC])dnl AC_LANG_SAVE # Source file extension for RC test sources. ac_ext=rc # Object file extension for compiled RC test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # Code to be used in simple compile tests lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }' # Code to be used in simple link tests lt_simple_link_test_code="$lt_simple_compile_test_code" # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC="$CC" lt_save_CFLAGS=$CFLAGS lt_save_GCC=$GCC GCC= CC=${RC-"windres"} CFLAGS= compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_CC_BASENAME([$compiler]) _LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes if test -n "$compiler"; then : _LT_CONFIG($1) fi GCC=$lt_save_GCC AC_LANG_RESTORE CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS ])# _LT_LANG_RC_CONFIG # LT_PROG_GCJ # ----------- AC_DEFUN([LT_PROG_GCJ], [m4_ifdef([AC_PROG_GCJ], [AC_PROG_GCJ], [m4_ifdef([A][M_PROG_GCJ], [A][M_PROG_GCJ], [AC_CHECK_TOOL(GCJ, gcj,) test "x${GCJFLAGS+set}" = xset || GCJFLAGS="-g -O2" AC_SUBST(GCJFLAGS)])])[]dnl ]) # Old name: AU_ALIAS([LT_AC_PROG_GCJ], [LT_PROG_GCJ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([LT_AC_PROG_GCJ], []) # LT_PROG_GO # ---------- AC_DEFUN([LT_PROG_GO], [AC_CHECK_TOOL(GOC, gccgo,) ]) # LT_PROG_RC # ---------- AC_DEFUN([LT_PROG_RC], [AC_CHECK_TOOL(RC, windres,) ]) # Old name: AU_ALIAS([LT_AC_PROG_RC], [LT_PROG_RC]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([LT_AC_PROG_RC], []) # _LT_DECL_EGREP # -------------- # If we don't have a new enough Autoconf to choose the best grep # available, choose the one first in the user's PATH. m4_defun([_LT_DECL_EGREP], [AC_REQUIRE([AC_PROG_EGREP])dnl AC_REQUIRE([AC_PROG_FGREP])dnl test -z "$GREP" && GREP=grep _LT_DECL([], [GREP], [1], [A grep program that handles long lines]) _LT_DECL([], [EGREP], [1], [An ERE matcher]) _LT_DECL([], [FGREP], [1], [A literal string matcher]) dnl Non-bleeding-edge autoconf doesn't subst GREP, so do it here too AC_SUBST([GREP]) ]) # _LT_DECL_OBJDUMP # -------------- # If we don't have a new enough Autoconf to choose the best objdump # available, choose the one first in the user's PATH. m4_defun([_LT_DECL_OBJDUMP], [AC_CHECK_TOOL(OBJDUMP, objdump, false) test -z "$OBJDUMP" && OBJDUMP=objdump _LT_DECL([], [OBJDUMP], [1], [An object symbol dumper]) AC_SUBST([OBJDUMP]) ]) # _LT_DECL_DLLTOOL # ---------------- # Ensure DLLTOOL variable is set. m4_defun([_LT_DECL_DLLTOOL], [AC_CHECK_TOOL(DLLTOOL, dlltool, false) test -z "$DLLTOOL" && DLLTOOL=dlltool _LT_DECL([], [DLLTOOL], [1], [DLL creation program]) AC_SUBST([DLLTOOL]) ]) # _LT_DECL_SED # ------------ # Check for a fully-functional sed program, that truncates # as few characters as possible. Prefer GNU sed if found. m4_defun([_LT_DECL_SED], [AC_PROG_SED test -z "$SED" && SED=sed Xsed="$SED -e 1s/^X//" _LT_DECL([], [SED], [1], [A sed program that does not truncate output]) _LT_DECL([], [Xsed], ["\$SED -e 1s/^X//"], [Sed that helps us avoid accidentally triggering echo(1) options like -n]) ])# _LT_DECL_SED m4_ifndef([AC_PROG_SED], [ # NOTE: This macro has been submitted for inclusion into # # GNU Autoconf as AC_PROG_SED. When it is available in # # a released version of Autoconf we should remove this # # macro and use it instead. # m4_defun([AC_PROG_SED], [AC_MSG_CHECKING([for a sed that does not truncate output]) AC_CACHE_VAL(lt_cv_path_SED, [# Loop through the user's path and test for sed and gsed. # Then use that list of sed's as ones to test for truncation. as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for lt_ac_prog in sed gsed; do for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$lt_ac_prog$ac_exec_ext"; then lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext" fi done done done IFS=$as_save_IFS lt_ac_max=0 lt_ac_count=0 # Add /usr/xpg4/bin/sed as it is typically found on Solaris # along with /bin/sed that truncates output. for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do test ! -f $lt_ac_sed && continue cat /dev/null > conftest.in lt_ac_count=0 echo $ECHO_N "0123456789$ECHO_C" >conftest.in # Check for GNU sed and select it if it is found. if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then lt_cv_path_SED=$lt_ac_sed break fi while true; do cat conftest.in conftest.in >conftest.tmp mv conftest.tmp conftest.in cp conftest.in conftest.nl echo >>conftest.nl $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break cmp -s conftest.out conftest.nl || break # 10000 chars as input seems more than enough test $lt_ac_count -gt 10 && break lt_ac_count=`expr $lt_ac_count + 1` if test $lt_ac_count -gt $lt_ac_max; then lt_ac_max=$lt_ac_count lt_cv_path_SED=$lt_ac_sed fi done done ]) SED=$lt_cv_path_SED AC_SUBST([SED]) AC_MSG_RESULT([$SED]) ])#AC_PROG_SED ])#m4_ifndef # Old name: AU_ALIAS([LT_AC_PROG_SED], [AC_PROG_SED]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([LT_AC_PROG_SED], []) # _LT_CHECK_SHELL_FEATURES # ------------------------ # Find out whether the shell is Bourne or XSI compatible, # or has some other useful features. m4_defun([_LT_CHECK_SHELL_FEATURES], [AC_MSG_CHECKING([whether the shell understands some XSI constructs]) # Try some XSI features xsi_shell=no ( _lt_dummy="a/b/c" test "${_lt_dummy##*/},${_lt_dummy%/*},${_lt_dummy#??}"${_lt_dummy%"$_lt_dummy"}, \ = c,a/b,b/c, \ && eval 'test $(( 1 + 1 )) -eq 2 \ && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \ && xsi_shell=yes AC_MSG_RESULT([$xsi_shell]) _LT_CONFIG_LIBTOOL_INIT([xsi_shell='$xsi_shell']) AC_MSG_CHECKING([whether the shell understands "+="]) lt_shell_append=no ( foo=bar; set foo baz; eval "$[1]+=\$[2]" && test "$foo" = barbaz ) \ >/dev/null 2>&1 \ && lt_shell_append=yes AC_MSG_RESULT([$lt_shell_append]) _LT_CONFIG_LIBTOOL_INIT([lt_shell_append='$lt_shell_append']) if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then lt_unset=unset else lt_unset=false fi _LT_DECL([], [lt_unset], [0], [whether the shell understands "unset"])dnl # test EBCDIC or ASCII case `echo X|tr X '\101'` in A) # ASCII based system # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr lt_SP2NL='tr \040 \012' lt_NL2SP='tr \015\012 \040\040' ;; *) # EBCDIC based system lt_SP2NL='tr \100 \n' lt_NL2SP='tr \r\n \100\100' ;; esac _LT_DECL([SP2NL], [lt_SP2NL], [1], [turn spaces into newlines])dnl _LT_DECL([NL2SP], [lt_NL2SP], [1], [turn newlines into spaces])dnl ])# _LT_CHECK_SHELL_FEATURES # _LT_PROG_FUNCTION_REPLACE (FUNCNAME, REPLACEMENT-BODY) # ------------------------------------------------------ # In `$cfgfile', look for function FUNCNAME delimited by `^FUNCNAME ()$' and # '^} FUNCNAME ', and replace its body with REPLACEMENT-BODY. m4_defun([_LT_PROG_FUNCTION_REPLACE], [dnl { sed -e '/^$1 ()$/,/^} # $1 /c\ $1 ()\ {\ m4_bpatsubsts([$2], [$], [\\], [^\([ ]\)], [\\\1]) } # Extended-shell $1 implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: ]) # _LT_PROG_REPLACE_SHELLFNS # ------------------------- # Replace existing portable implementations of several shell functions with # equivalent extended shell implementations where those features are available.. m4_defun([_LT_PROG_REPLACE_SHELLFNS], [if test x"$xsi_shell" = xyes; then _LT_PROG_FUNCTION_REPLACE([func_dirname], [dnl case ${1} in */*) func_dirname_result="${1%/*}${2}" ;; * ) func_dirname_result="${3}" ;; esac]) _LT_PROG_FUNCTION_REPLACE([func_basename], [dnl func_basename_result="${1##*/}"]) _LT_PROG_FUNCTION_REPLACE([func_dirname_and_basename], [dnl case ${1} in */*) func_dirname_result="${1%/*}${2}" ;; * ) func_dirname_result="${3}" ;; esac func_basename_result="${1##*/}"]) _LT_PROG_FUNCTION_REPLACE([func_stripname], [dnl # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are # positional parameters, so assign one to ordinary parameter first. func_stripname_result=${3} func_stripname_result=${func_stripname_result#"${1}"} func_stripname_result=${func_stripname_result%"${2}"}]) _LT_PROG_FUNCTION_REPLACE([func_split_long_opt], [dnl func_split_long_opt_name=${1%%=*} func_split_long_opt_arg=${1#*=}]) _LT_PROG_FUNCTION_REPLACE([func_split_short_opt], [dnl func_split_short_opt_arg=${1#??} func_split_short_opt_name=${1%"$func_split_short_opt_arg"}]) _LT_PROG_FUNCTION_REPLACE([func_lo2o], [dnl case ${1} in *.lo) func_lo2o_result=${1%.lo}.${objext} ;; *) func_lo2o_result=${1} ;; esac]) _LT_PROG_FUNCTION_REPLACE([func_xform], [ func_xform_result=${1%.*}.lo]) _LT_PROG_FUNCTION_REPLACE([func_arith], [ func_arith_result=$(( $[*] ))]) _LT_PROG_FUNCTION_REPLACE([func_len], [ func_len_result=${#1}]) fi if test x"$lt_shell_append" = xyes; then _LT_PROG_FUNCTION_REPLACE([func_append], [ eval "${1}+=\\${2}"]) _LT_PROG_FUNCTION_REPLACE([func_append_quoted], [dnl func_quote_for_eval "${2}" dnl m4 expansion turns \\\\ into \\, and then the shell eval turns that into \ eval "${1}+=\\\\ \\$func_quote_for_eval_result"]) # Save a `func_append' function call where possible by direct use of '+=' sed -e 's%func_append \([[a-zA-Z_]]\{1,\}\) "%\1+="%g' $cfgfile > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: else # Save a `func_append' function call even when '+=' is not available sed -e 's%func_append \([[a-zA-Z_]]\{1,\}\) "%\1="$\1%g' $cfgfile > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: fi if test x"$_lt_function_replace_fail" = x":"; then AC_MSG_WARN([Unable to substitute extended shell functions in $ofile]) fi ]) # _LT_PATH_CONVERSION_FUNCTIONS # ----------------------------- # Determine which file name conversion functions should be used by # func_to_host_file (and, implicitly, by func_to_host_path). These are needed # for certain cross-compile configurations and native mingw. m4_defun([_LT_PATH_CONVERSION_FUNCTIONS], [AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_REQUIRE([AC_CANONICAL_BUILD])dnl AC_MSG_CHECKING([how to convert $build file names to $host format]) AC_CACHE_VAL(lt_cv_to_host_file_cmd, [case $host in *-*-mingw* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32 ;; *-*-cygwin* ) lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32 ;; * ) # otherwise, assume *nix lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32 ;; esac ;; *-*-cygwin* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin ;; *-*-cygwin* ) lt_cv_to_host_file_cmd=func_convert_file_noop ;; * ) # otherwise, assume *nix lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin ;; esac ;; * ) # unhandled hosts (and "normal" native builds) lt_cv_to_host_file_cmd=func_convert_file_noop ;; esac ]) to_host_file_cmd=$lt_cv_to_host_file_cmd AC_MSG_RESULT([$lt_cv_to_host_file_cmd]) _LT_DECL([to_host_file_cmd], [lt_cv_to_host_file_cmd], [0], [convert $build file names to $host format])dnl AC_MSG_CHECKING([how to convert $build file names to toolchain format]) AC_CACHE_VAL(lt_cv_to_tool_file_cmd, [#assume ordinary cross tools, or native build. lt_cv_to_tool_file_cmd=func_convert_file_noop case $host in *-*-mingw* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32 ;; esac ;; esac ]) to_tool_file_cmd=$lt_cv_to_tool_file_cmd AC_MSG_RESULT([$lt_cv_to_tool_file_cmd]) _LT_DECL([to_tool_file_cmd], [lt_cv_to_tool_file_cmd], [0], [convert $build files to toolchain format])dnl ])# _LT_PATH_CONVERSION_FUNCTIONS # Helper functions for option handling. -*- Autoconf -*- # # Copyright (C) 2004, 2005, 2007, 2008, 2009 Free Software Foundation, # Inc. # Written by Gary V. Vaughan, 2004 # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. # serial 7 ltoptions.m4 # This is to help aclocal find these macros, as it can't see m4_define. AC_DEFUN([LTOPTIONS_VERSION], [m4_if([1])]) # _LT_MANGLE_OPTION(MACRO-NAME, OPTION-NAME) # ------------------------------------------ m4_define([_LT_MANGLE_OPTION], [[_LT_OPTION_]m4_bpatsubst($1__$2, [[^a-zA-Z0-9_]], [_])]) # _LT_SET_OPTION(MACRO-NAME, OPTION-NAME) # --------------------------------------- # Set option OPTION-NAME for macro MACRO-NAME, and if there is a # matching handler defined, dispatch to it. Other OPTION-NAMEs are # saved as a flag. m4_define([_LT_SET_OPTION], [m4_define(_LT_MANGLE_OPTION([$1], [$2]))dnl m4_ifdef(_LT_MANGLE_DEFUN([$1], [$2]), _LT_MANGLE_DEFUN([$1], [$2]), [m4_warning([Unknown $1 option `$2'])])[]dnl ]) # _LT_IF_OPTION(MACRO-NAME, OPTION-NAME, IF-SET, [IF-NOT-SET]) # ------------------------------------------------------------ # Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. m4_define([_LT_IF_OPTION], [m4_ifdef(_LT_MANGLE_OPTION([$1], [$2]), [$3], [$4])]) # _LT_UNLESS_OPTIONS(MACRO-NAME, OPTION-LIST, IF-NOT-SET) # ------------------------------------------------------- # Execute IF-NOT-SET unless all options in OPTION-LIST for MACRO-NAME # are set. m4_define([_LT_UNLESS_OPTIONS], [m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), [m4_ifdef(_LT_MANGLE_OPTION([$1], _LT_Option), [m4_define([$0_found])])])[]dnl m4_ifdef([$0_found], [m4_undefine([$0_found])], [$3 ])[]dnl ]) # _LT_SET_OPTIONS(MACRO-NAME, OPTION-LIST) # ---------------------------------------- # OPTION-LIST is a space-separated list of Libtool options associated # with MACRO-NAME. If any OPTION has a matching handler declared with # LT_OPTION_DEFINE, dispatch to that macro; otherwise complain about # the unknown option and exit. m4_defun([_LT_SET_OPTIONS], [# Set options m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), [_LT_SET_OPTION([$1], _LT_Option)]) m4_if([$1],[LT_INIT],[ dnl dnl Simply set some default values (i.e off) if boolean options were not dnl specified: _LT_UNLESS_OPTIONS([LT_INIT], [dlopen], [enable_dlopen=no ]) _LT_UNLESS_OPTIONS([LT_INIT], [win32-dll], [enable_win32_dll=no ]) dnl dnl If no reference was made to various pairs of opposing options, then dnl we run the default mode handler for the pair. For example, if neither dnl `shared' nor `disable-shared' was passed, we enable building of shared dnl archives by default: _LT_UNLESS_OPTIONS([LT_INIT], [shared disable-shared], [_LT_ENABLE_SHARED]) _LT_UNLESS_OPTIONS([LT_INIT], [static disable-static], [_LT_ENABLE_STATIC]) _LT_UNLESS_OPTIONS([LT_INIT], [pic-only no-pic], [_LT_WITH_PIC]) _LT_UNLESS_OPTIONS([LT_INIT], [fast-install disable-fast-install], [_LT_ENABLE_FAST_INSTALL]) ]) ])# _LT_SET_OPTIONS # _LT_MANGLE_DEFUN(MACRO-NAME, OPTION-NAME) # ----------------------------------------- m4_define([_LT_MANGLE_DEFUN], [[_LT_OPTION_DEFUN_]m4_bpatsubst(m4_toupper([$1__$2]), [[^A-Z0-9_]], [_])]) # LT_OPTION_DEFINE(MACRO-NAME, OPTION-NAME, CODE) # ----------------------------------------------- m4_define([LT_OPTION_DEFINE], [m4_define(_LT_MANGLE_DEFUN([$1], [$2]), [$3])[]dnl ])# LT_OPTION_DEFINE # dlopen # ------ LT_OPTION_DEFINE([LT_INIT], [dlopen], [enable_dlopen=yes ]) AU_DEFUN([AC_LIBTOOL_DLOPEN], [_LT_SET_OPTION([LT_INIT], [dlopen]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the `dlopen' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_DLOPEN], []) # win32-dll # --------- # Declare package support for building win32 dll's. LT_OPTION_DEFINE([LT_INIT], [win32-dll], [enable_win32_dll=yes case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*) AC_CHECK_TOOL(AS, as, false) AC_CHECK_TOOL(DLLTOOL, dlltool, false) AC_CHECK_TOOL(OBJDUMP, objdump, false) ;; esac test -z "$AS" && AS=as _LT_DECL([], [AS], [1], [Assembler program])dnl test -z "$DLLTOOL" && DLLTOOL=dlltool _LT_DECL([], [DLLTOOL], [1], [DLL creation program])dnl test -z "$OBJDUMP" && OBJDUMP=objdump _LT_DECL([], [OBJDUMP], [1], [Object dumper program])dnl ])# win32-dll AU_DEFUN([AC_LIBTOOL_WIN32_DLL], [AC_REQUIRE([AC_CANONICAL_HOST])dnl _LT_SET_OPTION([LT_INIT], [win32-dll]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the `win32-dll' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_WIN32_DLL], []) # _LT_ENABLE_SHARED([DEFAULT]) # ---------------------------- # implement the --enable-shared flag, and supports the `shared' and # `disable-shared' LT_INIT options. # DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. m4_define([_LT_ENABLE_SHARED], [m4_define([_LT_ENABLE_SHARED_DEFAULT], [m4_if($1, no, no, yes)])dnl AC_ARG_ENABLE([shared], [AS_HELP_STRING([--enable-shared@<:@=PKGS@:>@], [build shared libraries @<:@default=]_LT_ENABLE_SHARED_DEFAULT[@:>@])], [p=${PACKAGE-default} case $enableval in yes) enable_shared=yes ;; no) enable_shared=no ;; *) enable_shared=no # Look at the argument we got. We use all the common list separators. lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," for pkg in $enableval; do IFS="$lt_save_ifs" if test "X$pkg" = "X$p"; then enable_shared=yes fi done IFS="$lt_save_ifs" ;; esac], [enable_shared=]_LT_ENABLE_SHARED_DEFAULT) _LT_DECL([build_libtool_libs], [enable_shared], [0], [Whether or not to build shared libraries]) ])# _LT_ENABLE_SHARED LT_OPTION_DEFINE([LT_INIT], [shared], [_LT_ENABLE_SHARED([yes])]) LT_OPTION_DEFINE([LT_INIT], [disable-shared], [_LT_ENABLE_SHARED([no])]) # Old names: AC_DEFUN([AC_ENABLE_SHARED], [_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[shared]) ]) AC_DEFUN([AC_DISABLE_SHARED], [_LT_SET_OPTION([LT_INIT], [disable-shared]) ]) AU_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)]) AU_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AM_ENABLE_SHARED], []) dnl AC_DEFUN([AM_DISABLE_SHARED], []) # _LT_ENABLE_STATIC([DEFAULT]) # ---------------------------- # implement the --enable-static flag, and support the `static' and # `disable-static' LT_INIT options. # DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. m4_define([_LT_ENABLE_STATIC], [m4_define([_LT_ENABLE_STATIC_DEFAULT], [m4_if($1, no, no, yes)])dnl AC_ARG_ENABLE([static], [AS_HELP_STRING([--enable-static@<:@=PKGS@:>@], [build static libraries @<:@default=]_LT_ENABLE_STATIC_DEFAULT[@:>@])], [p=${PACKAGE-default} case $enableval in yes) enable_static=yes ;; no) enable_static=no ;; *) enable_static=no # Look at the argument we got. We use all the common list separators. lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," for pkg in $enableval; do IFS="$lt_save_ifs" if test "X$pkg" = "X$p"; then enable_static=yes fi done IFS="$lt_save_ifs" ;; esac], [enable_static=]_LT_ENABLE_STATIC_DEFAULT) _LT_DECL([build_old_libs], [enable_static], [0], [Whether or not to build static libraries]) ])# _LT_ENABLE_STATIC LT_OPTION_DEFINE([LT_INIT], [static], [_LT_ENABLE_STATIC([yes])]) LT_OPTION_DEFINE([LT_INIT], [disable-static], [_LT_ENABLE_STATIC([no])]) # Old names: AC_DEFUN([AC_ENABLE_STATIC], [_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[static]) ]) AC_DEFUN([AC_DISABLE_STATIC], [_LT_SET_OPTION([LT_INIT], [disable-static]) ]) AU_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)]) AU_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AM_ENABLE_STATIC], []) dnl AC_DEFUN([AM_DISABLE_STATIC], []) # _LT_ENABLE_FAST_INSTALL([DEFAULT]) # ---------------------------------- # implement the --enable-fast-install flag, and support the `fast-install' # and `disable-fast-install' LT_INIT options. # DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. m4_define([_LT_ENABLE_FAST_INSTALL], [m4_define([_LT_ENABLE_FAST_INSTALL_DEFAULT], [m4_if($1, no, no, yes)])dnl AC_ARG_ENABLE([fast-install], [AS_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@], [optimize for fast installation @<:@default=]_LT_ENABLE_FAST_INSTALL_DEFAULT[@:>@])], [p=${PACKAGE-default} case $enableval in yes) enable_fast_install=yes ;; no) enable_fast_install=no ;; *) enable_fast_install=no # Look at the argument we got. We use all the common list separators. lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," for pkg in $enableval; do IFS="$lt_save_ifs" if test "X$pkg" = "X$p"; then enable_fast_install=yes fi done IFS="$lt_save_ifs" ;; esac], [enable_fast_install=]_LT_ENABLE_FAST_INSTALL_DEFAULT) _LT_DECL([fast_install], [enable_fast_install], [0], [Whether or not to optimize for fast installation])dnl ])# _LT_ENABLE_FAST_INSTALL LT_OPTION_DEFINE([LT_INIT], [fast-install], [_LT_ENABLE_FAST_INSTALL([yes])]) LT_OPTION_DEFINE([LT_INIT], [disable-fast-install], [_LT_ENABLE_FAST_INSTALL([no])]) # Old names: AU_DEFUN([AC_ENABLE_FAST_INSTALL], [_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[fast-install]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the `fast-install' option into LT_INIT's first parameter.]) ]) AU_DEFUN([AC_DISABLE_FAST_INSTALL], [_LT_SET_OPTION([LT_INIT], [disable-fast-install]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the `disable-fast-install' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_ENABLE_FAST_INSTALL], []) dnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], []) # _LT_WITH_PIC([MODE]) # -------------------- # implement the --with-pic flag, and support the `pic-only' and `no-pic' # LT_INIT options. # MODE is either `yes' or `no'. If omitted, it defaults to `both'. m4_define([_LT_WITH_PIC], [AC_ARG_WITH([pic], [AS_HELP_STRING([--with-pic@<:@=PKGS@:>@], [try to use only PIC/non-PIC objects @<:@default=use both@:>@])], [lt_p=${PACKAGE-default} case $withval in yes|no) pic_mode=$withval ;; *) pic_mode=default # Look at the argument we got. We use all the common list separators. lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," for lt_pkg in $withval; do IFS="$lt_save_ifs" if test "X$lt_pkg" = "X$lt_p"; then pic_mode=yes fi done IFS="$lt_save_ifs" ;; esac], [pic_mode=default]) test -z "$pic_mode" && pic_mode=m4_default([$1], [default]) _LT_DECL([], [pic_mode], [0], [What type of objects to build])dnl ])# _LT_WITH_PIC LT_OPTION_DEFINE([LT_INIT], [pic-only], [_LT_WITH_PIC([yes])]) LT_OPTION_DEFINE([LT_INIT], [no-pic], [_LT_WITH_PIC([no])]) # Old name: AU_DEFUN([AC_LIBTOOL_PICMODE], [_LT_SET_OPTION([LT_INIT], [pic-only]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the `pic-only' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_PICMODE], []) m4_define([_LTDL_MODE], []) LT_OPTION_DEFINE([LTDL_INIT], [nonrecursive], [m4_define([_LTDL_MODE], [nonrecursive])]) LT_OPTION_DEFINE([LTDL_INIT], [recursive], [m4_define([_LTDL_MODE], [recursive])]) LT_OPTION_DEFINE([LTDL_INIT], [subproject], [m4_define([_LTDL_MODE], [subproject])]) m4_define([_LTDL_TYPE], []) LT_OPTION_DEFINE([LTDL_INIT], [installable], [m4_define([_LTDL_TYPE], [installable])]) LT_OPTION_DEFINE([LTDL_INIT], [convenience], [m4_define([_LTDL_TYPE], [convenience])]) # ltsugar.m4 -- libtool m4 base layer. -*-Autoconf-*- # # Copyright (C) 2004, 2005, 2007, 2008 Free Software Foundation, Inc. # Written by Gary V. Vaughan, 2004 # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. # serial 6 ltsugar.m4 # This is to help aclocal find these macros, as it can't see m4_define. AC_DEFUN([LTSUGAR_VERSION], [m4_if([0.1])]) # lt_join(SEP, ARG1, [ARG2...]) # ----------------------------- # Produce ARG1SEPARG2...SEPARGn, omitting [] arguments and their # associated separator. # Needed until we can rely on m4_join from Autoconf 2.62, since all earlier # versions in m4sugar had bugs. m4_define([lt_join], [m4_if([$#], [1], [], [$#], [2], [[$2]], [m4_if([$2], [], [], [[$2]_])$0([$1], m4_shift(m4_shift($@)))])]) m4_define([_lt_join], [m4_if([$#$2], [2], [], [m4_if([$2], [], [], [[$1$2]])$0([$1], m4_shift(m4_shift($@)))])]) # lt_car(LIST) # lt_cdr(LIST) # ------------ # Manipulate m4 lists. # These macros are necessary as long as will still need to support # Autoconf-2.59 which quotes differently. m4_define([lt_car], [[$1]]) m4_define([lt_cdr], [m4_if([$#], 0, [m4_fatal([$0: cannot be called without arguments])], [$#], 1, [], [m4_dquote(m4_shift($@))])]) m4_define([lt_unquote], $1) # lt_append(MACRO-NAME, STRING, [SEPARATOR]) # ------------------------------------------ # Redefine MACRO-NAME to hold its former content plus `SEPARATOR'`STRING'. # Note that neither SEPARATOR nor STRING are expanded; they are appended # to MACRO-NAME as is (leaving the expansion for when MACRO-NAME is invoked). # No SEPARATOR is output if MACRO-NAME was previously undefined (different # than defined and empty). # # This macro is needed until we can rely on Autoconf 2.62, since earlier # versions of m4sugar mistakenly expanded SEPARATOR but not STRING. m4_define([lt_append], [m4_define([$1], m4_ifdef([$1], [m4_defn([$1])[$3]])[$2])]) # lt_combine(SEP, PREFIX-LIST, INFIX, SUFFIX1, [SUFFIX2...]) # ---------------------------------------------------------- # Produce a SEP delimited list of all paired combinations of elements of # PREFIX-LIST with SUFFIX1 through SUFFIXn. Each element of the list # has the form PREFIXmINFIXSUFFIXn. # Needed until we can rely on m4_combine added in Autoconf 2.62. m4_define([lt_combine], [m4_if(m4_eval([$# > 3]), [1], [m4_pushdef([_Lt_sep], [m4_define([_Lt_sep], m4_defn([lt_car]))])]]dnl [[m4_foreach([_Lt_prefix], [$2], [m4_foreach([_Lt_suffix], ]m4_dquote(m4_dquote(m4_shift(m4_shift(m4_shift($@)))))[, [_Lt_sep([$1])[]m4_defn([_Lt_prefix])[$3]m4_defn([_Lt_suffix])])])])]) # lt_if_append_uniq(MACRO-NAME, VARNAME, [SEPARATOR], [UNIQ], [NOT-UNIQ]) # ----------------------------------------------------------------------- # Iff MACRO-NAME does not yet contain VARNAME, then append it (delimited # by SEPARATOR if supplied) and expand UNIQ, else NOT-UNIQ. m4_define([lt_if_append_uniq], [m4_ifdef([$1], [m4_if(m4_index([$3]m4_defn([$1])[$3], [$3$2$3]), [-1], [lt_append([$1], [$2], [$3])$4], [$5])], [lt_append([$1], [$2], [$3])$4])]) # lt_dict_add(DICT, KEY, VALUE) # ----------------------------- m4_define([lt_dict_add], [m4_define([$1($2)], [$3])]) # lt_dict_add_subkey(DICT, KEY, SUBKEY, VALUE) # -------------------------------------------- m4_define([lt_dict_add_subkey], [m4_define([$1($2:$3)], [$4])]) # lt_dict_fetch(DICT, KEY, [SUBKEY]) # ---------------------------------- m4_define([lt_dict_fetch], [m4_ifval([$3], m4_ifdef([$1($2:$3)], [m4_defn([$1($2:$3)])]), m4_ifdef([$1($2)], [m4_defn([$1($2)])]))]) # lt_if_dict_fetch(DICT, KEY, [SUBKEY], VALUE, IF-TRUE, [IF-FALSE]) # ----------------------------------------------------------------- m4_define([lt_if_dict_fetch], [m4_if(lt_dict_fetch([$1], [$2], [$3]), [$4], [$5], [$6])]) # lt_dict_filter(DICT, [SUBKEY], VALUE, [SEPARATOR], KEY, [...]) # -------------------------------------------------------------- m4_define([lt_dict_filter], [m4_if([$5], [], [], [lt_join(m4_quote(m4_default([$4], [[, ]])), lt_unquote(m4_split(m4_normalize(m4_foreach(_Lt_key, lt_car([m4_shiftn(4, $@)]), [lt_if_dict_fetch([$1], _Lt_key, [$2], [$3], [_Lt_key ])])))))])[]dnl ]) # ltversion.m4 -- version numbers -*- Autoconf -*- # # Copyright (C) 2004 Free Software Foundation, Inc. # Written by Scott James Remnant, 2004 # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. # @configure_input@ # serial 3337 ltversion.m4 # This file is part of GNU Libtool m4_define([LT_PACKAGE_VERSION], [2.4.2]) m4_define([LT_PACKAGE_REVISION], [1.3337]) AC_DEFUN([LTVERSION_VERSION], [macro_version='2.4.2' macro_revision='1.3337' _LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?]) _LT_DECL(, macro_revision, 0) ]) # lt~obsolete.m4 -- aclocal satisfying obsolete definitions. -*-Autoconf-*- # # Copyright (C) 2004, 2005, 2007, 2009 Free Software Foundation, Inc. # Written by Scott James Remnant, 2004. # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. # serial 5 lt~obsolete.m4 # These exist entirely to fool aclocal when bootstrapping libtool. # # In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN) # which have later been changed to m4_define as they aren't part of the # exported API, or moved to Autoconf or Automake where they belong. # # The trouble is, aclocal is a bit thick. It'll see the old AC_DEFUN # in /usr/share/aclocal/libtool.m4 and remember it, then when it sees us # using a macro with the same name in our local m4/libtool.m4 it'll # pull the old libtool.m4 in (it doesn't see our shiny new m4_define # and doesn't know about Autoconf macros at all.) # # So we provide this file, which has a silly filename so it's always # included after everything else. This provides aclocal with the # AC_DEFUNs it wants, but when m4 processes it, it doesn't do anything # because those macros already exist, or will be overwritten later. # We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6. # # Anytime we withdraw an AC_DEFUN or AU_DEFUN, remember to add it here. # Yes, that means every name once taken will need to remain here until # we give up compatibility with versions before 1.7, at which point # we need to keep only those names which we still refer to. # This is to help aclocal find these macros, as it can't see m4_define. AC_DEFUN([LTOBSOLETE_VERSION], [m4_if([1])]) m4_ifndef([AC_LIBTOOL_LINKER_OPTION], [AC_DEFUN([AC_LIBTOOL_LINKER_OPTION])]) m4_ifndef([AC_PROG_EGREP], [AC_DEFUN([AC_PROG_EGREP])]) m4_ifndef([_LT_AC_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH])]) m4_ifndef([_LT_AC_SHELL_INIT], [AC_DEFUN([_LT_AC_SHELL_INIT])]) m4_ifndef([_LT_AC_SYS_LIBPATH_AIX], [AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX])]) m4_ifndef([_LT_PROG_LTMAIN], [AC_DEFUN([_LT_PROG_LTMAIN])]) m4_ifndef([_LT_AC_TAGVAR], [AC_DEFUN([_LT_AC_TAGVAR])]) m4_ifndef([AC_LTDL_ENABLE_INSTALL], [AC_DEFUN([AC_LTDL_ENABLE_INSTALL])]) m4_ifndef([AC_LTDL_PREOPEN], [AC_DEFUN([AC_LTDL_PREOPEN])]) m4_ifndef([_LT_AC_SYS_COMPILER], [AC_DEFUN([_LT_AC_SYS_COMPILER])]) m4_ifndef([_LT_AC_LOCK], [AC_DEFUN([_LT_AC_LOCK])]) m4_ifndef([AC_LIBTOOL_SYS_OLD_ARCHIVE], [AC_DEFUN([AC_LIBTOOL_SYS_OLD_ARCHIVE])]) m4_ifndef([_LT_AC_TRY_DLOPEN_SELF], [AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF])]) m4_ifndef([AC_LIBTOOL_PROG_CC_C_O], [AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O])]) m4_ifndef([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], [AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS])]) m4_ifndef([AC_LIBTOOL_OBJDIR], [AC_DEFUN([AC_LIBTOOL_OBJDIR])]) m4_ifndef([AC_LTDL_OBJDIR], [AC_DEFUN([AC_LTDL_OBJDIR])]) m4_ifndef([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], [AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH])]) m4_ifndef([AC_LIBTOOL_SYS_LIB_STRIP], [AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP])]) m4_ifndef([AC_PATH_MAGIC], [AC_DEFUN([AC_PATH_MAGIC])]) m4_ifndef([AC_PROG_LD_GNU], [AC_DEFUN([AC_PROG_LD_GNU])]) m4_ifndef([AC_PROG_LD_RELOAD_FLAG], [AC_DEFUN([AC_PROG_LD_RELOAD_FLAG])]) m4_ifndef([AC_DEPLIBS_CHECK_METHOD], [AC_DEFUN([AC_DEPLIBS_CHECK_METHOD])]) m4_ifndef([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI])]) m4_ifndef([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], [AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])]) m4_ifndef([AC_LIBTOOL_PROG_COMPILER_PIC], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC])]) m4_ifndef([AC_LIBTOOL_PROG_LD_SHLIBS], [AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS])]) m4_ifndef([AC_LIBTOOL_POSTDEP_PREDEP], [AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP])]) m4_ifndef([LT_AC_PROG_EGREP], [AC_DEFUN([LT_AC_PROG_EGREP])]) m4_ifndef([LT_AC_PROG_SED], [AC_DEFUN([LT_AC_PROG_SED])]) m4_ifndef([_LT_CC_BASENAME], [AC_DEFUN([_LT_CC_BASENAME])]) m4_ifndef([_LT_COMPILER_BOILERPLATE], [AC_DEFUN([_LT_COMPILER_BOILERPLATE])]) m4_ifndef([_LT_LINKER_BOILERPLATE], [AC_DEFUN([_LT_LINKER_BOILERPLATE])]) m4_ifndef([_AC_PROG_LIBTOOL], [AC_DEFUN([_AC_PROG_LIBTOOL])]) m4_ifndef([AC_LIBTOOL_SETUP], [AC_DEFUN([AC_LIBTOOL_SETUP])]) m4_ifndef([_LT_AC_CHECK_DLFCN], [AC_DEFUN([_LT_AC_CHECK_DLFCN])]) m4_ifndef([AC_LIBTOOL_SYS_DYNAMIC_LINKER], [AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER])]) m4_ifndef([_LT_AC_TAGCONFIG], [AC_DEFUN([_LT_AC_TAGCONFIG])]) m4_ifndef([AC_DISABLE_FAST_INSTALL], [AC_DEFUN([AC_DISABLE_FAST_INSTALL])]) m4_ifndef([_LT_AC_LANG_CXX], [AC_DEFUN([_LT_AC_LANG_CXX])]) m4_ifndef([_LT_AC_LANG_F77], [AC_DEFUN([_LT_AC_LANG_F77])]) m4_ifndef([_LT_AC_LANG_GCJ], [AC_DEFUN([_LT_AC_LANG_GCJ])]) m4_ifndef([AC_LIBTOOL_LANG_C_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG])]) m4_ifndef([_LT_AC_LANG_C_CONFIG], [AC_DEFUN([_LT_AC_LANG_C_CONFIG])]) m4_ifndef([AC_LIBTOOL_LANG_CXX_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG])]) m4_ifndef([_LT_AC_LANG_CXX_CONFIG], [AC_DEFUN([_LT_AC_LANG_CXX_CONFIG])]) m4_ifndef([AC_LIBTOOL_LANG_F77_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG])]) m4_ifndef([_LT_AC_LANG_F77_CONFIG], [AC_DEFUN([_LT_AC_LANG_F77_CONFIG])]) m4_ifndef([AC_LIBTOOL_LANG_GCJ_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG])]) m4_ifndef([_LT_AC_LANG_GCJ_CONFIG], [AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG])]) m4_ifndef([AC_LIBTOOL_LANG_RC_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG])]) m4_ifndef([_LT_AC_LANG_RC_CONFIG], [AC_DEFUN([_LT_AC_LANG_RC_CONFIG])]) m4_ifndef([AC_LIBTOOL_CONFIG], [AC_DEFUN([AC_LIBTOOL_CONFIG])]) m4_ifndef([_LT_AC_FILE_LTDLL_C], [AC_DEFUN([_LT_AC_FILE_LTDLL_C])]) m4_ifndef([_LT_REQUIRED_DARWIN_CHECKS], [AC_DEFUN([_LT_REQUIRED_DARWIN_CHECKS])]) m4_ifndef([_LT_AC_PROG_CXXCPP], [AC_DEFUN([_LT_AC_PROG_CXXCPP])]) m4_ifndef([_LT_PREPARE_SED_QUOTE_VARS], [AC_DEFUN([_LT_PREPARE_SED_QUOTE_VARS])]) m4_ifndef([_LT_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_PROG_ECHO_BACKSLASH])]) m4_ifndef([_LT_PROG_F77], [AC_DEFUN([_LT_PROG_F77])]) m4_ifndef([_LT_PROG_FC], [AC_DEFUN([_LT_PROG_FC])]) m4_ifndef([_LT_PROG_CXX], [AC_DEFUN([_LT_PROG_CXX])]) # pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*- # serial 1 (pkg-config-0.24) # # Copyright © 2004 Scott James Remnant <scott@netsplit.com>. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # PKG_PROG_PKG_CONFIG([MIN-VERSION]) # ---------------------------------- AC_DEFUN([PKG_PROG_PKG_CONFIG], [m4_pattern_forbid([^_?PKG_[A-Z_]+$]) m4_pattern_allow([^PKG_CONFIG(_(PATH|LIBDIR|SYSROOT_DIR|ALLOW_SYSTEM_(CFLAGS|LIBS)))?$]) m4_pattern_allow([^PKG_CONFIG_(DISABLE_UNINSTALLED|TOP_BUILD_DIR|DEBUG_SPEW)$]) AC_ARG_VAR([PKG_CONFIG], [path to pkg-config utility]) AC_ARG_VAR([PKG_CONFIG_PATH], [directories to add to pkg-config's search path]) AC_ARG_VAR([PKG_CONFIG_LIBDIR], [path overriding pkg-config's built-in search path]) if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then AC_PATH_TOOL([PKG_CONFIG], [pkg-config]) fi if test -n "$PKG_CONFIG"; then _pkg_min_version=m4_default([$1], [0.9.0]) AC_MSG_CHECKING([pkg-config is at least version $_pkg_min_version]) if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) PKG_CONFIG="" fi fi[]dnl ])# PKG_PROG_PKG_CONFIG # PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) # # Check to see whether a particular set of modules exists. Similar # to PKG_CHECK_MODULES(), but does not set variables or print errors. # # Please remember that m4 expands AC_REQUIRE([PKG_PROG_PKG_CONFIG]) # only at the first occurence in configure.ac, so if the first place # it's called might be skipped (such as if it is within an "if", you # have to call PKG_CHECK_EXISTS manually # -------------------------------------------------------------- AC_DEFUN([PKG_CHECK_EXISTS], [AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl if test -n "$PKG_CONFIG" && \ AC_RUN_LOG([$PKG_CONFIG --exists --print-errors "$1"]); then m4_default([$2], [:]) m4_ifvaln([$3], [else $3])dnl fi]) # _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES]) # --------------------------------------------- m4_define([_PKG_CONFIG], [if test -n "$$1"; then pkg_cv_[]$1="$$1" elif test -n "$PKG_CONFIG"; then PKG_CHECK_EXISTS([$3], [pkg_cv_[]$1=`$PKG_CONFIG --[]$2 "$3" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes ], [pkg_failed=yes]) else pkg_failed=untried fi[]dnl ])# _PKG_CONFIG # _PKG_SHORT_ERRORS_SUPPORTED # ----------------------------- AC_DEFUN([_PKG_SHORT_ERRORS_SUPPORTED], [AC_REQUIRE([PKG_PROG_PKG_CONFIG]) if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then _pkg_short_errors_supported=yes else _pkg_short_errors_supported=no fi[]dnl ])# _PKG_SHORT_ERRORS_SUPPORTED # PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND], # [ACTION-IF-NOT-FOUND]) # # # Note that if there is a possibility the first call to # PKG_CHECK_MODULES might not happen, you should be sure to include an # explicit call to PKG_PROG_PKG_CONFIG in your configure.ac # # # -------------------------------------------------------------- AC_DEFUN([PKG_CHECK_MODULES], [AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl pkg_failed=no AC_MSG_CHECKING([for $1]) _PKG_CONFIG([$1][_CFLAGS], [cflags], [$2]) _PKG_CONFIG([$1][_LIBS], [libs], [$2]) m4_define([_PKG_TEXT], [Alternatively, you may set the environment variables $1[]_CFLAGS and $1[]_LIBS to avoid the need to call pkg-config. See the pkg-config man page for more details.]) if test $pkg_failed = yes; then AC_MSG_RESULT([no]) _PKG_SHORT_ERRORS_SUPPORTED if test $_pkg_short_errors_supported = yes; then $1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$2" 2>&1` else $1[]_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$2" 2>&1` fi # Put the nasty error message in config.log where it belongs echo "$$1[]_PKG_ERRORS" >&AS_MESSAGE_LOG_FD m4_default([$4], [AC_MSG_ERROR( [Package requirements ($2) were not met: $$1_PKG_ERRORS Consider adjusting the PKG_CONFIG_PATH environment variable if you installed software in a non-standard prefix. _PKG_TEXT])[]dnl ]) elif test $pkg_failed = untried; then AC_MSG_RESULT([no]) m4_default([$4], [AC_MSG_FAILURE( [The pkg-config script could not be found or is too old. Make sure it is in your PATH or set the PKG_CONFIG environment variable to the full path to pkg-config. _PKG_TEXT To get pkg-config, see <http://pkg-config.freedesktop.org/>.])[]dnl ]) else $1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS $1[]_LIBS=$pkg_cv_[]$1[]_LIBS AC_MSG_RESULT([yes]) $3 fi[]dnl ])# PKG_CHECK_MODULES # PKG_INSTALLDIR(DIRECTORY) # ------------------------- # Substitutes the variable pkgconfigdir as the location where a module # should install pkg-config .pc files. By default the directory is # $libdir/pkgconfig, but the default can be changed by passing # DIRECTORY. The user can override through the --with-pkgconfigdir # parameter. AC_DEFUN([PKG_INSTALLDIR], [m4_pushdef([pkg_default], [m4_default([$1], ['${libdir}/pkgconfig'])]) m4_pushdef([pkg_description], [pkg-config installation directory @<:@]pkg_default[@:>@]) AC_ARG_WITH([pkgconfigdir], [AS_HELP_STRING([--with-pkgconfigdir], pkg_description)],, [with_pkgconfigdir=]pkg_default) AC_SUBST([pkgconfigdir], [$with_pkgconfigdir]) m4_popdef([pkg_default]) m4_popdef([pkg_description]) ]) dnl PKG_INSTALLDIR # PKG_NOARCH_INSTALLDIR(DIRECTORY) # ------------------------- # Substitutes the variable noarch_pkgconfigdir as the location where a # module should install arch-independent pkg-config .pc files. By # default the directory is $datadir/pkgconfig, but the default can be # changed by passing DIRECTORY. The user can override through the # --with-noarch-pkgconfigdir parameter. AC_DEFUN([PKG_NOARCH_INSTALLDIR], [m4_pushdef([pkg_default], [m4_default([$1], ['${datadir}/pkgconfig'])]) m4_pushdef([pkg_description], [pkg-config arch-independent installation directory @<:@]pkg_default[@:>@]) AC_ARG_WITH([noarch-pkgconfigdir], [AS_HELP_STRING([--with-noarch-pkgconfigdir], pkg_description)],, [with_noarch_pkgconfigdir=]pkg_default) AC_SUBST([noarch_pkgconfigdir], [$with_noarch_pkgconfigdir]) m4_popdef([pkg_default]) m4_popdef([pkg_description]) ]) dnl PKG_NOARCH_INSTALLDIR # PKG_CHECK_VAR(VARIABLE, MODULE, CONFIG-VARIABLE, # [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) # ------------------------------------------- # Retrieves the value of the pkg-config variable for the given module. AC_DEFUN([PKG_CHECK_VAR], [AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl AC_ARG_VAR([$1], [value of $3 for $2, overriding pkg-config])dnl _PKG_CONFIG([$1], [variable="][$3]["], [$2]) AS_VAR_COPY([$1], [pkg_cv_][$1]) AS_VAR_IF([$1], [""], [$5], [$4])dnl ])# PKG_CHECK_VAR # Copyright (C) 2002-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_AUTOMAKE_VERSION(VERSION) # ---------------------------- # Automake X.Y traces this macro to ensure aclocal.m4 has been # generated from the m4 files accompanying Automake X.Y. # (This private macro should not be called outside this file.) AC_DEFUN([AM_AUTOMAKE_VERSION], [am__api_version='1.14' dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to dnl require some minimum version. Point them to the right macro. m4_if([$1], [1.14.1], [], [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl ]) # _AM_AUTOCONF_VERSION(VERSION) # ----------------------------- # aclocal traces this macro to find the Autoconf version. # This is a private macro too. Using m4_define simplifies # the logic in aclocal, which can simply ignore this definition. m4_define([_AM_AUTOCONF_VERSION], []) # AM_SET_CURRENT_AUTOMAKE_VERSION # ------------------------------- # Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. # This function is AC_REQUIREd by AM_INIT_AUTOMAKE. AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], [AM_AUTOMAKE_VERSION([1.14.1])dnl m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) # AM_AUX_DIR_EXPAND -*- Autoconf -*- # Copyright (C) 2001-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets # $ac_aux_dir to '$srcdir/foo'. In other projects, it is set to # '$srcdir', '$srcdir/..', or '$srcdir/../..'. # # Of course, Automake must honor this variable whenever it calls a # tool from the auxiliary directory. The problem is that $srcdir (and # therefore $ac_aux_dir as well) can be either absolute or relative, # depending on how configure is run. This is pretty annoying, since # it makes $ac_aux_dir quite unusable in subdirectories: in the top # source directory, any form will work fine, but in subdirectories a # relative path needs to be adjusted first. # # $ac_aux_dir/missing # fails when called from a subdirectory if $ac_aux_dir is relative # $top_srcdir/$ac_aux_dir/missing # fails if $ac_aux_dir is absolute, # fails when called from a subdirectory in a VPATH build with # a relative $ac_aux_dir # # The reason of the latter failure is that $top_srcdir and $ac_aux_dir # are both prefixed by $srcdir. In an in-source build this is usually # harmless because $srcdir is '.', but things will broke when you # start a VPATH build or use an absolute $srcdir. # # So we could use something similar to $top_srcdir/$ac_aux_dir/missing, # iff we strip the leading $srcdir from $ac_aux_dir. That would be: # am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"` # and then we would define $MISSING as # MISSING="\${SHELL} $am_aux_dir/missing" # This will work as long as MISSING is not called from configure, because # unfortunately $(top_srcdir) has no meaning in configure. # However there are other variables, like CC, which are often used in # configure, and could therefore not use this "fixed" $ac_aux_dir. # # Another solution, used here, is to always expand $ac_aux_dir to an # absolute PATH. The drawback is that using absolute paths prevent a # configured tree to be moved without reconfiguration. AC_DEFUN([AM_AUX_DIR_EXPAND], [AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl # Expand $ac_aux_dir to an absolute path. am_aux_dir=`cd "$ac_aux_dir" && pwd` ]) # AM_CONDITIONAL -*- Autoconf -*- # Copyright (C) 1997-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_CONDITIONAL(NAME, SHELL-CONDITION) # ------------------------------------- # Define a conditional. AC_DEFUN([AM_CONDITIONAL], [AC_PREREQ([2.52])dnl m4_if([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl AC_SUBST([$1_TRUE])dnl AC_SUBST([$1_FALSE])dnl _AM_SUBST_NOTMAKE([$1_TRUE])dnl _AM_SUBST_NOTMAKE([$1_FALSE])dnl m4_define([_AM_COND_VALUE_$1], [$2])dnl if $2; then $1_TRUE= $1_FALSE='#' else $1_TRUE='#' $1_FALSE= fi AC_CONFIG_COMMANDS_PRE( [if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then AC_MSG_ERROR([[conditional "$1" was never defined. Usually this means the macro was only invoked conditionally.]]) fi])]) # Copyright (C) 1999-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # There are a few dirty hacks below to avoid letting 'AC_PROG_CC' be # written in clear, in which case automake, when reading aclocal.m4, # will think it sees a *use*, and therefore will trigger all it's # C support machinery. Also note that it means that autoscan, seeing # CC etc. in the Makefile, will ask for an AC_PROG_CC use... # _AM_DEPENDENCIES(NAME) # ---------------------- # See how the compiler implements dependency checking. # NAME is "CC", "CXX", "OBJC", "OBJCXX", "UPC", or "GJC". # We try a few techniques and use that to set a single cache variable. # # We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was # modified to invoke _AM_DEPENDENCIES(CC); we would have a circular # dependency, and given that the user is not expected to run this macro, # just rely on AC_PROG_CC. AC_DEFUN([_AM_DEPENDENCIES], [AC_REQUIRE([AM_SET_DEPDIR])dnl AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl AC_REQUIRE([AM_MAKE_INCLUDE])dnl AC_REQUIRE([AM_DEP_TRACK])dnl m4_if([$1], [CC], [depcc="$CC" am_compiler_list=], [$1], [CXX], [depcc="$CXX" am_compiler_list=], [$1], [OBJC], [depcc="$OBJC" am_compiler_list='gcc3 gcc'], [$1], [OBJCXX], [depcc="$OBJCXX" am_compiler_list='gcc3 gcc'], [$1], [UPC], [depcc="$UPC" am_compiler_list=], [$1], [GCJ], [depcc="$GCJ" am_compiler_list='gcc3 gcc'], [depcc="$$1" am_compiler_list=]) AC_CACHE_CHECK([dependency style of $depcc], [am_cv_$1_dependencies_compiler_type], [if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named 'D' -- because '-MD' means "put the output # in D". rm -rf conftest.dir mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_$1_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp` fi am__universal=false m4_case([$1], [CC], [case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac], [CXX], [case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac]) for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with # Solaris 10 /bin/sh. echo '/* dummy */' > sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf # We check with '-c' and '-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle '-M -o', and we need to detect this. Also, some Intel # versions had trouble with output in subdirs. am__obj=sub/conftest.${OBJEXT-o} am__minus_obj="-o $am__obj" case $depmode in gcc) # This depmode causes a compiler race in universal mode. test "$am__universal" = false || continue ;; nosideeffect) # After this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested. if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; msvc7 | msvc7msys | msvisualcpp | msvcmsys) # This compiler won't grok '-c -o', but also, the minuso test has # not run yet. These depmodes are late enough in the game, and # so weak that their functioning should not be impacted. am__obj=conftest.${OBJEXT-o} am__minus_obj= ;; none) break ;; esac if depmode=$depmode \ source=sub/conftest.c object=$am__obj \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep $am__obj sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. # When given -MP, icc 7.0 and 7.1 complain thusly: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported if (grep 'ignoring option' conftest.err || grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else am_cv_$1_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_$1_dependencies_compiler_type=none fi ]) AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type]) AM_CONDITIONAL([am__fastdep$1], [ test "x$enable_dependency_tracking" != xno \ && test "$am_cv_$1_dependencies_compiler_type" = gcc3]) ]) # AM_SET_DEPDIR # ------------- # Choose a directory name for dependency files. # This macro is AC_REQUIREd in _AM_DEPENDENCIES. AC_DEFUN([AM_SET_DEPDIR], [AC_REQUIRE([AM_SET_LEADING_DOT])dnl AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl ]) # AM_DEP_TRACK # ------------ AC_DEFUN([AM_DEP_TRACK], [AC_ARG_ENABLE([dependency-tracking], [dnl AS_HELP_STRING( [--enable-dependency-tracking], [do not reject slow dependency extractors]) AS_HELP_STRING( [--disable-dependency-tracking], [speeds up one-time build])]) if test "x$enable_dependency_tracking" != xno; then am_depcomp="$ac_aux_dir/depcomp" AMDEPBACKSLASH='\' am__nodep='_no' fi AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) AC_SUBST([AMDEPBACKSLASH])dnl _AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl AC_SUBST([am__nodep])dnl _AM_SUBST_NOTMAKE([am__nodep])dnl ]) # Generate code to set up dependency tracking. -*- Autoconf -*- # Copyright (C) 1999-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_OUTPUT_DEPENDENCY_COMMANDS # ------------------------------ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], [{ # Older Autoconf quotes --file arguments for eval, but not when files # are listed without --file. Let's play safe and only enable the eval # if we detect the quoting. case $CONFIG_FILES in *\'*) eval set x "$CONFIG_FILES" ;; *) set x $CONFIG_FILES ;; esac shift for mf do # Strip MF so we end up with the name of the file. mf=`echo "$mf" | sed -e 's/:.*$//'` # Check whether this is an Automake generated Makefile or not. # We used to match only the files named 'Makefile.in', but # some people rename them; so instead we look at the file content. # Grep'ing the first line is not enough: some people post-process # each Makefile.in and add a new line on top of each file to say so. # Grep'ing the whole file is not good either: AIX grep has a line # limit of 2048, but all sed's we know have understand at least 4000. if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then dirpart=`AS_DIRNAME("$mf")` else continue fi # Extract the definition of DEPDIR, am__include, and am__quote # from the Makefile without running 'make'. DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` test -z "$DEPDIR" && continue am__include=`sed -n 's/^am__include = //p' < "$mf"` test -z "$am__include" && continue am__quote=`sed -n 's/^am__quote = //p' < "$mf"` # Find all dependency output files, they are included files with # $(DEPDIR) in their names. We invoke sed twice because it is the # simplest approach to changing $(DEPDIR) to its actual value in the # expansion. for file in `sed -n " s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do # Make sure the directory exists. test -f "$dirpart/$file" && continue fdir=`AS_DIRNAME(["$file"])` AS_MKDIR_P([$dirpart/$fdir]) # echo "creating $dirpart/$file" echo '# dummy' > "$dirpart/$file" done done } ])# _AM_OUTPUT_DEPENDENCY_COMMANDS # AM_OUTPUT_DEPENDENCY_COMMANDS # ----------------------------- # This macro should only be invoked once -- use via AC_REQUIRE. # # This code is only required when automatic dependency tracking # is enabled. FIXME. This creates each '.P' file that we will # need in order to bootstrap the dependency handling code. AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], [AC_CONFIG_COMMANDS([depfiles], [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"]) ]) # Do all the work for Automake. -*- Autoconf -*- # Copyright (C) 1996-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This macro actually does too much. Some checks are only needed if # your package does certain things. But this isn't really a big deal. dnl Redefine AC_PROG_CC to automatically invoke _AM_PROG_CC_C_O. m4_define([AC_PROG_CC], m4_defn([AC_PROG_CC]) [_AM_PROG_CC_C_O ]) # AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) # AM_INIT_AUTOMAKE([OPTIONS]) # ----------------------------------------------- # The call with PACKAGE and VERSION arguments is the old style # call (pre autoconf-2.50), which is being phased out. PACKAGE # and VERSION should now be passed to AC_INIT and removed from # the call to AM_INIT_AUTOMAKE. # We support both call styles for the transition. After # the next Automake release, Autoconf can make the AC_INIT # arguments mandatory, and then we can depend on a new Autoconf # release and drop the old call support. AC_DEFUN([AM_INIT_AUTOMAKE], [AC_PREREQ([2.65])dnl dnl Autoconf wants to disallow AM_ names. We explicitly allow dnl the ones we care about. m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl AC_REQUIRE([AC_PROG_INSTALL])dnl if test "`cd $srcdir && pwd`" != "`pwd`"; then # Use -I$(srcdir) only when $(srcdir) != ., so that make's output # is not polluted with repeated "-I." AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl # test to see if srcdir already configured if test -f $srcdir/config.status; then AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) fi fi # test whether we have cygpath if test -z "$CYGPATH_W"; then if (cygpath --version) >/dev/null 2>/dev/null; then CYGPATH_W='cygpath -w' else CYGPATH_W=echo fi fi AC_SUBST([CYGPATH_W]) # Define the identity of the package. dnl Distinguish between old-style and new-style calls. m4_ifval([$2], [AC_DIAGNOSE([obsolete], [$0: two- and three-arguments forms are deprecated.]) m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl AC_SUBST([PACKAGE], [$1])dnl AC_SUBST([VERSION], [$2])], [_AM_SET_OPTIONS([$1])dnl dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT. m4_if( m4_ifdef([AC_PACKAGE_NAME], [ok]):m4_ifdef([AC_PACKAGE_VERSION], [ok]), [ok:ok],, [m4_fatal([AC_INIT should be called with package and version arguments])])dnl AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl _AM_IF_OPTION([no-define],, [AC_DEFINE_UNQUOTED([PACKAGE], ["$PACKAGE"], [Name of package]) AC_DEFINE_UNQUOTED([VERSION], ["$VERSION"], [Version number of package])])dnl # Some tools Automake needs. AC_REQUIRE([AM_SANITY_CHECK])dnl AC_REQUIRE([AC_ARG_PROGRAM])dnl AM_MISSING_PROG([ACLOCAL], [aclocal-${am__api_version}]) AM_MISSING_PROG([AUTOCONF], [autoconf]) AM_MISSING_PROG([AUTOMAKE], [automake-${am__api_version}]) AM_MISSING_PROG([AUTOHEADER], [autoheader]) AM_MISSING_PROG([MAKEINFO], [makeinfo]) AC_REQUIRE([AM_PROG_INSTALL_SH])dnl AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl AC_REQUIRE([AC_PROG_MKDIR_P])dnl # For better backward compatibility. To be removed once Automake 1.9.x # dies out for good. For more background, see: # <http://lists.gnu.org/archive/html/automake/2012-07/msg00001.html> # <http://lists.gnu.org/archive/html/automake/2012-07/msg00014.html> AC_SUBST([mkdir_p], ['$(MKDIR_P)']) # We need awk for the "check" target. The system "awk" is bad on # some platforms. AC_REQUIRE([AC_PROG_AWK])dnl AC_REQUIRE([AC_PROG_MAKE_SET])dnl AC_REQUIRE([AM_SET_LEADING_DOT])dnl _AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], [_AM_PROG_TAR([v7])])]) _AM_IF_OPTION([no-dependencies],, [AC_PROVIDE_IFELSE([AC_PROG_CC], [_AM_DEPENDENCIES([CC])], [m4_define([AC_PROG_CC], m4_defn([AC_PROG_CC])[_AM_DEPENDENCIES([CC])])])dnl AC_PROVIDE_IFELSE([AC_PROG_CXX], [_AM_DEPENDENCIES([CXX])], [m4_define([AC_PROG_CXX], m4_defn([AC_PROG_CXX])[_AM_DEPENDENCIES([CXX])])])dnl AC_PROVIDE_IFELSE([AC_PROG_OBJC], [_AM_DEPENDENCIES([OBJC])], [m4_define([AC_PROG_OBJC], m4_defn([AC_PROG_OBJC])[_AM_DEPENDENCIES([OBJC])])])dnl AC_PROVIDE_IFELSE([AC_PROG_OBJCXX], [_AM_DEPENDENCIES([OBJCXX])], [m4_define([AC_PROG_OBJCXX], m4_defn([AC_PROG_OBJCXX])[_AM_DEPENDENCIES([OBJCXX])])])dnl ]) AC_REQUIRE([AM_SILENT_RULES])dnl dnl The testsuite driver may need to know about EXEEXT, so add the dnl 'am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This dnl macro is hooked onto _AC_COMPILER_EXEEXT early, see below. AC_CONFIG_COMMANDS_PRE(dnl [m4_provide_if([_AM_COMPILER_EXEEXT], [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl # POSIX will say in a future version that running "rm -f" with no argument # is OK; and we want to be able to make that assumption in our Makefile # recipes. So use an aggressive probe to check that the usage we want is # actually supported "in the wild" to an acceptable degree. # See automake bug#10828. # To make any issue more visible, cause the running configure to be aborted # by default if the 'rm' program in use doesn't match our expectations; the # user can still override this though. if rm -f && rm -fr && rm -rf; then : OK; else cat >&2 <<'END' Oops! Your 'rm' program seems unable to run without file operands specified on the command line, even when the '-f' option is present. This is contrary to the behaviour of most rm programs out there, and not conforming with the upcoming POSIX standard: <http://austingroupbugs.net/view.php?id=542> Please tell bug-automake@gnu.org about your system, including the value of your $PATH and any error possibly output before this message. This can help us improve future automake versions. END if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then echo 'Configuration will proceed anyway, since you have set the' >&2 echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2 echo >&2 else cat >&2 <<'END' Aborting the configuration process, to ensure you take notice of the issue. You can download and install GNU coreutils to get an 'rm' implementation that behaves properly: <http://www.gnu.org/software/coreutils/>. If you want to complete the configuration process using your problematic 'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM to "yes", and re-run configure. END AC_MSG_ERROR([Your 'rm' program is bad, sorry.]) fi fi ]) dnl Hook into '_AC_COMPILER_EXEEXT' early to learn its expansion. Do not dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further dnl mangled by Autoconf and run in a shell conditional statement. m4_define([_AC_COMPILER_EXEEXT], m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])]) # When config.status generates a header, we must update the stamp-h file. # This file resides in the same directory as the config header # that is generated. The stamp files are numbered to have different names. # Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the # loop where config.status creates the headers, so we can generate # our stamp files there. AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], [# Compute $1's index in $config_headers. _am_arg=$1 _am_stamp_count=1 for _am_header in $config_headers :; do case $_am_header in $_am_arg | $_am_arg:* ) break ;; * ) _am_stamp_count=`expr $_am_stamp_count + 1` ;; esac done echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) # Copyright (C) 2001-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_PROG_INSTALL_SH # ------------------ # Define $install_sh. AC_DEFUN([AM_PROG_INSTALL_SH], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl if test x"${install_sh}" != xset; then case $am_aux_dir in *\ * | *\ *) install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; *) install_sh="\${SHELL} $am_aux_dir/install-sh" esac fi AC_SUBST([install_sh])]) # Copyright (C) 2003-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # Check whether the underlying file-system supports filenames # with a leading dot. For instance MS-DOS doesn't. AC_DEFUN([AM_SET_LEADING_DOT], [rm -rf .tst 2>/dev/null mkdir .tst 2>/dev/null if test -d .tst; then am__leading_dot=. else am__leading_dot=_ fi rmdir .tst 2>/dev/null AC_SUBST([am__leading_dot])]) # Add --enable-maintainer-mode option to configure. -*- Autoconf -*- # From Jim Meyering # Copyright (C) 1996-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_MAINTAINER_MODE([DEFAULT-MODE]) # ---------------------------------- # Control maintainer-specific portions of Makefiles. # Default is to disable them, unless 'enable' is passed literally. # For symmetry, 'disable' may be passed as well. Anyway, the user # can override the default with the --enable/--disable switch. AC_DEFUN([AM_MAINTAINER_MODE], [m4_case(m4_default([$1], [disable]), [enable], [m4_define([am_maintainer_other], [disable])], [disable], [m4_define([am_maintainer_other], [enable])], [m4_define([am_maintainer_other], [enable]) m4_warn([syntax], [unexpected argument to AM@&t@_MAINTAINER_MODE: $1])]) AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles]) dnl maintainer-mode's default is 'disable' unless 'enable' is passed AC_ARG_ENABLE([maintainer-mode], [AS_HELP_STRING([--]am_maintainer_other[-maintainer-mode], am_maintainer_other[ make rules and dependencies not useful (and sometimes confusing) to the casual installer])], [USE_MAINTAINER_MODE=$enableval], [USE_MAINTAINER_MODE=]m4_if(am_maintainer_other, [enable], [no], [yes])) AC_MSG_RESULT([$USE_MAINTAINER_MODE]) AM_CONDITIONAL([MAINTAINER_MODE], [test $USE_MAINTAINER_MODE = yes]) MAINT=$MAINTAINER_MODE_TRUE AC_SUBST([MAINT])dnl ] ) # Check to see how 'make' treats includes. -*- Autoconf -*- # Copyright (C) 2001-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_MAKE_INCLUDE() # ----------------- # Check to see how make treats includes. AC_DEFUN([AM_MAKE_INCLUDE], [am_make=${MAKE-make} cat > confinc << 'END' am__doit: @echo this is the am__doit target .PHONY: am__doit END # If we don't find an include directive, just comment out the code. AC_MSG_CHECKING([for style of include used by $am_make]) am__include="#" am__quote= _am_result=none # First try GNU make style include. echo "include confinc" > confmf # Ignore all kinds of additional output from 'make'. case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=include am__quote= _am_result=GNU ;; esac # Now try BSD make style include. if test "$am__include" = "#"; then echo '.include "confinc"' > confmf case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=.include am__quote="\"" _am_result=BSD ;; esac fi AC_SUBST([am__include]) AC_SUBST([am__quote]) AC_MSG_RESULT([$_am_result]) rm -f confinc confmf ]) # Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- # Copyright (C) 1997-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_MISSING_PROG(NAME, PROGRAM) # ------------------------------ AC_DEFUN([AM_MISSING_PROG], [AC_REQUIRE([AM_MISSING_HAS_RUN]) $1=${$1-"${am_missing_run}$2"} AC_SUBST($1)]) # AM_MISSING_HAS_RUN # ------------------ # Define MISSING if not defined so far and test if it is modern enough. # If it is, set am_missing_run to use it, otherwise, to nothing. AC_DEFUN([AM_MISSING_HAS_RUN], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl AC_REQUIRE_AUX_FILE([missing])dnl if test x"${MISSING+set}" != xset; then case $am_aux_dir in *\ * | *\ *) MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; *) MISSING="\${SHELL} $am_aux_dir/missing" ;; esac fi # Use eval to expand $SHELL if eval "$MISSING --is-lightweight"; then am_missing_run="$MISSING " else am_missing_run= AC_MSG_WARN(['missing' script is too old or missing]) fi ]) # Helper functions for option handling. -*- Autoconf -*- # Copyright (C) 2001-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_MANGLE_OPTION(NAME) # ----------------------- AC_DEFUN([_AM_MANGLE_OPTION], [[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) # _AM_SET_OPTION(NAME) # -------------------- # Set option NAME. Presently that only means defining a flag for this option. AC_DEFUN([_AM_SET_OPTION], [m4_define(_AM_MANGLE_OPTION([$1]), [1])]) # _AM_SET_OPTIONS(OPTIONS) # ------------------------ # OPTIONS is a space-separated list of Automake options. AC_DEFUN([_AM_SET_OPTIONS], [m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) # _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET]) # ------------------------------------------- # Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. AC_DEFUN([_AM_IF_OPTION], [m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) # Copyright (C) 1999-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_PROG_CC_C_O # --------------- # Like AC_PROG_CC_C_O, but changed for automake. We rewrite AC_PROG_CC # to automatically call this. AC_DEFUN([_AM_PROG_CC_C_O], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl AC_REQUIRE_AUX_FILE([compile])dnl AC_LANG_PUSH([C])dnl AC_CACHE_CHECK( [whether $CC understands -c and -o together], [am_cv_prog_cc_c_o], [AC_LANG_CONFTEST([AC_LANG_PROGRAM([])]) # Make sure it works both with $CC and with simple cc. # Following AC_PROG_CC_C_O, we do the test twice because some # compilers refuse to overwrite an existing .o file with -o, # though they will create one. am_cv_prog_cc_c_o=yes for am_i in 1 2; do if AM_RUN_LOG([$CC -c conftest.$ac_ext -o conftest2.$ac_objext]) \ && test -f conftest2.$ac_objext; then : OK else am_cv_prog_cc_c_o=no break fi done rm -f core conftest* unset am_i]) if test "$am_cv_prog_cc_c_o" != yes; then # Losing compiler, so override with the script. # FIXME: It is wrong to rewrite CC. # But if we don't then we get into trouble of one sort or another. # A longer-term fix would be to have automake use am__CC in this case, # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" CC="$am_aux_dir/compile $CC" fi AC_LANG_POP([C])]) # For backward compatibility. AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])]) # Copyright (C) 2001-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_RUN_LOG(COMMAND) # ------------------- # Run COMMAND, save the exit status in ac_status, and log it. # (This has been adapted from Autoconf's _AC_RUN_LOG macro.) AC_DEFUN([AM_RUN_LOG], [{ echo "$as_me:$LINENO: $1" >&AS_MESSAGE_LOG_FD ($1) >&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD (exit $ac_status); }]) # Check to make sure that the build environment is sane. -*- Autoconf -*- # Copyright (C) 1996-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_SANITY_CHECK # --------------- AC_DEFUN([AM_SANITY_CHECK], [AC_MSG_CHECKING([whether build environment is sane]) # Reject unsafe characters in $srcdir or the absolute working directory # name. Accept space and tab only in the latter. am_lf=' ' case `pwd` in *[[\\\"\#\$\&\'\`$am_lf]]*) AC_MSG_ERROR([unsafe absolute working directory name]);; esac case $srcdir in *[[\\\"\#\$\&\'\`$am_lf\ \ ]]*) AC_MSG_ERROR([unsafe srcdir value: '$srcdir']);; esac # Do 'set' in a subshell so we don't clobber the current shell's # arguments. Must try -L first in case configure is actually a # symlink; some systems play weird games with the mod time of symlinks # (eg FreeBSD returns the mod time of the symlink's containing # directory). if ( am_has_slept=no for am_try in 1 2; do echo "timestamp, slept: $am_has_slept" > conftest.file set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` if test "$[*]" = "X"; then # -L didn't work. set X `ls -t "$srcdir/configure" conftest.file` fi if test "$[*]" != "X $srcdir/configure conftest.file" \ && test "$[*]" != "X conftest.file $srcdir/configure"; then # If neither matched, then we have a broken ls. This can happen # if, for instance, CONFIG_SHELL is bash and it inherits a # broken ls alias from the environment. This has actually # happened. Such a system could not be considered "sane". AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken alias in your environment]) fi if test "$[2]" = conftest.file || test $am_try -eq 2; then break fi # Just in case. sleep 1 am_has_slept=yes done test "$[2]" = conftest.file ) then # Ok. : else AC_MSG_ERROR([newly created file is older than distributed files! Check your system clock]) fi AC_MSG_RESULT([yes]) # If we didn't sleep, we still need to ensure time stamps of config.status and # generated files are strictly newer. am_sleep_pid= if grep 'slept: no' conftest.file >/dev/null 2>&1; then ( sleep 1 ) & am_sleep_pid=$! fi AC_CONFIG_COMMANDS_PRE( [AC_MSG_CHECKING([that generated files are newer than configure]) if test -n "$am_sleep_pid"; then # Hide warnings about reused PIDs. wait $am_sleep_pid 2>/dev/null fi AC_MSG_RESULT([done])]) rm -f conftest.file ]) # Copyright (C) 2009-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_SILENT_RULES([DEFAULT]) # -------------------------- # Enable less verbose build rules; with the default set to DEFAULT # ("yes" being less verbose, "no" or empty being verbose). AC_DEFUN([AM_SILENT_RULES], [AC_ARG_ENABLE([silent-rules], [dnl AS_HELP_STRING( [--enable-silent-rules], [less verbose build output (undo: "make V=1")]) AS_HELP_STRING( [--disable-silent-rules], [verbose build output (undo: "make V=0")])dnl ]) case $enable_silent_rules in @%:@ ((( yes) AM_DEFAULT_VERBOSITY=0;; no) AM_DEFAULT_VERBOSITY=1;; *) AM_DEFAULT_VERBOSITY=m4_if([$1], [yes], [0], [1]);; esac dnl dnl A few 'make' implementations (e.g., NonStop OS and NextStep) dnl do not support nested variable expansions. dnl See automake bug#9928 and bug#10237. am_make=${MAKE-make} AC_CACHE_CHECK([whether $am_make supports nested variables], [am_cv_make_support_nested_variables], [if AS_ECHO([['TRUE=$(BAR$(V)) BAR0=false BAR1=true V=1 am__doit: @$(TRUE) .PHONY: am__doit']]) | $am_make -f - >/dev/null 2>&1; then am_cv_make_support_nested_variables=yes else am_cv_make_support_nested_variables=no fi]) if test $am_cv_make_support_nested_variables = yes; then dnl Using '$V' instead of '$(V)' breaks IRIX make. AM_V='$(V)' AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' else AM_V=$AM_DEFAULT_VERBOSITY AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY fi AC_SUBST([AM_V])dnl AM_SUBST_NOTMAKE([AM_V])dnl AC_SUBST([AM_DEFAULT_V])dnl AM_SUBST_NOTMAKE([AM_DEFAULT_V])dnl AC_SUBST([AM_DEFAULT_VERBOSITY])dnl AM_BACKSLASH='\' AC_SUBST([AM_BACKSLASH])dnl _AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl ]) # Copyright (C) 2001-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_PROG_INSTALL_STRIP # --------------------- # One issue with vendor 'install' (even GNU) is that you can't # specify the program used to strip binaries. This is especially # annoying in cross-compiling environments, where the build's strip # is unlikely to handle the host's binaries. # Fortunately install-sh will honor a STRIPPROG variable, so we # always use install-sh in "make install-strip", and initialize # STRIPPROG with the value of the STRIP variable (set by the user). AC_DEFUN([AM_PROG_INSTALL_STRIP], [AC_REQUIRE([AM_PROG_INSTALL_SH])dnl # Installed binaries are usually stripped using 'strip' when the user # run "make install-strip". However 'strip' might not be the right # tool to use in cross-compilation environments, therefore Automake # will honor the 'STRIP' environment variable to overrule this program. dnl Don't test for $cross_compiling = yes, because it might be 'maybe'. if test "$cross_compiling" != no; then AC_CHECK_TOOL([STRIP], [strip], :) fi INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" AC_SUBST([INSTALL_STRIP_PROGRAM])]) # Copyright (C) 2006-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_SUBST_NOTMAKE(VARIABLE) # --------------------------- # Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in. # This macro is traced by Automake. AC_DEFUN([_AM_SUBST_NOTMAKE]) # AM_SUBST_NOTMAKE(VARIABLE) # -------------------------- # Public sister of _AM_SUBST_NOTMAKE. AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) # Check how to create a tarball. -*- Autoconf -*- # Copyright (C) 2004-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_PROG_TAR(FORMAT) # -------------------- # Check how to create a tarball in format FORMAT. # FORMAT should be one of 'v7', 'ustar', or 'pax'. # # Substitute a variable $(am__tar) that is a command # writing to stdout a FORMAT-tarball containing the directory # $tardir. # tardir=directory && $(am__tar) > result.tar # # Substitute a variable $(am__untar) that extract such # a tarball read from stdin. # $(am__untar) < result.tar # AC_DEFUN([_AM_PROG_TAR], [# Always define AMTAR for backward compatibility. Yes, it's still used # in the wild :-( We should find a proper way to deprecate it ... AC_SUBST([AMTAR], ['$${TAR-tar}']) # We'll loop over all known methods to create a tar archive until one works. _am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' m4_if([$1], [v7], [am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'], [m4_case([$1], [ustar], [# The POSIX 1988 'ustar' format is defined with fixed-size fields. # There is notably a 21 bits limit for the UID and the GID. In fact, # the 'pax' utility can hang on bigger UID/GID (see automake bug#8343 # and bug#13588). am_max_uid=2097151 # 2^21 - 1 am_max_gid=$am_max_uid # The $UID and $GID variables are not portable, so we need to resort # to the POSIX-mandated id(1) utility. Errors in the 'id' calls # below are definitely unexpected, so allow the users to see them # (that is, avoid stderr redirection). am_uid=`id -u || echo unknown` am_gid=`id -g || echo unknown` AC_MSG_CHECKING([whether UID '$am_uid' is supported by ustar format]) if test $am_uid -le $am_max_uid; then AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) _am_tools=none fi AC_MSG_CHECKING([whether GID '$am_gid' is supported by ustar format]) if test $am_gid -le $am_max_gid; then AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) _am_tools=none fi], [pax], [], [m4_fatal([Unknown tar format])]) AC_MSG_CHECKING([how to create a $1 tar archive]) # Go ahead even if we have the value already cached. We do so because we # need to set the values for the 'am__tar' and 'am__untar' variables. _am_tools=${am_cv_prog_tar_$1-$_am_tools} for _am_tool in $_am_tools; do case $_am_tool in gnutar) for _am_tar in tar gnutar gtar; do AM_RUN_LOG([$_am_tar --version]) && break done am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' am__untar="$_am_tar -xf -" ;; plaintar) # Must skip GNU tar: if it does not support --format= it doesn't create # ustar tarball either. (tar --version) >/dev/null 2>&1 && continue am__tar='tar chf - "$$tardir"' am__tar_='tar chf - "$tardir"' am__untar='tar xf -' ;; pax) am__tar='pax -L -x $1 -w "$$tardir"' am__tar_='pax -L -x $1 -w "$tardir"' am__untar='pax -r' ;; cpio) am__tar='find "$$tardir" -print | cpio -o -H $1 -L' am__tar_='find "$tardir" -print | cpio -o -H $1 -L' am__untar='cpio -i -H $1 -d' ;; none) am__tar=false am__tar_=false am__untar=false ;; esac # If the value was cached, stop now. We just wanted to have am__tar # and am__untar set. test -n "${am_cv_prog_tar_$1}" && break # tar/untar a dummy directory, and stop if the command works. rm -rf conftest.dir mkdir conftest.dir echo GrepMe > conftest.dir/file AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) rm -rf conftest.dir if test -s conftest.tar; then AM_RUN_LOG([$am__untar <conftest.tar]) AM_RUN_LOG([cat conftest.dir/file]) grep GrepMe conftest.dir/file >/dev/null 2>&1 && break fi done rm -rf conftest.dir AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) AC_MSG_RESULT([$am_cv_prog_tar_$1])]) AC_SUBST([am__tar]) AC_SUBST([am__untar]) ]) # _AM_PROG_TAR m4_include([acinclude.m4]) �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������libburn-1.4.2/CONTRIBUTORS��������������������������������������������������������������������������0000644�0001757�0001751�00000000144�12652644223�011771� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������Joe Neeman Philippe Rouquier Gabriel Craciunescu George Danchev Jean-Francois Wauthy Lorenzo Taylor ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������libburn-1.4.2/NEWS����������������������������������������������������������������������������������0000644�0001757�0001751�00000000021�12652644224�010603� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������nothing here now ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������libburn-1.4.2/INSTALL�������������������������������������������������������������������������������0000644�0001757�0001751�00000022310�12652644224�011142� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������Installation Instructions ************************* Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005, 2006 Free Software Foundation, Inc. This file is free documentation; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. Basic Installation ================== Briefly, the shell commands `./configure; make; make install' should configure, build, and install this package. The following more-detailed instructions are generic; see the `README' file for instructions specific to this package. The `configure' shell script attempts to guess correct values for various system-dependent variables used during compilation. It uses those values to create a `Makefile' in each directory of the package. It may also create one or more `.h' files containing system-dependent definitions. Finally, it creates a shell script `config.status' that you can run in the future to recreate the current configuration, and a file `config.log' containing compiler output (useful mainly for debugging `configure'). It can also use an optional file (typically called `config.cache' and enabled with `--cache-file=config.cache' or simply `-C') that saves the results of its tests to speed up reconfiguring. Caching is disabled by default to prevent problems with accidental use of stale cache files. If you need to do unusual things to compile the package, please try to figure out how `configure' could check whether to do them, and mail diffs or instructions to the address given in the `README' so they can be considered for the next release. If you are using the cache, and at some point `config.cache' contains results you don't want to keep, you may remove or edit it. The file `configure.ac' (or `configure.in') is used to create `configure' by a program called `autoconf'. You need `configure.ac' if you want to change it or regenerate `configure' using a newer version of `autoconf'. The simplest way to compile this package is: 1. `cd' to the directory containing the package's source code and type `./configure' to configure the package for your system. Running `configure' might take a while. While running, it prints some messages telling which features it is checking for. 2. Type `make' to compile the package. 3. Optionally, type `make check' to run any self-tests that come with the package. 4. Type `make install' to install the programs and any data files and documentation. 5. You can remove the program binaries and object files from the source code directory by typing `make clean'. To also remove the files that `configure' created (so you can compile the package for a different kind of computer), type `make distclean'. There is also a `make maintainer-clean' target, but that is intended mainly for the package's developers. If you use it, you may have to get all sorts of other programs in order to regenerate files that came with the distribution. Compilers and Options ===================== Some systems require unusual options for compilation or linking that the `configure' script does not know about. Run `./configure --help' for details on some of the pertinent environment variables. You can give `configure' initial values for configuration parameters by setting variables in the command line or in the environment. Here is an example: ./configure CC=c99 CFLAGS=-g LIBS=-lposix *Note Defining Variables::, for more details. Compiling For Multiple Architectures ==================================== You can compile the package for more than one kind of computer at the same time, by placing the object files for each architecture in their own directory. To do this, you can use GNU `make'. `cd' to the directory where you want the object files and executables to go and run the `configure' script. `configure' automatically checks for the source code in the directory that `configure' is in and in `..'. With a non-GNU `make', it is safer to compile the package for one architecture at a time in the source code directory. After you have installed the package for one architecture, use `make distclean' before reconfiguring for another architecture. Installation Names ================== By default, `make install' installs the package's commands under `/usr/local/bin', include files under `/usr/local/include', etc. You can specify an installation prefix other than `/usr/local' by giving `configure' the option `--prefix=PREFIX'. You can specify separate installation prefixes for architecture-specific files and architecture-independent files. If you pass the option `--exec-prefix=PREFIX' to `configure', the package uses PREFIX as the prefix for installing programs and libraries. Documentation and other data files still use the regular prefix. In addition, if you use an unusual directory layout you can give options like `--bindir=DIR' to specify different values for particular kinds of files. Run `configure --help' for a list of the directories you can set and what kinds of files go in them. If the package supports it, you can cause programs to be installed with an extra prefix or suffix on their names by giving `configure' the option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. Optional Features ================= Some packages pay attention to `--enable-FEATURE' options to `configure', where FEATURE indicates an optional part of the package. They may also pay attention to `--with-PACKAGE' options, where PACKAGE is something like `gnu-as' or `x' (for the X Window System). The `README' should mention any `--enable-' and `--with-' options that the package recognizes. For packages that use the X Window System, `configure' can usually find the X include and library files automatically, but if it doesn't, you can use the `configure' options `--x-includes=DIR' and `--x-libraries=DIR' to specify their locations. Specifying the System Type ========================== There may be some features `configure' cannot figure out automatically, but needs to determine by the type of machine the package will run on. Usually, assuming the package is built to be run on the _same_ architectures, `configure' can figure that out, but if it prints a message saying it cannot guess the machine type, give it the `--build=TYPE' option. TYPE can either be a short name for the system type, such as `sun4', or a canonical name which has the form: CPU-COMPANY-SYSTEM where SYSTEM can have one of these forms: OS KERNEL-OS See the file `config.sub' for the possible values of each field. If `config.sub' isn't included in this package, then this package doesn't need to know the machine type. If you are _building_ compiler tools for cross-compiling, you should use the option `--target=TYPE' to select the type of system they will produce code for. If you want to _use_ a cross compiler, that generates code for a platform different from the build platform, you should specify the "host" platform (i.e., that on which the generated programs will eventually be run) with `--host=TYPE'. Sharing Defaults ================ If you want to set default values for `configure' scripts to share, you can create a site shell script called `config.site' that gives default values for variables like `CC', `cache_file', and `prefix'. `configure' looks for `PREFIX/share/config.site' if it exists, then `PREFIX/etc/config.site' if it exists. Or, you can set the `CONFIG_SITE' environment variable to the location of the site script. A warning: not all `configure' scripts look for a site script. Defining Variables ================== Variables not defined in a site shell script can be set in the environment passed to `configure'. However, some packages may run configure again during the build, and the customized values of these variables may be lost. In order to avoid this problem, you should set them in the `configure' command line, using `VAR=value'. For example: ./configure CC=/usr/local2/bin/gcc causes the specified `gcc' to be used as the C compiler (unless it is overridden in the site shell script). Unfortunately, this technique does not work for `CONFIG_SHELL' due to an Autoconf bug. Until the bug is fixed you can use this workaround: CONFIG_SHELL=/bin/bash /bin/bash ./configure CONFIG_SHELL=/bin/bash `configure' Invocation ====================== `configure' recognizes the following options to control how it operates. `--help' `-h' Print a summary of the options to `configure', and exit. `--version' `-V' Print the version of Autoconf used to generate the `configure' script, and exit. `--cache-file=FILE' Enable the cache: use and save the results of the tests in FILE, traditionally `config.cache'. FILE defaults to `/dev/null' to disable caching. `--config-cache' `-C' Alias for `--cache-file=config.cache'. `--quiet' `--silent' `-q' Do not print messages saying which checks are being made. To suppress all normal output, redirect it to `/dev/null' (any error messages will still be shown). `--srcdir=DIR' Look for the package's source code in directory DIR. Usually `configure' can determine that directory automatically. `configure' also accepts some other, not widely useful, options. Run `configure --help' for more details. ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������libburn-1.4.2/configure�����������������������������������������������������������������������������0000755�0001757�0001751�00001550035�12652650101�012022� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������#! /bin/sh # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.69 for libburn 1.4.2. # # Report bugs to <http://libburnia-project.org>. # # # Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. # # # This configure script is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi as_nl=' ' export as_nl # Printing a long string crashes Solaris 7 /usr/bin/printf. as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo # Prefer a ksh shell builtin over an external printf program on Solaris, # but without wasting forks for bash or zsh. if test -z "$BASH_VERSION$ZSH_VERSION" \ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='print -r --' as_echo_n='print -rn --' elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='printf %s\n' as_echo_n='printf %s' else if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' as_echo_n='/usr/ucb/echo -n' else as_echo_body='eval expr "X$1" : "X\\(.*\\)"' as_echo_n_body='eval arg=$1; case $arg in #( *"$as_nl"*) expr "X$arg" : "X\\(.*\\)$as_nl"; arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; esac; expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" ' export as_echo_n_body as_echo_n='sh -c $as_echo_n_body as_echo' fi export as_echo_body as_echo='sh -c $as_echo_body as_echo' fi # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # Unset variables that we do not need and which cause bugs (e.g. in # pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" # suppresses any "Segmentation fault" message there. '((' could # trigger a bug in pdksh 5.2.14. for as_var in BASH_ENV ENV MAIL MAILPATH do eval test x\${$as_var+set} = xset \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH # Use a proper internal environment variable to ensure we don't fall # into an infinite loop, continuously re-executing ourselves. if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then _as_can_reexec=no; export _as_can_reexec; # We cannot yet assume a decent shell, so we have to provide a # neutralization value for shells without unset; and this also # works around shells that cannot unset nonexistent variables. # Preserve -v and -x to the replacement shell. BASH_ENV=/dev/null ENV=/dev/null (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV case $- in # (((( *v*x* | *x*v* ) as_opts=-vx ;; *v* ) as_opts=-v ;; *x* ) as_opts=-x ;; * ) as_opts= ;; esac exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} # Admittedly, this is quite paranoid, since all the known shells bail # out after a failed `exec'. $as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 as_fn_exit 255 fi # We don't want this to propagate to other subprocesses. { _as_can_reexec=; unset _as_can_reexec;} if test "x$CONFIG_SHELL" = x; then as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which # is contrary to our usage. Disable this feature. alias -g '\${1+\"\$@\"}'='\"\$@\"' setopt NO_GLOB_SUBST else case \`(set -o) 2>/dev/null\` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi " as_required="as_fn_return () { (exit \$1); } as_fn_success () { as_fn_return 0; } as_fn_failure () { as_fn_return 1; } as_fn_ret_success () { return 0; } as_fn_ret_failure () { return 1; } exitcode=0 as_fn_success || { exitcode=1; echo as_fn_success failed.; } as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : else exitcode=1; echo positional parameters were not saved. fi test x\$exitcode = x0 || exit 1 test -x / || exit 1" as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 test \$(( 1 + 1 )) = 2 || exit 1 test -n \"\${ZSH_VERSION+set}\${BASH_VERSION+set}\" || ( ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO PATH=/empty FPATH=/empty; export PATH FPATH test \"X\`printf %s \$ECHO\`\" = \"X\$ECHO\" \\ || test \"X\`print -r -- \$ECHO\`\" = \"X\$ECHO\" ) || exit 1" if (eval "$as_required") 2>/dev/null; then : as_have_required=yes else as_have_required=no fi if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR as_found=false for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. as_found=: case $as_dir in #( /*) for as_base in sh bash ksh sh5; do # Try only shells that exist, to save several forks. as_shell=$as_dir/$as_base if { test -f "$as_shell" || test -f "$as_shell.exe"; } && { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : CONFIG_SHELL=$as_shell as_have_required=yes if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : break 2 fi fi done;; esac as_found=false done $as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : CONFIG_SHELL=$SHELL as_have_required=yes fi; } IFS=$as_save_IFS if test "x$CONFIG_SHELL" != x; then : export CONFIG_SHELL # We cannot yet assume a decent shell, so we have to provide a # neutralization value for shells without unset; and this also # works around shells that cannot unset nonexistent variables. # Preserve -v and -x to the replacement shell. BASH_ENV=/dev/null ENV=/dev/null (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV case $- in # (((( *v*x* | *x*v* ) as_opts=-vx ;; *v* ) as_opts=-v ;; *x* ) as_opts=-x ;; * ) as_opts= ;; esac exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} # Admittedly, this is quite paranoid, since all the known shells bail # out after a failed `exec'. $as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 exit 255 fi if test x$as_have_required = xno; then : $as_echo "$0: This script requires a shell more modern than all" $as_echo "$0: the shells that I found on your system." if test x${ZSH_VERSION+set} = xset ; then $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" $as_echo "$0: be upgraded to zsh 4.3.4 or later." else $as_echo "$0: Please tell bug-autoconf@gnu.org and $0: http://libburnia-project.org about your system, $0: including any error possibly output before this $0: message. Then install a modern shell, or manually run $0: the script under such a shell if you do have one." fi exit 1 fi fi fi SHELL=${CONFIG_SHELL-/bin/sh} export SHELL # Unset more variables known to interfere with behavior of common tools. CLICOLOR_FORCE= GREP_OPTIONS= unset CLICOLOR_FORCE GREP_OPTIONS ## --------------------- ## ## M4sh Shell Functions. ## ## --------------------- ## # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p # as_fn_executable_p FILE # ----------------------- # Test if FILE is an executable regular file. as_fn_executable_p () { test -f "$1" && test -x "$1" } # as_fn_executable_p # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : eval 'as_fn_append () { eval $1+=\$2 }' else as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : eval 'as_fn_arith () { as_val=$(( $* )) }' else as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with STATUS, using 1 if that was 0. as_fn_error () { as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi $as_echo "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || $as_echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits as_lineno_1=$LINENO as_lineno_1a=$LINENO as_lineno_2=$LINENO as_lineno_2a=$LINENO eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) sed -n ' p /[$]LINENO/= ' <$as_myself | sed ' s/[$]LINENO.*/&-/ t lineno b :lineno N :loop s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ t loop s/-\n.*// ' >$as_me.lineno && chmod +x "$as_me.lineno" || { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } # If we had to re-execute with $CONFIG_SHELL, we're ensured to have # already done that, so ensure we don't try to do so again and fall # in an infinite loop. This has already happened in practice. _as_can_reexec=no; export _as_can_reexec # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensitive to this). . "./$as_me.lineno" # Exit status is that of the last command. exit } ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -pR'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -pR' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -pR' fi else as_ln_s='cp -pR' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi as_test_x='test -x' as_executable_p=as_fn_executable_p # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" SHELL=${CONFIG_SHELL-/bin/sh} test -n "$DJDIR" || exec 7<&0 </dev/null exec 6>&1 # Name of the host. # hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, # so uname gets run too. ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` # # Initializations. # ac_default_prefix=/usr/local ac_clean_files= ac_config_libobj_dir=. LIBOBJS= cross_compiling=no subdirs= MFLAGS= MAKEFLAGS= # Identity of this package. PACKAGE_NAME='libburn' PACKAGE_TARNAME='libburn' PACKAGE_VERSION='1.4.2' PACKAGE_STRING='libburn 1.4.2' PACKAGE_BUGREPORT='http://libburnia-project.org' PACKAGE_URL='' ac_default_prefix=/usr/local # Factoring default headers for most tests. ac_includes_default="\ #include <stdio.h> #ifdef HAVE_SYS_TYPES_H # include <sys/types.h> #endif #ifdef HAVE_SYS_STAT_H # include <sys/stat.h> #endif #ifdef STDC_HEADERS # include <stdlib.h> # include <stddef.h> #else # ifdef HAVE_STDLIB_H # include <stdlib.h> # endif #endif #ifdef HAVE_STRING_H # if !defined STDC_HEADERS && defined HAVE_MEMORY_H # include <memory.h> # endif # include <string.h> #endif #ifdef HAVE_STRINGS_H # include <strings.h> #endif #ifdef HAVE_INTTYPES_H # include <inttypes.h> #endif #ifdef HAVE_STDINT_H # include <stdint.h> #endif #ifdef HAVE_UNISTD_H # include <unistd.h> #endif" ac_subst_vars='am__EXEEXT_FALSE am__EXEEXT_TRUE LTLIBOBJS LIBOBJS LIBBURNIA_LDCONFIG_CMD LIBCDIO_LIBS LIBCDIO_CFLAGS PKG_CONFIG_LIBDIR PKG_CONFIG_PATH PKG_CONFIG LIBBURN_ARCH_LIBS LIBBURNIA_PKGCONFDIR ARCH THREAD_LIBS LIBTOOL_DEPS OTOOL64 OTOOL LIPO NMEDIT DSYMUTIL MANIFEST_TOOL RANLIB ac_ct_AR AR DLLTOOL OBJDUMP LN_S NM ac_ct_DUMPBIN DUMPBIN LD FGREP SED LIBTOOL EGREP GREP CPP am__fastdepCC_FALSE am__fastdepCC_TRUE CCDEPMODE am__nodep AMDEPBACKSLASH AMDEP_FALSE AMDEP_TRUE am__quote am__include DEPDIR OBJEXT EXEEXT ac_ct_CC CPPFLAGS LDFLAGS CFLAGS CC MAINT MAINTAINER_MODE_FALSE MAINTAINER_MODE_TRUE BURN_BINARY_AGE BURN_INTERFACE_AGE LT_CURRENT_MINUS_AGE LT_AGE LT_REVISION LT_CURRENT LT_RELEASE BURN_VERSION BURN_MICRO_VERSION BURN_MINOR_VERSION BURN_MAJOR_VERSION AM_BACKSLASH AM_DEFAULT_VERBOSITY AM_DEFAULT_V AM_V am__untar am__tar AMTAR am__leading_dot SET_MAKE AWK mkdir_p MKDIR_P INSTALL_STRIP_PROGRAM STRIP install_sh MAKEINFO AUTOHEADER AUTOMAKE AUTOCONF ACLOCAL VERSION PACKAGE CYGPATH_W am__isrc INSTALL_DATA INSTALL_SCRIPT INSTALL_PROGRAM target_os target_vendor target_cpu target host_os host_vendor host_cpu host build_os build_vendor build_cpu build target_alias host_alias build_alias LIBS ECHO_T ECHO_N ECHO_C DEFS mandir localedir libdir psdir pdfdir dvidir htmldir infodir docdir oldincludedir includedir localstatedir sharedstatedir sysconfdir datadir datarootdir libexecdir sbindir bindir program_transform_name prefix exec_prefix PACKAGE_URL PACKAGE_BUGREPORT PACKAGE_STRING PACKAGE_VERSION PACKAGE_TARNAME PACKAGE_NAME PATH_SEPARATOR SHELL' ac_subst_files='' ac_user_opts=' enable_option_checking enable_silent_rules enable_maintainer_mode enable_dependency_tracking enable_largefile enable_shared enable_static with_pic enable_fast_install with_gnu_ld with_sysroot enable_libtool_lock enable_track_src_odirect enable_dvd_obs_64k enable_dvd_obs_pad enable_pkg_check_modules enable_libcdio enable_versioned_libs enable_ldconfig_at_install enable_debug enable_libdir_pkgconfig enable_pkgconfig_path ' ac_precious_vars='build_alias host_alias target_alias CC CFLAGS LDFLAGS LIBS CPPFLAGS CPP PKG_CONFIG PKG_CONFIG_PATH PKG_CONFIG_LIBDIR LIBCDIO_CFLAGS LIBCDIO_LIBS' # Initialize some variables set by options. ac_init_help= ac_init_version=false ac_unrecognized_opts= ac_unrecognized_sep= # The variables have the same names as the options, with # dashes changed to underlines. cache_file=/dev/null exec_prefix=NONE no_create= no_recursion= prefix=NONE program_prefix=NONE program_suffix=NONE program_transform_name=s,x,x, silent= site= srcdir= verbose= x_includes=NONE x_libraries=NONE # Installation directory options. # These are left unexpanded so users can "make install exec_prefix=/foo" # and all the variables that are supposed to be based on exec_prefix # by default will actually change. # Use braces instead of parens because sh, perl, etc. also accept them. # (The list follows the same order as the GNU Coding Standards.) bindir='${exec_prefix}/bin' sbindir='${exec_prefix}/sbin' libexecdir='${exec_prefix}/libexec' datarootdir='${prefix}/share' datadir='${datarootdir}' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' includedir='${prefix}/include' oldincludedir='/usr/include' docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' infodir='${datarootdir}/info' htmldir='${docdir}' dvidir='${docdir}' pdfdir='${docdir}' psdir='${docdir}' libdir='${exec_prefix}/lib' localedir='${datarootdir}/locale' mandir='${datarootdir}/man' ac_prev= ac_dashdash= for ac_option do # If the previous option needs an argument, assign it. if test -n "$ac_prev"; then eval $ac_prev=\$ac_option ac_prev= continue fi case $ac_option in *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; *=) ac_optarg= ;; *) ac_optarg=yes ;; esac # Accept the important Cygnus configure options, so we can diagnose typos. case $ac_dashdash$ac_option in --) ac_dashdash=yes ;; -bindir | --bindir | --bindi | --bind | --bin | --bi) ac_prev=bindir ;; -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) bindir=$ac_optarg ;; -build | --build | --buil | --bui | --bu) ac_prev=build_alias ;; -build=* | --build=* | --buil=* | --bui=* | --bu=*) build_alias=$ac_optarg ;; -cache-file | --cache-file | --cache-fil | --cache-fi \ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) ac_prev=cache_file ;; -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) cache_file=$ac_optarg ;; --config-cache | -C) cache_file=config.cache ;; -datadir | --datadir | --datadi | --datad) ac_prev=datadir ;; -datadir=* | --datadir=* | --datadi=* | --datad=*) datadir=$ac_optarg ;; -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ | --dataroo | --dataro | --datar) ac_prev=datarootdir ;; -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) datarootdir=$ac_optarg ;; -disable-* | --disable-*) ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid feature name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=no ;; -docdir | --docdir | --docdi | --doc | --do) ac_prev=docdir ;; -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) docdir=$ac_optarg ;; -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) ac_prev=dvidir ;; -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) dvidir=$ac_optarg ;; -enable-* | --enable-*) ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid feature name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=\$ac_optarg ;; -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ | --exec | --exe | --ex) ac_prev=exec_prefix ;; -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ | --exec=* | --exe=* | --ex=*) exec_prefix=$ac_optarg ;; -gas | --gas | --ga | --g) # Obsolete; use --with-gas. with_gas=yes ;; -help | --help | --hel | --he | -h) ac_init_help=long ;; -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) ac_init_help=recursive ;; -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) ac_init_help=short ;; -host | --host | --hos | --ho) ac_prev=host_alias ;; -host=* | --host=* | --hos=* | --ho=*) host_alias=$ac_optarg ;; -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) ac_prev=htmldir ;; -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ | --ht=*) htmldir=$ac_optarg ;; -includedir | --includedir | --includedi | --included | --include \ | --includ | --inclu | --incl | --inc) ac_prev=includedir ;; -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ | --includ=* | --inclu=* | --incl=* | --inc=*) includedir=$ac_optarg ;; -infodir | --infodir | --infodi | --infod | --info | --inf) ac_prev=infodir ;; -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) infodir=$ac_optarg ;; -libdir | --libdir | --libdi | --libd) ac_prev=libdir ;; -libdir=* | --libdir=* | --libdi=* | --libd=*) libdir=$ac_optarg ;; -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ | --libexe | --libex | --libe) ac_prev=libexecdir ;; -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ | --libexe=* | --libex=* | --libe=*) libexecdir=$ac_optarg ;; -localedir | --localedir | --localedi | --localed | --locale) ac_prev=localedir ;; -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) localedir=$ac_optarg ;; -localstatedir | --localstatedir | --localstatedi | --localstated \ | --localstate | --localstat | --localsta | --localst | --locals) ac_prev=localstatedir ;; -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) localstatedir=$ac_optarg ;; -mandir | --mandir | --mandi | --mand | --man | --ma | --m) ac_prev=mandir ;; -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) mandir=$ac_optarg ;; -nfp | --nfp | --nf) # Obsolete; use --without-fp. with_fp=no ;; -no-create | --no-create | --no-creat | --no-crea | --no-cre \ | --no-cr | --no-c | -n) no_create=yes ;; -no-recursion | --no-recursion | --no-recursio | --no-recursi \ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) no_recursion=yes ;; -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ | --oldin | --oldi | --old | --ol | --o) ac_prev=oldincludedir ;; -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) oldincludedir=$ac_optarg ;; -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) ac_prev=prefix ;; -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) prefix=$ac_optarg ;; -program-prefix | --program-prefix | --program-prefi | --program-pref \ | --program-pre | --program-pr | --program-p) ac_prev=program_prefix ;; -program-prefix=* | --program-prefix=* | --program-prefi=* \ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) program_prefix=$ac_optarg ;; -program-suffix | --program-suffix | --program-suffi | --program-suff \ | --program-suf | --program-su | --program-s) ac_prev=program_suffix ;; -program-suffix=* | --program-suffix=* | --program-suffi=* \ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) program_suffix=$ac_optarg ;; -program-transform-name | --program-transform-name \ | --program-transform-nam | --program-transform-na \ | --program-transform-n | --program-transform- \ | --program-transform | --program-transfor \ | --program-transfo | --program-transf \ | --program-trans | --program-tran \ | --progr-tra | --program-tr | --program-t) ac_prev=program_transform_name ;; -program-transform-name=* | --program-transform-name=* \ | --program-transform-nam=* | --program-transform-na=* \ | --program-transform-n=* | --program-transform-=* \ | --program-transform=* | --program-transfor=* \ | --program-transfo=* | --program-transf=* \ | --program-trans=* | --program-tran=* \ | --progr-tra=* | --program-tr=* | --program-t=*) program_transform_name=$ac_optarg ;; -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) ac_prev=pdfdir ;; -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) pdfdir=$ac_optarg ;; -psdir | --psdir | --psdi | --psd | --ps) ac_prev=psdir ;; -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) psdir=$ac_optarg ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) silent=yes ;; -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ | --sbi=* | --sb=*) sbindir=$ac_optarg ;; -sharedstatedir | --sharedstatedir | --sharedstatedi \ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ | --sharedst | --shareds | --shared | --share | --shar \ | --sha | --sh) ac_prev=sharedstatedir ;; -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ | --sha=* | --sh=*) sharedstatedir=$ac_optarg ;; -site | --site | --sit) ac_prev=site ;; -site=* | --site=* | --sit=*) site=$ac_optarg ;; -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) ac_prev=srcdir ;; -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) srcdir=$ac_optarg ;; -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ | --syscon | --sysco | --sysc | --sys | --sy) ac_prev=sysconfdir ;; -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) sysconfdir=$ac_optarg ;; -target | --target | --targe | --targ | --tar | --ta | --t) ac_prev=target_alias ;; -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) target_alias=$ac_optarg ;; -v | -verbose | --verbose | --verbos | --verbo | --verb) verbose=yes ;; -version | --version | --versio | --versi | --vers | -V) ac_init_version=: ;; -with-* | --with-*) ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid package name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=\$ac_optarg ;; -without-* | --without-*) ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid package name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=no ;; --x) # Obsolete; use --with-x. with_x=yes ;; -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ | --x-incl | --x-inc | --x-in | --x-i) ac_prev=x_includes ;; -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) x_includes=$ac_optarg ;; -x-libraries | --x-libraries | --x-librarie | --x-librari \ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) ac_prev=x_libraries ;; -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) x_libraries=$ac_optarg ;; -*) as_fn_error $? "unrecognized option: \`$ac_option' Try \`$0 --help' for more information" ;; *=*) ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` # Reject names that are not valid shell variable names. case $ac_envvar in #( '' | [0-9]* | *[!_$as_cr_alnum]* ) as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; esac eval $ac_envvar=\$ac_optarg export $ac_envvar ;; *) # FIXME: should be removed in autoconf 3.0. $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" ;; esac done if test -n "$ac_prev"; then ac_option=--`echo $ac_prev | sed 's/_/-/g'` as_fn_error $? "missing argument to $ac_option" fi if test -n "$ac_unrecognized_opts"; then case $enable_option_checking in no) ;; fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; esac fi # Check all directory arguments for consistency. for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ datadir sysconfdir sharedstatedir localstatedir includedir \ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ libdir localedir mandir do eval ac_val=\$$ac_var # Remove trailing slashes. case $ac_val in */ ) ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` eval $ac_var=\$ac_val;; esac # Be sure to have absolute directory names. case $ac_val in [\\/$]* | ?:[\\/]* ) continue;; NONE | '' ) case $ac_var in *prefix ) continue;; esac;; esac as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" done # There might be people who depend on the old broken behavior: `$host' # used to hold the argument of --host etc. # FIXME: To remove some day. build=$build_alias host=$host_alias target=$target_alias # FIXME: To remove some day. if test "x$host_alias" != x; then if test "x$build_alias" = x; then cross_compiling=maybe elif test "x$build_alias" != "x$host_alias"; then cross_compiling=yes fi fi ac_tool_prefix= test -n "$host_alias" && ac_tool_prefix=$host_alias- test "$silent" = yes && exec 6>/dev/null ac_pwd=`pwd` && test -n "$ac_pwd" && ac_ls_di=`ls -di .` && ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || as_fn_error $? "working directory cannot be determined" test "X$ac_ls_di" = "X$ac_pwd_ls_di" || as_fn_error $? "pwd does not report name of working directory" # Find the source files, if location was not specified. if test -z "$srcdir"; then ac_srcdir_defaulted=yes # Try the directory containing this script, then the parent directory. ac_confdir=`$as_dirname -- "$as_myself" || $as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_myself" : 'X\(//\)[^/]' \| \ X"$as_myself" : 'X\(//\)$' \| \ X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_myself" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` srcdir=$ac_confdir if test ! -r "$srcdir/$ac_unique_file"; then srcdir=.. fi else ac_srcdir_defaulted=no fi if test ! -r "$srcdir/$ac_unique_file"; then test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" fi ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" ac_abs_confdir=`( cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" pwd)` # When building in place, set srcdir=. if test "$ac_abs_confdir" = "$ac_pwd"; then srcdir=. fi # Remove unnecessary trailing slashes from srcdir. # Double slashes in file names in object file debugging info # mess up M-x gdb in Emacs. case $srcdir in */) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; esac for ac_var in $ac_precious_vars; do eval ac_env_${ac_var}_set=\${${ac_var}+set} eval ac_env_${ac_var}_value=\$${ac_var} eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} eval ac_cv_env_${ac_var}_value=\$${ac_var} done # # Report the --help message. # if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF \`configure' configures libburn 1.4.2 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... To assign environment variables (e.g., CC, CFLAGS...), specify them as VAR=VALUE. See below for descriptions of some of the useful variables. Defaults for the options are specified in brackets. Configuration: -h, --help display this help and exit --help=short display options specific to this package --help=recursive display the short help of all the included packages -V, --version display version information and exit -q, --quiet, --silent do not print \`checking ...' messages --cache-file=FILE cache test results in FILE [disabled] -C, --config-cache alias for \`--cache-file=config.cache' -n, --no-create do not create output files --srcdir=DIR find the sources in DIR [configure dir or \`..'] Installation directories: --prefix=PREFIX install architecture-independent files in PREFIX [$ac_default_prefix] --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX [PREFIX] By default, \`make install' will install all the files in \`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify an installation prefix other than \`$ac_default_prefix' using \`--prefix', for instance \`--prefix=\$HOME'. For better control, use the options below. Fine tuning of the installation directories: --bindir=DIR user executables [EPREFIX/bin] --sbindir=DIR system admin executables [EPREFIX/sbin] --libexecdir=DIR program executables [EPREFIX/libexec] --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] --datadir=DIR read-only architecture-independent data [DATAROOTDIR] --infodir=DIR info documentation [DATAROOTDIR/info] --localedir=DIR locale-dependent data [DATAROOTDIR/locale] --mandir=DIR man documentation [DATAROOTDIR/man] --docdir=DIR documentation root [DATAROOTDIR/doc/libburn] --htmldir=DIR html documentation [DOCDIR] --dvidir=DIR dvi documentation [DOCDIR] --pdfdir=DIR pdf documentation [DOCDIR] --psdir=DIR ps documentation [DOCDIR] _ACEOF cat <<\_ACEOF Program names: --program-prefix=PREFIX prepend PREFIX to installed program names --program-suffix=SUFFIX append SUFFIX to installed program names --program-transform-name=PROGRAM run sed PROGRAM on installed program names System types: --build=BUILD configure for building on BUILD [guessed] --host=HOST cross-compile to build programs to run on HOST [BUILD] --target=TARGET configure for building compilers for TARGET [HOST] _ACEOF fi if test -n "$ac_init_help"; then case $ac_init_help in short | recursive ) echo "Configuration of libburn 1.4.2:";; esac cat <<\_ACEOF Optional Features: --disable-option-checking ignore unrecognized --enable/--with options --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] --enable-silent-rules less verbose build output (undo: "make V=1") --disable-silent-rules verbose build output (undo: "make V=0") --enable-maintainer-mode enable make rules and dependencies not useful (and sometimes confusing) to the casual installer --enable-dependency-tracking do not reject slow dependency extractors --disable-dependency-tracking speeds up one-time build --disable-largefile omit support for large files --enable-shared[=PKGS] build shared libraries [default=yes] --enable-static[=PKGS] build static libraries [default=yes] --enable-fast-install[=PKGS] optimize for fast installation [default=yes] --disable-libtool-lock avoid locking (might break parallel builds) --enable-track-src-odirect Enable use of O_DIRECT with track input, default=no --enable-dvd-obs-64k 64 KB default size for DVD writing, default=no --enable-dvd-obs-pad pad DVD DAO sessions to 32 or 64 KB, default=no --enable-pkg-check-modules Enable pkg-config check for libcdio , default=no --enable-libcdio Enable use of libcdio as system adapter, default=no (except on MSWindows) --enable-versioned-libs Enable strict symbol encapsulation , default=yes --enable-ldconfig-at-install On GNU/Linux run ldconfig, default=yes --enable-debug Disable aggressive optimizations default=yes --enable-libdir-pkgconfig Install to $libdir/pkgconfig on any OS, default=no --enable-pkgconfig-path=DIR Absolute path of directory for libisofs-*.pc Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) --with-pic[=PKGS] try to use only PIC/non-PIC objects [default=use both] --with-gnu-ld assume the C compiler uses GNU ld [default=no] --with-sysroot=DIR Search for dependent libraries within DIR (or the compiler's sysroot if not specified). Some influential environment variables: CC C compiler command CFLAGS C compiler flags LDFLAGS linker flags, e.g. -L<lib dir> if you have libraries in a nonstandard directory <lib dir> LIBS libraries to pass to the linker, e.g. -l<library> CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I<include dir> if you have headers in a nonstandard directory <include dir> CPP C preprocessor PKG_CONFIG path to pkg-config utility PKG_CONFIG_PATH directories to add to pkg-config's search path PKG_CONFIG_LIBDIR path overriding pkg-config's built-in search path LIBCDIO_CFLAGS C compiler flags for LIBCDIO, overriding pkg-config LIBCDIO_LIBS linker flags for LIBCDIO, overriding pkg-config Use these variables to override the choices made by `configure' or to help it to find libraries and programs with nonstandard names/locations. Report bugs to <http://libburnia-project.org>. _ACEOF ac_status=$? fi if test "$ac_init_help" = "recursive"; then # If there are subdirs, report their specific --help. for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue test -d "$ac_dir" || { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || continue ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix cd "$ac_dir" || { ac_status=$?; continue; } # Check for guested configure. if test -f "$ac_srcdir/configure.gnu"; then echo && $SHELL "$ac_srcdir/configure.gnu" --help=recursive elif test -f "$ac_srcdir/configure"; then echo && $SHELL "$ac_srcdir/configure" --help=recursive else $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 fi || ac_status=$? cd "$ac_pwd" || { ac_status=$?; break; } done fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF libburn configure 1.4.2 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. _ACEOF exit fi ## ------------------------ ## ## Autoconf initialization. ## ## ------------------------ ## # ac_fn_c_try_compile LINENO # -------------------------- # Try to compile conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_compile # ac_fn_c_try_run LINENO # ---------------------- # Try to link conftest.$ac_ext, and return whether this succeeded. Assumes # that executables *can* be run. ac_fn_c_try_run () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; }; then : ac_retval=0 else $as_echo "$as_me: program exited with status $ac_status" >&5 $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=$ac_status fi rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_run # ac_fn_c_try_cpp LINENO # ---------------------- # Try to preprocess conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_cpp () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } > conftest.i && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_cpp # ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES # ------------------------------------------------------- # Tests whether HEADER exists and can be compiled using the include files in # INCLUDES, setting the cache variable VAR accordingly. ac_fn_c_check_header_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 #include <$2> _ACEOF if ac_fn_c_try_compile "$LINENO"; then : eval "$3=yes" else eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_header_compile # ac_fn_c_try_link LINENO # ----------------------- # Try to link conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_link () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext conftest$ac_exeext if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || test -x conftest$ac_exeext }; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would # interfere with the next link command; also delete a directory that is # left behind by Apple's compiler. We do this before executing the actions. rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_link # ac_fn_c_check_func LINENO FUNC VAR # ---------------------------------- # Tests whether FUNC exists, setting the cache variable VAR accordingly ac_fn_c_check_func () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Define $2 to an innocuous variant, in case <limits.h> declares $2. For example, HP-UX 11i <limits.h> declares gettimeofday. */ #define $2 innocuous_$2 /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $2 (); below. Prefer <limits.h> to <assert.h> if __STDC__ is defined, since <limits.h> exists even on freestanding compilers. */ #ifdef __STDC__ # include <limits.h> #else # include <assert.h> #endif #undef $2 /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char $2 (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_$2 || defined __stub___$2 choke me #endif int main () { return $2 (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : eval "$3=yes" else eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_func # ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES # ------------------------------------------------------- # Tests whether HEADER exists, giving a warning if it cannot be compiled using # the include files in INCLUDES and setting the cache variable VAR # accordingly. ac_fn_c_check_header_mongrel () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if eval \${$3+:} false; then : { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } else # Is the header compilable? { $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5 $as_echo_n "checking $2 usability... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 #include <$2> _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_header_compiler=yes else ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5 $as_echo "$ac_header_compiler" >&6; } # Is the header present? { $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5 $as_echo_n "checking $2 presence... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include <$2> _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : ac_header_preproc=yes else ac_header_preproc=no fi rm -f conftest.err conftest.i conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5 $as_echo "$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #(( yes:no: ) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5 $as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} ;; no:yes:* ) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5 $as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5 $as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5 $as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5 $as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} ( $as_echo "## ------------------------------------------- ## ## Report this to http://libburnia-project.org ## ## ------------------------------------------- ##" ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else eval "$3=\$ac_header_compiler" fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_header_mongrel cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. It was created by libburn $as_me 1.4.2, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ _ACEOF exec 5>>config.log { cat <<_ASUNAME ## --------- ## ## Platform. ## ## --------- ## hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` uname -m = `(uname -m) 2>/dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` /bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` /bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` /usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` /bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` /bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` _ASUNAME as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. $as_echo "PATH: $as_dir" done IFS=$as_save_IFS } >&5 cat >&5 <<_ACEOF ## ----------- ## ## Core tests. ## ## ----------- ## _ACEOF # Keep a trace of the command line. # Strip out --no-create and --no-recursion so they do not pile up. # Strip out --silent because we don't want to record it for future runs. # Also quote any args containing shell meta-characters. # Make two passes to allow for proper duplicate-argument suppression. ac_configure_args= ac_configure_args0= ac_configure_args1= ac_must_keep_next=false for ac_pass in 1 2 do for ac_arg do case $ac_arg in -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) continue ;; *\'*) ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; esac case $ac_pass in 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; 2) as_fn_append ac_configure_args1 " '$ac_arg'" if test $ac_must_keep_next = true; then ac_must_keep_next=false # Got value, back to normal. else case $ac_arg in *=* | --config-cache | -C | -disable-* | --disable-* \ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ | -with-* | --with-* | -without-* | --without-* | --x) case "$ac_configure_args0 " in "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; esac ;; -* ) ac_must_keep_next=true ;; esac fi as_fn_append ac_configure_args " '$ac_arg'" ;; esac done done { ac_configure_args0=; unset ac_configure_args0;} { ac_configure_args1=; unset ac_configure_args1;} # When interrupted or exit'd, cleanup temporary files, and complete # config.log. We remove comments because anyway the quotes in there # would cause problems or look ugly. # WARNING: Use '\'' to represent an apostrophe within the trap. # WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. trap 'exit_status=$? # Save into config.log some information that might help in debugging. { echo $as_echo "## ---------------- ## ## Cache variables. ## ## ---------------- ##" echo # The following way of writing the cache mishandles newlines in values, ( for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; unset $ac_var;} ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( *${as_nl}ac_space=\ *) sed -n \ "s/'\''/'\''\\\\'\'''\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" ;; #( *) sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) echo $as_echo "## ----------------- ## ## Output variables. ## ## ----------------- ##" echo for ac_var in $ac_subst_vars do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac $as_echo "$ac_var='\''$ac_val'\''" done | sort echo if test -n "$ac_subst_files"; then $as_echo "## ------------------- ## ## File substitutions. ## ## ------------------- ##" echo for ac_var in $ac_subst_files do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac $as_echo "$ac_var='\''$ac_val'\''" done | sort echo fi if test -s confdefs.h; then $as_echo "## ----------- ## ## confdefs.h. ## ## ----------- ##" echo cat confdefs.h echo fi test "$ac_signal" != 0 && $as_echo "$as_me: caught signal $ac_signal" $as_echo "$as_me: exit $exit_status" } >&5 rm -f core *.core core.conftest.* && rm -f -r conftest* confdefs* conf$$* $ac_clean_files && exit $exit_status ' 0 for ac_signal in 1 2 13 15; do trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal done ac_signal=0 # confdefs.h avoids OS command line length limits that DEFS can exceed. rm -f -r conftest* confdefs.h $as_echo "/* confdefs.h */" > confdefs.h # Predefined preprocessor variables. cat >>confdefs.h <<_ACEOF #define PACKAGE_NAME "$PACKAGE_NAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_TARNAME "$PACKAGE_TARNAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_VERSION "$PACKAGE_VERSION" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_STRING "$PACKAGE_STRING" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_URL "$PACKAGE_URL" _ACEOF # Let the site file select an alternate cache file if it wants to. # Prefer an explicitly selected file to automatically selected ones. ac_site_file1=NONE ac_site_file2=NONE if test -n "$CONFIG_SITE"; then # We do not want a PATH search for config.site. case $CONFIG_SITE in #(( -*) ac_site_file1=./$CONFIG_SITE;; */*) ac_site_file1=$CONFIG_SITE;; *) ac_site_file1=./$CONFIG_SITE;; esac elif test "x$prefix" != xNONE; then ac_site_file1=$prefix/share/config.site ac_site_file2=$prefix/etc/config.site else ac_site_file1=$ac_default_prefix/share/config.site ac_site_file2=$ac_default_prefix/etc/config.site fi for ac_site_file in "$ac_site_file1" "$ac_site_file2" do test "x$ac_site_file" = xNONE && continue if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 $as_echo "$as_me: loading site script $ac_site_file" >&6;} sed 's/^/| /' "$ac_site_file" >&5 . "$ac_site_file" \ || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "failed to load site script $ac_site_file See \`config.log' for more details" "$LINENO" 5; } fi done if test -r "$cache_file"; then # Some versions of bash will fail to source /dev/null (special files # actually), so we avoid doing that. DJGPP emulates it as a regular file. if test /dev/null != "$cache_file" && test -f "$cache_file"; then { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 $as_echo "$as_me: loading cache $cache_file" >&6;} case $cache_file in [\\/]* | ?:[\\/]* ) . "$cache_file";; *) . "./$cache_file";; esac fi else { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 $as_echo "$as_me: creating cache $cache_file" >&6;} >$cache_file fi # Check that the precious variables saved in the cache have kept the same # value. ac_cache_corrupted=false for ac_var in $ac_precious_vars; do eval ac_old_set=\$ac_cv_env_${ac_var}_set eval ac_new_set=\$ac_env_${ac_var}_set eval ac_old_val=\$ac_cv_env_${ac_var}_value eval ac_new_val=\$ac_env_${ac_var}_value case $ac_old_set,$ac_new_set in set,) { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 $as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} ac_cache_corrupted=: ;; ,set) { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 $as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} ac_cache_corrupted=: ;; ,);; *) if test "x$ac_old_val" != "x$ac_new_val"; then # differences in whitespace do not lead to failure. ac_old_val_w=`echo x $ac_old_val` ac_new_val_w=`echo x $ac_new_val` if test "$ac_old_val_w" != "$ac_new_val_w"; then { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 $as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} ac_cache_corrupted=: else { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 $as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} eval $ac_var=\$ac_old_val fi { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 $as_echo "$as_me: former value: \`$ac_old_val'" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 $as_echo "$as_me: current value: \`$ac_new_val'" >&2;} fi;; esac # Pass precious variables to config.status. if test "$ac_new_set" = set; then case $ac_new_val in *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; *) ac_arg=$ac_var=$ac_new_val ;; esac case " $ac_configure_args " in *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. *) as_fn_append ac_configure_args " '$ac_arg'" ;; esac fi done if $ac_cache_corrupted; then { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 $as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 fi ## -------------------- ## ## Main body of script. ## ## -------------------- ## ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_aux_dir= for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do if test -f "$ac_dir/install-sh"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install-sh -c" break elif test -f "$ac_dir/install.sh"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install.sh -c" break elif test -f "$ac_dir/shtool"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/shtool install -c" break fi done if test -z "$ac_aux_dir"; then as_fn_error $? "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5 fi # These three variables are undocumented and unsupported, # and are intended to be withdrawn in a future Autoconf release. # They can cause serious problems if a builder's source tree is in a directory # whose full name contains unusual characters. ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. # Make sure we can run config.sub. $SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5 { $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 $as_echo_n "checking build system type... " >&6; } if ${ac_cv_build+:} false; then : $as_echo_n "(cached) " >&6 else ac_build_alias=$build_alias test "x$ac_build_alias" = x && ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"` test "x$ac_build_alias" = x && as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5 ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` || as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5 $as_echo "$ac_cv_build" >&6; } case $ac_cv_build in *-*-*) ;; *) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;; esac build=$ac_cv_build ac_save_IFS=$IFS; IFS='-' set x $ac_cv_build shift build_cpu=$1 build_vendor=$2 shift; shift # Remember, the first character of IFS is used to create $*, # except with old shells: build_os=$* IFS=$ac_save_IFS case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5 $as_echo_n "checking host system type... " >&6; } if ${ac_cv_host+:} false; then : $as_echo_n "(cached) " >&6 else if test "x$host_alias" = x; then ac_cv_host=$ac_cv_build else ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` || as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5 fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5 $as_echo "$ac_cv_host" >&6; } case $ac_cv_host in *-*-*) ;; *) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;; esac host=$ac_cv_host ac_save_IFS=$IFS; IFS='-' set x $ac_cv_host shift host_cpu=$1 host_vendor=$2 shift; shift # Remember, the first character of IFS is used to create $*, # except with old shells: host_os=$* IFS=$ac_save_IFS case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking target system type" >&5 $as_echo_n "checking target system type... " >&6; } if ${ac_cv_target+:} false; then : $as_echo_n "(cached) " >&6 else if test "x$target_alias" = x; then ac_cv_target=$ac_cv_host else ac_cv_target=`$SHELL "$ac_aux_dir/config.sub" $target_alias` || as_fn_error $? "$SHELL $ac_aux_dir/config.sub $target_alias failed" "$LINENO" 5 fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_target" >&5 $as_echo "$ac_cv_target" >&6; } case $ac_cv_target in *-*-*) ;; *) as_fn_error $? "invalid value of canonical target" "$LINENO" 5;; esac target=$ac_cv_target ac_save_IFS=$IFS; IFS='-' set x $ac_cv_target shift target_cpu=$1 target_vendor=$2 shift; shift # Remember, the first character of IFS is used to create $*, # except with old shells: target_os=$* IFS=$ac_save_IFS case $target_os in *\ *) target_os=`echo "$target_os" | sed 's/ /-/g'`;; esac # The aliases save the names the user supplied, while $host etc. # will get canonicalized. test -n "$target_alias" && test "$program_prefix$program_suffix$program_transform_name" = \ NONENONEs,x,x, && program_prefix=${target_alias}- case $target_os in freebsd* | netbsd*) LDFLAGS="$LDFLAGS -L/usr/local/lib" CPPFLAGS="$CPPFLAGS -I/usr/local/include" ;; esac am__api_version='1.14' # Find a good install program. We prefer a C program (faster), # so one script is as good as another. But avoid the broken or # incompatible versions: # SysV /etc/install, /usr/sbin/install # SunOS /usr/etc/install # IRIX /sbin/install # AIX /bin/install # AmigaOS /C/install, which installs bootblocks on floppy discs # AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag # AFS /usr/afsws/bin/install, which mishandles nonexistent args # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" # OS/2's system install, which has a completely different semantic # ./install, which can be erroneously created by make from ./install.sh. # Reject install programs that cannot install multiple files. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 $as_echo_n "checking for a BSD-compatible install... " >&6; } if test -z "$INSTALL"; then if ${ac_cv_path_install+:} false; then : $as_echo_n "(cached) " >&6 else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. # Account for people who put trailing slashes in PATH elements. case $as_dir/ in #(( ./ | .// | /[cC]/* | \ /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ /usr/ucb/* ) ;; *) # OSF1 and SCO ODT 3.0 have their own names for install. # Don't use installbsd from OSF since it installs stuff as root # by default. for ac_prog in ginstall scoinst install; do for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then if test $ac_prog = install && grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # AIX install. It has an incompatible calling convention. : elif test $ac_prog = install && grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # program-specific install script used by HP pwplus--don't use. : else rm -rf conftest.one conftest.two conftest.dir echo one > conftest.one echo two > conftest.two mkdir conftest.dir if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" && test -s conftest.one && test -s conftest.two && test -s conftest.dir/conftest.one && test -s conftest.dir/conftest.two then ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" break 3 fi fi fi done done ;; esac done IFS=$as_save_IFS rm -rf conftest.one conftest.two conftest.dir fi if test "${ac_cv_path_install+set}" = set; then INSTALL=$ac_cv_path_install else # As a last resort, use the slow shell script. Don't cache a # value for INSTALL within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the value is a relative name. INSTALL=$ac_install_sh fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 $as_echo "$INSTALL" >&6; } # Use test -z because SunOS4 sh mishandles braces in ${var-val}. # It thinks the first close brace ends the variable substitution. test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5 $as_echo_n "checking whether build environment is sane... " >&6; } # Reject unsafe characters in $srcdir or the absolute working directory # name. Accept space and tab only in the latter. am_lf=' ' case `pwd` in *[\\\"\#\$\&\'\`$am_lf]*) as_fn_error $? "unsafe absolute working directory name" "$LINENO" 5;; esac case $srcdir in *[\\\"\#\$\&\'\`$am_lf\ \ ]*) as_fn_error $? "unsafe srcdir value: '$srcdir'" "$LINENO" 5;; esac # Do 'set' in a subshell so we don't clobber the current shell's # arguments. Must try -L first in case configure is actually a # symlink; some systems play weird games with the mod time of symlinks # (eg FreeBSD returns the mod time of the symlink's containing # directory). if ( am_has_slept=no for am_try in 1 2; do echo "timestamp, slept: $am_has_slept" > conftest.file set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` if test "$*" = "X"; then # -L didn't work. set X `ls -t "$srcdir/configure" conftest.file` fi if test "$*" != "X $srcdir/configure conftest.file" \ && test "$*" != "X conftest.file $srcdir/configure"; then # If neither matched, then we have a broken ls. This can happen # if, for instance, CONFIG_SHELL is bash and it inherits a # broken ls alias from the environment. This has actually # happened. Such a system could not be considered "sane". as_fn_error $? "ls -t appears to fail. Make sure there is not a broken alias in your environment" "$LINENO" 5 fi if test "$2" = conftest.file || test $am_try -eq 2; then break fi # Just in case. sleep 1 am_has_slept=yes done test "$2" = conftest.file ) then # Ok. : else as_fn_error $? "newly created file is older than distributed files! Check your system clock" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } # If we didn't sleep, we still need to ensure time stamps of config.status and # generated files are strictly newer. am_sleep_pid= if grep 'slept: no' conftest.file >/dev/null 2>&1; then ( sleep 1 ) & am_sleep_pid=$! fi rm -f conftest.file test "$program_prefix" != NONE && program_transform_name="s&^&$program_prefix&;$program_transform_name" # Use a double $ so make ignores it. test "$program_suffix" != NONE && program_transform_name="s&\$&$program_suffix&;$program_transform_name" # Double any \ or $. # By default was `s,x,x', remove it if useless. ac_script='s/[\\$]/&&/g;s/;s,x,x,$//' program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"` # Expand $ac_aux_dir to an absolute path. am_aux_dir=`cd "$ac_aux_dir" && pwd` if test x"${MISSING+set}" != xset; then case $am_aux_dir in *\ * | *\ *) MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; *) MISSING="\${SHELL} $am_aux_dir/missing" ;; esac fi # Use eval to expand $SHELL if eval "$MISSING --is-lightweight"; then am_missing_run="$MISSING " else am_missing_run= { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 'missing' script is too old or missing" >&5 $as_echo "$as_me: WARNING: 'missing' script is too old or missing" >&2;} fi if test x"${install_sh}" != xset; then case $am_aux_dir in *\ * | *\ *) install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; *) install_sh="\${SHELL} $am_aux_dir/install-sh" esac fi # Installed binaries are usually stripped using 'strip' when the user # run "make install-strip". However 'strip' might not be the right # tool to use in cross-compilation environments, therefore Automake # will honor the 'STRIP' environment variable to overrule this program. if test "$cross_compiling" != no; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. set dummy ${ac_tool_prefix}strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_STRIP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$STRIP"; then ac_cv_prog_STRIP="$STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_STRIP="${ac_tool_prefix}strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi STRIP=$ac_cv_prog_STRIP if test -n "$STRIP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 $as_echo "$STRIP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_STRIP"; then ac_ct_STRIP=$STRIP # Extract the first word of "strip", so it can be a program name with args. set dummy strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_STRIP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_STRIP"; then ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_STRIP="strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP if test -n "$ac_ct_STRIP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 $as_echo "$ac_ct_STRIP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_STRIP" = x; then STRIP=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac STRIP=$ac_ct_STRIP fi else STRIP="$ac_cv_prog_STRIP" fi fi INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p" >&5 $as_echo_n "checking for a thread-safe mkdir -p... " >&6; } if test -z "$MKDIR_P"; then if ${ac_cv_path_mkdir+:} false; then : $as_echo_n "(cached) " >&6 else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in mkdir gmkdir; do for ac_exec_ext in '' $ac_executable_extensions; do as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext" || continue case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #( 'mkdir (GNU coreutils) '* | \ 'mkdir (coreutils) '* | \ 'mkdir (fileutils) '4.1*) ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext break 3;; esac done done done IFS=$as_save_IFS fi test -d ./--version && rmdir ./--version if test "${ac_cv_path_mkdir+set}" = set; then MKDIR_P="$ac_cv_path_mkdir -p" else # As a last resort, use the slow shell script. Don't cache a # value for MKDIR_P within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the value is a relative name. MKDIR_P="$ac_install_sh -d" fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5 $as_echo "$MKDIR_P" >&6; } for ac_prog in gawk mawk nawk awk do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_AWK+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$AWK"; then ac_cv_prog_AWK="$AWK" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_AWK="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi AWK=$ac_cv_prog_AWK if test -n "$AWK"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 $as_echo "$AWK" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$AWK" && break done { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 $as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } set x ${MAKE-make} ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then : $as_echo_n "(cached) " >&6 else cat >conftest.make <<\_ACEOF SHELL = /bin/sh all: @echo '@@@%%%=$(MAKE)=@@@%%%' _ACEOF # GNU make sometimes prints "make[1]: Entering ...", which would confuse us. case `${MAKE-make} -f conftest.make 2>/dev/null` in *@@@%%%=?*=@@@%%%*) eval ac_cv_prog_make_${ac_make}_set=yes;; *) eval ac_cv_prog_make_${ac_make}_set=no;; esac rm -f conftest.make fi if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } SET_MAKE= else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } SET_MAKE="MAKE=${MAKE-make}" fi rm -rf .tst 2>/dev/null mkdir .tst 2>/dev/null if test -d .tst; then am__leading_dot=. else am__leading_dot=_ fi rmdir .tst 2>/dev/null # Check whether --enable-silent-rules was given. if test "${enable_silent_rules+set}" = set; then : enableval=$enable_silent_rules; fi case $enable_silent_rules in # ((( yes) AM_DEFAULT_VERBOSITY=0;; no) AM_DEFAULT_VERBOSITY=1;; *) AM_DEFAULT_VERBOSITY=1;; esac am_make=${MAKE-make} { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5 $as_echo_n "checking whether $am_make supports nested variables... " >&6; } if ${am_cv_make_support_nested_variables+:} false; then : $as_echo_n "(cached) " >&6 else if $as_echo 'TRUE=$(BAR$(V)) BAR0=false BAR1=true V=1 am__doit: @$(TRUE) .PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then am_cv_make_support_nested_variables=yes else am_cv_make_support_nested_variables=no fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5 $as_echo "$am_cv_make_support_nested_variables" >&6; } if test $am_cv_make_support_nested_variables = yes; then AM_V='$(V)' AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' else AM_V=$AM_DEFAULT_VERBOSITY AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY fi AM_BACKSLASH='\' if test "`cd $srcdir && pwd`" != "`pwd`"; then # Use -I$(srcdir) only when $(srcdir) != ., so that make's output # is not polluted with repeated "-I." am__isrc=' -I$(srcdir)' # test to see if srcdir already configured if test -f $srcdir/config.status; then as_fn_error $? "source directory already configured; run \"make distclean\" there first" "$LINENO" 5 fi fi # test whether we have cygpath if test -z "$CYGPATH_W"; then if (cygpath --version) >/dev/null 2>/dev/null; then CYGPATH_W='cygpath -w' else CYGPATH_W=echo fi fi # Define the identity of the package. PACKAGE='libburn' VERSION='1.4.2' cat >>confdefs.h <<_ACEOF #define PACKAGE "$PACKAGE" _ACEOF cat >>confdefs.h <<_ACEOF #define VERSION "$VERSION" _ACEOF # Some tools Automake needs. ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} # For better backward compatibility. To be removed once Automake 1.9.x # dies out for good. For more background, see: # <http://lists.gnu.org/archive/html/automake/2012-07/msg00001.html> # <http://lists.gnu.org/archive/html/automake/2012-07/msg00014.html> mkdir_p='$(MKDIR_P)' # We need awk for the "check" target. The system "awk" is bad on # some platforms. # Always define AMTAR for backward compatibility. Yes, it's still used # in the wild :-( We should find a proper way to deprecate it ... AMTAR='$${TAR-tar}' # We'll loop over all known methods to create a tar archive until one works. _am_tools='gnutar pax cpio none' am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -' # POSIX will say in a future version that running "rm -f" with no argument # is OK; and we want to be able to make that assumption in our Makefile # recipes. So use an aggressive probe to check that the usage we want is # actually supported "in the wild" to an acceptable degree. # See automake bug#10828. # To make any issue more visible, cause the running configure to be aborted # by default if the 'rm' program in use doesn't match our expectations; the # user can still override this though. if rm -f && rm -fr && rm -rf; then : OK; else cat >&2 <<'END' Oops! Your 'rm' program seems unable to run without file operands specified on the command line, even when the '-f' option is present. This is contrary to the behaviour of most rm programs out there, and not conforming with the upcoming POSIX standard: <http://austingroupbugs.net/view.php?id=542> Please tell bug-automake@gnu.org about your system, including the value of your $PATH and any error possibly output before this message. This can help us improve future automake versions. END if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then echo 'Configuration will proceed anyway, since you have set the' >&2 echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2 echo >&2 else cat >&2 <<'END' Aborting the configuration process, to ensure you take notice of the issue. You can download and install GNU coreutils to get an 'rm' implementation that behaves properly: <http://www.gnu.org/software/coreutils/>. If you want to complete the configuration process using your problematic 'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM to "yes", and re-run configure. END as_fn_error $? "Your 'rm' program is bad, sorry." "$LINENO" 5 fi fi BURN_MAJOR_VERSION=1 BURN_MINOR_VERSION=4 BURN_MICRO_VERSION=2 BURN_VERSION=$BURN_MAJOR_VERSION.$BURN_MINOR_VERSION.$BURN_MICRO_VERSION LT_RELEASE=$BURN_MAJOR_VERSION.$BURN_MINOR_VERSION.$BURN_MICRO_VERSION LT_CURRENT=99 LT_AGE=95 LT_REVISION=0 LT_CURRENT_MINUS_AGE=`expr $LT_CURRENT - $LT_AGE` BURN_INTERFACE_AGE=$LT_REVISION BURN_BINARY_AGE=`expr $LT_AGE + $BURN_INTERFACE_AGE` test "$prefix" = "NONE" && prefix=$ac_default_prefix { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable maintainer-specific portions of Makefiles" >&5 $as_echo_n "checking whether to enable maintainer-specific portions of Makefiles... " >&6; } # Check whether --enable-maintainer-mode was given. if test "${enable_maintainer_mode+set}" = set; then : enableval=$enable_maintainer_mode; USE_MAINTAINER_MODE=$enableval else USE_MAINTAINER_MODE=no fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $USE_MAINTAINER_MODE" >&5 $as_echo "$USE_MAINTAINER_MODE" >&6; } if test $USE_MAINTAINER_MODE = yes; then MAINTAINER_MODE_TRUE= MAINTAINER_MODE_FALSE='#' else MAINTAINER_MODE_TRUE='#' MAINTAINER_MODE_FALSE= fi MAINT=$MAINTAINER_MODE_TRUE DEPDIR="${am__leading_dot}deps" ac_config_commands="$ac_config_commands depfiles" am_make=${MAKE-make} cat > confinc << 'END' am__doit: @echo this is the am__doit target .PHONY: am__doit END # If we don't find an include directive, just comment out the code. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for style of include used by $am_make" >&5 $as_echo_n "checking for style of include used by $am_make... " >&6; } am__include="#" am__quote= _am_result=none # First try GNU make style include. echo "include confinc" > confmf # Ignore all kinds of additional output from 'make'. case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=include am__quote= _am_result=GNU ;; esac # Now try BSD make style include. if test "$am__include" = "#"; then echo '.include "confinc"' > confmf case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=.include am__quote="\"" _am_result=BSD ;; esac fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $_am_result" >&5 $as_echo "$_am_result" >&6; } rm -f confinc confmf # Check whether --enable-dependency-tracking was given. if test "${enable_dependency_tracking+set}" = set; then : enableval=$enable_dependency_tracking; fi if test "x$enable_dependency_tracking" != xno; then am_depcomp="$ac_aux_dir/depcomp" AMDEPBACKSLASH='\' am__nodep='_no' fi if test "x$enable_dependency_tracking" != xno; then AMDEP_TRUE= AMDEP_FALSE='#' else AMDEP_TRUE='#' AMDEP_FALSE= fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. set dummy ${ac_tool_prefix}gcc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_CC"; then ac_ct_CC=$CC # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi else CC="$ac_cv_prog_CC" fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. set dummy ${ac_tool_prefix}cc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi fi if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else ac_prog_rejected=no as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue fi ac_cv_prog_CC="cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS if test $ac_prog_rejected = yes; then # We found a bogon in the path, so make sure we never use it. set dummy $ac_cv_prog_CC shift if test $# != 0; then # We chose a different compiler from the bogus one. # However, it has the same basename, so the bogon will be chosen # first if we set CC to just the basename; use the full file name. shift ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" fi fi fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then for ac_prog in cl.exe do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$CC" && break done fi if test -z "$CC"; then ac_ct_CC=$CC for ac_prog in cl.exe do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_CC" && break done if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi fi fi test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "no acceptable C compiler found in \$PATH See \`config.log' for more details" "$LINENO" 5; } # Provide some information about the compiler. $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 set X $ac_compile ac_compiler=$2 for ac_option in --version -v -V -qversion; do { { ac_try="$ac_compiler $ac_option >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compiler $ac_option >&5") 2>conftest.err ac_status=$? if test -s conftest.err; then sed '10a\ ... rest of stderr output deleted ... 10q' conftest.err >conftest.er1 cat conftest.er1 >&5 fi rm -f conftest.er1 conftest.err $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } done cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" # Try to create an executable without -o first, disregard a.out. # It will help us diagnose broken compilers, and finding out an intuition # of exeext. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 $as_echo_n "checking whether the C compiler works... " >&6; } ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` # The possible output files: ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" ac_rmfiles= for ac_file in $ac_files do case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; * ) ac_rmfiles="$ac_rmfiles $ac_file";; esac done rm -f $ac_rmfiles if { { ac_try="$ac_link_default" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link_default") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. # So ignore a value of `no', otherwise this would lead to `EXEEXT = no' # in a Makefile. We should not override ac_cv_exeext if it was cached, # so that the user can short-circuit this test for compilers unknown to # Autoconf. for ac_file in $ac_files '' do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; [ab].out ) # We found the default executable, but exeext='' is most # certainly right. break;; *.* ) if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; then :; else ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` fi # We set ac_cv_exeext here because the later test for it is not # safe: cross compilers may not add the suffix if given an `-o' # argument, so we may need to know it at that point already. # Even if this section looks crufty: it has the advantage of # actually working. break;; * ) break;; esac done test "$ac_cv_exeext" = no && ac_cv_exeext= else ac_file='' fi if test -z "$ac_file"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "C compiler cannot create executables See \`config.log' for more details" "$LINENO" 5; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 $as_echo_n "checking for C compiler default output file name... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 $as_echo "$ac_file" >&6; } ac_exeext=$ac_cv_exeext rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out ac_clean_files=$ac_clean_files_save { $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 $as_echo_n "checking for suffix of executables... " >&6; } if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : # If both `conftest.exe' and `conftest' are `present' (well, observable) # catch `conftest.exe'. For instance with Cygwin, `ls conftest' will # work properly (i.e., refer to `conftest.exe'), while it won't with # `rm'. for ac_file in conftest.exe conftest conftest.*; do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` break;; * ) break;; esac done else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of executables: cannot compile and link See \`config.log' for more details" "$LINENO" 5; } fi rm -f conftest conftest$ac_cv_exeext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 $as_echo "$ac_cv_exeext" >&6; } rm -f conftest.$ac_ext EXEEXT=$ac_cv_exeext ac_exeext=$EXEEXT cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include <stdio.h> int main () { FILE *f = fopen ("conftest.out", "w"); return ferror (f) || fclose (f) != 0; ; return 0; } _ACEOF ac_clean_files="$ac_clean_files conftest.out" # Check that the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 $as_echo_n "checking whether we are cross compiling... " >&6; } if test "$cross_compiling" != yes; then { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if { ac_try='./conftest$ac_cv_exeext' { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; }; then cross_compiling=no else if test "$cross_compiling" = maybe; then cross_compiling=yes else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run C compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details" "$LINENO" 5; } fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 $as_echo "$cross_compiling" >&6; } rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out ac_clean_files=$ac_clean_files_save { $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 $as_echo_n "checking for suffix of object files... " >&6; } if ${ac_cv_objext+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.o conftest.obj if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : for ac_file in conftest.o conftest.obj conftest.*; do test -f "$ac_file" || continue; case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` break;; esac done else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of object files: cannot compile See \`config.log' for more details" "$LINENO" 5; } fi rm -f conftest.$ac_cv_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 $as_echo "$ac_cv_objext" >&6; } OBJEXT=$ac_cv_objext ac_objext=$OBJEXT { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 $as_echo_n "checking whether we are using the GNU C compiler... " >&6; } if ${ac_cv_c_compiler_gnu+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_compiler_gnu=yes else ac_compiler_gnu=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_c_compiler_gnu=$ac_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 $as_echo "$ac_cv_c_compiler_gnu" >&6; } if test $ac_compiler_gnu = yes; then GCC=yes else GCC= fi ac_test_CFLAGS=${CFLAGS+set} ac_save_CFLAGS=$CFLAGS { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 $as_echo_n "checking whether $CC accepts -g... " >&6; } if ${ac_cv_prog_cc_g+:} false; then : $as_echo_n "(cached) " >&6 else ac_save_c_werror_flag=$ac_c_werror_flag ac_c_werror_flag=yes ac_cv_prog_cc_g=no CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_g=yes else CFLAGS="" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : else ac_c_werror_flag=$ac_save_c_werror_flag CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_g=yes fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_c_werror_flag=$ac_save_c_werror_flag fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 $as_echo "$ac_cv_prog_cc_g" >&6; } if test "$ac_test_CFLAGS" = set; then CFLAGS=$ac_save_CFLAGS elif test $ac_cv_prog_cc_g = yes; then if test "$GCC" = yes; then CFLAGS="-g -O2" else CFLAGS="-g" fi else if test "$GCC" = yes; then CFLAGS="-O2" else CFLAGS= fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 $as_echo_n "checking for $CC option to accept ISO C89... " >&6; } if ${ac_cv_prog_cc_c89+:} false; then : $as_echo_n "(cached) " >&6 else ac_cv_prog_cc_c89=no ac_save_CC=$CC cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include <stdarg.h> #include <stdio.h> struct stat; /* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ struct buf { int x; }; FILE * (*rcsopen) (struct buf *, struct stat *, int); static char *e (p, i) char **p; int i; { return p[i]; } static char *f (char * (*g) (char **, int), char **p, ...) { char *s; va_list v; va_start (v,p); s = g (p, va_arg (v,int)); va_end (v); return s; } /* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has function prototypes and stuff, but not '\xHH' hex character constants. These don't provoke an error unfortunately, instead are silently treated as 'x'. The following induces an error, until -std is added to get proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an array size at least. It's necessary to write '\x00'==0 to get something that's true only with -std. */ int osf4_cc_array ['\x00' == 0 ? 1 : -1]; /* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters inside strings and character constants. */ #define FOO(x) 'x' int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; int test (int i, double x); struct s1 {int (*f) (int a);}; struct s2 {int (*f) (double a);}; int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); int argc; char **argv; int main () { return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; ; return 0; } _ACEOF for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" do CC="$ac_save_CC $ac_arg" if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_c89=$ac_arg fi rm -f core conftest.err conftest.$ac_objext test "x$ac_cv_prog_cc_c89" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC fi # AC_CACHE_VAL case "x$ac_cv_prog_cc_c89" in x) { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 $as_echo "none needed" >&6; } ;; xno) { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 $as_echo "unsupported" >&6; } ;; *) CC="$CC $ac_cv_prog_cc_c89" { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 $as_echo "$ac_cv_prog_cc_c89" >&6; } ;; esac if test "x$ac_cv_prog_cc_c89" != xno; then : fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC understands -c and -o together" >&5 $as_echo_n "checking whether $CC understands -c and -o together... " >&6; } if ${am_cv_prog_cc_c_o+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF # Make sure it works both with $CC and with simple cc. # Following AC_PROG_CC_C_O, we do the test twice because some # compilers refuse to overwrite an existing .o file with -o, # though they will create one. am_cv_prog_cc_c_o=yes for am_i in 1 2; do if { echo "$as_me:$LINENO: $CC -c conftest.$ac_ext -o conftest2.$ac_objext" >&5 ($CC -c conftest.$ac_ext -o conftest2.$ac_objext) >&5 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } \ && test -f conftest2.$ac_objext; then : OK else am_cv_prog_cc_c_o=no break fi done rm -f core conftest* unset am_i fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_cc_c_o" >&5 $as_echo "$am_cv_prog_cc_c_o" >&6; } if test "$am_cv_prog_cc_c_o" != yes; then # Losing compiler, so override with the script. # FIXME: It is wrong to rewrite CC. # But if we don't then we get into trouble of one sort or another. # A longer-term fix would be to have automake use am__CC in this case, # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" CC="$am_aux_dir/compile $CC" fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu depcc="$CC" am_compiler_list= { $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 $as_echo_n "checking dependency style of $depcc... " >&6; } if ${am_cv_CC_dependencies_compiler_type+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named 'D' -- because '-MD' means "put the output # in D". rm -rf conftest.dir mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_CC_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` fi am__universal=false case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with # Solaris 10 /bin/sh. echo '/* dummy */' > sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf # We check with '-c' and '-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle '-M -o', and we need to detect this. Also, some Intel # versions had trouble with output in subdirs. am__obj=sub/conftest.${OBJEXT-o} am__minus_obj="-o $am__obj" case $depmode in gcc) # This depmode causes a compiler race in universal mode. test "$am__universal" = false || continue ;; nosideeffect) # After this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested. if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; msvc7 | msvc7msys | msvisualcpp | msvcmsys) # This compiler won't grok '-c -o', but also, the minuso test has # not run yet. These depmodes are late enough in the game, and # so weak that their functioning should not be impacted. am__obj=conftest.${OBJEXT-o} am__minus_obj= ;; none) break ;; esac if depmode=$depmode \ source=sub/conftest.c object=$am__obj \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep $am__obj sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. # When given -MP, icc 7.0 and 7.1 complain thusly: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported if (grep 'ignoring option' conftest.err || grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else am_cv_CC_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_CC_dependencies_compiler_type=none fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5 $as_echo "$am_cv_CC_dependencies_compiler_type" >&6; } CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type if test "x$enable_dependency_tracking" != xno \ && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then am__fastdepCC_TRUE= am__fastdepCC_FALSE='#' else am__fastdepCC_TRUE='#' am__fastdepCC_FALSE= fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for an ANSI C-conforming const" >&5 $as_echo_n "checking for an ANSI C-conforming const... " >&6; } if ${ac_cv_c_const+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { #ifndef __cplusplus /* Ultrix mips cc rejects this sort of thing. */ typedef int charset[2]; const charset cs = { 0, 0 }; /* SunOS 4.1.1 cc rejects this. */ char const *const *pcpcc; char **ppc; /* NEC SVR4.0.2 mips cc rejects this. */ struct point {int x, y;}; static struct point const zero = {0,0}; /* AIX XL C 1.02.0.0 rejects this. It does not let you subtract one const X* pointer from another in an arm of an if-expression whose if-part is not a constant expression */ const char *g = "string"; pcpcc = &g + (g ? g-g : 0); /* HPUX 7.0 cc rejects these. */ ++pcpcc; ppc = (char**) pcpcc; pcpcc = (char const *const *) ppc; { /* SCO 3.2v4 cc rejects this sort of thing. */ char tx; char *t = &tx; char const *s = 0 ? (char *) 0 : (char const *) 0; *t++ = 0; if (s) return 0; } { /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */ int x[] = {25, 17}; const int *foo = &x[0]; ++foo; } { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */ typedef const int *iptr; iptr p = 0; ++p; } { /* AIX XL C 1.02.0.0 rejects this sort of thing, saying "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */ struct s { int j; const int *ap[3]; } bx; struct s *b = &bx; b->j = 5; } { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */ const int foo = 10; if (!foo) return 0; } return !cs[0] && !zero.x; #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_c_const=yes else ac_cv_c_const=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_const" >&5 $as_echo "$ac_cv_c_const" >&6; } if test $ac_cv_c_const = no; then $as_echo "#define const /**/" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for inline" >&5 $as_echo_n "checking for inline... " >&6; } if ${ac_cv_c_inline+:} false; then : $as_echo_n "(cached) " >&6 else ac_cv_c_inline=no for ac_kw in inline __inline__ __inline; do cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifndef __cplusplus typedef int foo_t; static $ac_kw foo_t static_foo () {return 0; } $ac_kw foo_t foo () {return 0; } #endif _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_c_inline=$ac_kw fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext test "$ac_cv_c_inline" != no && break done fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_inline" >&5 $as_echo "$ac_cv_c_inline" >&6; } case $ac_cv_c_inline in inline | yes) ;; *) case $ac_cv_c_inline in no) ac_val=;; *) ac_val=$ac_cv_c_inline;; esac cat >>confdefs.h <<_ACEOF #ifndef __cplusplus #define inline $ac_val #endif _ACEOF ;; esac ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 $as_echo_n "checking how to run the C preprocessor... " >&6; } # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= fi if test -z "$CPP"; then if ${ac_cv_prog_CPP+:} false; then : $as_echo_n "(cached) " >&6 else # Double quotes because CPP needs to be expanded for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" do ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since # <limits.h> exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include <limits.h> #else # include <assert.h> #endif Syntax error _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include <ac_nonexistent.h> _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : break fi done ac_cv_prog_CPP=$CPP fi CPP=$ac_cv_prog_CPP else ac_cv_prog_CPP=$CPP fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 $as_echo "$CPP" >&6; } ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since # <limits.h> exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include <limits.h> #else # include <assert.h> #endif Syntax error _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include <ac_nonexistent.h> _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "C preprocessor \"$CPP\" fails sanity check See \`config.log' for more details" "$LINENO" 5; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 $as_echo_n "checking for grep that handles long lines and -e... " >&6; } if ${ac_cv_path_GREP+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$GREP"; then ac_path_GREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in grep ggrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_GREP" || continue # Check for GNU ac_path_GREP and select it if it is found. # Check for GNU $ac_path_GREP case `"$ac_path_GREP" --version 2>&1` in *GNU*) ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo 'GREP' >> "conftest.nl" "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_GREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_GREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_GREP"; then as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_GREP=$GREP fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 $as_echo "$ac_cv_path_GREP" >&6; } GREP="$ac_cv_path_GREP" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 $as_echo_n "checking for egrep... " >&6; } if ${ac_cv_path_EGREP+:} false; then : $as_echo_n "(cached) " >&6 else if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 then ac_cv_path_EGREP="$GREP -E" else if test -z "$EGREP"; then ac_path_EGREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in egrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_EGREP" || continue # Check for GNU ac_path_EGREP and select it if it is found. # Check for GNU $ac_path_EGREP case `"$ac_path_EGREP" --version 2>&1` in *GNU*) ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo 'EGREP' >> "conftest.nl" "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_EGREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_EGREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_EGREP"; then as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_EGREP=$EGREP fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 $as_echo "$ac_cv_path_EGREP" >&6; } EGREP="$ac_cv_path_EGREP" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 $as_echo_n "checking for ANSI C header files... " >&6; } if ${ac_cv_header_stdc+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include <stdlib.h> #include <stdarg.h> #include <string.h> #include <float.h> int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_header_stdc=yes else ac_cv_header_stdc=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include <string.h> _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "memchr" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include <stdlib.h> _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "free" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. if test "$cross_compiling" = yes; then : : else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include <ctype.h> #include <stdlib.h> #if ((' ' & 0x0FF) == 0x020) # define ISLOWER(c) ('a' <= (c) && (c) <= 'z') # define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) #else # define ISLOWER(c) \ (('a' <= (c) && (c) <= 'i') \ || ('j' <= (c) && (c) <= 'r') \ || ('s' <= (c) && (c) <= 'z')) # define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) #endif #define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) int main () { int i; for (i = 0; i < 256; i++) if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) return 2; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : else ac_cv_header_stdc=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 $as_echo "$ac_cv_header_stdc" >&6; } if test $ac_cv_header_stdc = yes; then $as_echo "#define STDC_HEADERS 1" >>confdefs.h fi # On IRIX 5.3, sys/types and inttypes.h are conflicting. for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ inttypes.h stdint.h unistd.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default " if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether byte ordering is bigendian" >&5 $as_echo_n "checking whether byte ordering is bigendian... " >&6; } if ${ac_cv_c_bigendian+:} false; then : $as_echo_n "(cached) " >&6 else ac_cv_c_bigendian=unknown # See if we're dealing with a universal compiler. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifndef __APPLE_CC__ not a universal capable compiler #endif typedef int dummy; _ACEOF if ac_fn_c_try_compile "$LINENO"; then : # Check for potential -arch flags. It is not universal unless # there are at least two -arch flags with different values. ac_arch= ac_prev= for ac_word in $CC $CFLAGS $CPPFLAGS $LDFLAGS; do if test -n "$ac_prev"; then case $ac_word in i?86 | x86_64 | ppc | ppc64) if test -z "$ac_arch" || test "$ac_arch" = "$ac_word"; then ac_arch=$ac_word else ac_cv_c_bigendian=universal break fi ;; esac ac_prev= elif test "x$ac_word" = "x-arch"; then ac_prev=arch fi done fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext if test $ac_cv_c_bigendian = unknown; then # See if sys/param.h defines the BYTE_ORDER macro. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include <sys/types.h> #include <sys/param.h> int main () { #if ! (defined BYTE_ORDER && defined BIG_ENDIAN \ && defined LITTLE_ENDIAN && BYTE_ORDER && BIG_ENDIAN \ && LITTLE_ENDIAN) bogus endian macros #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : # It does; now see whether it defined to BIG_ENDIAN or not. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include <sys/types.h> #include <sys/param.h> int main () { #if BYTE_ORDER != BIG_ENDIAN not big endian #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_c_bigendian=yes else ac_cv_c_bigendian=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi if test $ac_cv_c_bigendian = unknown; then # See if <limits.h> defines _LITTLE_ENDIAN or _BIG_ENDIAN (e.g., Solaris). cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include <limits.h> int main () { #if ! (defined _LITTLE_ENDIAN || defined _BIG_ENDIAN) bogus endian macros #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : # It does; now see whether it defined to _BIG_ENDIAN or not. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include <limits.h> int main () { #ifndef _BIG_ENDIAN not big endian #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_c_bigendian=yes else ac_cv_c_bigendian=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi if test $ac_cv_c_bigendian = unknown; then # Compile a test program. if test "$cross_compiling" = yes; then : # Try to guess by grepping values from an object file. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ short int ascii_mm[] = { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 }; short int ascii_ii[] = { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 }; int use_ascii (int i) { return ascii_mm[i] + ascii_ii[i]; } short int ebcdic_ii[] = { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 }; short int ebcdic_mm[] = { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 }; int use_ebcdic (int i) { return ebcdic_mm[i] + ebcdic_ii[i]; } extern int foo; int main () { return use_ascii (foo) == use_ebcdic (foo); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : if grep BIGenDianSyS conftest.$ac_objext >/dev/null; then ac_cv_c_bigendian=yes fi if grep LiTTleEnDian conftest.$ac_objext >/dev/null ; then if test "$ac_cv_c_bigendian" = unknown; then ac_cv_c_bigendian=no else # finding both strings is unlikely to happen, but who knows? ac_cv_c_bigendian=unknown fi fi fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_includes_default int main () { /* Are we little or big endian? From Harbison&Steele. */ union { long int l; char c[sizeof (long int)]; } u; u.l = 1; return u.c[sizeof (long int) - 1] == 1; ; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : ac_cv_c_bigendian=no else ac_cv_c_bigendian=yes fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_bigendian" >&5 $as_echo "$ac_cv_c_bigendian" >&6; } case $ac_cv_c_bigendian in #( yes) $as_echo "#define WORDS_BIGENDIAN 1" >>confdefs.h ;; #( no) ;; #( universal) $as_echo "#define AC_APPLE_UNIVERSAL_BUILD 1" >>confdefs.h ;; #( *) as_fn_error $? "unknown endianness presetting ac_cv_c_bigendian=no (or yes) will help" "$LINENO" 5 ;; esac # Check whether --enable-largefile was given. if test "${enable_largefile+set}" = set; then : enableval=$enable_largefile; fi if test "$enable_largefile" != no; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for special C compiler options needed for large files" >&5 $as_echo_n "checking for special C compiler options needed for large files... " >&6; } if ${ac_cv_sys_largefile_CC+:} false; then : $as_echo_n "(cached) " >&6 else ac_cv_sys_largefile_CC=no if test "$GCC" != yes; then ac_save_CC=$CC while :; do # IRIX 6.2 and later do not support large files by default, # so use the C compiler's -n32 option if that helps. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include <sys/types.h> /* Check that off_t can represent 2**63 - 1 correctly. We can't simply define LARGE_OFF_T to be 9223372036854775807, since some C++ compilers masquerading as C compilers incorrectly reject 9223372036854775807. */ #define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31)) int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 && LARGE_OFF_T % 2147483647 == 1) ? 1 : -1]; int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : break fi rm -f core conftest.err conftest.$ac_objext CC="$CC -n32" if ac_fn_c_try_compile "$LINENO"; then : ac_cv_sys_largefile_CC=' -n32'; break fi rm -f core conftest.err conftest.$ac_objext break done CC=$ac_save_CC rm -f conftest.$ac_ext fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_largefile_CC" >&5 $as_echo "$ac_cv_sys_largefile_CC" >&6; } if test "$ac_cv_sys_largefile_CC" != no; then CC=$CC$ac_cv_sys_largefile_CC fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _FILE_OFFSET_BITS value needed for large files" >&5 $as_echo_n "checking for _FILE_OFFSET_BITS value needed for large files... " >&6; } if ${ac_cv_sys_file_offset_bits+:} false; then : $as_echo_n "(cached) " >&6 else while :; do cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include <sys/types.h> /* Check that off_t can represent 2**63 - 1 correctly. We can't simply define LARGE_OFF_T to be 9223372036854775807, since some C++ compilers masquerading as C compilers incorrectly reject 9223372036854775807. */ #define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31)) int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 && LARGE_OFF_T % 2147483647 == 1) ? 1 : -1]; int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_sys_file_offset_bits=no; break fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #define _FILE_OFFSET_BITS 64 #include <sys/types.h> /* Check that off_t can represent 2**63 - 1 correctly. We can't simply define LARGE_OFF_T to be 9223372036854775807, since some C++ compilers masquerading as C compilers incorrectly reject 9223372036854775807. */ #define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31)) int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 && LARGE_OFF_T % 2147483647 == 1) ? 1 : -1]; int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_sys_file_offset_bits=64; break fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_sys_file_offset_bits=unknown break done fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_file_offset_bits" >&5 $as_echo "$ac_cv_sys_file_offset_bits" >&6; } case $ac_cv_sys_file_offset_bits in #( no | unknown) ;; *) cat >>confdefs.h <<_ACEOF #define _FILE_OFFSET_BITS $ac_cv_sys_file_offset_bits _ACEOF ;; esac rm -rf conftest* if test $ac_cv_sys_file_offset_bits = unknown; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _LARGE_FILES value needed for large files" >&5 $as_echo_n "checking for _LARGE_FILES value needed for large files... " >&6; } if ${ac_cv_sys_large_files+:} false; then : $as_echo_n "(cached) " >&6 else while :; do cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include <sys/types.h> /* Check that off_t can represent 2**63 - 1 correctly. We can't simply define LARGE_OFF_T to be 9223372036854775807, since some C++ compilers masquerading as C compilers incorrectly reject 9223372036854775807. */ #define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31)) int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 && LARGE_OFF_T % 2147483647 == 1) ? 1 : -1]; int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_sys_large_files=no; break fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #define _LARGE_FILES 1 #include <sys/types.h> /* Check that off_t can represent 2**63 - 1 correctly. We can't simply define LARGE_OFF_T to be 9223372036854775807, since some C++ compilers masquerading as C compilers incorrectly reject 9223372036854775807. */ #define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31)) int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 && LARGE_OFF_T % 2147483647 == 1) ? 1 : -1]; int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_sys_large_files=1; break fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_sys_large_files=unknown break done fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_large_files" >&5 $as_echo "$ac_cv_sys_large_files" >&6; } case $ac_cv_sys_large_files in #( no | unknown) ;; *) cat >>confdefs.h <<_ACEOF #define _LARGE_FILES $ac_cv_sys_large_files _ACEOF ;; esac rm -rf conftest* fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _LARGEFILE_SOURCE value needed for large files" >&5 $as_echo_n "checking for _LARGEFILE_SOURCE value needed for large files... " >&6; } if ${ac_cv_sys_largefile_source+:} false; then : $as_echo_n "(cached) " >&6 else while :; do cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include <sys/types.h> /* for off_t */ #include <stdio.h> int main () { int (*fp) (FILE *, off_t, int) = fseeko; return fseeko (stdin, 0, 0) && fp (stdin, 0, 0); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_sys_largefile_source=no; break fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #define _LARGEFILE_SOURCE 1 #include <sys/types.h> /* for off_t */ #include <stdio.h> int main () { int (*fp) (FILE *, off_t, int) = fseeko; return fseeko (stdin, 0, 0) && fp (stdin, 0, 0); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_sys_largefile_source=1; break fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext ac_cv_sys_largefile_source=unknown break done fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_largefile_source" >&5 $as_echo "$ac_cv_sys_largefile_source" >&6; } case $ac_cv_sys_largefile_source in #( no | unknown) ;; *) cat >>confdefs.h <<_ACEOF #define _LARGEFILE_SOURCE $ac_cv_sys_largefile_source _ACEOF ;; esac rm -rf conftest* # We used to try defining _XOPEN_SOURCE=500 too, to work around a bug # in glibc 2.1.3, but that breaks too many other things. # If you want fseeko and ftello with glibc, upgrade to a fixed glibc. if test $ac_cv_sys_largefile_source != unknown; then $as_echo "#define HAVE_FSEEKO 1" >>confdefs.h fi ac_fn_c_check_func "$LINENO" "fseeko" "ac_cv_func_fseeko" if test "x$ac_cv_func_fseeko" = xyes; then : fi if test ! $ac_cv_func_fseeko; then as_fn_error $? "Libburn requires largefile support." "$LINENO" 5 fi case `pwd` in *\ * | *\ *) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&5 $as_echo "$as_me: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&2;} ;; esac macro_version='2.4.2' macro_revision='1.3337' ltmain="$ac_aux_dir/ltmain.sh" # Backslashify metacharacters that are still active within # double-quoted strings. sed_quote_subst='s/\(["`$\\]\)/\\\1/g' # Same as above, but do not quote variable references. double_quote_subst='s/\(["`\\]\)/\\\1/g' # Sed substitution to delay expansion of an escaped shell variable in a # double_quote_subst'ed string. delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' # Sed substitution to delay expansion of an escaped single quote. delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' # Sed substitution to avoid accidental globbing in evaled expressions no_glob_subst='s/\*/\\\*/g' ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to print strings" >&5 $as_echo_n "checking how to print strings... " >&6; } # Test print first, because it will be a builtin if present. if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \ test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then ECHO='print -r --' elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then ECHO='printf %s\n' else # Use this function as a fallback that always works. func_fallback_echo () { eval 'cat <<_LTECHO_EOF $1 _LTECHO_EOF' } ECHO='func_fallback_echo' fi # func_echo_all arg... # Invoke $ECHO with all args, space-separated. func_echo_all () { $ECHO "" } case "$ECHO" in printf*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: printf" >&5 $as_echo "printf" >&6; } ;; print*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: print -r" >&5 $as_echo "print -r" >&6; } ;; *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: cat" >&5 $as_echo "cat" >&6; } ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5 $as_echo_n "checking for a sed that does not truncate output... " >&6; } if ${ac_cv_path_SED+:} false; then : $as_echo_n "(cached) " >&6 else ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ for ac_i in 1 2 3 4 5 6 7; do ac_script="$ac_script$as_nl$ac_script" done echo "$ac_script" 2>/dev/null | sed 99q >conftest.sed { ac_script=; unset ac_script;} if test -z "$SED"; then ac_path_SED_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in sed gsed; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_SED="$as_dir/$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_SED" || continue # Check for GNU ac_path_SED and select it if it is found. # Check for GNU $ac_path_SED case `"$ac_path_SED" --version 2>&1` in *GNU*) ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo '' >> "conftest.nl" "$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_SED_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_SED="$ac_path_SED" ac_path_SED_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_SED_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_SED"; then as_fn_error $? "no acceptable sed could be found in \$PATH" "$LINENO" 5 fi else ac_cv_path_SED=$SED fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5 $as_echo "$ac_cv_path_SED" >&6; } SED="$ac_cv_path_SED" rm -f conftest.sed test -z "$SED" && SED=sed Xsed="$SED -e 1s/^X//" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for fgrep" >&5 $as_echo_n "checking for fgrep... " >&6; } if ${ac_cv_path_FGREP+:} false; then : $as_echo_n "(cached) " >&6 else if echo 'ab*c' | $GREP -F 'ab*c' >/dev/null 2>&1 then ac_cv_path_FGREP="$GREP -F" else if test -z "$FGREP"; then ac_path_FGREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in fgrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_FGREP="$as_dir/$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_FGREP" || continue # Check for GNU ac_path_FGREP and select it if it is found. # Check for GNU $ac_path_FGREP case `"$ac_path_FGREP" --version 2>&1` in *GNU*) ac_cv_path_FGREP="$ac_path_FGREP" ac_path_FGREP_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo 'FGREP' >> "conftest.nl" "$ac_path_FGREP" FGREP < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_FGREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_FGREP="$ac_path_FGREP" ac_path_FGREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_FGREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_FGREP"; then as_fn_error $? "no acceptable fgrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_FGREP=$FGREP fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_FGREP" >&5 $as_echo "$ac_cv_path_FGREP" >&6; } FGREP="$ac_cv_path_FGREP" test -z "$GREP" && GREP=grep # Check whether --with-gnu-ld was given. if test "${with_gnu_ld+set}" = set; then : withval=$with_gnu_ld; test "$withval" = no || with_gnu_ld=yes else with_gnu_ld=no fi ac_prog=ld if test "$GCC" = yes; then # Check if gcc -print-prog-name=ld gives a path. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5 $as_echo_n "checking for ld used by $CC... " >&6; } case $host in *-*-mingw*) # gcc leaves a trailing carriage return which upsets mingw ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; *) ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; esac case $ac_prog in # Accept absolute paths. [\\/]* | ?:[\\/]*) re_direlt='/[^/][^/]*/\.\./' # Canonicalize the pathname of ld ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` done test -z "$LD" && LD="$ac_prog" ;; "") # If it fails, then pretend we aren't using GCC. ac_prog=ld ;; *) # If it is relative, then search for the first ld in PATH. with_gnu_ld=unknown ;; esac elif test "$with_gnu_ld" = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5 $as_echo_n "checking for GNU ld... " >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5 $as_echo_n "checking for non-GNU ld... " >&6; } fi if ${lt_cv_path_LD+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$LD"; then lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR for ac_dir in $PATH; do IFS="$lt_save_ifs" test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then lt_cv_path_LD="$ac_dir/$ac_prog" # Check to see if the program is GNU ld. I'd rather use --version, # but apparently some variants of GNU ld only accept -v. # Break only if it was the GNU/non-GNU ld that we prefer. case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in *GNU* | *'with BFD'*) test "$with_gnu_ld" != no && break ;; *) test "$with_gnu_ld" != yes && break ;; esac fi done IFS="$lt_save_ifs" else lt_cv_path_LD="$LD" # Let the user override the test with a path. fi fi LD="$lt_cv_path_LD" if test -n "$LD"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LD" >&5 $as_echo "$LD" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5 { $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5 $as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; } if ${lt_cv_prog_gnu_ld+:} false; then : $as_echo_n "(cached) " >&6 else # I'd rather use --version here, but apparently some GNU lds only accept -v. case `$LD -v 2>&1 </dev/null` in *GNU* | *'with BFD'*) lt_cv_prog_gnu_ld=yes ;; *) lt_cv_prog_gnu_ld=no ;; esac fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_gnu_ld" >&5 $as_echo "$lt_cv_prog_gnu_ld" >&6; } with_gnu_ld=$lt_cv_prog_gnu_ld { $as_echo "$as_me:${as_lineno-$LINENO}: checking for BSD- or MS-compatible name lister (nm)" >&5 $as_echo_n "checking for BSD- or MS-compatible name lister (nm)... " >&6; } if ${lt_cv_path_NM+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$NM"; then # Let the user override the test. lt_cv_path_NM="$NM" else lt_nm_to_check="${ac_tool_prefix}nm" if test -n "$ac_tool_prefix" && test "$build" = "$host"; then lt_nm_to_check="$lt_nm_to_check nm" fi for lt_tmp_nm in $lt_nm_to_check; do lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do IFS="$lt_save_ifs" test -z "$ac_dir" && ac_dir=. tmp_nm="$ac_dir/$lt_tmp_nm" if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then # Check to see if the nm accepts a BSD-compat flag. # Adding the `sed 1q' prevents false positives on HP-UX, which says: # nm: unknown option "B" ignored # Tru64's nm complains that /dev/null is an invalid object file case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in */dev/null* | *'Invalid file or object type'*) lt_cv_path_NM="$tmp_nm -B" break ;; *) case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in */dev/null*) lt_cv_path_NM="$tmp_nm -p" break ;; *) lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but continue # so that we can try to find one that supports BSD flags ;; esac ;; esac fi done IFS="$lt_save_ifs" done : ${lt_cv_path_NM=no} fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_NM" >&5 $as_echo "$lt_cv_path_NM" >&6; } if test "$lt_cv_path_NM" != "no"; then NM="$lt_cv_path_NM" else # Didn't find any BSD compatible name lister, look for dumpbin. if test -n "$DUMPBIN"; then : # Let the user override the test. else if test -n "$ac_tool_prefix"; then for ac_prog in dumpbin "link -dump" do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_DUMPBIN+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$DUMPBIN"; then ac_cv_prog_DUMPBIN="$DUMPBIN" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_DUMPBIN="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi DUMPBIN=$ac_cv_prog_DUMPBIN if test -n "$DUMPBIN"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DUMPBIN" >&5 $as_echo "$DUMPBIN" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$DUMPBIN" && break done fi if test -z "$DUMPBIN"; then ac_ct_DUMPBIN=$DUMPBIN for ac_prog in dumpbin "link -dump" do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_DUMPBIN+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_DUMPBIN"; then ac_cv_prog_ac_ct_DUMPBIN="$ac_ct_DUMPBIN" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_DUMPBIN="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_DUMPBIN=$ac_cv_prog_ac_ct_DUMPBIN if test -n "$ac_ct_DUMPBIN"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DUMPBIN" >&5 $as_echo "$ac_ct_DUMPBIN" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_DUMPBIN" && break done if test "x$ac_ct_DUMPBIN" = x; then DUMPBIN=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac DUMPBIN=$ac_ct_DUMPBIN fi fi case `$DUMPBIN -symbols /dev/null 2>&1 | sed '1q'` in *COFF*) DUMPBIN="$DUMPBIN -symbols" ;; *) DUMPBIN=: ;; esac fi if test "$DUMPBIN" != ":"; then NM="$DUMPBIN" fi fi test -z "$NM" && NM=nm { $as_echo "$as_me:${as_lineno-$LINENO}: checking the name lister ($NM) interface" >&5 $as_echo_n "checking the name lister ($NM) interface... " >&6; } if ${lt_cv_nm_interface+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_nm_interface="BSD nm" echo "int some_variable = 0;" > conftest.$ac_ext (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&5) (eval "$ac_compile" 2>conftest.err) cat conftest.err >&5 (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&5) (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) cat conftest.err >&5 (eval echo "\"\$as_me:$LINENO: output\"" >&5) cat conftest.out >&5 if $GREP 'External.*some_variable' conftest.out > /dev/null; then lt_cv_nm_interface="MS dumpbin" fi rm -f conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_nm_interface" >&5 $as_echo "$lt_cv_nm_interface" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5 $as_echo_n "checking whether ln -s works... " >&6; } LN_S=$as_ln_s if test "$LN_S" = "ln -s"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5 $as_echo "no, using $LN_S" >&6; } fi # find the maximum length of command line arguments { $as_echo "$as_me:${as_lineno-$LINENO}: checking the maximum length of command line arguments" >&5 $as_echo_n "checking the maximum length of command line arguments... " >&6; } if ${lt_cv_sys_max_cmd_len+:} false; then : $as_echo_n "(cached) " >&6 else i=0 teststring="ABCD" case $build_os in msdosdjgpp*) # On DJGPP, this test can blow up pretty badly due to problems in libc # (any single argument exceeding 2000 bytes causes a buffer overrun # during glob expansion). Even if it were fixed, the result of this # check would be larger than it should be. lt_cv_sys_max_cmd_len=12288; # 12K is about right ;; gnu*) # Under GNU Hurd, this test is not required because there is # no limit to the length of command line arguments. # Libtool will interpret -1 as no limit whatsoever lt_cv_sys_max_cmd_len=-1; ;; cygwin* | mingw* | cegcc*) # On Win9x/ME, this test blows up -- it succeeds, but takes # about 5 minutes as the teststring grows exponentially. # Worse, since 9x/ME are not pre-emptively multitasking, # you end up with a "frozen" computer, even though with patience # the test eventually succeeds (with a max line length of 256k). # Instead, let's just punt: use the minimum linelength reported by # all of the supported platforms: 8192 (on NT/2K/XP). lt_cv_sys_max_cmd_len=8192; ;; mint*) # On MiNT this can take a long time and run out of memory. lt_cv_sys_max_cmd_len=8192; ;; amigaos*) # On AmigaOS with pdksh, this test takes hours, literally. # So we just punt and use a minimum line length of 8192. lt_cv_sys_max_cmd_len=8192; ;; netbsd* | freebsd* | openbsd* | darwin* | dragonfly*) # This has been around since 386BSD, at least. Likely further. if test -x /sbin/sysctl; then lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` elif test -x /usr/sbin/sysctl; then lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` else lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs fi # And add a safety zone lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` ;; interix*) # We know the value 262144 and hardcode it with a safety zone (like BSD) lt_cv_sys_max_cmd_len=196608 ;; os2*) # The test takes a long time on OS/2. lt_cv_sys_max_cmd_len=8192 ;; osf*) # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not # nice to cause kernel panics so lets avoid the loop below. # First set a reasonable default. lt_cv_sys_max_cmd_len=16384 # if test -x /sbin/sysconfig; then case `/sbin/sysconfig -q proc exec_disable_arg_limit` in *1*) lt_cv_sys_max_cmd_len=-1 ;; esac fi ;; sco3.2v5*) lt_cv_sys_max_cmd_len=102400 ;; sysv5* | sco5v6* | sysv4.2uw2*) kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` if test -n "$kargmax"; then lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[ ]//'` else lt_cv_sys_max_cmd_len=32768 fi ;; *) lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` if test -n "$lt_cv_sys_max_cmd_len" && \ test undefined != "$lt_cv_sys_max_cmd_len"; then lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` else # Make teststring a little bigger before we do anything with it. # a 1K string should be a reasonable start. for i in 1 2 3 4 5 6 7 8 ; do teststring=$teststring$teststring done SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} # If test is not a shell built-in, we'll probably end up computing a # maximum length that is only half of the actual maximum length, but # we can't tell. while { test "X"`env echo "$teststring$teststring" 2>/dev/null` \ = "X$teststring$teststring"; } >/dev/null 2>&1 && test $i != 17 # 1/2 MB should be enough do i=`expr $i + 1` teststring=$teststring$teststring done # Only check the string length outside the loop. lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` teststring= # Add a significant safety factor because C++ compilers can tack on # massive amounts of additional arguments before passing them to the # linker. It appears as though 1/2 is a usable value. lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` fi ;; esac fi if test -n $lt_cv_sys_max_cmd_len ; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sys_max_cmd_len" >&5 $as_echo "$lt_cv_sys_max_cmd_len" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: none" >&5 $as_echo "none" >&6; } fi max_cmd_len=$lt_cv_sys_max_cmd_len : ${CP="cp -f"} : ${MV="mv -f"} : ${RM="rm -f"} { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the shell understands some XSI constructs" >&5 $as_echo_n "checking whether the shell understands some XSI constructs... " >&6; } # Try some XSI features xsi_shell=no ( _lt_dummy="a/b/c" test "${_lt_dummy##*/},${_lt_dummy%/*},${_lt_dummy#??}"${_lt_dummy%"$_lt_dummy"}, \ = c,a/b,b/c, \ && eval 'test $(( 1 + 1 )) -eq 2 \ && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \ && xsi_shell=yes { $as_echo "$as_me:${as_lineno-$LINENO}: result: $xsi_shell" >&5 $as_echo "$xsi_shell" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the shell understands \"+=\"" >&5 $as_echo_n "checking whether the shell understands \"+=\"... " >&6; } lt_shell_append=no ( foo=bar; set foo baz; eval "$1+=\$2" && test "$foo" = barbaz ) \ >/dev/null 2>&1 \ && lt_shell_append=yes { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_shell_append" >&5 $as_echo "$lt_shell_append" >&6; } if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then lt_unset=unset else lt_unset=false fi # test EBCDIC or ASCII case `echo X|tr X '\101'` in A) # ASCII based system # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr lt_SP2NL='tr \040 \012' lt_NL2SP='tr \015\012 \040\040' ;; *) # EBCDIC based system lt_SP2NL='tr \100 \n' lt_NL2SP='tr \r\n \100\100' ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to $host format" >&5 $as_echo_n "checking how to convert $build file names to $host format... " >&6; } if ${lt_cv_to_host_file_cmd+:} false; then : $as_echo_n "(cached) " >&6 else case $host in *-*-mingw* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32 ;; *-*-cygwin* ) lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32 ;; * ) # otherwise, assume *nix lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32 ;; esac ;; *-*-cygwin* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin ;; *-*-cygwin* ) lt_cv_to_host_file_cmd=func_convert_file_noop ;; * ) # otherwise, assume *nix lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin ;; esac ;; * ) # unhandled hosts (and "normal" native builds) lt_cv_to_host_file_cmd=func_convert_file_noop ;; esac fi to_host_file_cmd=$lt_cv_to_host_file_cmd { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_host_file_cmd" >&5 $as_echo "$lt_cv_to_host_file_cmd" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to toolchain format" >&5 $as_echo_n "checking how to convert $build file names to toolchain format... " >&6; } if ${lt_cv_to_tool_file_cmd+:} false; then : $as_echo_n "(cached) " >&6 else #assume ordinary cross tools, or native build. lt_cv_to_tool_file_cmd=func_convert_file_noop case $host in *-*-mingw* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32 ;; esac ;; esac fi to_tool_file_cmd=$lt_cv_to_tool_file_cmd { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_tool_file_cmd" >&5 $as_echo "$lt_cv_to_tool_file_cmd" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $LD option to reload object files" >&5 $as_echo_n "checking for $LD option to reload object files... " >&6; } if ${lt_cv_ld_reload_flag+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_ld_reload_flag='-r' fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_reload_flag" >&5 $as_echo "$lt_cv_ld_reload_flag" >&6; } reload_flag=$lt_cv_ld_reload_flag case $reload_flag in "" | " "*) ;; *) reload_flag=" $reload_flag" ;; esac reload_cmds='$LD$reload_flag -o $output$reload_objs' case $host_os in cygwin* | mingw* | pw32* | cegcc*) if test "$GCC" != yes; then reload_cmds=false fi ;; darwin*) if test "$GCC" = yes; then reload_cmds='$LTCC $LTCFLAGS -nostdlib ${wl}-r -o $output$reload_objs' else reload_cmds='$LD$reload_flag -o $output$reload_objs' fi ;; esac if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args. set dummy ${ac_tool_prefix}objdump; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_OBJDUMP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$OBJDUMP"; then ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi OBJDUMP=$ac_cv_prog_OBJDUMP if test -n "$OBJDUMP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5 $as_echo "$OBJDUMP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_OBJDUMP"; then ac_ct_OBJDUMP=$OBJDUMP # Extract the first word of "objdump", so it can be a program name with args. set dummy objdump; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_OBJDUMP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_OBJDUMP"; then ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_OBJDUMP="objdump" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP if test -n "$ac_ct_OBJDUMP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5 $as_echo "$ac_ct_OBJDUMP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_OBJDUMP" = x; then OBJDUMP="false" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac OBJDUMP=$ac_ct_OBJDUMP fi else OBJDUMP="$ac_cv_prog_OBJDUMP" fi test -z "$OBJDUMP" && OBJDUMP=objdump { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to recognize dependent libraries" >&5 $as_echo_n "checking how to recognize dependent libraries... " >&6; } if ${lt_cv_deplibs_check_method+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_file_magic_cmd='$MAGIC_CMD' lt_cv_file_magic_test_file= lt_cv_deplibs_check_method='unknown' # Need to set the preceding variable on all platforms that support # interlibrary dependencies. # 'none' -- dependencies not supported. # `unknown' -- same as none, but documents that we really don't know. # 'pass_all' -- all dependencies passed with no checks. # 'test_compile' -- check by making test program. # 'file_magic [[regex]]' -- check by looking for files in library path # which responds to the $file_magic_cmd with a given extended regex. # If you have `file' or equivalent on your system and you're not sure # whether `pass_all' will *always* work, you probably want this one. case $host_os in aix[4-9]*) lt_cv_deplibs_check_method=pass_all ;; beos*) lt_cv_deplibs_check_method=pass_all ;; bsdi[45]*) lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)' lt_cv_file_magic_cmd='/usr/bin/file -L' lt_cv_file_magic_test_file=/shlib/libc.so ;; cygwin*) # func_win32_libid is a shell function defined in ltmain.sh lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' lt_cv_file_magic_cmd='func_win32_libid' ;; mingw* | pw32*) # Base MSYS/MinGW do not provide the 'file' command needed by # func_win32_libid shell function, so use a weaker test based on 'objdump', # unless we find 'file', for example because we are cross-compiling. # func_win32_libid assumes BSD nm, so disallow it if using MS dumpbin. if ( test "$lt_cv_nm_interface" = "BSD nm" && file / ) >/dev/null 2>&1; then lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' lt_cv_file_magic_cmd='func_win32_libid' else # Keep this pattern in sync with the one in func_win32_libid. lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' lt_cv_file_magic_cmd='$OBJDUMP -f' fi ;; cegcc*) # use the weaker test based on 'objdump'. See mingw*. lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' lt_cv_file_magic_cmd='$OBJDUMP -f' ;; darwin* | rhapsody*) lt_cv_deplibs_check_method=pass_all ;; freebsd* | dragonfly*) if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then case $host_cpu in i*86 ) # Not sure whether the presence of OpenBSD here was a mistake. # Let's accept both of them until this is cleared up. lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[3-9]86 (compact )?demand paged shared library' lt_cv_file_magic_cmd=/usr/bin/file lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` ;; esac else lt_cv_deplibs_check_method=pass_all fi ;; haiku*) lt_cv_deplibs_check_method=pass_all ;; hpux10.20* | hpux11*) lt_cv_file_magic_cmd=/usr/bin/file case $host_cpu in ia64*) lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64' lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so ;; hppa*64*) lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]' lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl ;; *) lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9]\.[0-9]) shared library' lt_cv_file_magic_test_file=/usr/lib/libc.sl ;; esac ;; interix[3-9]*) # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|\.a)$' ;; irix5* | irix6* | nonstopux*) case $LD in *-32|*"-32 ") libmagic=32-bit;; *-n32|*"-n32 ") libmagic=N32;; *-64|*"-64 ") libmagic=64-bit;; *) libmagic=never-match;; esac lt_cv_deplibs_check_method=pass_all ;; # This must be glibc/ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) lt_cv_deplibs_check_method=pass_all ;; netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' else lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|_pic\.a)$' fi ;; newos6*) lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)' lt_cv_file_magic_cmd=/usr/bin/file lt_cv_file_magic_test_file=/usr/lib/libnls.so ;; *nto* | *qnx*) lt_cv_deplibs_check_method=pass_all ;; openbsd*) if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|\.so|_pic\.a)$' else lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' fi ;; osf3* | osf4* | osf5*) lt_cv_deplibs_check_method=pass_all ;; rdos*) lt_cv_deplibs_check_method=pass_all ;; solaris*) lt_cv_deplibs_check_method=pass_all ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) lt_cv_deplibs_check_method=pass_all ;; sysv4 | sysv4.3*) case $host_vendor in motorola) lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]' lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` ;; ncr) lt_cv_deplibs_check_method=pass_all ;; sequent) lt_cv_file_magic_cmd='/bin/file' lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )' ;; sni) lt_cv_file_magic_cmd='/bin/file' lt_cv_deplibs_check_method="file_magic ELF [0-9][0-9]*-bit [LM]SB dynamic lib" lt_cv_file_magic_test_file=/lib/libc.so ;; siemens) lt_cv_deplibs_check_method=pass_all ;; pc) lt_cv_deplibs_check_method=pass_all ;; esac ;; tpf*) lt_cv_deplibs_check_method=pass_all ;; esac fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_deplibs_check_method" >&5 $as_echo "$lt_cv_deplibs_check_method" >&6; } file_magic_glob= want_nocaseglob=no if test "$build" = "$host"; then case $host_os in mingw* | pw32*) if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then want_nocaseglob=yes else file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[\1]\/[\1]\/g;/g"` fi ;; esac fi file_magic_cmd=$lt_cv_file_magic_cmd deplibs_check_method=$lt_cv_deplibs_check_method test -z "$deplibs_check_method" && deplibs_check_method=unknown if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}dlltool", so it can be a program name with args. set dummy ${ac_tool_prefix}dlltool; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_DLLTOOL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$DLLTOOL"; then ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi DLLTOOL=$ac_cv_prog_DLLTOOL if test -n "$DLLTOOL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DLLTOOL" >&5 $as_echo "$DLLTOOL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_DLLTOOL"; then ac_ct_DLLTOOL=$DLLTOOL # Extract the first word of "dlltool", so it can be a program name with args. set dummy dlltool; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_DLLTOOL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_DLLTOOL"; then ac_cv_prog_ac_ct_DLLTOOL="$ac_ct_DLLTOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_DLLTOOL="dlltool" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_DLLTOOL=$ac_cv_prog_ac_ct_DLLTOOL if test -n "$ac_ct_DLLTOOL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DLLTOOL" >&5 $as_echo "$ac_ct_DLLTOOL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_DLLTOOL" = x; then DLLTOOL="false" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac DLLTOOL=$ac_ct_DLLTOOL fi else DLLTOOL="$ac_cv_prog_DLLTOOL" fi test -z "$DLLTOOL" && DLLTOOL=dlltool { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to associate runtime and link libraries" >&5 $as_echo_n "checking how to associate runtime and link libraries... " >&6; } if ${lt_cv_sharedlib_from_linklib_cmd+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_sharedlib_from_linklib_cmd='unknown' case $host_os in cygwin* | mingw* | pw32* | cegcc*) # two different shell functions defined in ltmain.sh # decide which to use based on capabilities of $DLLTOOL case `$DLLTOOL --help 2>&1` in *--identify-strict*) lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib ;; *) lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback ;; esac ;; *) # fallback: assume linklib IS sharedlib lt_cv_sharedlib_from_linklib_cmd="$ECHO" ;; esac fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sharedlib_from_linklib_cmd" >&5 $as_echo "$lt_cv_sharedlib_from_linklib_cmd" >&6; } sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO if test -n "$ac_tool_prefix"; then for ac_prog in ar do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_AR+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$AR"; then ac_cv_prog_AR="$AR" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_AR="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi AR=$ac_cv_prog_AR if test -n "$AR"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5 $as_echo "$AR" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$AR" && break done fi if test -z "$AR"; then ac_ct_AR=$AR for ac_prog in ar do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_AR+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_AR"; then ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_AR="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_AR=$ac_cv_prog_ac_ct_AR if test -n "$ac_ct_AR"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5 $as_echo "$ac_ct_AR" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_AR" && break done if test "x$ac_ct_AR" = x; then AR="false" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac AR=$ac_ct_AR fi fi : ${AR=ar} : ${AR_FLAGS=cru} { $as_echo "$as_me:${as_lineno-$LINENO}: checking for archiver @FILE support" >&5 $as_echo_n "checking for archiver @FILE support... " >&6; } if ${lt_cv_ar_at_file+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_ar_at_file=no cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : echo conftest.$ac_objext > conftest.lst lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&5' { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5 (eval $lt_ar_try) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if test "$ac_status" -eq 0; then # Ensure the archiver fails upon bogus file names. rm -f conftest.$ac_objext libconftest.a { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5 (eval $lt_ar_try) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if test "$ac_status" -ne 0; then lt_cv_ar_at_file=@ fi fi rm -f conftest.* libconftest.a fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ar_at_file" >&5 $as_echo "$lt_cv_ar_at_file" >&6; } if test "x$lt_cv_ar_at_file" = xno; then archiver_list_spec= else archiver_list_spec=$lt_cv_ar_at_file fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. set dummy ${ac_tool_prefix}strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_STRIP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$STRIP"; then ac_cv_prog_STRIP="$STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_STRIP="${ac_tool_prefix}strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi STRIP=$ac_cv_prog_STRIP if test -n "$STRIP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 $as_echo "$STRIP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_STRIP"; then ac_ct_STRIP=$STRIP # Extract the first word of "strip", so it can be a program name with args. set dummy strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_STRIP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_STRIP"; then ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_STRIP="strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP if test -n "$ac_ct_STRIP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 $as_echo "$ac_ct_STRIP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_STRIP" = x; then STRIP=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac STRIP=$ac_ct_STRIP fi else STRIP="$ac_cv_prog_STRIP" fi test -z "$STRIP" && STRIP=: if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. set dummy ${ac_tool_prefix}ranlib; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_RANLIB+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$RANLIB"; then ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi RANLIB=$ac_cv_prog_RANLIB if test -n "$RANLIB"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5 $as_echo "$RANLIB" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_RANLIB"; then ac_ct_RANLIB=$RANLIB # Extract the first word of "ranlib", so it can be a program name with args. set dummy ranlib; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_RANLIB+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_RANLIB"; then ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_RANLIB="ranlib" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB if test -n "$ac_ct_RANLIB"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5 $as_echo "$ac_ct_RANLIB" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_RANLIB" = x; then RANLIB=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac RANLIB=$ac_ct_RANLIB fi else RANLIB="$ac_cv_prog_RANLIB" fi test -z "$RANLIB" && RANLIB=: # Determine commands to create old-style static archives. old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' old_postinstall_cmds='chmod 644 $oldlib' old_postuninstall_cmds= if test -n "$RANLIB"; then case $host_os in openbsd*) old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib" ;; *) old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib" ;; esac old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib" fi case $host_os in darwin*) lock_old_archive_extraction=yes ;; *) lock_old_archive_extraction=no ;; esac # If no C compiler was specified, use CC. LTCC=${LTCC-"$CC"} # If no C compiler flags were specified, use CFLAGS. LTCFLAGS=${LTCFLAGS-"$CFLAGS"} # Allow CC to be a program name with arguments. compiler=$CC # Check for command to grab the raw symbol name followed by C symbol from nm. { $as_echo "$as_me:${as_lineno-$LINENO}: checking command to parse $NM output from $compiler object" >&5 $as_echo_n "checking command to parse $NM output from $compiler object... " >&6; } if ${lt_cv_sys_global_symbol_pipe+:} false; then : $as_echo_n "(cached) " >&6 else # These are sane defaults that work on at least a few old systems. # [They come from Ultrix. What could be older than Ultrix?!! ;)] # Character class describing NM global symbol codes. symcode='[BCDEGRST]' # Regexp to match symbols that can be accessed directly from C. sympat='\([_A-Za-z][_A-Za-z0-9]*\)' # Define system-specific variables. case $host_os in aix*) symcode='[BCDT]' ;; cygwin* | mingw* | pw32* | cegcc*) symcode='[ABCDGISTW]' ;; hpux*) if test "$host_cpu" = ia64; then symcode='[ABCDEGRST]' fi ;; irix* | nonstopux*) symcode='[BCDEGRST]' ;; osf*) symcode='[BCDEGQRST]' ;; solaris*) symcode='[BDRT]' ;; sco3.2v5*) symcode='[DT]' ;; sysv4.2uw2*) symcode='[DT]' ;; sysv5* | sco5v6* | unixware* | OpenUNIX*) symcode='[ABDT]' ;; sysv4) symcode='[DFNSTU]' ;; esac # If we're using GNU nm, then use its standard symbol codes. case `$NM -V 2>&1` in *GNU* | *'with BFD'*) symcode='[ABCDGIRSTW]' ;; esac # Transform an extracted symbol line into a proper C declaration. # Some systems (esp. on ia64) link data and code symbols differently, # so use this general approach. lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" # Transform an extracted symbol line into symbol name and symbol address lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\)[ ]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"\2\", (void *) \&\2},/p'" lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([^ ]*\)[ ]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \(lib[^ ]*\)$/ {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"lib\2\", (void *) \&\2},/p'" # Handle CRLF in mingw tool chain opt_cr= case $build_os in mingw*) opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp ;; esac # Try without a prefix underscore, then with it. for ac_symprfx in "" "_"; do # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. symxfrm="\\1 $ac_symprfx\\2 \\2" # Write the raw and C identifiers. if test "$lt_cv_nm_interface" = "MS dumpbin"; then # Fake it for dumpbin and say T for any non-static function # and D for any global variable. # Also find C++ and __fastcall symbols from MSVC++, # which start with @ or ?. lt_cv_sys_global_symbol_pipe="$AWK '"\ " {last_section=section; section=\$ 3};"\ " /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\ " /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ " \$ 0!~/External *\|/{next};"\ " / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ " {if(hide[section]) next};"\ " {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\ " {split(\$ 0, a, /\||\r/); split(a[2], s)};"\ " s[1]~/^[@?]/{print s[1], s[1]; next};"\ " s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\ " ' prfx=^$ac_symprfx" else lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[ ]\($symcode$symcode*\)[ ][ ]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" fi lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'" # Check to see that the pipe works correctly. pipe_works=no rm -f conftest* cat > conftest.$ac_ext <<_LT_EOF #ifdef __cplusplus extern "C" { #endif char nm_test_var; void nm_test_func(void); void nm_test_func(void){} #ifdef __cplusplus } #endif int main(){nm_test_var='a';nm_test_func();return(0);} _LT_EOF if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then # Now try to grab the symbols. nlist=conftest.nm if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist\""; } >&5 (eval $NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && test -s "$nlist"; then # Try sorting and uniquifying the output. if sort "$nlist" | uniq > "$nlist"T; then mv -f "$nlist"T "$nlist" else rm -f "$nlist"T fi # Make sure that we snagged all the symbols we need. if $GREP ' nm_test_var$' "$nlist" >/dev/null; then if $GREP ' nm_test_func$' "$nlist" >/dev/null; then cat <<_LT_EOF > conftest.$ac_ext /* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ #if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE) /* DATA imports from DLLs on WIN32 con't be const, because runtime relocations are performed -- see ld's documentation on pseudo-relocs. */ # define LT_DLSYM_CONST #elif defined(__osf__) /* This system does not cope well with relocations in const data. */ # define LT_DLSYM_CONST #else # define LT_DLSYM_CONST const #endif #ifdef __cplusplus extern "C" { #endif _LT_EOF # Now generate the symbol file. eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' cat <<_LT_EOF >> conftest.$ac_ext /* The mapping between symbol names and symbols. */ LT_DLSYM_CONST struct { const char *name; void *address; } lt__PROGRAM__LTX_preloaded_symbols[] = { { "@PROGRAM@", (void *) 0 }, _LT_EOF $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext cat <<\_LT_EOF >> conftest.$ac_ext {0, (void *) 0} }; /* This works around a problem in FreeBSD linker */ #ifdef FREEBSD_WORKAROUND static const void *lt_preloaded_setup() { return lt__PROGRAM__LTX_preloaded_symbols; } #endif #ifdef __cplusplus } #endif _LT_EOF # Now try linking the two files. mv conftest.$ac_objext conftstm.$ac_objext lt_globsym_save_LIBS=$LIBS lt_globsym_save_CFLAGS=$CFLAGS LIBS="conftstm.$ac_objext" CFLAGS="$CFLAGS$lt_prog_compiler_no_builtin_flag" if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 (eval $ac_link) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && test -s conftest${ac_exeext}; then pipe_works=yes fi LIBS=$lt_globsym_save_LIBS CFLAGS=$lt_globsym_save_CFLAGS else echo "cannot find nm_test_func in $nlist" >&5 fi else echo "cannot find nm_test_var in $nlist" >&5 fi else echo "cannot run $lt_cv_sys_global_symbol_pipe" >&5 fi else echo "$progname: failed program was:" >&5 cat conftest.$ac_ext >&5 fi rm -rf conftest* conftst* # Do not use the global_symbol_pipe unless it works. if test "$pipe_works" = yes; then break else lt_cv_sys_global_symbol_pipe= fi done fi if test -z "$lt_cv_sys_global_symbol_pipe"; then lt_cv_sys_global_symbol_to_cdecl= fi if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: failed" >&5 $as_echo "failed" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5 $as_echo "ok" >&6; } fi # Response file support. if test "$lt_cv_nm_interface" = "MS dumpbin"; then nm_file_list_spec='@' elif $NM --help 2>/dev/null | grep '[@]FILE' >/dev/null; then nm_file_list_spec='@' fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sysroot" >&5 $as_echo_n "checking for sysroot... " >&6; } # Check whether --with-sysroot was given. if test "${with_sysroot+set}" = set; then : withval=$with_sysroot; else with_sysroot=no fi lt_sysroot= case ${with_sysroot} in #( yes) if test "$GCC" = yes; then lt_sysroot=`$CC --print-sysroot 2>/dev/null` fi ;; #( /*) lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"` ;; #( no|'') ;; #( *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${with_sysroot}" >&5 $as_echo "${with_sysroot}" >&6; } as_fn_error $? "The sysroot must be an absolute path." "$LINENO" 5 ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${lt_sysroot:-no}" >&5 $as_echo "${lt_sysroot:-no}" >&6; } # Check whether --enable-libtool-lock was given. if test "${enable_libtool_lock+set}" = set; then : enableval=$enable_libtool_lock; fi test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes # Some flags need to be propagated to the compiler or linker for good # libtool support. case $host in ia64-*-hpux*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then case `/usr/bin/file conftest.$ac_objext` in *ELF-32*) HPUX_IA64_MODE="32" ;; *ELF-64*) HPUX_IA64_MODE="64" ;; esac fi rm -rf conftest* ;; *-*-irix6*) # Find out which ABI we are using. echo '#line '$LINENO' "configure"' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then if test "$lt_cv_prog_gnu_ld" = yes; then case `/usr/bin/file conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -melf32bsmip" ;; *N32*) LD="${LD-ld} -melf32bmipn32" ;; *64-bit*) LD="${LD-ld} -melf64bmip" ;; esac else case `/usr/bin/file conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -32" ;; *N32*) LD="${LD-ld} -n32" ;; *64-bit*) LD="${LD-ld} -64" ;; esac fi fi rm -rf conftest* ;; x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then case `/usr/bin/file conftest.o` in *32-bit*) case $host in x86_64-*kfreebsd*-gnu) LD="${LD-ld} -m elf_i386_fbsd" ;; x86_64-*linux*) case `/usr/bin/file conftest.o` in *x86-64*) LD="${LD-ld} -m elf32_x86_64" ;; *) LD="${LD-ld} -m elf_i386" ;; esac ;; powerpc64le-*) LD="${LD-ld} -m elf32lppclinux" ;; powerpc64-*) LD="${LD-ld} -m elf32ppclinux" ;; s390x-*linux*) LD="${LD-ld} -m elf_s390" ;; sparc64-*linux*) LD="${LD-ld} -m elf32_sparc" ;; esac ;; *64-bit*) case $host in x86_64-*kfreebsd*-gnu) LD="${LD-ld} -m elf_x86_64_fbsd" ;; x86_64-*linux*) LD="${LD-ld} -m elf_x86_64" ;; powerpcle-*) LD="${LD-ld} -m elf64lppc" ;; powerpc-*) LD="${LD-ld} -m elf64ppc" ;; s390*-*linux*|s390*-*tpf*) LD="${LD-ld} -m elf64_s390" ;; sparc*-*linux*) LD="${LD-ld} -m elf64_sparc" ;; esac ;; esac fi rm -rf conftest* ;; *-*-sco3.2v5*) # On SCO OpenServer 5, we need -belf to get full-featured binaries. SAVE_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -belf" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler needs -belf" >&5 $as_echo_n "checking whether the C compiler needs -belf... " >&6; } if ${lt_cv_cc_needs_belf+:} false; then : $as_echo_n "(cached) " >&6 else ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : lt_cv_cc_needs_belf=yes else lt_cv_cc_needs_belf=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_cc_needs_belf" >&5 $as_echo "$lt_cv_cc_needs_belf" >&6; } if test x"$lt_cv_cc_needs_belf" != x"yes"; then # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf CFLAGS="$SAVE_CFLAGS" fi ;; *-*solaris*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then case `/usr/bin/file conftest.o` in *64-bit*) case $lt_cv_prog_gnu_ld in yes*) case $host in i?86-*-solaris*) LD="${LD-ld} -m elf_x86_64" ;; sparc*-*-solaris*) LD="${LD-ld} -m elf64_sparc" ;; esac # GNU ld 2.21 introduced _sol2 emulations. Use them if available. if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then LD="${LD-ld}_sol2" fi ;; *) if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then LD="${LD-ld} -64" fi ;; esac ;; esac fi rm -rf conftest* ;; esac need_locks="$enable_libtool_lock" if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}mt", so it can be a program name with args. set dummy ${ac_tool_prefix}mt; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_MANIFEST_TOOL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$MANIFEST_TOOL"; then ac_cv_prog_MANIFEST_TOOL="$MANIFEST_TOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_MANIFEST_TOOL="${ac_tool_prefix}mt" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi MANIFEST_TOOL=$ac_cv_prog_MANIFEST_TOOL if test -n "$MANIFEST_TOOL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MANIFEST_TOOL" >&5 $as_echo "$MANIFEST_TOOL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_MANIFEST_TOOL"; then ac_ct_MANIFEST_TOOL=$MANIFEST_TOOL # Extract the first word of "mt", so it can be a program name with args. set dummy mt; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_MANIFEST_TOOL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_MANIFEST_TOOL"; then ac_cv_prog_ac_ct_MANIFEST_TOOL="$ac_ct_MANIFEST_TOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_MANIFEST_TOOL="mt" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_MANIFEST_TOOL=$ac_cv_prog_ac_ct_MANIFEST_TOOL if test -n "$ac_ct_MANIFEST_TOOL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_MANIFEST_TOOL" >&5 $as_echo "$ac_ct_MANIFEST_TOOL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_MANIFEST_TOOL" = x; then MANIFEST_TOOL=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac MANIFEST_TOOL=$ac_ct_MANIFEST_TOOL fi else MANIFEST_TOOL="$ac_cv_prog_MANIFEST_TOOL" fi test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $MANIFEST_TOOL is a manifest tool" >&5 $as_echo_n "checking if $MANIFEST_TOOL is a manifest tool... " >&6; } if ${lt_cv_path_mainfest_tool+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_path_mainfest_tool=no echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&5 $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out cat conftest.err >&5 if $GREP 'Manifest Tool' conftest.out > /dev/null; then lt_cv_path_mainfest_tool=yes fi rm -f conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_mainfest_tool" >&5 $as_echo "$lt_cv_path_mainfest_tool" >&6; } if test "x$lt_cv_path_mainfest_tool" != xyes; then MANIFEST_TOOL=: fi case $host_os in rhapsody* | darwin*) if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}dsymutil", so it can be a program name with args. set dummy ${ac_tool_prefix}dsymutil; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_DSYMUTIL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$DSYMUTIL"; then ac_cv_prog_DSYMUTIL="$DSYMUTIL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_DSYMUTIL="${ac_tool_prefix}dsymutil" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi DSYMUTIL=$ac_cv_prog_DSYMUTIL if test -n "$DSYMUTIL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DSYMUTIL" >&5 $as_echo "$DSYMUTIL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_DSYMUTIL"; then ac_ct_DSYMUTIL=$DSYMUTIL # Extract the first word of "dsymutil", so it can be a program name with args. set dummy dsymutil; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_DSYMUTIL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_DSYMUTIL"; then ac_cv_prog_ac_ct_DSYMUTIL="$ac_ct_DSYMUTIL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_DSYMUTIL="dsymutil" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_DSYMUTIL=$ac_cv_prog_ac_ct_DSYMUTIL if test -n "$ac_ct_DSYMUTIL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DSYMUTIL" >&5 $as_echo "$ac_ct_DSYMUTIL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_DSYMUTIL" = x; then DSYMUTIL=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac DSYMUTIL=$ac_ct_DSYMUTIL fi else DSYMUTIL="$ac_cv_prog_DSYMUTIL" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}nmedit", so it can be a program name with args. set dummy ${ac_tool_prefix}nmedit; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_NMEDIT+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$NMEDIT"; then ac_cv_prog_NMEDIT="$NMEDIT" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_NMEDIT="${ac_tool_prefix}nmedit" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi NMEDIT=$ac_cv_prog_NMEDIT if test -n "$NMEDIT"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $NMEDIT" >&5 $as_echo "$NMEDIT" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_NMEDIT"; then ac_ct_NMEDIT=$NMEDIT # Extract the first word of "nmedit", so it can be a program name with args. set dummy nmedit; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_NMEDIT+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_NMEDIT"; then ac_cv_prog_ac_ct_NMEDIT="$ac_ct_NMEDIT" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_NMEDIT="nmedit" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_NMEDIT=$ac_cv_prog_ac_ct_NMEDIT if test -n "$ac_ct_NMEDIT"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_NMEDIT" >&5 $as_echo "$ac_ct_NMEDIT" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_NMEDIT" = x; then NMEDIT=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac NMEDIT=$ac_ct_NMEDIT fi else NMEDIT="$ac_cv_prog_NMEDIT" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}lipo", so it can be a program name with args. set dummy ${ac_tool_prefix}lipo; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_LIPO+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$LIPO"; then ac_cv_prog_LIPO="$LIPO" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_LIPO="${ac_tool_prefix}lipo" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi LIPO=$ac_cv_prog_LIPO if test -n "$LIPO"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIPO" >&5 $as_echo "$LIPO" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_LIPO"; then ac_ct_LIPO=$LIPO # Extract the first word of "lipo", so it can be a program name with args. set dummy lipo; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_LIPO+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_LIPO"; then ac_cv_prog_ac_ct_LIPO="$ac_ct_LIPO" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_LIPO="lipo" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_LIPO=$ac_cv_prog_ac_ct_LIPO if test -n "$ac_ct_LIPO"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_LIPO" >&5 $as_echo "$ac_ct_LIPO" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_LIPO" = x; then LIPO=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac LIPO=$ac_ct_LIPO fi else LIPO="$ac_cv_prog_LIPO" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}otool", so it can be a program name with args. set dummy ${ac_tool_prefix}otool; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_OTOOL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$OTOOL"; then ac_cv_prog_OTOOL="$OTOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_OTOOL="${ac_tool_prefix}otool" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi OTOOL=$ac_cv_prog_OTOOL if test -n "$OTOOL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL" >&5 $as_echo "$OTOOL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_OTOOL"; then ac_ct_OTOOL=$OTOOL # Extract the first word of "otool", so it can be a program name with args. set dummy otool; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_OTOOL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_OTOOL"; then ac_cv_prog_ac_ct_OTOOL="$ac_ct_OTOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_OTOOL="otool" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_OTOOL=$ac_cv_prog_ac_ct_OTOOL if test -n "$ac_ct_OTOOL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL" >&5 $as_echo "$ac_ct_OTOOL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_OTOOL" = x; then OTOOL=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac OTOOL=$ac_ct_OTOOL fi else OTOOL="$ac_cv_prog_OTOOL" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}otool64", so it can be a program name with args. set dummy ${ac_tool_prefix}otool64; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_OTOOL64+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$OTOOL64"; then ac_cv_prog_OTOOL64="$OTOOL64" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_OTOOL64="${ac_tool_prefix}otool64" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi OTOOL64=$ac_cv_prog_OTOOL64 if test -n "$OTOOL64"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL64" >&5 $as_echo "$OTOOL64" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_OTOOL64"; then ac_ct_OTOOL64=$OTOOL64 # Extract the first word of "otool64", so it can be a program name with args. set dummy otool64; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_OTOOL64+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_OTOOL64"; then ac_cv_prog_ac_ct_OTOOL64="$ac_ct_OTOOL64" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_OTOOL64="otool64" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_OTOOL64=$ac_cv_prog_ac_ct_OTOOL64 if test -n "$ac_ct_OTOOL64"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL64" >&5 $as_echo "$ac_ct_OTOOL64" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_OTOOL64" = x; then OTOOL64=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac OTOOL64=$ac_ct_OTOOL64 fi else OTOOL64="$ac_cv_prog_OTOOL64" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -single_module linker flag" >&5 $as_echo_n "checking for -single_module linker flag... " >&6; } if ${lt_cv_apple_cc_single_mod+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_apple_cc_single_mod=no if test -z "${LT_MULTI_MODULE}"; then # By default we will add the -single_module flag. You can override # by either setting the environment variable LT_MULTI_MODULE # non-empty at configure time, or by adding -multi_module to the # link flags. rm -rf libconftest.dylib* echo "int foo(void){return 1;}" > conftest.c echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ -dynamiclib -Wl,-single_module conftest.c" >&5 $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ -dynamiclib -Wl,-single_module conftest.c 2>conftest.err _lt_result=$? # If there is a non-empty error log, and "single_module" # appears in it, assume the flag caused a linker warning if test -s conftest.err && $GREP single_module conftest.err; then cat conftest.err >&5 # Otherwise, if the output was created with a 0 exit code from # the compiler, it worked. elif test -f libconftest.dylib && test $_lt_result -eq 0; then lt_cv_apple_cc_single_mod=yes else cat conftest.err >&5 fi rm -rf libconftest.dylib* rm -f conftest.* fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_apple_cc_single_mod" >&5 $as_echo "$lt_cv_apple_cc_single_mod" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -exported_symbols_list linker flag" >&5 $as_echo_n "checking for -exported_symbols_list linker flag... " >&6; } if ${lt_cv_ld_exported_symbols_list+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_ld_exported_symbols_list=no save_LDFLAGS=$LDFLAGS echo "_main" > conftest.sym LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : lt_cv_ld_exported_symbols_list=yes else lt_cv_ld_exported_symbols_list=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LDFLAGS="$save_LDFLAGS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_exported_symbols_list" >&5 $as_echo "$lt_cv_ld_exported_symbols_list" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -force_load linker flag" >&5 $as_echo_n "checking for -force_load linker flag... " >&6; } if ${lt_cv_ld_force_load+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_ld_force_load=no cat > conftest.c << _LT_EOF int forced_loaded() { return 2;} _LT_EOF echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&5 $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&5 echo "$AR cru libconftest.a conftest.o" >&5 $AR cru libconftest.a conftest.o 2>&5 echo "$RANLIB libconftest.a" >&5 $RANLIB libconftest.a 2>&5 cat > conftest.c << _LT_EOF int main() { return 0;} _LT_EOF echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&5 $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err _lt_result=$? if test -s conftest.err && $GREP force_load conftest.err; then cat conftest.err >&5 elif test -f conftest && test $_lt_result -eq 0 && $GREP forced_load conftest >/dev/null 2>&1 ; then lt_cv_ld_force_load=yes else cat conftest.err >&5 fi rm -f conftest.err libconftest.a conftest conftest.c rm -rf conftest.dSYM fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_force_load" >&5 $as_echo "$lt_cv_ld_force_load" >&6; } case $host_os in rhapsody* | darwin1.[012]) _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;; darwin1.*) _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; darwin*) # darwin 5.x on # if running on 10.5 or later, the deployment target defaults # to the OS version, if on x86, and 10.4, the deployment # target defaults to 10.4. Don't you love it? case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in 10.0,*86*-darwin8*|10.0,*-darwin[91]*) _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; 10.[012]*) _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; 10.*) _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; esac ;; esac if test "$lt_cv_apple_cc_single_mod" = "yes"; then _lt_dar_single_mod='$single_module' fi if test "$lt_cv_ld_exported_symbols_list" = "yes"; then _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym' else _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}' fi if test "$DSYMUTIL" != ":" && test "$lt_cv_ld_force_load" = "no"; then _lt_dsymutil='~$DSYMUTIL $lib || :' else _lt_dsymutil= fi ;; esac for ac_header in dlfcn.h do : ac_fn_c_check_header_compile "$LINENO" "dlfcn.h" "ac_cv_header_dlfcn_h" "$ac_includes_default " if test "x$ac_cv_header_dlfcn_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_DLFCN_H 1 _ACEOF fi done # Set options enable_dlopen=no enable_win32_dll=no # Check whether --enable-shared was given. if test "${enable_shared+set}" = set; then : enableval=$enable_shared; p=${PACKAGE-default} case $enableval in yes) enable_shared=yes ;; no) enable_shared=no ;; *) enable_shared=no # Look at the argument we got. We use all the common list separators. lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," for pkg in $enableval; do IFS="$lt_save_ifs" if test "X$pkg" = "X$p"; then enable_shared=yes fi done IFS="$lt_save_ifs" ;; esac else enable_shared=yes fi # Check whether --enable-static was given. if test "${enable_static+set}" = set; then : enableval=$enable_static; p=${PACKAGE-default} case $enableval in yes) enable_static=yes ;; no) enable_static=no ;; *) enable_static=no # Look at the argument we got. We use all the common list separators. lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," for pkg in $enableval; do IFS="$lt_save_ifs" if test "X$pkg" = "X$p"; then enable_static=yes fi done IFS="$lt_save_ifs" ;; esac else enable_static=yes fi # Check whether --with-pic was given. if test "${with_pic+set}" = set; then : withval=$with_pic; lt_p=${PACKAGE-default} case $withval in yes|no) pic_mode=$withval ;; *) pic_mode=default # Look at the argument we got. We use all the common list separators. lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," for lt_pkg in $withval; do IFS="$lt_save_ifs" if test "X$lt_pkg" = "X$lt_p"; then pic_mode=yes fi done IFS="$lt_save_ifs" ;; esac else pic_mode=default fi test -z "$pic_mode" && pic_mode=default # Check whether --enable-fast-install was given. if test "${enable_fast_install+set}" = set; then : enableval=$enable_fast_install; p=${PACKAGE-default} case $enableval in yes) enable_fast_install=yes ;; no) enable_fast_install=no ;; *) enable_fast_install=no # Look at the argument we got. We use all the common list separators. lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," for pkg in $enableval; do IFS="$lt_save_ifs" if test "X$pkg" = "X$p"; then enable_fast_install=yes fi done IFS="$lt_save_ifs" ;; esac else enable_fast_install=yes fi # This can be used to rebuild libtool when needed LIBTOOL_DEPS="$ltmain" # Always use our own libtool. LIBTOOL='$(SHELL) $(top_builddir)/libtool' test -z "$LN_S" && LN_S="ln -s" if test -n "${ZSH_VERSION+set}" ; then setopt NO_GLOB_SUBST fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for objdir" >&5 $as_echo_n "checking for objdir... " >&6; } if ${lt_cv_objdir+:} false; then : $as_echo_n "(cached) " >&6 else rm -f .libs 2>/dev/null mkdir .libs 2>/dev/null if test -d .libs; then lt_cv_objdir=.libs else # MS-DOS does not allow filenames that begin with a dot. lt_cv_objdir=_libs fi rmdir .libs 2>/dev/null fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_objdir" >&5 $as_echo "$lt_cv_objdir" >&6; } objdir=$lt_cv_objdir cat >>confdefs.h <<_ACEOF #define LT_OBJDIR "$lt_cv_objdir/" _ACEOF case $host_os in aix3*) # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. if test "X${COLLECT_NAMES+set}" != Xset; then COLLECT_NAMES= export COLLECT_NAMES fi ;; esac # Global variables: ofile=libtool can_build_shared=yes # All known linkers require a `.a' archive for static linking (except MSVC, # which needs '.lib'). libext=a with_gnu_ld="$lt_cv_prog_gnu_ld" old_CC="$CC" old_CFLAGS="$CFLAGS" # Set sane defaults for various variables test -z "$CC" && CC=cc test -z "$LTCC" && LTCC=$CC test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS test -z "$LD" && LD=ld test -z "$ac_objext" && ac_objext=o for cc_temp in $compiler""; do case $cc_temp in compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; \-*) ;; *) break;; esac done cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` # Only perform the check for file, if the check method requires it test -z "$MAGIC_CMD" && MAGIC_CMD=file case $deplibs_check_method in file_magic*) if test "$file_magic_cmd" = '$MAGIC_CMD'; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${ac_tool_prefix}file" >&5 $as_echo_n "checking for ${ac_tool_prefix}file... " >&6; } if ${lt_cv_path_MAGIC_CMD+:} false; then : $as_echo_n "(cached) " >&6 else case $MAGIC_CMD in [\\/*] | ?:[\\/]*) lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. ;; *) lt_save_MAGIC_CMD="$MAGIC_CMD" lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" for ac_dir in $ac_dummy; do IFS="$lt_save_ifs" test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/${ac_tool_prefix}file; then lt_cv_path_MAGIC_CMD="$ac_dir/${ac_tool_prefix}file" if test -n "$file_magic_test_file"; then case $deplibs_check_method in "file_magic "*) file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` MAGIC_CMD="$lt_cv_path_MAGIC_CMD" if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | $EGREP "$file_magic_regex" > /dev/null; then : else cat <<_LT_EOF 1>&2 *** Warning: the command libtool uses to detect shared libraries, *** $file_magic_cmd, produces output that libtool cannot recognize. *** The result is that libtool may fail to recognize shared libraries *** as such. This will affect the creation of libtool libraries that *** depend on shared libraries, but programs linked with such libtool *** libraries will work regardless of this problem. Nevertheless, you *** may want to report the problem to your system manager and/or to *** bug-libtool@gnu.org _LT_EOF fi ;; esac fi break fi done IFS="$lt_save_ifs" MAGIC_CMD="$lt_save_MAGIC_CMD" ;; esac fi MAGIC_CMD="$lt_cv_path_MAGIC_CMD" if test -n "$MAGIC_CMD"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 $as_echo "$MAGIC_CMD" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test -z "$lt_cv_path_MAGIC_CMD"; then if test -n "$ac_tool_prefix"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for file" >&5 $as_echo_n "checking for file... " >&6; } if ${lt_cv_path_MAGIC_CMD+:} false; then : $as_echo_n "(cached) " >&6 else case $MAGIC_CMD in [\\/*] | ?:[\\/]*) lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. ;; *) lt_save_MAGIC_CMD="$MAGIC_CMD" lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" for ac_dir in $ac_dummy; do IFS="$lt_save_ifs" test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/file; then lt_cv_path_MAGIC_CMD="$ac_dir/file" if test -n "$file_magic_test_file"; then case $deplibs_check_method in "file_magic "*) file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` MAGIC_CMD="$lt_cv_path_MAGIC_CMD" if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | $EGREP "$file_magic_regex" > /dev/null; then : else cat <<_LT_EOF 1>&2 *** Warning: the command libtool uses to detect shared libraries, *** $file_magic_cmd, produces output that libtool cannot recognize. *** The result is that libtool may fail to recognize shared libraries *** as such. This will affect the creation of libtool libraries that *** depend on shared libraries, but programs linked with such libtool *** libraries will work regardless of this problem. Nevertheless, you *** may want to report the problem to your system manager and/or to *** bug-libtool@gnu.org _LT_EOF fi ;; esac fi break fi done IFS="$lt_save_ifs" MAGIC_CMD="$lt_save_MAGIC_CMD" ;; esac fi MAGIC_CMD="$lt_cv_path_MAGIC_CMD" if test -n "$MAGIC_CMD"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 $as_echo "$MAGIC_CMD" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi else MAGIC_CMD=: fi fi fi ;; esac # Use C for the default configuration in the libtool script lt_save_CC="$CC" ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu # Source file extension for C test sources. ac_ext=c # Object file extension for compiled C test sources. objext=o objext=$objext # Code to be used in simple compile tests lt_simple_compile_test_code="int some_variable = 0;" # Code to be used in simple link tests lt_simple_link_test_code='int main(){return(0);}' # If no C compiler was specified, use CC. LTCC=${LTCC-"$CC"} # If no C compiler flags were specified, use CFLAGS. LTCFLAGS=${LTCFLAGS-"$CFLAGS"} # Allow CC to be a program name with arguments. compiler=$CC # Save the default compiler, since it gets overwritten when the other # tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. compiler_DEFAULT=$CC # save warnings/boilerplate of simple test code ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" >conftest.$ac_ext eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_compiler_boilerplate=`cat conftest.err` $RM conftest* ac_outfile=conftest.$ac_objext echo "$lt_simple_link_test_code" >conftest.$ac_ext eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_linker_boilerplate=`cat conftest.err` $RM -r conftest* if test -n "$compiler"; then lt_prog_compiler_no_builtin_flag= if test "$GCC" = yes; then case $cc_basename in nvcc*) lt_prog_compiler_no_builtin_flag=' -Xcompiler -fno-builtin' ;; *) lt_prog_compiler_no_builtin_flag=' -fno-builtin' ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -fno-rtti -fno-exceptions" >&5 $as_echo_n "checking if $compiler supports -fno-rtti -fno-exceptions... " >&6; } if ${lt_cv_prog_compiler_rtti_exceptions+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_rtti_exceptions=no ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-fno-rtti -fno-exceptions" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. # The option is referenced via a variable to avoid confusing sed. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler_rtti_exceptions=yes fi fi $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_rtti_exceptions" >&5 $as_echo "$lt_cv_prog_compiler_rtti_exceptions" >&6; } if test x"$lt_cv_prog_compiler_rtti_exceptions" = xyes; then lt_prog_compiler_no_builtin_flag="$lt_prog_compiler_no_builtin_flag -fno-rtti -fno-exceptions" else : fi fi lt_prog_compiler_wl= lt_prog_compiler_pic= lt_prog_compiler_static= if test "$GCC" = yes; then lt_prog_compiler_wl='-Wl,' lt_prog_compiler_static='-static' case $host_os in aix*) # All AIX code is PIC. if test "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor lt_prog_compiler_static='-Bstatic' fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support lt_prog_compiler_pic='-fPIC' ;; m68k) # FIXME: we need at least 68020 code to build shared libraries, but # adding the `-m68020' flag to GCC prevents building anything better, # like `-m68040'. lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4' ;; esac ;; beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) # PIC is the default for these OSes. ;; mingw* | cygwin* | pw32* | os2* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). # Although the cygwin gcc ignores -fPIC, still need this for old-style # (--disable-auto-import) libraries lt_prog_compiler_pic='-DDLL_EXPORT' ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files lt_prog_compiler_pic='-fno-common' ;; haiku*) # PIC is the default for Haiku. # The "-static" flag exists, but is broken. lt_prog_compiler_static= ;; hpux*) # PIC is the default for 64-bit PA HP-UX, but not for 32-bit # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag # sets the default TLS model and affects inlining. case $host_cpu in hppa*64*) # +Z the default ;; *) lt_prog_compiler_pic='-fPIC' ;; esac ;; interix[3-9]*) # Interix 3.x gcc -fpic/-fPIC options generate broken code. # Instead, we relocate shared libraries at runtime. ;; msdosdjgpp*) # Just because we use GCC doesn't mean we suddenly get shared libraries # on systems that don't support them. lt_prog_compiler_can_build_shared=no enable_shared=no ;; *nto* | *qnx*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. lt_prog_compiler_pic='-fPIC -shared' ;; sysv4*MP*) if test -d /usr/nec; then lt_prog_compiler_pic=-Kconform_pic fi ;; *) lt_prog_compiler_pic='-fPIC' ;; esac case $cc_basename in nvcc*) # Cuda Compiler Driver 2.2 lt_prog_compiler_wl='-Xlinker ' if test -n "$lt_prog_compiler_pic"; then lt_prog_compiler_pic="-Xcompiler $lt_prog_compiler_pic" fi ;; esac else # PORTME Check for flag to pass linker flags through the system compiler. case $host_os in aix*) lt_prog_compiler_wl='-Wl,' if test "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor lt_prog_compiler_static='-Bstatic' else lt_prog_compiler_static='-bnso -bI:/lib/syscalls.exp' fi ;; mingw* | cygwin* | pw32* | os2* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). lt_prog_compiler_pic='-DDLL_EXPORT' ;; hpux9* | hpux10* | hpux11*) lt_prog_compiler_wl='-Wl,' # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but # not for PA HP-UX. case $host_cpu in hppa*64*|ia64*) # +Z the default ;; *) lt_prog_compiler_pic='+Z' ;; esac # Is there a better lt_prog_compiler_static that works with the bundled CC? lt_prog_compiler_static='${wl}-a ${wl}archive' ;; irix5* | irix6* | nonstopux*) lt_prog_compiler_wl='-Wl,' # PIC (with -KPIC) is the default. lt_prog_compiler_static='-non_shared' ;; linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) case $cc_basename in # old Intel for x86_64 which still supported -KPIC. ecc*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-static' ;; # icc used to be incompatible with GCC. # ICC 10 doesn't accept -KPIC any more. icc* | ifort*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-fPIC' lt_prog_compiler_static='-static' ;; # Lahey Fortran 8.1. lf95*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='--shared' lt_prog_compiler_static='--static' ;; nagfor*) # NAG Fortran compiler lt_prog_compiler_wl='-Wl,-Wl,,' lt_prog_compiler_pic='-PIC' lt_prog_compiler_static='-Bstatic' ;; pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) # Portland Group compilers (*not* the Pentium gcc compiler, # which looks to be a dead project) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-fpic' lt_prog_compiler_static='-Bstatic' ;; ccc*) lt_prog_compiler_wl='-Wl,' # All Alpha code is PIC. lt_prog_compiler_static='-non_shared' ;; xl* | bgxl* | bgf* | mpixl*) # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-qpic' lt_prog_compiler_static='-qstaticlink' ;; *) case `$CC -V 2>&1 | sed 5q` in *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [1-7].* | *Sun*Fortran*\ 8.[0-3]*) # Sun Fortran 8.3 passes all unrecognized flags to the linker lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' lt_prog_compiler_wl='' ;; *Sun\ F* | *Sun*Fortran*) lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' lt_prog_compiler_wl='-Qoption ld ' ;; *Sun\ C*) # Sun C 5.9 lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' lt_prog_compiler_wl='-Wl,' ;; *Intel*\ [CF]*Compiler*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-fPIC' lt_prog_compiler_static='-static' ;; *Portland\ Group*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-fpic' lt_prog_compiler_static='-Bstatic' ;; esac ;; esac ;; newsos6) lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' ;; *nto* | *qnx*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. lt_prog_compiler_pic='-fPIC -shared' ;; osf3* | osf4* | osf5*) lt_prog_compiler_wl='-Wl,' # All OSF/1 code is PIC. lt_prog_compiler_static='-non_shared' ;; rdos*) lt_prog_compiler_static='-non_shared' ;; solaris*) lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' case $cc_basename in f77* | f90* | f95* | sunf77* | sunf90* | sunf95*) lt_prog_compiler_wl='-Qoption ld ';; *) lt_prog_compiler_wl='-Wl,';; esac ;; sunos4*) lt_prog_compiler_wl='-Qoption ld ' lt_prog_compiler_pic='-PIC' lt_prog_compiler_static='-Bstatic' ;; sysv4 | sysv4.2uw2* | sysv4.3*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' ;; sysv4*MP*) if test -d /usr/nec ;then lt_prog_compiler_pic='-Kconform_pic' lt_prog_compiler_static='-Bstatic' fi ;; sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' ;; unicos*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_can_build_shared=no ;; uts4*) lt_prog_compiler_pic='-pic' lt_prog_compiler_static='-Bstatic' ;; *) lt_prog_compiler_can_build_shared=no ;; esac fi case $host_os in # For platforms which do not support PIC, -DPIC is meaningless: *djgpp*) lt_prog_compiler_pic= ;; *) lt_prog_compiler_pic="$lt_prog_compiler_pic -DPIC" ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5 $as_echo_n "checking for $compiler option to produce PIC... " >&6; } if ${lt_cv_prog_compiler_pic+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_pic=$lt_prog_compiler_pic fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic" >&5 $as_echo "$lt_cv_prog_compiler_pic" >&6; } lt_prog_compiler_pic=$lt_cv_prog_compiler_pic # # Check to make sure the PIC flag actually works. # if test -n "$lt_prog_compiler_pic"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic works" >&5 $as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic works... " >&6; } if ${lt_cv_prog_compiler_pic_works+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_pic_works=no ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="$lt_prog_compiler_pic -DPIC" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. # The option is referenced via a variable to avoid confusing sed. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler_pic_works=yes fi fi $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works" >&5 $as_echo "$lt_cv_prog_compiler_pic_works" >&6; } if test x"$lt_cv_prog_compiler_pic_works" = xyes; then case $lt_prog_compiler_pic in "" | " "*) ;; *) lt_prog_compiler_pic=" $lt_prog_compiler_pic" ;; esac else lt_prog_compiler_pic= lt_prog_compiler_can_build_shared=no fi fi # # Check to make sure the static flag actually works. # wl=$lt_prog_compiler_wl eval lt_tmp_static_flag=\"$lt_prog_compiler_static\" { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5 $as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; } if ${lt_cv_prog_compiler_static_works+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_static_works=no save_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS $lt_tmp_static_flag" echo "$lt_simple_link_test_code" > conftest.$ac_ext if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then # The linker can only warn and ignore the option if not recognized # So say no if there are warnings if test -s conftest.err; then # Append any errors to the config.log. cat conftest.err 1>&5 $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler_static_works=yes fi else lt_cv_prog_compiler_static_works=yes fi fi $RM -r conftest* LDFLAGS="$save_LDFLAGS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works" >&5 $as_echo "$lt_cv_prog_compiler_static_works" >&6; } if test x"$lt_cv_prog_compiler_static_works" = xyes; then : else lt_prog_compiler_static= fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 $as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } if ${lt_cv_prog_compiler_c_o+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_c_o=no $RM -r conftest 2>/dev/null mkdir conftest cd conftest mkdir out echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-o out/conftest2.$ac_objext" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then lt_cv_prog_compiler_c_o=yes fi fi chmod u+w . 2>&5 $RM conftest* # SGI C++ compiler will create directory out/ii_files/ for # template instantiation test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files $RM out/* && rmdir out cd .. $RM -r conftest $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 $as_echo "$lt_cv_prog_compiler_c_o" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 $as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } if ${lt_cv_prog_compiler_c_o+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_c_o=no $RM -r conftest 2>/dev/null mkdir conftest cd conftest mkdir out echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-o out/conftest2.$ac_objext" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then lt_cv_prog_compiler_c_o=yes fi fi chmod u+w . 2>&5 $RM conftest* # SGI C++ compiler will create directory out/ii_files/ for # template instantiation test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files $RM out/* && rmdir out cd .. $RM -r conftest $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 $as_echo "$lt_cv_prog_compiler_c_o" >&6; } hard_links="nottested" if test "$lt_cv_prog_compiler_c_o" = no && test "$need_locks" != no; then # do not overwrite the value of need_locks provided by the user { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5 $as_echo_n "checking if we can lock with hard links... " >&6; } hard_links=yes $RM conftest* ln conftest.a conftest.b 2>/dev/null && hard_links=no touch conftest.a ln conftest.a conftest.b 2>&5 || hard_links=no ln conftest.a conftest.b 2>/dev/null && hard_links=no { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5 $as_echo "$hard_links" >&6; } if test "$hard_links" = no; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5 $as_echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;} need_locks=warn fi else need_locks=no fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 $as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } runpath_var= allow_undefined_flag= always_export_symbols=no archive_cmds= archive_expsym_cmds= compiler_needs_object=no enable_shared_with_static_runtimes=no export_dynamic_flag_spec= export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' hardcode_automatic=no hardcode_direct=no hardcode_direct_absolute=no hardcode_libdir_flag_spec= hardcode_libdir_separator= hardcode_minus_L=no hardcode_shlibpath_var=unsupported inherit_rpath=no link_all_deplibs=unknown module_cmds= module_expsym_cmds= old_archive_from_new_cmds= old_archive_from_expsyms_cmds= thread_safe_flag_spec= whole_archive_flag_spec= # include_expsyms should be a list of space-separated symbols to be *always* # included in the symbol list include_expsyms= # exclude_expsyms can be an extended regexp of symbols to exclude # it will be wrapped by ` (' and `)$', so one must not match beginning or # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', # as well as any symbol that contains `d'. exclude_expsyms='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*' # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out # platforms (ab)use it in PIC code, but their linkers get confused if # the symbol is explicitly referenced. Since portable code cannot # rely on this symbol name, it's probably fine to never include it in # preloaded symbol tables. # Exclude shared library initialization/finalization symbols. extract_expsyms_cmds= case $host_os in cygwin* | mingw* | pw32* | cegcc*) # FIXME: the MSVC++ port hasn't been tested in a loooong time # When not using gcc, we currently assume that we are using # Microsoft Visual C++. if test "$GCC" != yes; then with_gnu_ld=no fi ;; interix*) # we just hope/assume this is gcc and not c89 (= MSVC++) with_gnu_ld=yes ;; openbsd*) with_gnu_ld=no ;; linux* | k*bsd*-gnu | gnu*) link_all_deplibs=no ;; esac ld_shlibs=yes # On some targets, GNU ld is compatible enough with the native linker # that we're better off using the native interface for both. lt_use_gnu_ld_interface=no if test "$with_gnu_ld" = yes; then case $host_os in aix*) # The AIX port of GNU ld has always aspired to compatibility # with the native linker. However, as the warning in the GNU ld # block says, versions before 2.19.5* couldn't really create working # shared libraries, regardless of the interface used. case `$LD -v 2>&1` in *\ \(GNU\ Binutils\)\ 2.19.5*) ;; *\ \(GNU\ Binutils\)\ 2.[2-9]*) ;; *\ \(GNU\ Binutils\)\ [3-9]*) ;; *) lt_use_gnu_ld_interface=yes ;; esac ;; *) lt_use_gnu_ld_interface=yes ;; esac fi if test "$lt_use_gnu_ld_interface" = yes; then # If archive_cmds runs LD, not CC, wlarc should be empty wlarc='${wl}' # Set some defaults for GNU ld with shared library support. These # are reset later if shared libraries are not supported. Putting them # here allows them to be overridden if necessary. runpath_var=LD_RUN_PATH hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' export_dynamic_flag_spec='${wl}--export-dynamic' # ancient GNU ld didn't support --whole-archive et. al. if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then whole_archive_flag_spec="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' else whole_archive_flag_spec= fi supports_anon_versioning=no case `$LD -v 2>&1` in *GNU\ gold*) supports_anon_versioning=yes ;; *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11 *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... *\ 2.11.*) ;; # other 2.11 versions *) supports_anon_versioning=yes ;; esac # See if GNU ld supports shared libraries. case $host_os in aix[3-9]*) # On AIX/PPC, the GNU linker is very broken if test "$host_cpu" != ia64; then ld_shlibs=no cat <<_LT_EOF 1>&2 *** Warning: the GNU linker, at least up to release 2.19, is reported *** to be unable to reliably create shared libraries on AIX. *** Therefore, libtool is disabling shared libraries support. If you *** really care for shared libraries, you may want to install binutils *** 2.20 or above, or modify your PATH so that a non-GNU linker is found. *** You will then need to restart the configuration process. _LT_EOF fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds='' ;; m68k) archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' hardcode_libdir_flag_spec='-L$libdir' hardcode_minus_L=yes ;; esac ;; beos*) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then allow_undefined_flag=unsupported # Joseph Beckenbach <jrb3@best.com> says some releases of gcc # support --undefined. This deserves some investigation. FIXME archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' else ld_shlibs=no fi ;; cygwin* | mingw* | pw32* | cegcc*) # _LT_TAGVAR(hardcode_libdir_flag_spec, ) is actually meaningless, # as there is no search path for DLLs. hardcode_libdir_flag_spec='-L$libdir' export_dynamic_flag_spec='${wl}--export-all-symbols' allow_undefined_flag=unsupported always_export_symbols=no enable_shared_with_static_runtimes=yes export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols' exclude_expsyms='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname' if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' # If the export-symbols file already is a .def file (1st line # is EXPORTS), use it as is; otherwise, prepend... archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then cp $export_symbols $output_objdir/$soname.def; else echo EXPORTS > $output_objdir/$soname.def; cat $export_symbols >> $output_objdir/$soname.def; fi~ $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' else ld_shlibs=no fi ;; haiku*) archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' link_all_deplibs=yes ;; interix[3-9]*) hardcode_direct=no hardcode_shlibpath_var=no hardcode_libdir_flag_spec='${wl}-rpath,$libdir' export_dynamic_flag_spec='${wl}-E' # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. # Instead, shared libraries are loaded at an image base (0x10000000 by # default) and relocated if they conflict, which is a slow very memory # consuming and fragmenting process. To avoid this, we pick a random, # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link # time. Moving up from 0x10000000 also allows more sbrk(2) space. archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' archive_expsym_cmds='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ;; gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) tmp_diet=no if test "$host_os" = linux-dietlibc; then case $cc_basename in diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) esac fi if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ && test "$tmp_diet" = no then tmp_addflag=' $pic_flag' tmp_sharedflag='-shared' case $cc_basename,$host_cpu in pgcc*) # Portland Group C compiler whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' tmp_addflag=' $pic_flag' ;; pgf77* | pgf90* | pgf95* | pgfortran*) # Portland Group f77 and f90 compilers whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' tmp_addflag=' $pic_flag -Mnomain' ;; ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 tmp_addflag=' -i_dynamic' ;; efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 tmp_addflag=' -i_dynamic -nofor_main' ;; ifc* | ifort*) # Intel Fortran compiler tmp_addflag=' -nofor_main' ;; lf95*) # Lahey Fortran 8.1 whole_archive_flag_spec= tmp_sharedflag='--shared' ;; xl[cC]* | bgxl[cC]* | mpixl[cC]*) # IBM XL C 8.0 on PPC (deal with xlf below) tmp_sharedflag='-qmkshrobj' tmp_addflag= ;; nvcc*) # Cuda Compiler Driver 2.2 whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' compiler_needs_object=yes ;; esac case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C 5.9 whole_archive_flag_spec='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' compiler_needs_object=yes tmp_sharedflag='-G' ;; *Sun\ F*) # Sun Fortran 8.3 tmp_sharedflag='-G' ;; esac archive_cmds='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' if test "x$supports_anon_versioning" = xyes; then archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' fi case $cc_basename in xlf* | bgf* | bgxlf* | mpixlf*) # IBM XL Fortran 10.1 on PPC cannot create shared libs itself whole_archive_flag_spec='--whole-archive$convenience --no-whole-archive' hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib' if test "x$supports_anon_versioning" = xyes; then archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' fi ;; esac else ld_shlibs=no fi ;; netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' wlarc= else archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' fi ;; solaris*) if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then ld_shlibs=no cat <<_LT_EOF 1>&2 *** Warning: The releases 2.8.* of the GNU linker cannot reliably *** create shared libraries on Solaris systems. Therefore, libtool *** is disabling shared libraries support. We urge you to upgrade GNU *** binutils to release 2.9.1 or newer. Another option is to modify *** your PATH or compiler configuration so that the native linker is *** used, and then restart. _LT_EOF elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' else ld_shlibs=no fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) case `$LD -v 2>&1` in *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*) ld_shlibs=no cat <<_LT_EOF 1>&2 *** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not *** reliably create shared libraries on SCO systems. Therefore, libtool *** is disabling shared libraries support. We urge you to upgrade GNU *** binutils to release 2.16.91.0.3 or newer. Another option is to modify *** your PATH or compiler configuration so that the native linker is *** used, and then restart. _LT_EOF ;; *) # For security reasons, it is highly recommended that you always # use absolute paths for naming shared libraries, and exclude the # DT_RUNPATH tag from executables and libraries. But doing so # requires that you compile everything twice, which is a pain. if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' else ld_shlibs=no fi ;; esac ;; sunos4*) archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' wlarc= hardcode_direct=yes hardcode_shlibpath_var=no ;; *) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' else ld_shlibs=no fi ;; esac if test "$ld_shlibs" = no; then runpath_var= hardcode_libdir_flag_spec= export_dynamic_flag_spec= whole_archive_flag_spec= fi else # PORTME fill in a description of your system's linker (not GNU ld) case $host_os in aix3*) allow_undefined_flag=unsupported always_export_symbols=yes archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' # Note: this linker hardcodes the directories in LIBPATH if there # are no directories specified by -L. hardcode_minus_L=yes if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then # Neither direct hardcoding nor static linking is supported with a # broken collect2. hardcode_direct=unsupported fi ;; aix[4-9]*) if test "$host_cpu" = ia64; then # On IA64, the linker does run time linking by default, so we don't # have to do anything special. aix_use_runtimelinking=no exp_sym_flag='-Bexport' no_entry_flag="" else # If we're using GNU nm, then we don't want the "-C" option. # -C means demangle to AIX nm, but means don't demangle with GNU nm # Also, AIX nm treats weak defined symbols like other global # defined symbols, whereas GNU nm marks them as "W". if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' else export_symbols_cmds='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' fi aix_use_runtimelinking=no # Test if we are trying to use run time linking or normal # AIX style linking. If -brtl is somewhere in LDFLAGS, we # need to do runtime linking. case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) for ld_flag in $LDFLAGS; do if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then aix_use_runtimelinking=yes break fi done ;; esac exp_sym_flag='-bexport' no_entry_flag='-bnoentry' fi # When large executables or shared objects are built, AIX ld can # have problems creating the table of contents. If linking a library # or program results in "error TOC overflow" add -mminimal-toc to # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. archive_cmds='' hardcode_direct=yes hardcode_direct_absolute=yes hardcode_libdir_separator=':' link_all_deplibs=yes file_list_spec='${wl}-f,' if test "$GCC" = yes; then case $host_os in aix4.[012]|aix4.[012].*) # We only want to do this on AIX 4.2 and lower, the check # below for broken collect2 doesn't work under 4.3+ collect2name=`${CC} -print-prog-name=collect2` if test -f "$collect2name" && strings "$collect2name" | $GREP resolve_lib_name >/dev/null then # We have reworked collect2 : else # We have old collect2 hardcode_direct=unsupported # It fails to find uninstalled libraries when the uninstalled # path is not listed in the libpath. Setting hardcode_minus_L # to unsupported forces relinking hardcode_minus_L=yes hardcode_libdir_flag_spec='-L$libdir' hardcode_libdir_separator= fi ;; esac shared_flag='-shared' if test "$aix_use_runtimelinking" = yes; then shared_flag="$shared_flag "'${wl}-G' fi link_all_deplibs=no else # not using gcc if test "$host_cpu" = ia64; then # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release # chokes on -Wl,-G. The following line is correct: shared_flag='-G' else if test "$aix_use_runtimelinking" = yes; then shared_flag='${wl}-G' else shared_flag='${wl}-bM:SRE' fi fi fi export_dynamic_flag_spec='${wl}-bexpall' # It seems that -bexpall does not export symbols beginning with # underscore (_), so it is better to generate a list of symbols to export. always_export_symbols=yes if test "$aix_use_runtimelinking" = yes; then # Warning - without using the other runtime loading flags (-brtl), # -berok will link without error, but may produce a broken library. allow_undefined_flag='-berok' # Determine the default libpath from the value encoded in an # empty executable. if test "${lt_cv_aix_libpath+set}" = set; then aix_libpath=$lt_cv_aix_libpath else if ${lt_cv_aix_libpath_+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : lt_aix_libpath_sed=' /Import File Strings/,/^$/ { /^0/ { s/^0 *\([^ ]*\) *$/\1/ p } }' lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` # Check for a 64-bit object if we didn't find anything. if test -z "$lt_cv_aix_libpath_"; then lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` fi fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext if test -z "$lt_cv_aix_libpath_"; then lt_cv_aix_libpath_="/usr/lib:/lib" fi fi aix_libpath=$lt_cv_aix_libpath_ fi hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" archive_expsym_cmds='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" else if test "$host_cpu" = ia64; then hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib' allow_undefined_flag="-z nodefs" archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" else # Determine the default libpath from the value encoded in an # empty executable. if test "${lt_cv_aix_libpath+set}" = set; then aix_libpath=$lt_cv_aix_libpath else if ${lt_cv_aix_libpath_+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : lt_aix_libpath_sed=' /Import File Strings/,/^$/ { /^0/ { s/^0 *\([^ ]*\) *$/\1/ p } }' lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` # Check for a 64-bit object if we didn't find anything. if test -z "$lt_cv_aix_libpath_"; then lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` fi fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext if test -z "$lt_cv_aix_libpath_"; then lt_cv_aix_libpath_="/usr/lib:/lib" fi fi aix_libpath=$lt_cv_aix_libpath_ fi hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" # Warning - without using the other run time loading flags, # -berok will link without error, but may produce a broken library. no_undefined_flag=' ${wl}-bernotok' allow_undefined_flag=' ${wl}-berok' if test "$with_gnu_ld" = yes; then # We only use this code for GNU lds that support --whole-archive. whole_archive_flag_spec='${wl}--whole-archive$convenience ${wl}--no-whole-archive' else # Exported symbols can be pulled into shared objects from archives whole_archive_flag_spec='$convenience' fi archive_cmds_need_lc=yes # This is similar to how AIX traditionally builds its shared libraries. archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' fi fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds='' ;; m68k) archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' hardcode_libdir_flag_spec='-L$libdir' hardcode_minus_L=yes ;; esac ;; bsdi[45]*) export_dynamic_flag_spec=-rdynamic ;; cygwin* | mingw* | pw32* | cegcc*) # When not using gcc, we currently assume that we are using # Microsoft Visual C++. # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. case $cc_basename in cl*) # Native MSVC hardcode_libdir_flag_spec=' ' allow_undefined_flag=unsupported always_export_symbols=yes file_list_spec='@' # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=".dll" # FIXME: Setting linknames here is a bad hack. archive_cmds='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames=' archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then sed -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp; else sed -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp; fi~ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ linknames=' # The linker will not automatically build a static lib if we build a DLL. # _LT_TAGVAR(old_archive_from_new_cmds, )='true' enable_shared_with_static_runtimes=yes exclude_expsyms='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1,DATA/'\'' | $SED -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols' # Don't use ranlib old_postinstall_cmds='chmod 644 $oldlib' postlink_cmds='lt_outputfile="@OUTPUT@"~ lt_tool_outputfile="@TOOL_OUTPUT@"~ case $lt_outputfile in *.exe|*.EXE) ;; *) lt_outputfile="$lt_outputfile.exe" lt_tool_outputfile="$lt_tool_outputfile.exe" ;; esac~ if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; $RM "$lt_outputfile.manifest"; fi' ;; *) # Assume MSVC wrapper hardcode_libdir_flag_spec=' ' allow_undefined_flag=unsupported # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=".dll" # FIXME: Setting linknames here is a bad hack. archive_cmds='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames=' # The linker will automatically build a .lib file if we build a DLL. old_archive_from_new_cmds='true' # FIXME: Should let the user specify the lib program. old_archive_cmds='lib -OUT:$oldlib$oldobjs$old_deplibs' enable_shared_with_static_runtimes=yes ;; esac ;; darwin* | rhapsody*) archive_cmds_need_lc=no hardcode_direct=no hardcode_automatic=yes hardcode_shlibpath_var=unsupported if test "$lt_cv_ld_force_load" = "yes"; then whole_archive_flag_spec='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' else whole_archive_flag_spec='' fi link_all_deplibs=yes allow_undefined_flag="$_lt_dar_allow_undefined" case $cc_basename in ifort*) _lt_dar_can_shared=yes ;; *) _lt_dar_can_shared=$GCC ;; esac if test "$_lt_dar_can_shared" = "yes"; then output_verbose_link_cmd=func_echo_all archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" else ld_shlibs=no fi ;; dgux*) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_libdir_flag_spec='-L$libdir' hardcode_shlibpath_var=no ;; # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor # support. Future versions do this automatically, but an explicit c++rt0.o # does not break anything, and helps significantly (at the cost of a little # extra space). freebsd2.2*) archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' hardcode_libdir_flag_spec='-R$libdir' hardcode_direct=yes hardcode_shlibpath_var=no ;; # Unfortunately, older versions of FreeBSD 2 do not have this feature. freebsd2.*) archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' hardcode_direct=yes hardcode_minus_L=yes hardcode_shlibpath_var=no ;; # FreeBSD 3 and greater uses gcc -shared to do shared libraries. freebsd* | dragonfly*) archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' hardcode_libdir_flag_spec='-R$libdir' hardcode_direct=yes hardcode_shlibpath_var=no ;; hpux9*) if test "$GCC" = yes; then archive_cmds='$RM $output_objdir/$soname~$CC -shared $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' else archive_cmds='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' fi hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' hardcode_libdir_separator=: hardcode_direct=yes # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. hardcode_minus_L=yes export_dynamic_flag_spec='${wl}-E' ;; hpux10*) if test "$GCC" = yes && test "$with_gnu_ld" = no; then archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' fi if test "$with_gnu_ld" = no; then hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' hardcode_libdir_separator=: hardcode_direct=yes hardcode_direct_absolute=yes export_dynamic_flag_spec='${wl}-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. hardcode_minus_L=yes fi ;; hpux11*) if test "$GCC" = yes && test "$with_gnu_ld" = no; then case $host_cpu in hppa*64*) archive_cmds='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' ;; esac else case $host_cpu in hppa*64*) archive_cmds='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) # Older versions of the 11.00 compiler do not understand -b yet # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does) { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC understands -b" >&5 $as_echo_n "checking if $CC understands -b... " >&6; } if ${lt_cv_prog_compiler__b+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler__b=no save_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS -b" echo "$lt_simple_link_test_code" > conftest.$ac_ext if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then # The linker can only warn and ignore the option if not recognized # So say no if there are warnings if test -s conftest.err; then # Append any errors to the config.log. cat conftest.err 1>&5 $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler__b=yes fi else lt_cv_prog_compiler__b=yes fi fi $RM -r conftest* LDFLAGS="$save_LDFLAGS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler__b" >&5 $as_echo "$lt_cv_prog_compiler__b" >&6; } if test x"$lt_cv_prog_compiler__b" = xyes; then archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' fi ;; esac fi if test "$with_gnu_ld" = no; then hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' hardcode_libdir_separator=: case $host_cpu in hppa*64*|ia64*) hardcode_direct=no hardcode_shlibpath_var=no ;; *) hardcode_direct=yes hardcode_direct_absolute=yes export_dynamic_flag_spec='${wl}-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. hardcode_minus_L=yes ;; esac fi ;; irix5* | irix6* | nonstopux*) if test "$GCC" = yes; then archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' # Try to use the -exported_symbol ld option, if it does not # work, assume that -exports_file does not work either and # implicitly export all symbols. # This should be the same for all languages, so no per-tag cache variable. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $host_os linker accepts -exported_symbol" >&5 $as_echo_n "checking whether the $host_os linker accepts -exported_symbol... " >&6; } if ${lt_cv_irix_exported_symbol+:} false; then : $as_echo_n "(cached) " >&6 else save_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int foo (void) { return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : lt_cv_irix_exported_symbol=yes else lt_cv_irix_exported_symbol=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LDFLAGS="$save_LDFLAGS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_irix_exported_symbol" >&5 $as_echo "$lt_cv_irix_exported_symbol" >&6; } if test "$lt_cv_irix_exported_symbol" = yes; then archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib' fi else archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib' fi archive_cmds_need_lc='no' hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' hardcode_libdir_separator=: inherit_rpath=yes link_all_deplibs=yes ;; netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out else archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF fi hardcode_libdir_flag_spec='-R$libdir' hardcode_direct=yes hardcode_shlibpath_var=no ;; newsos6) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_direct=yes hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' hardcode_libdir_separator=: hardcode_shlibpath_var=no ;; *nto* | *qnx*) ;; openbsd*) if test -f /usr/libexec/ld.so; then hardcode_direct=yes hardcode_shlibpath_var=no hardcode_direct_absolute=yes if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' hardcode_libdir_flag_spec='${wl}-rpath,$libdir' export_dynamic_flag_spec='${wl}-E' else case $host_os in openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*) archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' hardcode_libdir_flag_spec='-R$libdir' ;; *) archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' hardcode_libdir_flag_spec='${wl}-rpath,$libdir' ;; esac fi else ld_shlibs=no fi ;; os2*) hardcode_libdir_flag_spec='-L$libdir' hardcode_minus_L=yes allow_undefined_flag=unsupported archive_cmds='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~echo DATA >> $output_objdir/$libname.def~echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' old_archive_from_new_cmds='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' ;; osf3*) if test "$GCC" = yes; then allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' else allow_undefined_flag=' -expect_unresolved \*' archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' fi archive_cmds_need_lc='no' hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' hardcode_libdir_separator=: ;; osf4* | osf5*) # as osf3* with the addition of -msym flag if test "$GCC" = yes; then allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' archive_cmds='$CC -shared${allow_undefined_flag} $pic_flag $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' else allow_undefined_flag=' -expect_unresolved \*' archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' archive_expsym_cmds='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp' # Both c and cxx compiler support -rpath directly hardcode_libdir_flag_spec='-rpath $libdir' fi archive_cmds_need_lc='no' hardcode_libdir_separator=: ;; solaris*) no_undefined_flag=' -z defs' if test "$GCC" = yes; then wlarc='${wl}' archive_cmds='$CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' else case `$CC -V 2>&1` in *"Compilers 5.0"*) wlarc='' archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' ;; *) wlarc='${wl}' archive_cmds='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' ;; esac fi hardcode_libdir_flag_spec='-R$libdir' hardcode_shlibpath_var=no case $host_os in solaris2.[0-5] | solaris2.[0-5].*) ;; *) # The compiler driver will combine and reorder linker options, # but understands `-z linker_flag'. GCC discards it without `$wl', # but is careful enough not to reorder. # Supported since Solaris 2.6 (maybe 2.5.1?) if test "$GCC" = yes; then whole_archive_flag_spec='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' else whole_archive_flag_spec='-z allextract$convenience -z defaultextract' fi ;; esac link_all_deplibs=yes ;; sunos4*) if test "x$host_vendor" = xsequent; then # Use $CC to link under sequent, because it throws in some extra .o # files that make .init and .fini sections work. archive_cmds='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' fi hardcode_libdir_flag_spec='-L$libdir' hardcode_direct=yes hardcode_minus_L=yes hardcode_shlibpath_var=no ;; sysv4) case $host_vendor in sni) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_direct=yes # is this really true??? ;; siemens) ## LD is ld it makes a PLAMLIB ## CC just makes a GrossModule. archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags' reload_cmds='$CC -r -o $output$reload_objs' hardcode_direct=no ;; motorola) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_direct=no #Motorola manual says yes, but my tests say they lie ;; esac runpath_var='LD_RUN_PATH' hardcode_shlibpath_var=no ;; sysv4.3*) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_shlibpath_var=no export_dynamic_flag_spec='-Bexport' ;; sysv4*MP*) if test -d /usr/nec; then archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_shlibpath_var=no runpath_var=LD_RUN_PATH hardcode_runpath_var=yes ld_shlibs=yes fi ;; sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) no_undefined_flag='${wl}-z,text' archive_cmds_need_lc=no hardcode_shlibpath_var=no runpath_var='LD_RUN_PATH' if test "$GCC" = yes; then archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; sysv5* | sco3.2v5* | sco5v6*) # Note: We can NOT use -z defs as we might desire, because we do not # link with -lc, and that would cause any symbols used from libc to # always be unresolved, which means just about no library would # ever link correctly. If we're not using GNU ld we use -z text # though, which does catch some bad symbols but isn't as heavy-handed # as -z defs. no_undefined_flag='${wl}-z,text' allow_undefined_flag='${wl}-z,nodefs' archive_cmds_need_lc=no hardcode_shlibpath_var=no hardcode_libdir_flag_spec='${wl}-R,$libdir' hardcode_libdir_separator=':' link_all_deplibs=yes export_dynamic_flag_spec='${wl}-Bexport' runpath_var='LD_RUN_PATH' if test "$GCC" = yes; then archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; uts4*) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_libdir_flag_spec='-L$libdir' hardcode_shlibpath_var=no ;; *) ld_shlibs=no ;; esac if test x$host_vendor = xsni; then case $host in sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) export_dynamic_flag_spec='${wl}-Blargedynsym' ;; esac fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs" >&5 $as_echo "$ld_shlibs" >&6; } test "$ld_shlibs" = no && can_build_shared=no with_gnu_ld=$with_gnu_ld # # Do we need to explicitly link libc? # case "x$archive_cmds_need_lc" in x|xyes) # Assume -lc should be added archive_cmds_need_lc=yes if test "$enable_shared" = yes && test "$GCC" = yes; then case $archive_cmds in *'~'*) # FIXME: we may have to deal with multi-command sequences. ;; '$CC '*) # Test whether the compiler implicitly links with -lc since on some # systems, -lgcc has to come before -lc. If gcc already passes -lc # to ld, don't add -lc before -lgcc. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5 $as_echo_n "checking whether -lc should be explicitly linked in... " >&6; } if ${lt_cv_archive_cmds_need_lc+:} false; then : $as_echo_n "(cached) " >&6 else $RM conftest* echo "$lt_simple_compile_test_code" > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } 2>conftest.err; then soname=conftest lib=conftest libobjs=conftest.$ac_objext deplibs= wl=$lt_prog_compiler_wl pic_flag=$lt_prog_compiler_pic compiler_flags=-v linker_flags=-v verstring= output_objdir=. libname=conftest lt_save_allow_undefined_flag=$allow_undefined_flag allow_undefined_flag= if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5 (eval $archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } then lt_cv_archive_cmds_need_lc=no else lt_cv_archive_cmds_need_lc=yes fi allow_undefined_flag=$lt_save_allow_undefined_flag else cat conftest.err 1>&5 fi $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc" >&5 $as_echo "$lt_cv_archive_cmds_need_lc" >&6; } archive_cmds_need_lc=$lt_cv_archive_cmds_need_lc ;; esac fi ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5 $as_echo_n "checking dynamic linker characteristics... " >&6; } if test "$GCC" = yes; then case $host_os in darwin*) lt_awk_arg="/^libraries:/,/LR/" ;; *) lt_awk_arg="/^libraries:/" ;; esac case $host_os in mingw* | cegcc*) lt_sed_strip_eq="s,=\([A-Za-z]:\),\1,g" ;; *) lt_sed_strip_eq="s,=/,/,g" ;; esac lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq` case $lt_search_path_spec in *\;*) # if the path contains ";" then we assume it to be the separator # otherwise default to the standard path separator (i.e. ":") - it is # assumed that no part of a normal pathname contains ";" but that should # okay in the real world where ";" in dirpaths is itself problematic. lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'` ;; *) lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"` ;; esac # Ok, now we have the path, separated by spaces, we can step through it # and add multilib dir if necessary. lt_tmp_lt_search_path_spec= lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` for lt_sys_path in $lt_search_path_spec; do if test -d "$lt_sys_path/$lt_multi_os_dir"; then lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir" else test -d "$lt_sys_path" && \ lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" fi done lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk ' BEGIN {RS=" "; FS="/|\n";} { lt_foo=""; lt_count=0; for (lt_i = NF; lt_i > 0; lt_i--) { if ($lt_i != "" && $lt_i != ".") { if ($lt_i == "..") { lt_count++; } else { if (lt_count == 0) { lt_foo="/" $lt_i lt_foo; } else { lt_count--; } } } } if (lt_foo != "") { lt_freq[lt_foo]++; } if (lt_freq[lt_foo] == 1) { print lt_foo; } }'` # AWK program above erroneously prepends '/' to C:/dos/paths # for these hosts. case $host_os in mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ $SED 's,/\([A-Za-z]:\),\1,g'` ;; esac sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP` else sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" fi library_names_spec= libname_spec='lib$name' soname_spec= shrext_cmds=".so" postinstall_cmds= postuninstall_cmds= finish_cmds= finish_eval= shlibpath_var= shlibpath_overrides_runpath=unknown version_type=none dynamic_linker="$host_os ld.so" sys_lib_dlsearch_path_spec="/lib /usr/lib" need_lib_prefix=unknown hardcode_into_libs=no # when you set need_version to no, make sure it does not cause -set_version # flags to be left without arguments need_version=unknown case $host_os in aix3*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' shlibpath_var=LIBPATH # AIX 3 has no versioning support, so we append a major version to the name. soname_spec='${libname}${release}${shared_ext}$major' ;; aix[4-9]*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no hardcode_into_libs=yes if test "$host_cpu" = ia64; then # AIX 5 supports IA64 library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH else # With GCC up to 2.95.x, collect2 would create an import file # for dependence libraries. The import file would start with # the line `#! .'. This would cause the generated library to # depend on `.', always an invalid library. This was fixed in # development snapshots of GCC prior to 3.0. case $host_os in aix4 | aix4.[01] | aix4.[01].*) if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' echo ' yes ' echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then : else can_build_shared=no fi ;; esac # AIX (on Power*) has no versioning support, so currently we can not hardcode correct # soname into executable. Probably we can add versioning support to # collect2, so additional links can be useful in future. if test "$aix_use_runtimelinking" = yes; then # If using run time linking (on AIX 4.2 or later) use lib<name>.so # instead of lib<name>.a to let people know that these are not # typical AIX shared libraries. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' else # We preserve .a as extension for shared libraries through AIX4.2 # and later when we are not doing run time linking. library_names_spec='${libname}${release}.a $libname.a' soname_spec='${libname}${release}${shared_ext}$major' fi shlibpath_var=LIBPATH fi ;; amigaos*) case $host_cpu in powerpc) # Since July 2007 AmigaOS4 officially supports .so libraries. # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ;; m68k) library_names_spec='$libname.ixlibrary $libname.a' # Create ${libname}_ixlibrary.a entries in /sys/libs. finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' ;; esac ;; beos*) library_names_spec='${libname}${shared_ext}' dynamic_linker="$host_os ld.so" shlibpath_var=LIBRARY_PATH ;; bsdi[45]*) version_type=linux # correct to gnu/linux during the next big refactor need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" # the default ld.so.conf also contains /usr/contrib/lib and # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow # libtool to hard-code these into programs ;; cygwin* | mingw* | pw32* | cegcc*) version_type=windows shrext_cmds=".dll" need_version=no need_lib_prefix=no case $GCC,$cc_basename in yes,*) # gcc library_names_spec='$libname.dll.a' # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \${file}`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname~ chmod a+x \$dldir/$dlname~ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; fi' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' shlibpath_overrides_runpath=yes case $host_os in cygwin*) # Cygwin DLLs use 'cyg' prefix rather than 'lib' soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api" ;; mingw* | cegcc*) # MinGW DLLs use traditional 'lib' prefix soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' ;; pw32*) # pw32 DLLs use 'pw' prefix rather than 'lib' library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' ;; esac dynamic_linker='Win32 ld.exe' ;; *,cl*) # Native MSVC libname_spec='$name' soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' library_names_spec='${libname}.dll.lib' case $build_os in mingw*) sys_lib_search_path_spec= lt_save_ifs=$IFS IFS=';' for lt_path in $LIB do IFS=$lt_save_ifs # Let DOS variable expansion print the short 8.3 style file name. lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" done IFS=$lt_save_ifs # Convert to MSYS style. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'` ;; cygwin*) # Convert to unix form, then to dos form, then back to unix form # but this time dos style (no spaces!) so that the unix form looks # like /cygdrive/c/PROGRA~1:/cygdr... sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` ;; *) sys_lib_search_path_spec="$LIB" if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then # It is most probably a Windows format PATH. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` else sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` fi # FIXME: find the short name or the path components, as spaces are # common. (e.g. "Program Files" -> "PROGRA~1") ;; esac # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \${file}`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' shlibpath_overrides_runpath=yes dynamic_linker='Win32 link.exe' ;; *) # Assume MSVC wrapper library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib' dynamic_linker='Win32 ld.exe' ;; esac # FIXME: first we should search . and the directory the executable is in shlibpath_var=PATH ;; darwin* | rhapsody*) dynamic_linker="$host_os dyld" version_type=darwin need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext' soname_spec='${libname}${release}${major}$shared_ext' shlibpath_overrides_runpath=yes shlibpath_var=DYLD_LIBRARY_PATH shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib" sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' ;; dgux*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH ;; freebsd* | dragonfly*) # DragonFly does not have aout. When/if they implement a new # versioning mechanism, adjust this. if test -x /usr/bin/objformat; then objformat=`/usr/bin/objformat` else case $host_os in freebsd[23].*) objformat=aout ;; *) objformat=elf ;; esac fi version_type=freebsd-$objformat case $version_type in freebsd-elf*) library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' need_version=no need_lib_prefix=no ;; freebsd-*) library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' need_version=yes ;; esac shlibpath_var=LD_LIBRARY_PATH case $host_os in freebsd2.*) shlibpath_overrides_runpath=yes ;; freebsd3.[01]* | freebsdelf3.[01]*) shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; *) # from 4.6 on, and DragonFly shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; esac ;; haiku*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no dynamic_linker="$host_os runtime_loader" library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LIBRARY_PATH shlibpath_overrides_runpath=yes sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' hardcode_into_libs=yes ;; hpux9* | hpux10* | hpux11*) # Give a soname corresponding to the major version so that dld.sl refuses to # link against other versions. version_type=sunos need_lib_prefix=no need_version=no case $host_cpu in ia64*) shrext_cmds='.so' hardcode_into_libs=yes dynamic_linker="$host_os dld.so" shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' if test "X$HPUX_IA64_MODE" = X32; then sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" else sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" fi sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; hppa*64*) shrext_cmds='.sl' hardcode_into_libs=yes dynamic_linker="$host_os dld.sl" shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; *) shrext_cmds='.sl' dynamic_linker="$host_os dld.sl" shlibpath_var=SHLIB_PATH shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' ;; esac # HP-UX runs *really* slowly unless shared libraries are mode 555, ... postinstall_cmds='chmod 555 $lib' # or fails outright, so override atomically: install_override_mode=555 ;; interix[3-9]*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; irix5* | irix6* | nonstopux*) case $host_os in nonstopux*) version_type=nonstopux ;; *) if test "$lt_cv_prog_gnu_ld" = yes; then version_type=linux # correct to gnu/linux during the next big refactor else version_type=irix fi ;; esac need_lib_prefix=no need_version=no soname_spec='${libname}${release}${shared_ext}$major' library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' case $host_os in irix5* | nonstopux*) libsuff= shlibsuff= ;; *) case $LD in # libtool.m4 will add one of these switches to LD *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") libsuff= shlibsuff= libmagic=32-bit;; *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") libsuff=32 shlibsuff=N32 libmagic=N32;; *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") libsuff=64 shlibsuff=64 libmagic=64-bit;; *) libsuff= shlibsuff= libmagic=never-match;; esac ;; esac shlibpath_var=LD_LIBRARY${shlibsuff}_PATH shlibpath_overrides_runpath=no sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" hardcode_into_libs=yes ;; # No shared lib support for Linux oldld, aout, or coff. linux*oldld* | linux*aout* | linux*coff*) dynamic_linker=no ;; # This must be glibc/ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no # Some binutils ld are patched to set DT_RUNPATH if ${lt_cv_shlibpath_overrides_runpath+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_shlibpath_overrides_runpath=no save_LDFLAGS=$LDFLAGS save_libdir=$libdir eval "libdir=/foo; wl=\"$lt_prog_compiler_wl\"; \ LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec\"" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then : lt_cv_shlibpath_overrides_runpath=yes fi fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LDFLAGS=$save_LDFLAGS libdir=$save_libdir fi shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath # This implies no fast_install, which is unacceptable. # Some rework will be needed to allow for fast_install # before this can be enabled. hardcode_into_libs=yes # Append ld.so.conf contents to the search path if test -f /etc/ld.so.conf; then lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" fi # We used to test for /lib/ld.so.1 and disable shared libraries on # powerpc, because MkLinux only supported shared libraries with the # GNU dynamic linker. Since this was broken with cross compilers, # most powerpc-linux boxes support dynamic linking these days and # people can always --disable-shared, the test was removed, and we # assume the GNU/Linux dynamic linker is in use. dynamic_linker='GNU/Linux ld.so' ;; netbsdelf*-gnu) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='NetBSD ld.elf_so' ;; netbsd*) # ts B51007 : changed version_type for lt_main.sh from "sunos" to "netbsd" version_type=netbsd need_lib_prefix=no need_version=no if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' dynamic_linker='NetBSD (a.out) ld.so' else library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' dynamic_linker='NetBSD ld.elf_so' fi shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; newsos6) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes ;; *nto* | *qnx*) version_type=qnx need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='ldqnx.so' ;; openbsd*) version_type=sunos sys_lib_dlsearch_path_spec="/usr/lib" need_lib_prefix=no # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. case $host_os in openbsd3.3 | openbsd3.3.*) need_version=yes ;; *) need_version=no ;; esac library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' shlibpath_var=LD_LIBRARY_PATH if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then case $host_os in openbsd2.[89] | openbsd2.[89].*) shlibpath_overrides_runpath=no ;; *) shlibpath_overrides_runpath=yes ;; esac else shlibpath_overrides_runpath=yes fi ;; os2*) libname_spec='$name' shrext_cmds=".dll" need_lib_prefix=no library_names_spec='$libname${shared_ext} $libname.a' dynamic_linker='OS/2 ld.exe' shlibpath_var=LIBPATH ;; osf3* | osf4* | osf5*) version_type=osf need_lib_prefix=no need_version=no soname_spec='${libname}${release}${shared_ext}$major' library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" ;; rdos*) dynamic_linker=no ;; solaris*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes # ldd complains unless libraries are executable postinstall_cmds='chmod +x $lib' ;; sunos4*) version_type=sunos library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes if test "$with_gnu_ld" = yes; then need_lib_prefix=no fi need_version=yes ;; sysv4 | sysv4.3*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH case $host_vendor in sni) shlibpath_overrides_runpath=no need_lib_prefix=no runpath_var=LD_RUN_PATH ;; siemens) need_lib_prefix=no ;; motorola) need_lib_prefix=no need_version=no shlibpath_overrides_runpath=no sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' ;; esac ;; sysv4*MP*) if test -d /usr/nec ;then version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' soname_spec='$libname${shared_ext}.$major' shlibpath_var=LD_LIBRARY_PATH fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) version_type=freebsd-elf need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes if test "$with_gnu_ld" = yes; then sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' else sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' case $host_os in sco3.2v5*) sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" ;; esac fi sys_lib_dlsearch_path_spec='/usr/lib' ;; tpf*) # TPF is a cross-target only. Preferred cross-host = GNU/Linux. version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; uts4*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH ;; *) dynamic_linker=no ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5 $as_echo "$dynamic_linker" >&6; } test "$dynamic_linker" = no && can_build_shared=no variables_saved_for_relink="PATH $shlibpath_var $runpath_var" if test "$GCC" = yes; then variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" fi if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec" fi if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5 $as_echo_n "checking how to hardcode library paths into programs... " >&6; } hardcode_action= if test -n "$hardcode_libdir_flag_spec" || test -n "$runpath_var" || test "X$hardcode_automatic" = "Xyes" ; then # We can hardcode non-existent directories. if test "$hardcode_direct" != no && # If the only mechanism to avoid hardcoding is shlibpath_var, we # have to relink, otherwise we might link with an installed library # when we should be linking with a yet-to-be-installed one ## test "$_LT_TAGVAR(hardcode_shlibpath_var, )" != no && test "$hardcode_minus_L" != no; then # Linking always hardcodes the temporary library directory. hardcode_action=relink else # We can link without hardcoding, and we can hardcode nonexisting dirs. hardcode_action=immediate fi else # We cannot hardcode anything, or else we can only hardcode existing # directories. hardcode_action=unsupported fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action" >&5 $as_echo "$hardcode_action" >&6; } if test "$hardcode_action" = relink || test "$inherit_rpath" = yes; then # Fast installation is not supported enable_fast_install=no elif test "$shlibpath_overrides_runpath" = yes || test "$enable_shared" = no; then # Fast installation is not necessary enable_fast_install=needless fi if test "x$enable_dlopen" != xyes; then enable_dlopen=unknown enable_dlopen_self=unknown enable_dlopen_self_static=unknown else lt_cv_dlopen=no lt_cv_dlopen_libs= case $host_os in beos*) lt_cv_dlopen="load_add_on" lt_cv_dlopen_libs= lt_cv_dlopen_self=yes ;; mingw* | pw32* | cegcc*) lt_cv_dlopen="LoadLibrary" lt_cv_dlopen_libs= ;; cygwin*) lt_cv_dlopen="dlopen" lt_cv_dlopen_libs= ;; darwin*) # if libdl is installed we need to link against it { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 $as_echo_n "checking for dlopen in -ldl... " >&6; } if ${ac_cv_lib_dl_dlopen+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldl $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dlopen (); int main () { return dlopen (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_dl_dlopen=yes else ac_cv_lib_dl_dlopen=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 $as_echo "$ac_cv_lib_dl_dlopen" >&6; } if test "x$ac_cv_lib_dl_dlopen" = xyes; then : lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" else lt_cv_dlopen="dyld" lt_cv_dlopen_libs= lt_cv_dlopen_self=yes fi ;; *) ac_fn_c_check_func "$LINENO" "shl_load" "ac_cv_func_shl_load" if test "x$ac_cv_func_shl_load" = xyes; then : lt_cv_dlopen="shl_load" else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shl_load in -ldld" >&5 $as_echo_n "checking for shl_load in -ldld... " >&6; } if ${ac_cv_lib_dld_shl_load+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldld $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char shl_load (); int main () { return shl_load (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_dld_shl_load=yes else ac_cv_lib_dld_shl_load=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_shl_load" >&5 $as_echo "$ac_cv_lib_dld_shl_load" >&6; } if test "x$ac_cv_lib_dld_shl_load" = xyes; then : lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld" else ac_fn_c_check_func "$LINENO" "dlopen" "ac_cv_func_dlopen" if test "x$ac_cv_func_dlopen" = xyes; then : lt_cv_dlopen="dlopen" else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 $as_echo_n "checking for dlopen in -ldl... " >&6; } if ${ac_cv_lib_dl_dlopen+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldl $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dlopen (); int main () { return dlopen (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_dl_dlopen=yes else ac_cv_lib_dl_dlopen=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 $as_echo "$ac_cv_lib_dl_dlopen" >&6; } if test "x$ac_cv_lib_dl_dlopen" = xyes; then : lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -lsvld" >&5 $as_echo_n "checking for dlopen in -lsvld... " >&6; } if ${ac_cv_lib_svld_dlopen+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lsvld $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dlopen (); int main () { return dlopen (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_svld_dlopen=yes else ac_cv_lib_svld_dlopen=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_svld_dlopen" >&5 $as_echo "$ac_cv_lib_svld_dlopen" >&6; } if test "x$ac_cv_lib_svld_dlopen" = xyes; then : lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld" else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dld_link in -ldld" >&5 $as_echo_n "checking for dld_link in -ldld... " >&6; } if ${ac_cv_lib_dld_dld_link+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldld $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dld_link (); int main () { return dld_link (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_dld_dld_link=yes else ac_cv_lib_dld_dld_link=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_dld_link" >&5 $as_echo "$ac_cv_lib_dld_dld_link" >&6; } if test "x$ac_cv_lib_dld_dld_link" = xyes; then : lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld" fi fi fi fi fi fi ;; esac if test "x$lt_cv_dlopen" != xno; then enable_dlopen=yes else enable_dlopen=no fi case $lt_cv_dlopen in dlopen) save_CPPFLAGS="$CPPFLAGS" test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" save_LDFLAGS="$LDFLAGS" wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" save_LIBS="$LIBS" LIBS="$lt_cv_dlopen_libs $LIBS" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a program can dlopen itself" >&5 $as_echo_n "checking whether a program can dlopen itself... " >&6; } if ${lt_cv_dlopen_self+:} false; then : $as_echo_n "(cached) " >&6 else if test "$cross_compiling" = yes; then : lt_cv_dlopen_self=cross else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF #line $LINENO "configure" #include "confdefs.h" #if HAVE_DLFCN_H #include <dlfcn.h> #endif #include <stdio.h> #ifdef RTLD_GLOBAL # define LT_DLGLOBAL RTLD_GLOBAL #else # ifdef DL_GLOBAL # define LT_DLGLOBAL DL_GLOBAL # else # define LT_DLGLOBAL 0 # endif #endif /* We may have to define LT_DLLAZY_OR_NOW in the command line if we find out it does not work in some platform. */ #ifndef LT_DLLAZY_OR_NOW # ifdef RTLD_LAZY # define LT_DLLAZY_OR_NOW RTLD_LAZY # else # ifdef DL_LAZY # define LT_DLLAZY_OR_NOW DL_LAZY # else # ifdef RTLD_NOW # define LT_DLLAZY_OR_NOW RTLD_NOW # else # ifdef DL_NOW # define LT_DLLAZY_OR_NOW DL_NOW # else # define LT_DLLAZY_OR_NOW 0 # endif # endif # endif # endif #endif /* When -fvisbility=hidden is used, assume the code has been annotated correspondingly for the symbols needed. */ #if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) int fnord () __attribute__((visibility("default"))); #endif int fnord () { return 42; } int main () { void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); int status = $lt_dlunknown; if (self) { if (dlsym (self,"fnord")) status = $lt_dlno_uscore; else { if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; else puts (dlerror ()); } /* dlclose (self); */ } else puts (dlerror ()); return status; } _LT_EOF if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 (eval $ac_link) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && test -s conftest${ac_exeext} 2>/dev/null; then (./conftest; exit; ) >&5 2>/dev/null lt_status=$? case x$lt_status in x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;; x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;; x$lt_dlunknown|x*) lt_cv_dlopen_self=no ;; esac else : # compilation failed lt_cv_dlopen_self=no fi fi rm -fr conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self" >&5 $as_echo "$lt_cv_dlopen_self" >&6; } if test "x$lt_cv_dlopen_self" = xyes; then wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a statically linked program can dlopen itself" >&5 $as_echo_n "checking whether a statically linked program can dlopen itself... " >&6; } if ${lt_cv_dlopen_self_static+:} false; then : $as_echo_n "(cached) " >&6 else if test "$cross_compiling" = yes; then : lt_cv_dlopen_self_static=cross else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF #line $LINENO "configure" #include "confdefs.h" #if HAVE_DLFCN_H #include <dlfcn.h> #endif #include <stdio.h> #ifdef RTLD_GLOBAL # define LT_DLGLOBAL RTLD_GLOBAL #else # ifdef DL_GLOBAL # define LT_DLGLOBAL DL_GLOBAL # else # define LT_DLGLOBAL 0 # endif #endif /* We may have to define LT_DLLAZY_OR_NOW in the command line if we find out it does not work in some platform. */ #ifndef LT_DLLAZY_OR_NOW # ifdef RTLD_LAZY # define LT_DLLAZY_OR_NOW RTLD_LAZY # else # ifdef DL_LAZY # define LT_DLLAZY_OR_NOW DL_LAZY # else # ifdef RTLD_NOW # define LT_DLLAZY_OR_NOW RTLD_NOW # else # ifdef DL_NOW # define LT_DLLAZY_OR_NOW DL_NOW # else # define LT_DLLAZY_OR_NOW 0 # endif # endif # endif # endif #endif /* When -fvisbility=hidden is used, assume the code has been annotated correspondingly for the symbols needed. */ #if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) int fnord () __attribute__((visibility("default"))); #endif int fnord () { return 42; } int main () { void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); int status = $lt_dlunknown; if (self) { if (dlsym (self,"fnord")) status = $lt_dlno_uscore; else { if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; else puts (dlerror ()); } /* dlclose (self); */ } else puts (dlerror ()); return status; } _LT_EOF if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 (eval $ac_link) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && test -s conftest${ac_exeext} 2>/dev/null; then (./conftest; exit; ) >&5 2>/dev/null lt_status=$? case x$lt_status in x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;; x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;; x$lt_dlunknown|x*) lt_cv_dlopen_self_static=no ;; esac else : # compilation failed lt_cv_dlopen_self_static=no fi fi rm -fr conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self_static" >&5 $as_echo "$lt_cv_dlopen_self_static" >&6; } fi CPPFLAGS="$save_CPPFLAGS" LDFLAGS="$save_LDFLAGS" LIBS="$save_LIBS" ;; esac case $lt_cv_dlopen_self in yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; *) enable_dlopen_self=unknown ;; esac case $lt_cv_dlopen_self_static in yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; *) enable_dlopen_self_static=unknown ;; esac fi striplib= old_striplib= { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether stripping libraries is possible" >&5 $as_echo_n "checking whether stripping libraries is possible... " >&6; } if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" test -z "$striplib" && striplib="$STRIP --strip-unneeded" { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else # FIXME - insert some real tests, host_os isn't really good enough case $host_os in darwin*) if test -n "$STRIP" ; then striplib="$STRIP -x" old_striplib="$STRIP -S" { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi ;; *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } ;; esac fi # Report which library types will actually be built { $as_echo "$as_me:${as_lineno-$LINENO}: checking if libtool supports shared libraries" >&5 $as_echo_n "checking if libtool supports shared libraries... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: $can_build_shared" >&5 $as_echo "$can_build_shared" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build shared libraries" >&5 $as_echo_n "checking whether to build shared libraries... " >&6; } test "$can_build_shared" = "no" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. case $host_os in aix3*) test "$enable_shared" = yes && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix[4-9]*) if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then test "$enable_shared" = yes && enable_static=no fi ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_shared" >&5 $as_echo "$enable_shared" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build static libraries" >&5 $as_echo_n "checking whether to build static libraries... " >&6; } # Make sure either enable_shared or enable_static is yes. test "$enable_shared" = yes || enable_static=yes { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_static" >&5 $as_echo "$enable_static" >&6; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu CC="$lt_save_CC" ac_config_commands="$ac_config_commands libtool" # Only expand once: LIBTOOL="$LIBTOOL --silent" for ac_header do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done THREAD_LIBS=-lpthread ARCH="" LIBBURNIA_PKGCONFDIR="$libdir"/pkgconfig { $as_echo "$as_me:${as_lineno-$LINENO}: checking target operating system" >&5 $as_echo_n "checking target operating system... " >&6; } LIBBURNIA_LDCONFIG_CMD="echo 'No ldconfig run performed. If needed, configure manually for:'" case $target in *-*-linux*) ARCH=linux LIBBURN_ARCH_LIBS= LIBBURNIA_LDCONFIG_CMD=ldconfig ;; *-*-freebsd*) ARCH=freebsd LIBBURN_ARCH_LIBS=-lcam LIBBURNIA_PKGCONFDIR=$(echo "$libdir" | sed 's/\/lib$/\/libdata/')/pkgconfig ;; *-kfreebsd*-gnu*) ARCH=freebsd LIBBURN_ARCH_LIBS=-lcam ;; *-solaris*) ARCH=solaris LIBBURN_ARCH_LIBS=-lvolmgt ;; *) ARCH= LIBBURN_ARCH_LIBS= # AC_ERROR([You are attempting to compile for an unsupported platform]) ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ARCH" >&5 $as_echo "$ARCH" >&6; } STATVFS_DEF=-DLibburn_os_has_statvfS ac_fn_c_check_header_mongrel "$LINENO" "sys/statvfs.h" "ac_cv_header_sys_statvfs_h" "$ac_includes_default" if test "x$ac_cv_header_sys_statvfs_h" = xyes; then : X= else STATVFS_DEF= fi ac_fn_c_check_func "$LINENO" "statvfs" "ac_cv_func_statvfs" if test "x$ac_cv_func_statvfs" = xyes; then : X= else STATVFS_DEF= fi CFLAGS="$STATVFS_DEF $CFLAGS" # Check whether --enable-track-src-odirect was given. if test "${enable_track_src_odirect+set}" = set; then : enableval=$enable_track_src_odirect; else enable_track_src_odirect=no fi if test x$enable_track_src_odirect = xyes; then LIBBURN_O_DIRECT_DEF="-DLibburn_read_o_direcT" echo "enabled use of O_DIRECT with track input" else LIBBURN_O_DIRECT_DEF= echo "disabled use of O_DIRECT with track input" fi CFLAGS="$LIBBURN_O_DIRECT_DEF $CFLAGS" # Check whether --enable-dvd-obs-64k was given. if test "${enable_dvd_obs_64k+set}" = set; then : enableval=$enable_dvd_obs_64k; else enable_dvd_obs_64k=no fi if test x$enable_dvd_obs_64k = xyes; then LIBBURN_DVD_OBS_64K="-DLibburn_dvd_obs_default_64K" echo "enabled write size default 64 KB on DVD" else LIBBURN_DVD_OBS_64K= echo "disabled write size default 64 KB on DVD" fi CFLAGS="$LIBBURN_DVD_OBS_64K $CFLAGS" # Check whether --enable-dvd-obs-pad was given. if test "${enable_dvd_obs_pad+set}" = set; then : enableval=$enable_dvd_obs_pad; else enable_dvd_obs_pad=no fi if test x$enable_dvd_obs_pad = xyes; then LIBBURN_DVD_OBS_PAD="-DLibburn_dvd_always_obs_paD" echo "enabled padding of DVD DAO sessions to 32 or 64 KB" else LIBBURN_DVD_OBS_64K= echo "disabled padding of DVD DAO sessions to 32 or 64 KB" fi CFLAGS="$LIBBURN_DVD_OBS_PAD $CFLAGS" case $host_os in cygwin*|mingw*) default_libcdio=yes ;; *) default_libcdio=no ;; esac # Check for proper library versions if this is desired. # (It fails too often on too many systems.) # Check whether --enable-pkg-check-modules was given. if test "${enable_pkg_check_modules+set}" = set; then : enableval=$enable_pkg_check_modules; else enable_pkg_check_modules=no fi # Check whether --enable-libcdio was given. if test "${enable_libcdio+set}" = set; then : enableval=$enable_libcdio; else enable_libcdio=$default_libcdio fi if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args. set dummy ${ac_tool_prefix}pkg-config; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_PKG_CONFIG+:} false; then : $as_echo_n "(cached) " >&6 else case $PKG_CONFIG in [\\/]* | ?:[\\/]*) ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi PKG_CONFIG=$ac_cv_path_PKG_CONFIG if test -n "$PKG_CONFIG"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PKG_CONFIG" >&5 $as_echo "$PKG_CONFIG" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_path_PKG_CONFIG"; then ac_pt_PKG_CONFIG=$PKG_CONFIG # Extract the first word of "pkg-config", so it can be a program name with args. set dummy pkg-config; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_ac_pt_PKG_CONFIG+:} false; then : $as_echo_n "(cached) " >&6 else case $ac_pt_PKG_CONFIG in [\\/]* | ?:[\\/]*) ac_cv_path_ac_pt_PKG_CONFIG="$ac_pt_PKG_CONFIG" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_ac_pt_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi ac_pt_PKG_CONFIG=$ac_cv_path_ac_pt_PKG_CONFIG if test -n "$ac_pt_PKG_CONFIG"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_PKG_CONFIG" >&5 $as_echo "$ac_pt_PKG_CONFIG" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_pt_PKG_CONFIG" = x; then PKG_CONFIG="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac PKG_CONFIG=$ac_pt_PKG_CONFIG fi else PKG_CONFIG="$ac_cv_path_PKG_CONFIG" fi fi if test -n "$PKG_CONFIG"; then _pkg_min_version=0.9.0 { $as_echo "$as_me:${as_lineno-$LINENO}: checking pkg-config is at least version $_pkg_min_version" >&5 $as_echo_n "checking pkg-config is at least version $_pkg_min_version... " >&6; } if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } PKG_CONFIG="" fi fi if test x$enable_libcdio = xyes; then LIBCDIO_DEF="-DLibburn_use_libcdiO" ac_fn_c_check_header_mongrel "$LINENO" "cdio/cdio.h" "ac_cv_header_cdio_cdio_h" "$ac_includes_default" if test "x$ac_cv_header_cdio_cdio_h" = xyes; then : { $as_echo "$as_me:${as_lineno-$LINENO}: checking for mmc_last_cmd_sense in -lcdio" >&5 $as_echo_n "checking for mmc_last_cmd_sense in -lcdio... " >&6; } if ${ac_cv_lib_cdio_mmc_last_cmd_sense+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lcdio $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char mmc_last_cmd_sense (); int main () { return mmc_last_cmd_sense (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_cdio_mmc_last_cmd_sense=yes else ac_cv_lib_cdio_mmc_last_cmd_sense=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_cdio_mmc_last_cmd_sense" >&5 $as_echo "$ac_cv_lib_cdio_mmc_last_cmd_sense" >&6; } if test "x$ac_cv_lib_cdio_mmc_last_cmd_sense" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBCDIO 1 _ACEOF LIBS="-lcdio $LIBS" else LIBCDIO_DEF= fi else LIBCDIO_DEF= fi else LIBCDIO_DEF= fi if test x$LIBCDIO_DEF = x then if test x$enable_libcdio = xyes then echo "WARNING: could not enable use of libcdio as system adapter" fi else echo "enabled use of libcdio as system adapter" CFLAGS="$LIBCDIO_DEF $CFLAGS" if test x$enable_pkg_check_modules = xyes; then LIBCDIO_REQUIRED=0.83 pkg_failed=no { $as_echo "$as_me:${as_lineno-$LINENO}: checking for LIBCDIO" >&5 $as_echo_n "checking for LIBCDIO... " >&6; } if test -n "$LIBCDIO_CFLAGS"; then pkg_cv_LIBCDIO_CFLAGS="$LIBCDIO_CFLAGS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libcdio >= \$LIBCDIO_REQUIRED\""; } >&5 ($PKG_CONFIG --exists --print-errors "libcdio >= $LIBCDIO_REQUIRED") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_LIBCDIO_CFLAGS=`$PKG_CONFIG --cflags "libcdio >= $LIBCDIO_REQUIRED" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi else pkg_failed=untried fi if test -n "$LIBCDIO_LIBS"; then pkg_cv_LIBCDIO_LIBS="$LIBCDIO_LIBS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libcdio >= \$LIBCDIO_REQUIRED\""; } >&5 ($PKG_CONFIG --exists --print-errors "libcdio >= $LIBCDIO_REQUIRED") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_LIBCDIO_LIBS=`$PKG_CONFIG --libs "libcdio >= $LIBCDIO_REQUIRED" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi else pkg_failed=untried fi if test $pkg_failed = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then _pkg_short_errors_supported=yes else _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then LIBCDIO_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libcdio >= $LIBCDIO_REQUIRED" 2>&1` else LIBCDIO_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libcdio >= $LIBCDIO_REQUIRED" 2>&1` fi # Put the nasty error message in config.log where it belongs echo "$LIBCDIO_PKG_ERRORS" >&5 as_fn_error $? "Package requirements (libcdio >= $LIBCDIO_REQUIRED) were not met: $LIBCDIO_PKG_ERRORS Consider adjusting the PKG_CONFIG_PATH environment variable if you installed software in a non-standard prefix. Alternatively, you may set the environment variables LIBCDIO_CFLAGS and LIBCDIO_LIBS to avoid the need to call pkg-config. See the pkg-config man page for more details." "$LINENO" 5 elif test $pkg_failed = untried; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it is in your PATH or set the PKG_CONFIG environment variable to the full path to pkg-config. Alternatively, you may set the environment variables LIBCDIO_CFLAGS and LIBCDIO_LIBS to avoid the need to call pkg-config. See the pkg-config man page for more details. To get pkg-config, see <http://pkg-config.freedesktop.org/>. See \`config.log' for more details" "$LINENO" 5; } else LIBCDIO_CFLAGS=$pkg_cv_LIBCDIO_CFLAGS LIBCDIO_LIBS=$pkg_cv_LIBCDIO_LIBS { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } fi else echo "checking for LIBCDIO... skipped, no --enable-pkg-check-modules" fi fi # Library versioning normally serves a complex purpose. # Since libburn obeys strict ABI backward compatibility, it needs only the # simple feature to declare function names "global:" or "local:". Only the # global ones are visible to applications at library load time. # Check whether --enable-versioned-libs was given. if test "${enable_versioned_libs+set}" = set; then : enableval=$enable_versioned_libs; else enable_versioned_libs=yes fi if test x$enable_versioned_libs = xyes; then vers_libs_test=no libburnia_save_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS -Wl,--version-script=libburn/libburn.ver" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include <stdio.h> int main () { printf("Hello\n"); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : vers_libs_test="yes" else vers_libs_test="no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext if test x$vers_libs_test = xno then LDFLAGS="$libburnia_save_LDFLAGS" fi if test x$vers_libs_test = xno then echo "disabled strict symbol encapsulation (test failed)" else echo "enabled strict symbol encapsulation" fi else echo "disabled strict symbol encapsulation" fi # Check whether --enable-ldconfig-at-install was given. if test "${enable_ldconfig_at_install+set}" = set; then : enableval=$enable_ldconfig_at_install; else ldconfig_at_install=yes fi if test x$ldconfig_at_install = xyes; then dummy=dummy else LIBBURNIA_LDCONFIG_CMD="echo 'NOTE: ldconfig is disabled. If needed, configure manually for:'" echo "disabled run of ldconfig during installation on GNU/Linux" fi # Check whether --enable-debug was given. if test "${enable_debug+set}" = set; then : enableval=$enable_debug; else enable_debug=yes fi if test x$enable_debug != xyes; then if test x$GCC = xyes; then CFLAGS="-O3 $CFLAGS" CFLAGS="-fexpensive-optimizations $CFLAGS" fi CFLAGS="-DNDEBUG $CFLAGS" else if test x$GCC = xyes; then CFLAGS="-g -pedantic -Wall -Wextra -Wno-unused-parameter -Wno-char-subscripts $CFLAGS" fi CFLAGS="-DDEBUG $CFLAGS" fi ### for testing --enable-libdir-pkgconfig on Linux ### LIBBURNIA_PKGCONFDIR="$libdir"data/pkgconfig if test "x$LIBBURNIA_PKGCONFDIR" = "x$libdir"/pkgconfig then dummy=dummy else # Check whether --enable-libdir-pkgconfig was given. if test "${enable_libdir_pkgconfig+set}" = set; then : enableval=$enable_libdir_pkgconfig; else enable_libdir_pkgconfig="no" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for --enable-libdir-pkgconfig" >&5 $as_echo_n "checking for --enable-libdir-pkgconfig... " >&6; } if test "x$enable_libdir_pkgconfig" = xyes then LIBBURNIA_PKGCONFDIR="$libdir"/pkgconfig fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_libdir_pkgconfig" >&5 $as_echo "$enable_libdir_pkgconfig" >&6; } fi libburnia_pkgconfig_override="no" # Check whether --enable-pkgconfig-path was given. if test "${enable_pkgconfig_path+set}" = set; then : enableval=$enable_pkgconfig_path; libburnia_pkgconfig_override="yes" else enable_pkgconfig_path="none" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for overridden pkgconfig directory path" >&5 $as_echo_n "checking for overridden pkgconfig directory path... " >&6; } if test "x$enable_pkgconfig_path" = xno then libburnia_pkgconfig_override="no" fi if test "x$enable_pkgconfig_path" = x -o "x$enable_pkgconfig_path" = xyes then libburnia_pkgconfig_override="invalid argument" fi if test "x$libburnia_pkgconfig_override" = xyes then LIBBURNIA_PKGCONFDIR="$enable_pkgconfig_path" { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIBBURNIA_PKGCONFDIR" >&5 $as_echo "$LIBBURNIA_PKGCONFDIR" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: $libburnia_pkgconfig_override" >&5 $as_echo "$libburnia_pkgconfig_override" >&6; } fi ### AC_MSG_RESULT([LIBBURNIA_PKGCONFDIR = $LIBBURNIA_PKGCONFDIR]) ac_config_files="$ac_config_files Makefile doc/doxygen.conf version.h libburn-1.pc" cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure # tests run on this system so they can be shared between configure # scripts and configure runs, see configure's option --config-cache. # It is not useful on other systems. If it contains results you don't # want to keep, you may remove or edit it. # # config.status only pays attention to the cache file if you give it # the --recheck option to rerun configure. # # `ac_cv_env_foo' variables (set or unset) will be overridden when # loading this file, other *unset* `ac_cv_foo' will be assigned the # following values. _ACEOF # The following way of writing the cache mishandles newlines in values, # but we know of no workaround that is simple, portable, and efficient. # So, we kill variables containing newlines. # Ultrix sh set writes to stderr and can't be redirected directly, # and sets the high bit in the cache file unless we assign to the vars. ( for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; unset $ac_var;} ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space=' '; set) 2>&1` in #( *${as_nl}ac_space=\ *) # `set' does not quote correctly, so add quotes: double-quote # substitution turns \\\\ into \\, and sed turns \\ into \. sed -n \ "s/'/'\\\\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" ;; #( *) # `set' quotes correctly as required by POSIX, so do not add quotes. sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) | sed ' /^ac_cv_env_/b end t clear :clear s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ t end s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ :end' >>confcache if diff "$cache_file" confcache >/dev/null 2>&1; then :; else if test -w "$cache_file"; then if test "x$cache_file" != "x/dev/null"; then { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 $as_echo "$as_me: updating cache $cache_file" >&6;} if test ! -f "$cache_file" || test -h "$cache_file"; then cat confcache >"$cache_file" else case $cache_file in #( */* | ?:*) mv -f confcache "$cache_file"$$ && mv -f "$cache_file"$$ "$cache_file" ;; #( *) mv -f confcache "$cache_file" ;; esac fi fi else { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 $as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} fi fi rm -f confcache test "x$prefix" = xNONE && prefix=$ac_default_prefix # Let make expand exec_prefix. test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' # Transform confdefs.h into DEFS. # Protect against shell expansion while executing Makefile rules. # Protect against Makefile macro expansion. # # If the first sed substitution is executed (which looks for macros that # take arguments), then branch to the quote section. Otherwise, # look for a macro that doesn't take arguments. ac_script=' :mline /\\$/{ N s,\\\n,, b mline } t clear :clear s/^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*([^)]*)\)[ ]*\(.*\)/-D\1=\2/g t quote s/^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\)/-D\1=\2/g t quote b any :quote s/[ `~#$^&*(){}\\|;'\''"<>?]/\\&/g s/\[/\\&/g s/\]/\\&/g s/\$/$$/g H :any ${ g s/^\n// s/\n/ /g p } ' DEFS=`sed -n "$ac_script" confdefs.h` ac_libobjs= ac_ltlibobjs= U= for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue # 1. Remove the extension, and $U if already installed. ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' ac_i=`$as_echo "$ac_i" | sed "$ac_script"` # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR # will be set to the directory where LIBOBJS objects are built. as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' done LIBOBJS=$ac_libobjs LTLIBOBJS=$ac_ltlibobjs { $as_echo "$as_me:${as_lineno-$LINENO}: checking that generated files are newer than configure" >&5 $as_echo_n "checking that generated files are newer than configure... " >&6; } if test -n "$am_sleep_pid"; then # Hide warnings about reused PIDs. wait $am_sleep_pid 2>/dev/null fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: done" >&5 $as_echo "done" >&6; } if test -n "$EXEEXT"; then am__EXEEXT_TRUE= am__EXEEXT_FALSE='#' else am__EXEEXT_TRUE='#' am__EXEEXT_FALSE= fi if test -z "${MAINTAINER_MODE_TRUE}" && test -z "${MAINTAINER_MODE_FALSE}"; then as_fn_error $? "conditional \"MAINTAINER_MODE\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then as_fn_error $? "conditional \"AMDEP\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then as_fn_error $? "conditional \"am__fastdepCC\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi : "${CONFIG_STATUS=./config.status}" ac_write_fail=0 ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files $CONFIG_STATUS" { $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 $as_echo "$as_me: creating $CONFIG_STATUS" >&6;} as_write_fail=0 cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 #! $SHELL # Generated by $as_me. # Run this file to recreate the current configuration. # Compiler output produced by configure, useful for debugging # configure, is in config.log if it exists. debug=false ac_cs_recheck=false ac_cs_silent=false SHELL=\${CONFIG_SHELL-$SHELL} export SHELL _ASEOF cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi as_nl=' ' export as_nl # Printing a long string crashes Solaris 7 /usr/bin/printf. as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo # Prefer a ksh shell builtin over an external printf program on Solaris, # but without wasting forks for bash or zsh. if test -z "$BASH_VERSION$ZSH_VERSION" \ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='print -r --' as_echo_n='print -rn --' elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='printf %s\n' as_echo_n='printf %s' else if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' as_echo_n='/usr/ucb/echo -n' else as_echo_body='eval expr "X$1" : "X\\(.*\\)"' as_echo_n_body='eval arg=$1; case $arg in #( *"$as_nl"*) expr "X$arg" : "X\\(.*\\)$as_nl"; arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; esac; expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" ' export as_echo_n_body as_echo_n='sh -c $as_echo_n_body as_echo' fi export as_echo_body as_echo='sh -c $as_echo_body as_echo' fi # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # Unset variables that we do not need and which cause bugs (e.g. in # pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" # suppresses any "Segmentation fault" message there. '((' could # trigger a bug in pdksh 5.2.14. for as_var in BASH_ENV ENV MAIL MAILPATH do eval test x\${$as_var+set} = xset \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with STATUS, using 1 if that was 0. as_fn_error () { as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi $as_echo "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : eval 'as_fn_append () { eval $1+=\$2 }' else as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : eval 'as_fn_arith () { as_val=$(( $* )) }' else as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || $as_echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -pR'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -pR' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -pR' fi else as_ln_s='cp -pR' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi # as_fn_executable_p FILE # ----------------------- # Test if FILE is an executable regular file. as_fn_executable_p () { test -f "$1" && test -x "$1" } # as_fn_executable_p as_test_x='test -x' as_executable_p=as_fn_executable_p # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" exec 6>&1 ## ----------------------------------- ## ## Main body of $CONFIG_STATUS script. ## ## ----------------------------------- ## _ASEOF test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Save the log message, to keep $0 and so on meaningful, and to # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" This file was extended by libburn $as_me 1.4.2, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS CONFIG_LINKS = $CONFIG_LINKS CONFIG_COMMANDS = $CONFIG_COMMANDS $ $0 $@ on `(hostname || uname -n) 2>/dev/null | sed 1q` " _ACEOF case $ac_config_files in *" "*) set x $ac_config_files; shift; ac_config_files=$*;; esac cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # Files that config.status was made for. config_files="$ac_config_files" config_commands="$ac_config_commands" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 ac_cs_usage="\ \`$as_me' instantiates files and other configuration actions from templates according to the current configuration. Unless the files and actions are specified as TAGs, all are instantiated by default. Usage: $0 [OPTION]... [TAG]... -h, --help print this help, then exit -V, --version print version number and configuration settings, then exit --config print configuration, then exit -q, --quiet, --silent do not print progress messages -d, --debug don't remove temporary files --recheck update $as_me by reconfiguring in the same conditions --file=FILE[:TEMPLATE] instantiate the configuration file FILE Configuration files: $config_files Configuration commands: $config_commands Report bugs to <http://libburnia-project.org>." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ libburn config.status 1.4.2 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" Copyright (C) 2012 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." ac_pwd='$ac_pwd' srcdir='$srcdir' INSTALL='$INSTALL' MKDIR_P='$MKDIR_P' AWK='$AWK' test -n "\$AWK" || AWK=awk _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # The default lists apply if the user does not specify any file. ac_need_defaults=: while test $# != 0 do case $1 in --*=?*) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` ac_shift=: ;; --*=) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg= ac_shift=: ;; *) ac_option=$1 ac_optarg=$2 ac_shift=shift ;; esac case $ac_option in # Handling of the options. -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) ac_cs_recheck=: ;; --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) $as_echo "$ac_cs_version"; exit ;; --config | --confi | --conf | --con | --co | --c ) $as_echo "$ac_cs_config"; exit ;; --debug | --debu | --deb | --de | --d | -d ) debug=: ;; --file | --fil | --fi | --f ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; '') as_fn_error $? "missing file argument" ;; esac as_fn_append CONFIG_FILES " '$ac_optarg'" ac_need_defaults=false;; --he | --h | --help | --hel | -h ) $as_echo "$ac_cs_usage"; exit ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil | --si | --s) ac_cs_silent=: ;; # This is an error. -*) as_fn_error $? "unrecognized option: \`$1' Try \`$0 --help' for more information." ;; *) as_fn_append ac_config_targets " $1" ac_need_defaults=false ;; esac shift done ac_configure_extra_args= if $ac_cs_silent; then exec 6>/dev/null ac_configure_extra_args="$ac_configure_extra_args --silent" fi _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 if \$ac_cs_recheck; then set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion shift \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 CONFIG_SHELL='$SHELL' export CONFIG_SHELL exec "\$@" fi _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 exec 5>>config.log { echo sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX ## Running $as_me. ## _ASBOX $as_echo "$ac_log" } >&5 _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # # INIT-COMMANDS # AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir" # The HP-UX ksh and POSIX shell print the target directory to stdout # if CDPATH is set. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH sed_quote_subst='$sed_quote_subst' double_quote_subst='$double_quote_subst' delay_variable_subst='$delay_variable_subst' macro_version='`$ECHO "$macro_version" | $SED "$delay_single_quote_subst"`' macro_revision='`$ECHO "$macro_revision" | $SED "$delay_single_quote_subst"`' enable_shared='`$ECHO "$enable_shared" | $SED "$delay_single_quote_subst"`' enable_static='`$ECHO "$enable_static" | $SED "$delay_single_quote_subst"`' pic_mode='`$ECHO "$pic_mode" | $SED "$delay_single_quote_subst"`' enable_fast_install='`$ECHO "$enable_fast_install" | $SED "$delay_single_quote_subst"`' SHELL='`$ECHO "$SHELL" | $SED "$delay_single_quote_subst"`' ECHO='`$ECHO "$ECHO" | $SED "$delay_single_quote_subst"`' PATH_SEPARATOR='`$ECHO "$PATH_SEPARATOR" | $SED "$delay_single_quote_subst"`' host_alias='`$ECHO "$host_alias" | $SED "$delay_single_quote_subst"`' host='`$ECHO "$host" | $SED "$delay_single_quote_subst"`' host_os='`$ECHO "$host_os" | $SED "$delay_single_quote_subst"`' build_alias='`$ECHO "$build_alias" | $SED "$delay_single_quote_subst"`' build='`$ECHO "$build" | $SED "$delay_single_quote_subst"`' build_os='`$ECHO "$build_os" | $SED "$delay_single_quote_subst"`' SED='`$ECHO "$SED" | $SED "$delay_single_quote_subst"`' Xsed='`$ECHO "$Xsed" | $SED "$delay_single_quote_subst"`' GREP='`$ECHO "$GREP" | $SED "$delay_single_quote_subst"`' EGREP='`$ECHO "$EGREP" | $SED "$delay_single_quote_subst"`' FGREP='`$ECHO "$FGREP" | $SED "$delay_single_quote_subst"`' LD='`$ECHO "$LD" | $SED "$delay_single_quote_subst"`' NM='`$ECHO "$NM" | $SED "$delay_single_quote_subst"`' LN_S='`$ECHO "$LN_S" | $SED "$delay_single_quote_subst"`' max_cmd_len='`$ECHO "$max_cmd_len" | $SED "$delay_single_quote_subst"`' ac_objext='`$ECHO "$ac_objext" | $SED "$delay_single_quote_subst"`' exeext='`$ECHO "$exeext" | $SED "$delay_single_quote_subst"`' lt_unset='`$ECHO "$lt_unset" | $SED "$delay_single_quote_subst"`' lt_SP2NL='`$ECHO "$lt_SP2NL" | $SED "$delay_single_quote_subst"`' lt_NL2SP='`$ECHO "$lt_NL2SP" | $SED "$delay_single_quote_subst"`' lt_cv_to_host_file_cmd='`$ECHO "$lt_cv_to_host_file_cmd" | $SED "$delay_single_quote_subst"`' lt_cv_to_tool_file_cmd='`$ECHO "$lt_cv_to_tool_file_cmd" | $SED "$delay_single_quote_subst"`' reload_flag='`$ECHO "$reload_flag" | $SED "$delay_single_quote_subst"`' reload_cmds='`$ECHO "$reload_cmds" | $SED "$delay_single_quote_subst"`' OBJDUMP='`$ECHO "$OBJDUMP" | $SED "$delay_single_quote_subst"`' deplibs_check_method='`$ECHO "$deplibs_check_method" | $SED "$delay_single_quote_subst"`' file_magic_cmd='`$ECHO "$file_magic_cmd" | $SED "$delay_single_quote_subst"`' file_magic_glob='`$ECHO "$file_magic_glob" | $SED "$delay_single_quote_subst"`' want_nocaseglob='`$ECHO "$want_nocaseglob" | $SED "$delay_single_quote_subst"`' DLLTOOL='`$ECHO "$DLLTOOL" | $SED "$delay_single_quote_subst"`' sharedlib_from_linklib_cmd='`$ECHO "$sharedlib_from_linklib_cmd" | $SED "$delay_single_quote_subst"`' AR='`$ECHO "$AR" | $SED "$delay_single_quote_subst"`' AR_FLAGS='`$ECHO "$AR_FLAGS" | $SED "$delay_single_quote_subst"`' archiver_list_spec='`$ECHO "$archiver_list_spec" | $SED "$delay_single_quote_subst"`' STRIP='`$ECHO "$STRIP" | $SED "$delay_single_quote_subst"`' RANLIB='`$ECHO "$RANLIB" | $SED "$delay_single_quote_subst"`' old_postinstall_cmds='`$ECHO "$old_postinstall_cmds" | $SED "$delay_single_quote_subst"`' old_postuninstall_cmds='`$ECHO "$old_postuninstall_cmds" | $SED "$delay_single_quote_subst"`' old_archive_cmds='`$ECHO "$old_archive_cmds" | $SED "$delay_single_quote_subst"`' lock_old_archive_extraction='`$ECHO "$lock_old_archive_extraction" | $SED "$delay_single_quote_subst"`' CC='`$ECHO "$CC" | $SED "$delay_single_quote_subst"`' CFLAGS='`$ECHO "$CFLAGS" | $SED "$delay_single_quote_subst"`' compiler='`$ECHO "$compiler" | $SED "$delay_single_quote_subst"`' GCC='`$ECHO "$GCC" | $SED "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_pipe='`$ECHO "$lt_cv_sys_global_symbol_pipe" | $SED "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_to_cdecl='`$ECHO "$lt_cv_sys_global_symbol_to_cdecl" | $SED "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_to_c_name_address='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address" | $SED "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix" | $SED "$delay_single_quote_subst"`' nm_file_list_spec='`$ECHO "$nm_file_list_spec" | $SED "$delay_single_quote_subst"`' lt_sysroot='`$ECHO "$lt_sysroot" | $SED "$delay_single_quote_subst"`' objdir='`$ECHO "$objdir" | $SED "$delay_single_quote_subst"`' MAGIC_CMD='`$ECHO "$MAGIC_CMD" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_no_builtin_flag='`$ECHO "$lt_prog_compiler_no_builtin_flag" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_pic='`$ECHO "$lt_prog_compiler_pic" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_wl='`$ECHO "$lt_prog_compiler_wl" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_static='`$ECHO "$lt_prog_compiler_static" | $SED "$delay_single_quote_subst"`' lt_cv_prog_compiler_c_o='`$ECHO "$lt_cv_prog_compiler_c_o" | $SED "$delay_single_quote_subst"`' need_locks='`$ECHO "$need_locks" | $SED "$delay_single_quote_subst"`' MANIFEST_TOOL='`$ECHO "$MANIFEST_TOOL" | $SED "$delay_single_quote_subst"`' DSYMUTIL='`$ECHO "$DSYMUTIL" | $SED "$delay_single_quote_subst"`' NMEDIT='`$ECHO "$NMEDIT" | $SED "$delay_single_quote_subst"`' LIPO='`$ECHO "$LIPO" | $SED "$delay_single_quote_subst"`' OTOOL='`$ECHO "$OTOOL" | $SED "$delay_single_quote_subst"`' OTOOL64='`$ECHO "$OTOOL64" | $SED "$delay_single_quote_subst"`' libext='`$ECHO "$libext" | $SED "$delay_single_quote_subst"`' shrext_cmds='`$ECHO "$shrext_cmds" | $SED "$delay_single_quote_subst"`' extract_expsyms_cmds='`$ECHO "$extract_expsyms_cmds" | $SED "$delay_single_quote_subst"`' archive_cmds_need_lc='`$ECHO "$archive_cmds_need_lc" | $SED "$delay_single_quote_subst"`' enable_shared_with_static_runtimes='`$ECHO "$enable_shared_with_static_runtimes" | $SED "$delay_single_quote_subst"`' export_dynamic_flag_spec='`$ECHO "$export_dynamic_flag_spec" | $SED "$delay_single_quote_subst"`' whole_archive_flag_spec='`$ECHO "$whole_archive_flag_spec" | $SED "$delay_single_quote_subst"`' compiler_needs_object='`$ECHO "$compiler_needs_object" | $SED "$delay_single_quote_subst"`' old_archive_from_new_cmds='`$ECHO "$old_archive_from_new_cmds" | $SED "$delay_single_quote_subst"`' old_archive_from_expsyms_cmds='`$ECHO "$old_archive_from_expsyms_cmds" | $SED "$delay_single_quote_subst"`' archive_cmds='`$ECHO "$archive_cmds" | $SED "$delay_single_quote_subst"`' archive_expsym_cmds='`$ECHO "$archive_expsym_cmds" | $SED "$delay_single_quote_subst"`' module_cmds='`$ECHO "$module_cmds" | $SED "$delay_single_quote_subst"`' module_expsym_cmds='`$ECHO "$module_expsym_cmds" | $SED "$delay_single_quote_subst"`' with_gnu_ld='`$ECHO "$with_gnu_ld" | $SED "$delay_single_quote_subst"`' allow_undefined_flag='`$ECHO "$allow_undefined_flag" | $SED "$delay_single_quote_subst"`' no_undefined_flag='`$ECHO "$no_undefined_flag" | $SED "$delay_single_quote_subst"`' hardcode_libdir_flag_spec='`$ECHO "$hardcode_libdir_flag_spec" | $SED "$delay_single_quote_subst"`' hardcode_libdir_separator='`$ECHO "$hardcode_libdir_separator" | $SED "$delay_single_quote_subst"`' hardcode_direct='`$ECHO "$hardcode_direct" | $SED "$delay_single_quote_subst"`' hardcode_direct_absolute='`$ECHO "$hardcode_direct_absolute" | $SED "$delay_single_quote_subst"`' hardcode_minus_L='`$ECHO "$hardcode_minus_L" | $SED "$delay_single_quote_subst"`' hardcode_shlibpath_var='`$ECHO "$hardcode_shlibpath_var" | $SED "$delay_single_quote_subst"`' hardcode_automatic='`$ECHO "$hardcode_automatic" | $SED "$delay_single_quote_subst"`' inherit_rpath='`$ECHO "$inherit_rpath" | $SED "$delay_single_quote_subst"`' link_all_deplibs='`$ECHO "$link_all_deplibs" | $SED "$delay_single_quote_subst"`' always_export_symbols='`$ECHO "$always_export_symbols" | $SED "$delay_single_quote_subst"`' export_symbols_cmds='`$ECHO "$export_symbols_cmds" | $SED "$delay_single_quote_subst"`' exclude_expsyms='`$ECHO "$exclude_expsyms" | $SED "$delay_single_quote_subst"`' include_expsyms='`$ECHO "$include_expsyms" | $SED "$delay_single_quote_subst"`' prelink_cmds='`$ECHO "$prelink_cmds" | $SED "$delay_single_quote_subst"`' postlink_cmds='`$ECHO "$postlink_cmds" | $SED "$delay_single_quote_subst"`' file_list_spec='`$ECHO "$file_list_spec" | $SED "$delay_single_quote_subst"`' variables_saved_for_relink='`$ECHO "$variables_saved_for_relink" | $SED "$delay_single_quote_subst"`' need_lib_prefix='`$ECHO "$need_lib_prefix" | $SED "$delay_single_quote_subst"`' need_version='`$ECHO "$need_version" | $SED "$delay_single_quote_subst"`' version_type='`$ECHO "$version_type" | $SED "$delay_single_quote_subst"`' runpath_var='`$ECHO "$runpath_var" | $SED "$delay_single_quote_subst"`' shlibpath_var='`$ECHO "$shlibpath_var" | $SED "$delay_single_quote_subst"`' shlibpath_overrides_runpath='`$ECHO "$shlibpath_overrides_runpath" | $SED "$delay_single_quote_subst"`' libname_spec='`$ECHO "$libname_spec" | $SED "$delay_single_quote_subst"`' library_names_spec='`$ECHO "$library_names_spec" | $SED "$delay_single_quote_subst"`' soname_spec='`$ECHO "$soname_spec" | $SED "$delay_single_quote_subst"`' install_override_mode='`$ECHO "$install_override_mode" | $SED "$delay_single_quote_subst"`' postinstall_cmds='`$ECHO "$postinstall_cmds" | $SED "$delay_single_quote_subst"`' postuninstall_cmds='`$ECHO "$postuninstall_cmds" | $SED "$delay_single_quote_subst"`' finish_cmds='`$ECHO "$finish_cmds" | $SED "$delay_single_quote_subst"`' finish_eval='`$ECHO "$finish_eval" | $SED "$delay_single_quote_subst"`' hardcode_into_libs='`$ECHO "$hardcode_into_libs" | $SED "$delay_single_quote_subst"`' sys_lib_search_path_spec='`$ECHO "$sys_lib_search_path_spec" | $SED "$delay_single_quote_subst"`' sys_lib_dlsearch_path_spec='`$ECHO "$sys_lib_dlsearch_path_spec" | $SED "$delay_single_quote_subst"`' hardcode_action='`$ECHO "$hardcode_action" | $SED "$delay_single_quote_subst"`' enable_dlopen='`$ECHO "$enable_dlopen" | $SED "$delay_single_quote_subst"`' enable_dlopen_self='`$ECHO "$enable_dlopen_self" | $SED "$delay_single_quote_subst"`' enable_dlopen_self_static='`$ECHO "$enable_dlopen_self_static" | $SED "$delay_single_quote_subst"`' old_striplib='`$ECHO "$old_striplib" | $SED "$delay_single_quote_subst"`' striplib='`$ECHO "$striplib" | $SED "$delay_single_quote_subst"`' LTCC='$LTCC' LTCFLAGS='$LTCFLAGS' compiler='$compiler_DEFAULT' # A function that is used when there is no print builtin or printf. func_fallback_echo () { eval 'cat <<_LTECHO_EOF \$1 _LTECHO_EOF' } # Quote evaled strings. for var in SHELL \ ECHO \ PATH_SEPARATOR \ SED \ GREP \ EGREP \ FGREP \ LD \ NM \ LN_S \ lt_SP2NL \ lt_NL2SP \ reload_flag \ OBJDUMP \ deplibs_check_method \ file_magic_cmd \ file_magic_glob \ want_nocaseglob \ DLLTOOL \ sharedlib_from_linklib_cmd \ AR \ AR_FLAGS \ archiver_list_spec \ STRIP \ RANLIB \ CC \ CFLAGS \ compiler \ lt_cv_sys_global_symbol_pipe \ lt_cv_sys_global_symbol_to_cdecl \ lt_cv_sys_global_symbol_to_c_name_address \ lt_cv_sys_global_symbol_to_c_name_address_lib_prefix \ nm_file_list_spec \ lt_prog_compiler_no_builtin_flag \ lt_prog_compiler_pic \ lt_prog_compiler_wl \ lt_prog_compiler_static \ lt_cv_prog_compiler_c_o \ need_locks \ MANIFEST_TOOL \ DSYMUTIL \ NMEDIT \ LIPO \ OTOOL \ OTOOL64 \ shrext_cmds \ export_dynamic_flag_spec \ whole_archive_flag_spec \ compiler_needs_object \ with_gnu_ld \ allow_undefined_flag \ no_undefined_flag \ hardcode_libdir_flag_spec \ hardcode_libdir_separator \ exclude_expsyms \ include_expsyms \ file_list_spec \ variables_saved_for_relink \ libname_spec \ library_names_spec \ soname_spec \ install_override_mode \ finish_eval \ old_striplib \ striplib; do case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in *[\\\\\\\`\\"\\\$]*) eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" ;; *) eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" ;; esac done # Double-quote double-evaled strings. for var in reload_cmds \ old_postinstall_cmds \ old_postuninstall_cmds \ old_archive_cmds \ extract_expsyms_cmds \ old_archive_from_new_cmds \ old_archive_from_expsyms_cmds \ archive_cmds \ archive_expsym_cmds \ module_cmds \ module_expsym_cmds \ export_symbols_cmds \ prelink_cmds \ postlink_cmds \ postinstall_cmds \ postuninstall_cmds \ finish_cmds \ sys_lib_search_path_spec \ sys_lib_dlsearch_path_spec; do case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in *[\\\\\\\`\\"\\\$]*) eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" ;; *) eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" ;; esac done ac_aux_dir='$ac_aux_dir' xsi_shell='$xsi_shell' lt_shell_append='$lt_shell_append' # See if we are running on zsh, and set the options which allow our # commands through without removal of \ escapes INIT. if test -n "\${ZSH_VERSION+set}" ; then setopt NO_GLOB_SUBST fi PACKAGE='$PACKAGE' VERSION='$VERSION' TIMESTAMP='$TIMESTAMP' RM='$RM' ofile='$ofile' _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Handling of arguments. for ac_config_target in $ac_config_targets do case $ac_config_target in "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; "libtool") CONFIG_COMMANDS="$CONFIG_COMMANDS libtool" ;; "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; "doc/doxygen.conf") CONFIG_FILES="$CONFIG_FILES doc/doxygen.conf" ;; "version.h") CONFIG_FILES="$CONFIG_FILES version.h" ;; "libburn-1.pc") CONFIG_FILES="$CONFIG_FILES libburn-1.pc" ;; *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; esac done # If the user did not use the arguments to specify the items to instantiate, # then the envvar interface is used. Set only those that are not. # We use the long form for the default assignment because of an extremely # bizarre bug on SunOS 4.1.3. if $ac_need_defaults; then test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands fi # Have a temporary directory for convenience. Make it in the build tree # simply because there is no reason against having it here, and in addition, # creating and moving files from /tmp can sometimes cause problems. # Hook for its removal unless debugging. # Note that there is a small window in which the directory will not be cleaned: # after its creation but before its name has been assigned to `$tmp'. $debug || { tmp= ac_tmp= trap 'exit_status=$? : "${ac_tmp:=$tmp}" { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status ' 0 trap 'as_fn_exit 1' 1 2 13 15 } # Create a (secure) tmp directory for tmp files. { tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && test -d "$tmp" } || { tmp=./conf$$-$RANDOM (umask 077 && mkdir "$tmp") } || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 ac_tmp=$tmp # Set up the scripts for CONFIG_FILES section. # No need to generate them if there are no CONFIG_FILES. # This happens for instance with `./config.status config.h'. if test -n "$CONFIG_FILES"; then ac_cr=`echo X | tr X '\015'` # On cygwin, bash can eat \r inside `` if the user requested igncr. # But we know of no other shell where ac_cr would be empty at this # point, so we can use a bashism as a fallback. if test "x$ac_cr" = x; then eval ac_cr=\$\'\\r\' fi ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' </dev/null 2>/dev/null` if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then ac_cs_awk_cr='\\r' else ac_cs_awk_cr=$ac_cr fi echo 'BEGIN {' >"$ac_tmp/subs1.awk" && _ACEOF { echo "cat >conf$$subs.awk <<_ACEOF" && echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && echo "_ACEOF" } >conf$$subs.sh || as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` ac_delim='%!_!# ' for ac_last_try in false false false false false :; do . ./conf$$subs.sh || as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` if test $ac_delim_n = $ac_delim_num; then break elif $ac_last_try; then as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done rm -f conf$$subs.sh cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && _ACEOF sed -n ' h s/^/S["/; s/!.*/"]=/ p g s/^[^!]*!// :repl t repl s/'"$ac_delim"'$// t delim :nl h s/\(.\{148\}\)..*/\1/ t more1 s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ p n b repl :more1 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t nl :delim h s/\(.\{148\}\)..*/\1/ t more2 s/["\\]/\\&/g; s/^/"/; s/$/"/ p b :more2 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t delim ' <conf$$subs.awk | sed ' /^[^""]/{ N s/\n// } ' >>$CONFIG_STATUS || ac_write_fail=1 rm -f conf$$subs.awk cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 _ACAWK cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && for (key in S) S_is_set[key] = 1 FS = "" } { line = $ 0 nfields = split(line, field, "@") substed = 0 len = length(field[1]) for (i = 2; i < nfields; i++) { key = field[i] keylen = length(key) if (S_is_set[key]) { value = S[key] line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) len += length(value) + length(field[++i]) substed = 1 } else len += 1 + keylen } print line } _ACAWK _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" else cat fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 _ACEOF # VPATH may cause trouble with some makes, so we remove sole $(srcdir), # ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and # trailing colons and then remove the whole line if VPATH becomes empty # (actually we leave an empty line to preserve line numbers). if test "x$srcdir" = x.; then ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ h s/// s/^/:/ s/[ ]*$/:/ s/:\$(srcdir):/:/g s/:\${srcdir}:/:/g s/:@srcdir@:/:/g s/^:*// s/:*$// x s/\(=[ ]*\).*/\1/ G s/\n// s/^[^=]*=[ ]*$// }' fi cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 fi # test -n "$CONFIG_FILES" eval set X " :F $CONFIG_FILES :C $CONFIG_COMMANDS" shift for ac_tag do case $ac_tag in :[FHLC]) ac_mode=$ac_tag; continue;; esac case $ac_mode$ac_tag in :[FHL]*:*);; :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; :[FH]-) ac_tag=-:-;; :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; esac ac_save_IFS=$IFS IFS=: set x $ac_tag IFS=$ac_save_IFS shift ac_file=$1 shift case $ac_mode in :L) ac_source=$1;; :[FH]) ac_file_inputs= for ac_f do case $ac_f in -) ac_f="$ac_tmp/stdin";; *) # Look for the file first in the build tree, then in the source tree # (if the path is not absolute). The absolute path cannot be DOS-style, # because $ac_f cannot contain `:'. test -f "$ac_f" || case $ac_f in [\\/$]*) false;; *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; esac || as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; esac case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac as_fn_append ac_file_inputs " '$ac_f'" done # Let's still pretend it is `configure' which instantiates (i.e., don't # use $as_me), people would be surprised to read: # /* config.h. Generated by config.status. */ configure_input='Generated from '` $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' `' by configure.' if test x"$ac_file" != x-; then configure_input="$ac_file. $configure_input" { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 $as_echo "$as_me: creating $ac_file" >&6;} fi # Neutralize special characters interpreted by sed in replacement strings. case $configure_input in #( *\&* | *\|* | *\\* ) ac_sed_conf_input=`$as_echo "$configure_input" | sed 's/[\\\\&|]/\\\\&/g'`;; #( *) ac_sed_conf_input=$configure_input;; esac case $ac_tag in *:-:* | *:-) cat >"$ac_tmp/stdin" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; esac ;; esac ac_dir=`$as_dirname -- "$ac_file" || $as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$ac_file" : 'X\(//\)[^/]' \| \ X"$ac_file" : 'X\(//\)$' \| \ X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$ac_file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` as_dir="$ac_dir"; as_fn_mkdir_p ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix case $ac_mode in :F) # # CONFIG_FILE # case $INSTALL in [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; esac ac_MKDIR_P=$MKDIR_P case $MKDIR_P in [\\/$]* | ?:[\\/]* ) ;; */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;; esac _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # If the template does not know about datarootdir, expand it. # FIXME: This hack should be removed a few years after 2.60. ac_datarootdir_hack=; ac_datarootdir_seen= ac_sed_dataroot=' /datarootdir/ { p q } /@datadir@/p /@docdir@/p /@infodir@/p /@localedir@/p /@mandir@/p' case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in *datarootdir*) ac_datarootdir_seen=yes;; *@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 $as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_datarootdir_hack=' s&@datadir@&$datadir&g s&@docdir@&$docdir&g s&@infodir@&$infodir&g s&@localedir@&$localedir&g s&@mandir@&$mandir&g s&\\\${datarootdir}&$datarootdir&g' ;; esac _ACEOF # Neutralize VPATH when `$srcdir' = `.'. # Shell code in configure.ac might set extrasub. # FIXME: do we really want to maintain this feature? cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_sed_extra="$ac_vpsub $extrasub _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 :t /@[a-zA-Z_][a-zA-Z_0-9]*@/!b s|@configure_input@|$ac_sed_conf_input|;t t s&@top_builddir@&$ac_top_builddir_sub&;t t s&@top_build_prefix@&$ac_top_build_prefix&;t t s&@srcdir@&$ac_srcdir&;t t s&@abs_srcdir@&$ac_abs_srcdir&;t t s&@top_srcdir@&$ac_top_srcdir&;t t s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t s&@builddir@&$ac_builddir&;t t s&@abs_builddir@&$ac_abs_builddir&;t t s&@abs_top_builddir@&$ac_abs_top_builddir&;t t s&@INSTALL@&$ac_INSTALL&;t t s&@MKDIR_P@&$ac_MKDIR_P&;t t $ac_datarootdir_hack " eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ "$ac_tmp/out"`; test -z "$ac_out"; } && { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&5 $as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&2;} rm -f "$ac_tmp/stdin" case $ac_file in -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; esac \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; :C) { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5 $as_echo "$as_me: executing $ac_file commands" >&6;} ;; esac case $ac_file$ac_mode in "depfiles":C) test x"$AMDEP_TRUE" != x"" || { # Older Autoconf quotes --file arguments for eval, but not when files # are listed without --file. Let's play safe and only enable the eval # if we detect the quoting. case $CONFIG_FILES in *\'*) eval set x "$CONFIG_FILES" ;; *) set x $CONFIG_FILES ;; esac shift for mf do # Strip MF so we end up with the name of the file. mf=`echo "$mf" | sed -e 's/:.*$//'` # Check whether this is an Automake generated Makefile or not. # We used to match only the files named 'Makefile.in', but # some people rename them; so instead we look at the file content. # Grep'ing the first line is not enough: some people post-process # each Makefile.in and add a new line on top of each file to say so. # Grep'ing the whole file is not good either: AIX grep has a line # limit of 2048, but all sed's we know have understand at least 4000. if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then dirpart=`$as_dirname -- "$mf" || $as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$mf" : 'X\(//\)[^/]' \| \ X"$mf" : 'X\(//\)$' \| \ X"$mf" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$mf" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` else continue fi # Extract the definition of DEPDIR, am__include, and am__quote # from the Makefile without running 'make'. DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` test -z "$DEPDIR" && continue am__include=`sed -n 's/^am__include = //p' < "$mf"` test -z "$am__include" && continue am__quote=`sed -n 's/^am__quote = //p' < "$mf"` # Find all dependency output files, they are included files with # $(DEPDIR) in their names. We invoke sed twice because it is the # simplest approach to changing $(DEPDIR) to its actual value in the # expansion. for file in `sed -n " s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do # Make sure the directory exists. test -f "$dirpart/$file" && continue fdir=`$as_dirname -- "$file" || $as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$file" : 'X\(//\)[^/]' \| \ X"$file" : 'X\(//\)$' \| \ X"$file" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` as_dir=$dirpart/$fdir; as_fn_mkdir_p # echo "creating $dirpart/$file" echo '# dummy' > "$dirpart/$file" done done } ;; "libtool":C) # See if we are running on zsh, and set the options which allow our # commands through without removal of \ escapes. if test -n "${ZSH_VERSION+set}" ; then setopt NO_GLOB_SUBST fi cfgfile="${ofile}T" trap "$RM \"$cfgfile\"; exit 1" 1 2 15 $RM "$cfgfile" cat <<_LT_EOF >> "$cfgfile" #! $SHELL # `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services. # Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION # Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: # NOTE: Changes made to this file will be lost: look at ltmain.sh. # # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, # 2006, 2007, 2008, 2009, 2010, 2011 Free Software # Foundation, Inc. # Written by Gordon Matzigkeit, 1996 # # This file is part of GNU Libtool. # # GNU Libtool is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License as # published by the Free Software Foundation; either version 2 of # the License, or (at your option) any later version. # # As a special exception to the GNU General Public License, # if you distribute this file as part of a program or library that # is built using GNU Libtool, you may include this file under the # same distribution terms that you use for the rest of that program. # # GNU Libtool is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with GNU Libtool; see the file COPYING. If not, a copy # can be downloaded from http://www.gnu.org/licenses/gpl.html, or # obtained by writing to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # The names of the tagged configurations supported by this script. available_tags="" # ### BEGIN LIBTOOL CONFIG # Which release of libtool.m4 was used? macro_version=$macro_version macro_revision=$macro_revision # Whether or not to build shared libraries. build_libtool_libs=$enable_shared # Whether or not to build static libraries. build_old_libs=$enable_static # What type of objects to build. pic_mode=$pic_mode # Whether or not to optimize for fast installation. fast_install=$enable_fast_install # Shell to use when invoking shell scripts. SHELL=$lt_SHELL # An echo program that protects backslashes. ECHO=$lt_ECHO # The PATH separator for the build system. PATH_SEPARATOR=$lt_PATH_SEPARATOR # The host system. host_alias=$host_alias host=$host host_os=$host_os # The build system. build_alias=$build_alias build=$build build_os=$build_os # A sed program that does not truncate output. SED=$lt_SED # Sed that helps us avoid accidentally triggering echo(1) options like -n. Xsed="\$SED -e 1s/^X//" # A grep program that handles long lines. GREP=$lt_GREP # An ERE matcher. EGREP=$lt_EGREP # A literal string matcher. FGREP=$lt_FGREP # A BSD- or MS-compatible name lister. NM=$lt_NM # Whether we need soft or hard links. LN_S=$lt_LN_S # What is the maximum length of a command? max_cmd_len=$max_cmd_len # Object file suffix (normally "o"). objext=$ac_objext # Executable file suffix (normally ""). exeext=$exeext # whether the shell understands "unset". lt_unset=$lt_unset # turn spaces into newlines. SP2NL=$lt_lt_SP2NL # turn newlines into spaces. NL2SP=$lt_lt_NL2SP # convert \$build file names to \$host format. to_host_file_cmd=$lt_cv_to_host_file_cmd # convert \$build files to toolchain format. to_tool_file_cmd=$lt_cv_to_tool_file_cmd # An object symbol dumper. OBJDUMP=$lt_OBJDUMP # Method to check whether dependent libraries are shared objects. deplibs_check_method=$lt_deplibs_check_method # Command to use when deplibs_check_method = "file_magic". file_magic_cmd=$lt_file_magic_cmd # How to find potential files when deplibs_check_method = "file_magic". file_magic_glob=$lt_file_magic_glob # Find potential files using nocaseglob when deplibs_check_method = "file_magic". want_nocaseglob=$lt_want_nocaseglob # DLL creation program. DLLTOOL=$lt_DLLTOOL # Command to associate shared and link libraries. sharedlib_from_linklib_cmd=$lt_sharedlib_from_linklib_cmd # The archiver. AR=$lt_AR # Flags to create an archive. AR_FLAGS=$lt_AR_FLAGS # How to feed a file listing to the archiver. archiver_list_spec=$lt_archiver_list_spec # A symbol stripping program. STRIP=$lt_STRIP # Commands used to install an old-style archive. RANLIB=$lt_RANLIB old_postinstall_cmds=$lt_old_postinstall_cmds old_postuninstall_cmds=$lt_old_postuninstall_cmds # Whether to use a lock for old archive extraction. lock_old_archive_extraction=$lock_old_archive_extraction # A C compiler. LTCC=$lt_CC # LTCC compiler flags. LTCFLAGS=$lt_CFLAGS # Take the output of nm and produce a listing of raw symbols and C names. global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe # Transform the output of nm in a proper C declaration. global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl # Transform the output of nm in a C name address pair. global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address # Transform the output of nm in a C name address pair when lib prefix is needed. global_symbol_to_c_name_address_lib_prefix=$lt_lt_cv_sys_global_symbol_to_c_name_address_lib_prefix # Specify filename containing input files for \$NM. nm_file_list_spec=$lt_nm_file_list_spec # The root where to search for dependent libraries,and in which our libraries should be installed. lt_sysroot=$lt_sysroot # The name of the directory that contains temporary libtool files. objdir=$objdir # Used to examine libraries when file_magic_cmd begins with "file". MAGIC_CMD=$MAGIC_CMD # Must we lock files when doing compilation? need_locks=$lt_need_locks # Manifest tool. MANIFEST_TOOL=$lt_MANIFEST_TOOL # Tool to manipulate archived DWARF debug symbol files on Mac OS X. DSYMUTIL=$lt_DSYMUTIL # Tool to change global to local symbols on Mac OS X. NMEDIT=$lt_NMEDIT # Tool to manipulate fat objects and archives on Mac OS X. LIPO=$lt_LIPO # ldd/readelf like tool for Mach-O binaries on Mac OS X. OTOOL=$lt_OTOOL # ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4. OTOOL64=$lt_OTOOL64 # Old archive suffix (normally "a"). libext=$libext # Shared library suffix (normally ".so"). shrext_cmds=$lt_shrext_cmds # The commands to extract the exported symbol list from a shared archive. extract_expsyms_cmds=$lt_extract_expsyms_cmds # Variables whose values should be saved in libtool wrapper scripts and # restored at link time. variables_saved_for_relink=$lt_variables_saved_for_relink # Do we need the "lib" prefix for modules? need_lib_prefix=$need_lib_prefix # Do we need a version for libraries? need_version=$need_version # Library versioning type. version_type=$version_type # Shared library runtime path variable. runpath_var=$runpath_var # Shared library path variable. shlibpath_var=$shlibpath_var # Is shlibpath searched before the hard-coded library search path? shlibpath_overrides_runpath=$shlibpath_overrides_runpath # Format of library name prefix. libname_spec=$lt_libname_spec # List of archive names. First name is the real one, the rest are links. # The last name is the one that the linker finds with -lNAME library_names_spec=$lt_library_names_spec # The coded name of the library, if different from the real name. soname_spec=$lt_soname_spec # Permission mode override for installation of shared libraries. install_override_mode=$lt_install_override_mode # Command to use after installation of a shared archive. postinstall_cmds=$lt_postinstall_cmds # Command to use after uninstallation of a shared archive. postuninstall_cmds=$lt_postuninstall_cmds # Commands used to finish a libtool library installation in a directory. finish_cmds=$lt_finish_cmds # As "finish_cmds", except a single script fragment to be evaled but # not shown. finish_eval=$lt_finish_eval # Whether we should hardcode library paths into libraries. hardcode_into_libs=$hardcode_into_libs # Compile-time system search path for libraries. sys_lib_search_path_spec=$lt_sys_lib_search_path_spec # Run-time system search path for libraries. sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec # Whether dlopen is supported. dlopen_support=$enable_dlopen # Whether dlopen of programs is supported. dlopen_self=$enable_dlopen_self # Whether dlopen of statically linked programs is supported. dlopen_self_static=$enable_dlopen_self_static # Commands to strip libraries. old_striplib=$lt_old_striplib striplib=$lt_striplib # The linker used to build libraries. LD=$lt_LD # How to create reloadable object files. reload_flag=$lt_reload_flag reload_cmds=$lt_reload_cmds # Commands used to build an old-style archive. old_archive_cmds=$lt_old_archive_cmds # A language specific compiler. CC=$lt_compiler # Is the compiler the GNU compiler? with_gcc=$GCC # Compiler flag to turn off builtin functions. no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag # Additional compiler flags for building library objects. pic_flag=$lt_lt_prog_compiler_pic # How to pass a linker flag through the compiler. wl=$lt_lt_prog_compiler_wl # Compiler flag to prevent dynamic linking. link_static_flag=$lt_lt_prog_compiler_static # Does compiler simultaneously support -c and -o options? compiler_c_o=$lt_lt_cv_prog_compiler_c_o # Whether or not to add -lc for building shared libraries. build_libtool_need_lc=$archive_cmds_need_lc # Whether or not to disallow shared libs when runtime libs are static. allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes # Compiler flag to allow reflexive dlopens. export_dynamic_flag_spec=$lt_export_dynamic_flag_spec # Compiler flag to generate shared objects directly from archives. whole_archive_flag_spec=$lt_whole_archive_flag_spec # Whether the compiler copes with passing no objects directly. compiler_needs_object=$lt_compiler_needs_object # Create an old-style archive from a shared archive. old_archive_from_new_cmds=$lt_old_archive_from_new_cmds # Create a temporary old-style archive to link instead of a shared archive. old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds # Commands used to build a shared archive. archive_cmds=$lt_archive_cmds archive_expsym_cmds=$lt_archive_expsym_cmds # Commands used to build a loadable module if different from building # a shared archive. module_cmds=$lt_module_cmds module_expsym_cmds=$lt_module_expsym_cmds # Whether we are building with GNU ld or not. with_gnu_ld=$lt_with_gnu_ld # Flag that allows shared libraries with undefined symbols to be built. allow_undefined_flag=$lt_allow_undefined_flag # Flag that enforces no undefined symbols. no_undefined_flag=$lt_no_undefined_flag # Flag to hardcode \$libdir into a binary during linking. # This must work even if \$libdir does not exist hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec # Whether we need a single "-rpath" flag with a separated argument. hardcode_libdir_separator=$lt_hardcode_libdir_separator # Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes # DIR into the resulting binary. hardcode_direct=$hardcode_direct # Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes # DIR into the resulting binary and the resulting library dependency is # "absolute",i.e impossible to change by setting \${shlibpath_var} if the # library is relocated. hardcode_direct_absolute=$hardcode_direct_absolute # Set to "yes" if using the -LDIR flag during linking hardcodes DIR # into the resulting binary. hardcode_minus_L=$hardcode_minus_L # Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR # into the resulting binary. hardcode_shlibpath_var=$hardcode_shlibpath_var # Set to "yes" if building a shared library automatically hardcodes DIR # into the library and all subsequent libraries and executables linked # against it. hardcode_automatic=$hardcode_automatic # Set to yes if linker adds runtime paths of dependent libraries # to runtime path list. inherit_rpath=$inherit_rpath # Whether libtool must link a program against all its dependency libraries. link_all_deplibs=$link_all_deplibs # Set to "yes" if exported symbols are required. always_export_symbols=$always_export_symbols # The commands to list exported symbols. export_symbols_cmds=$lt_export_symbols_cmds # Symbols that should not be listed in the preloaded symbols. exclude_expsyms=$lt_exclude_expsyms # Symbols that must always be exported. include_expsyms=$lt_include_expsyms # Commands necessary for linking programs (against libraries) with templates. prelink_cmds=$lt_prelink_cmds # Commands necessary for finishing linking programs. postlink_cmds=$lt_postlink_cmds # Specify filename containing input files. file_list_spec=$lt_file_list_spec # How to hardcode a shared library path into an executable. hardcode_action=$hardcode_action # ### END LIBTOOL CONFIG _LT_EOF case $host_os in aix3*) cat <<\_LT_EOF >> "$cfgfile" # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. if test "X${COLLECT_NAMES+set}" != Xset; then COLLECT_NAMES= export COLLECT_NAMES fi _LT_EOF ;; esac ltmain="$ac_aux_dir/ltmain.sh" # We use sed instead of cat because bash on DJGPP gets confused if # if finds mixed CR/LF and LF-only lines. Since sed operates in # text mode, it properly converts lines to CR/LF. This bash problem # is reportedly fixed, but why not run on old versions too? sed '$q' "$ltmain" >> "$cfgfile" \ || (rm -f "$cfgfile"; exit 1) if test x"$xsi_shell" = xyes; then sed -e '/^func_dirname ()$/,/^} # func_dirname /c\ func_dirname ()\ {\ \ case ${1} in\ \ */*) func_dirname_result="${1%/*}${2}" ;;\ \ * ) func_dirname_result="${3}" ;;\ \ esac\ } # Extended-shell func_dirname implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: sed -e '/^func_basename ()$/,/^} # func_basename /c\ func_basename ()\ {\ \ func_basename_result="${1##*/}"\ } # Extended-shell func_basename implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: sed -e '/^func_dirname_and_basename ()$/,/^} # func_dirname_and_basename /c\ func_dirname_and_basename ()\ {\ \ case ${1} in\ \ */*) func_dirname_result="${1%/*}${2}" ;;\ \ * ) func_dirname_result="${3}" ;;\ \ esac\ \ func_basename_result="${1##*/}"\ } # Extended-shell func_dirname_and_basename implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: sed -e '/^func_stripname ()$/,/^} # func_stripname /c\ func_stripname ()\ {\ \ # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are\ \ # positional parameters, so assign one to ordinary parameter first.\ \ func_stripname_result=${3}\ \ func_stripname_result=${func_stripname_result#"${1}"}\ \ func_stripname_result=${func_stripname_result%"${2}"}\ } # Extended-shell func_stripname implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: sed -e '/^func_split_long_opt ()$/,/^} # func_split_long_opt /c\ func_split_long_opt ()\ {\ \ func_split_long_opt_name=${1%%=*}\ \ func_split_long_opt_arg=${1#*=}\ } # Extended-shell func_split_long_opt implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: sed -e '/^func_split_short_opt ()$/,/^} # func_split_short_opt /c\ func_split_short_opt ()\ {\ \ func_split_short_opt_arg=${1#??}\ \ func_split_short_opt_name=${1%"$func_split_short_opt_arg"}\ } # Extended-shell func_split_short_opt implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: sed -e '/^func_lo2o ()$/,/^} # func_lo2o /c\ func_lo2o ()\ {\ \ case ${1} in\ \ *.lo) func_lo2o_result=${1%.lo}.${objext} ;;\ \ *) func_lo2o_result=${1} ;;\ \ esac\ } # Extended-shell func_lo2o implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: sed -e '/^func_xform ()$/,/^} # func_xform /c\ func_xform ()\ {\ func_xform_result=${1%.*}.lo\ } # Extended-shell func_xform implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: sed -e '/^func_arith ()$/,/^} # func_arith /c\ func_arith ()\ {\ func_arith_result=$(( $* ))\ } # Extended-shell func_arith implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: sed -e '/^func_len ()$/,/^} # func_len /c\ func_len ()\ {\ func_len_result=${#1}\ } # Extended-shell func_len implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: fi if test x"$lt_shell_append" = xyes; then sed -e '/^func_append ()$/,/^} # func_append /c\ func_append ()\ {\ eval "${1}+=\\${2}"\ } # Extended-shell func_append implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: sed -e '/^func_append_quoted ()$/,/^} # func_append_quoted /c\ func_append_quoted ()\ {\ \ func_quote_for_eval "${2}"\ \ eval "${1}+=\\\\ \\$func_quote_for_eval_result"\ } # Extended-shell func_append_quoted implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: # Save a `func_append' function call where possible by direct use of '+=' sed -e 's%func_append \([a-zA-Z_]\{1,\}\) "%\1+="%g' $cfgfile > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: else # Save a `func_append' function call even when '+=' is not available sed -e 's%func_append \([a-zA-Z_]\{1,\}\) "%\1="$\1%g' $cfgfile > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: fi if test x"$_lt_function_replace_fail" = x":"; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Unable to substitute extended shell functions in $ofile" >&5 $as_echo "$as_me: WARNING: Unable to substitute extended shell functions in $ofile" >&2;} fi mv -f "$cfgfile" "$ofile" || (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") chmod +x "$ofile" ;; esac done # for ac_tag as_fn_exit 0 _ACEOF ac_clean_files=$ac_clean_files_save test $ac_write_fail = 0 || as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 # configure is writing to config.log, and then calls config.status. # config.status does its own redirection, appending to config.log. # Unfortunately, on DOS this fails, as config.log is still kept open # by configure, so config.status won't be able to write to it; its # output is simply discarded. So we exec the FD to /dev/null, # effectively closing config.log, so it can be properly (re)opened and # appended to by config.status. When coming back to configure, we # need to make the FD available again. if test "$no_create" != yes; then ac_cs_success=: ac_config_status_args= test "$silent" = yes && ac_config_status_args="$ac_config_status_args --quiet" exec 5>/dev/null $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false exec 5>>config.log # Use ||, not &&, to avoid exiting from the if with $? = 1, which # would make configure fail if this is the last instruction. $ac_cs_success || as_fn_exit 1 fi if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} fi ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������libburn-1.4.2/missing�������������������������������������������������������������������������������0000755�0001757�0001751�00000015330�12652650102�011504� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������#! /bin/sh # Common wrapper for a few potentially missing GNU programs. scriptversion=2013-10-28.13; # UTC # Copyright (C) 1996-2013 Free Software Foundation, Inc. # Originally written by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. if test $# -eq 0; then echo 1>&2 "Try '$0 --help' for more information" exit 1 fi case $1 in --is-lightweight) # Used by our autoconf macros to check whether the available missing # script is modern enough. exit 0 ;; --run) # Back-compat with the calling convention used by older automake. shift ;; -h|--h|--he|--hel|--help) echo "\ $0 [OPTION]... PROGRAM [ARGUMENT]... Run 'PROGRAM [ARGUMENT]...', returning a proper advice when this fails due to PROGRAM being missing or too old. Options: -h, --help display this help and exit -v, --version output version information and exit Supported PROGRAM values: aclocal autoconf autoheader autom4te automake makeinfo bison yacc flex lex help2man Version suffixes to PROGRAM as well as the prefixes 'gnu-', 'gnu', and 'g' are ignored when checking the name. Send bug reports to <bug-automake@gnu.org>." exit $? ;; -v|--v|--ve|--ver|--vers|--versi|--versio|--version) echo "missing $scriptversion (GNU Automake)" exit $? ;; -*) echo 1>&2 "$0: unknown '$1' option" echo 1>&2 "Try '$0 --help' for more information" exit 1 ;; esac # Run the given program, remember its exit status. "$@"; st=$? # If it succeeded, we are done. test $st -eq 0 && exit 0 # Also exit now if we it failed (or wasn't found), and '--version' was # passed; such an option is passed most likely to detect whether the # program is present and works. case $2 in --version|--help) exit $st;; esac # Exit code 63 means version mismatch. This often happens when the user # tries to use an ancient version of a tool on a file that requires a # minimum version. if test $st -eq 63; then msg="probably too old" elif test $st -eq 127; then # Program was missing. msg="missing on your system" else # Program was found and executed, but failed. Give up. exit $st fi perl_URL=http://www.perl.org/ flex_URL=http://flex.sourceforge.net/ gnu_software_URL=http://www.gnu.org/software program_details () { case $1 in aclocal|automake) echo "The '$1' program is part of the GNU Automake package:" echo "<$gnu_software_URL/automake>" echo "It also requires GNU Autoconf, GNU m4 and Perl in order to run:" echo "<$gnu_software_URL/autoconf>" echo "<$gnu_software_URL/m4/>" echo "<$perl_URL>" ;; autoconf|autom4te|autoheader) echo "The '$1' program is part of the GNU Autoconf package:" echo "<$gnu_software_URL/autoconf/>" echo "It also requires GNU m4 and Perl in order to run:" echo "<$gnu_software_URL/m4/>" echo "<$perl_URL>" ;; esac } give_advice () { # Normalize program name to check for. normalized_program=`echo "$1" | sed ' s/^gnu-//; t s/^gnu//; t s/^g//; t'` printf '%s\n' "'$1' is $msg." configure_deps="'configure.ac' or m4 files included by 'configure.ac'" case $normalized_program in autoconf*) echo "You should only need it if you modified 'configure.ac'," echo "or m4 files included by it." program_details 'autoconf' ;; autoheader*) echo "You should only need it if you modified 'acconfig.h' or" echo "$configure_deps." program_details 'autoheader' ;; automake*) echo "You should only need it if you modified 'Makefile.am' or" echo "$configure_deps." program_details 'automake' ;; aclocal*) echo "You should only need it if you modified 'acinclude.m4' or" echo "$configure_deps." program_details 'aclocal' ;; autom4te*) echo "You might have modified some maintainer files that require" echo "the 'autom4te' program to be rebuilt." program_details 'autom4te' ;; bison*|yacc*) echo "You should only need it if you modified a '.y' file." echo "You may want to install the GNU Bison package:" echo "<$gnu_software_URL/bison/>" ;; lex*|flex*) echo "You should only need it if you modified a '.l' file." echo "You may want to install the Fast Lexical Analyzer package:" echo "<$flex_URL>" ;; help2man*) echo "You should only need it if you modified a dependency" \ "of a man page." echo "You may want to install the GNU Help2man package:" echo "<$gnu_software_URL/help2man/>" ;; makeinfo*) echo "You should only need it if you modified a '.texi' file, or" echo "any other file indirectly affecting the aspect of the manual." echo "You might want to install the Texinfo package:" echo "<$gnu_software_URL/texinfo/>" echo "The spurious makeinfo call might also be the consequence of" echo "using a buggy 'make' (AIX, DU, IRIX), in which case you might" echo "want to install GNU make:" echo "<$gnu_software_URL/make/>" ;; *) echo "You might have modified some files without having the proper" echo "tools for further handling them. Check the 'README' file, it" echo "often tells you about the needed prerequisites for installing" echo "this package. You may also peek at any GNU archive site, in" echo "case some other package contains this missing '$1' program." ;; esac } give_advice "$1" | sed -e '1s/^/WARNING: /' \ -e '2,$s/^/ /' >&2 # Propagate the correct exit status (expected to be 127 for a program # not found, 63 for a program that failed due to version mismatch). exit $st # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC" # time-stamp-end: "; # UTC" # End: ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������libburn-1.4.2/Makefile.am���������������������������������������������������������������������������0000644�0001757�0001751�00000013672�12652644224�012160� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ # ts A90315 : LIBBURNIA_PKGCONFDIR is defined OS specific in acinclude.m4 # was: pkgconfigdir=$(libdir)/pkgconfig pkgconfigdir=$(LIBBURNIA_PKGCONFDIR) libincludedir=$(includedir)/libburn lib_LTLIBRARIES = libburn/libburn.la ACLOCAL_AMFLAGS = -I ./ ## ========================================================================= ## # Build libraries libburn_libburn_la_LDFLAGS = \ -version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE) # This causes undesired .o names # configure.ac appends -D options to variable CFLAG ### libburn_libburn_la_CFLAGS = $(LIBBURN_DVD_OBS_64K) libburn_libburn_la_LIBADD = $(LIBBURN_ARCH_LIBS) $(THREAD_LIBS) libburn_libburn_la_SOURCES = \ libburn/async.c \ libburn/async.h \ libburn/back_hacks.h \ libburn/cdtext.c \ libburn/cleanup.c \ libburn/cleanup.h \ libburn/crc.c \ libburn/crc.h \ libburn/debug.c \ libburn/debug.h \ libburn/drive.c \ libburn/drive.h \ libburn/ecma130ab.c \ libburn/ecma130ab.h \ libburn/error.h \ libburn/file.c \ libburn/file.h \ libburn/init.c \ libburn/init.h \ libburn/libburn.h \ libburn/libdax_audioxtr.h \ libburn/libdax_audioxtr.c \ libburn/libdax_msgs.h \ libburn/libdax_msgs.c \ libburn/mmc.c \ libburn/mmc.h \ libburn/null.c \ libburn/null.h \ libburn/options.c \ libburn/options.h \ libburn/os.h \ libburn/read.c \ libburn/read.h \ libburn/sbc.c \ libburn/sbc.h \ libburn/sector.c \ libburn/sector.h \ libburn/sg.c \ libburn/sg.h \ libburn/source.h \ libburn/source.c \ libburn/spc.c \ libburn/spc.h \ libburn/structure.c \ libburn/structure.h \ libburn/toc.c \ libburn/toc.h \ libburn/transport.h \ libburn/util.c \ libburn/util.h \ libburn/write.c \ libburn/write.h ## libburn/sg-@ARCH@.c \ libinclude_HEADERS = \ libburn/libburn.h install-exec-hook: $(LIBBURNIA_LDCONFIG_CMD) "$(DESTDIR)$(libdir)" || echo 'NOTE: Explicit dynamic library configuration failed. If needed, configure manually for:' "$(DESTDIR)$(libdir)" ## ========================================================================= ## ## Build test applications noinst_PROGRAMS = \ test/libburner \ test/offst_source \ test/telltoc \ test/dewav \ test/fake_au \ test/poll bin_PROGRAMS = \ cdrskin/cdrskin LIBBURN_EXTRALIBS = $(LIBBURN_ARCH_LIBS) $(THREAD_LIBS) test_libburner_CPPFLAGS = -Ilibburn test_libburner_LDADD = $(libburn_libburn_la_OBJECTS) $(LIBBURN_EXTRALIBS) test_libburner_SOURCES = test/libburner.c test_offst_source_CPPFLAGS = -Ilibburn test_offst_source_LDADD = $(libburn_libburn_la_OBJECTS) $(LIBBURN_EXTRALIBS) test_offst_source_SOURCES = test/offst_source.c test_telltoc_CPPFLAGS = -Ilibburn test_telltoc_LDADD = $(libburn_libburn_la_OBJECTS) $(LIBBURN_EXTRALIBS) test_telltoc_SOURCES = test/telltoc.c test_dewav_CPPFLAGS = -Ilibburn test_dewav_LDADD = $(libburn_libburn_la_OBJECTS) $(LIBBURN_EXTRALIBS) test_dewav_SOURCES = test/dewav.c test_fake_au_CPPFLAGS = test_fake_au_LDADD = test_fake_au_SOURCES = test/fake_au.c test_poll_CPPFLAGS = -Ilibburn test_poll_LDADD = $(libburn_libburn_la_OBJECTS) $(LIBBURN_EXTRALIBS) test_poll_SOURCES = test/poll.c ## cdrskin construction site - ts A60816 - B51128 cdrskin_cdrskin_CPPFLAGS = -Ilibburn cdrskin_cdrskin_CFLAGS = -DCdrskin_libburn_1_4_2 # cdrskin_cdrskin_LDADD = $(libburn_libburn_la_OBJECTS) $(LIBBURN_EXTRALIBS) # ts A80123, change proposed by Simon Huggins to cause dynamic libburn linking cdrskin_cdrskin_LDADD = libburn/libburn.la $(LIBBURN_EXTRALIBS) cdrskin_cdrskin_SOURCES = cdrskin/cdrskin.c cdrskin/cdrfifo.c cdrskin/cdrfifo.h cdrskin/cdrskin_timestamp.h ## ## Open questions: how to compute $timestamp and express -DX="$timestamp" ## # "make clean" shall remove a few stubborn .libs directories # which George Danchev reported Dec 03 2011. # Learned from: http://www.gnu.org/software/automake/manual/automake.html#Clean clean-local: -rm -rf cdrskin/.libs test/.libs ## ========================================================================= ## ## Build documentation (You need Doxygen for this to work) webhost = http://libburn-api.pykix.org webpath = / docdir = $(DESTDIR)$(prefix)/share/doc/$(PACKAGE)-$(VERSION) doc: doc/html doc/html: doc/doxygen.conf if [ -f ./doc/doc.lock ]; then \ $(RM) -r doc/html; \ doxygen doc/doxygen.conf; \ fi doc-upload: doc/html scp -r $</* $(webhost):$(webpath) ## ts B00729 ## Not by default any more. ## It is unclear who is supposed to create file ./doc/doc.lock # all: doc install-data-local: if [ -f ./doc/doc.lock ]; then \ $(mkinstalldirs) $(docdir)/html; \ $(INSTALL_DATA) doc/html/* $(docdir)/html; \ fi uninstall-local: rm -rf $(docdir) ## ========================================================================= ## # Indent source files indent_files = \ $(libburn_libburn_la_SOURCES) \ $(test_poll_SOURCES) indent: $(indent_files) indent -bad -bap -nbbb -nbbo -nbc -bli0 -br -bls \ -cdw -ce -cli0 -ncs -nbfda -i8 -l79 -lc79 \ -lp -saf -sai -nprs -npsl -saw -sob -ss -ut \ -sbi0 -nsc -ts8 -npcs -ncdb -fca \ $^ .PHONY: indent ## ========================================================================= ## # Extra things nodist_pkgconfig_DATA = \ libburn-1.pc # http://www.nada.kth.se/cgi-bin/info?(automake.info)Man%20pages man_MANS = cdrskin/cdrskin.1 EXTRA_DIST = \ bootstrap \ libburn-1.pc.in \ version.h.in \ doc/comments \ doc/doxygen.conf.in \ doc/cookbook.txt \ doc/mediainfo.txt \ doc/cdtext.txt \ README \ AUTHORS \ CONTRIBUTORS \ COPYRIGHT \ cdrskin/README \ cdrskin/cdrecord_spy.sh \ cdrskin/compile_cdrskin.sh \ cdrskin/convert_man_to_html.sh \ cdrskin/changelog.txt \ cdrskin/cdrskin_eng.html \ cdrskin/wiki_plain.txt \ cdrskin/cleanup.h \ cdrskin/cleanup.c \ libburn/libburn.ver \ libburn/os-dummy.h \ libburn/os-freebsd.h \ libburn/os-linux.h \ libburn/os-libcdio.h \ libburn/os-solaris.h \ libburn/os-netbsd.h \ libburn/sg-dummy.c \ libburn/sg-freebsd.c \ libburn/sg-linux.c \ libburn/sg-libcdio.c \ libburn/sg-solaris.c \ libburn/sg-netbsd.c \ COPYING \ NEWS \ ChangeLog \ INSTALL \ $(man_MANS) ����������������������������������������������������������������������libburn-1.4.2/config.sub����������������������������������������������������������������������������0000755�0001757�0001751�00000105775�12652650102�012105� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������#! /bin/sh # Configuration validation subroutine script. # Copyright 1992-2014 Free Software Foundation, Inc. timestamp='2014-09-11' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, see <http://www.gnu.org/licenses/>. # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that # program. This Exception is an additional permission under section 7 # of the GNU General Public License, version 3 ("GPLv3"). # Please send patches with a ChangeLog entry to config-patches@gnu.org. # # Configuration subroutine to validate and canonicalize a configuration type. # Supply the specified configuration type as an argument. # If it is invalid, we print an error message on stderr and exit with code 1. # Otherwise, we print the canonical config type on stdout and succeed. # You can get the latest version of this script from: # http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD # This file is supposed to be the same for all GNU packages # and recognize all the CPU types, system types and aliases # that are meaningful with *any* GNU software. # Each package is responsible for reporting which valid configurations # it does not support. The user should be able to distinguish # a failure to support a valid configuration from a meaningless # configuration. # The goal of this file is to map all the various variations of a given # machine specification into a single specification in the form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM # or in some cases, the newer four-part form: # CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM # It is wrong to echo any other type of specification. me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] CPU-MFR-OPSYS $0 [OPTION] ALIAS Canonicalize a configuration name. Operation modes: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit Report bugs and patches to <config-patches@gnu.org>." version="\ GNU config.sub ($timestamp) Copyright 1992-2014 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" Try \`$me --help' for more information." # Parse command line while test $# -gt 0 ; do case $1 in --time-stamp | --time* | -t ) echo "$timestamp" ; exit ;; --version | -v ) echo "$version" ; exit ;; --help | --h* | -h ) echo "$usage"; exit ;; -- ) # Stop option processing shift; break ;; - ) # Use stdin as input. break ;; -* ) echo "$me: invalid option $1$help" exit 1 ;; *local*) # First pass through any local machine types. echo $1 exit ;; * ) break ;; esac done case $# in 0) echo "$me: missing argument$help" >&2 exit 1;; 1) ;; *) echo "$me: too many arguments$help" >&2 exit 1;; esac # Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). # Here we must recognize all the valid KERNEL-OS combinations. maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` case $maybe_os in nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \ linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \ knetbsd*-gnu* | netbsd*-gnu* | \ kopensolaris*-gnu* | \ storm-chaos* | os2-emx* | rtmk-nova*) os=-$maybe_os basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` ;; android-linux) os=-linux-android basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown ;; *) basic_machine=`echo $1 | sed 's/-[^-]*$//'` if [ $basic_machine != $1 ] then os=`echo $1 | sed 's/.*-/-/'` else os=; fi ;; esac ### Let's recognize common machines as not being operating systems so ### that things like config.sub decstation-3100 work. We also ### recognize some manufacturers as not being operating systems, so we ### can provide default operating systems below. case $os in -sun*os*) # Prevent following clause from handling this invalid input. ;; -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ -apple | -axis | -knuth | -cray | -microblaze*) os= basic_machine=$1 ;; -bluegene*) os=-cnk ;; -sim | -cisco | -oki | -wec | -winbond) os= basic_machine=$1 ;; -scout) ;; -wrs) os=-vxworks basic_machine=$1 ;; -chorusos*) os=-chorusos basic_machine=$1 ;; -chorusrdb) os=-chorusrdb basic_machine=$1 ;; -hiux*) os=-hiuxwe2 ;; -sco6) os=-sco5v6 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco5) os=-sco3.2v5 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco4) os=-sco3.2v4 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco3.2.[4-9]*) os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco3.2v[4-9]*) # Don't forget version if it is 3.2v4 or newer. basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco5v6*) # Don't forget version if it is 3.2v4 or newer. basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco*) os=-sco3.2v2 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -udk*) basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -isc) os=-isc2.2 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -clix*) basic_machine=clipper-intergraph ;; -isc*) basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -lynx*178) os=-lynxos178 ;; -lynx*5) os=-lynxos5 ;; -lynx*) os=-lynxos ;; -ptx*) basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` ;; -windowsnt*) os=`echo $os | sed -e 's/windowsnt/winnt/'` ;; -psos*) os=-psos ;; -mint | -mint[0-9]*) basic_machine=m68k-atari os=-mint ;; esac # Decode aliases for certain CPU-COMPANY combinations. case $basic_machine in # Recognize the basic CPU types without company name. # Some are omitted here because they have special meanings below. 1750a | 580 \ | a29k \ | aarch64 | aarch64_be \ | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ | am33_2.0 \ | arc | arceb \ | arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \ | avr | avr32 \ | be32 | be64 \ | bfin \ | c4x | c8051 | clipper \ | d10v | d30v | dlx | dsp16xx \ | epiphany \ | fido | fr30 | frv \ | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ | hexagon \ | i370 | i860 | i960 | ia64 \ | ip2k | iq2000 \ | k1om \ | le32 | le64 \ | lm32 \ | m32c | m32r | m32rle | m68000 | m68k | m88k \ | maxq | mb | microblaze | microblazeel | mcore | mep | metag \ | mips | mipsbe | mipseb | mipsel | mipsle \ | mips16 \ | mips64 | mips64el \ | mips64octeon | mips64octeonel \ | mips64orion | mips64orionel \ | mips64r5900 | mips64r5900el \ | mips64vr | mips64vrel \ | mips64vr4100 | mips64vr4100el \ | mips64vr4300 | mips64vr4300el \ | mips64vr5000 | mips64vr5000el \ | mips64vr5900 | mips64vr5900el \ | mipsisa32 | mipsisa32el \ | mipsisa32r2 | mipsisa32r2el \ | mipsisa32r6 | mipsisa32r6el \ | mipsisa64 | mipsisa64el \ | mipsisa64r2 | mipsisa64r2el \ | mipsisa64r6 | mipsisa64r6el \ | mipsisa64sb1 | mipsisa64sb1el \ | mipsisa64sr71k | mipsisa64sr71kel \ | mipsr5900 | mipsr5900el \ | mipstx39 | mipstx39el \ | mn10200 | mn10300 \ | moxie \ | mt \ | msp430 \ | nds32 | nds32le | nds32be \ | nios | nios2 | nios2eb | nios2el \ | ns16k | ns32k \ | open8 | or1k | or1knd | or32 \ | pdp10 | pdp11 | pj | pjl \ | powerpc | powerpc64 | powerpc64le | powerpcle \ | pyramid \ | riscv32 | riscv64 \ | rl78 | rx \ | score \ | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ | sh64 | sh64le \ | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ | spu \ | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \ | ubicom32 \ | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \ | we32k \ | x86 | xc16x | xstormy16 | xtensa \ | z8k | z80) basic_machine=$basic_machine-unknown ;; c54x) basic_machine=tic54x-unknown ;; c55x) basic_machine=tic55x-unknown ;; c6x) basic_machine=tic6x-unknown ;; m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip) basic_machine=$basic_machine-unknown os=-none ;; m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) ;; ms1) basic_machine=mt-unknown ;; strongarm | thumb | xscale) basic_machine=arm-unknown ;; xgate) basic_machine=$basic_machine-unknown os=-none ;; xscaleeb) basic_machine=armeb-unknown ;; xscaleel) basic_machine=armel-unknown ;; # We use `pc' rather than `unknown' # because (1) that's what they normally are, and # (2) the word "unknown" tends to confuse beginning users. i*86 | x86_64) basic_machine=$basic_machine-pc ;; # Object if more than one company name word. *-*-*) echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 exit 1 ;; # Recognize the basic CPU types with company name. 580-* \ | a29k-* \ | aarch64-* | aarch64_be-* \ | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ | alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \ | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ | avr-* | avr32-* \ | be32-* | be64-* \ | bfin-* | bs2000-* \ | c[123]* | c30-* | [cjt]90-* | c4x-* \ | c8051-* | clipper-* | craynv-* | cydra-* \ | d10v-* | d30v-* | dlx-* \ | elxsi-* \ | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ | h8300-* | h8500-* \ | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ | hexagon-* \ | i*86-* | i860-* | i960-* | ia64-* \ | ip2k-* | iq2000-* \ | k1om-* \ | le32-* | le64-* \ | lm32-* \ | m32c-* | m32r-* | m32rle-* \ | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \ | microblaze-* | microblazeel-* \ | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ | mips16-* \ | mips64-* | mips64el-* \ | mips64octeon-* | mips64octeonel-* \ | mips64orion-* | mips64orionel-* \ | mips64r5900-* | mips64r5900el-* \ | mips64vr-* | mips64vrel-* \ | mips64vr4100-* | mips64vr4100el-* \ | mips64vr4300-* | mips64vr4300el-* \ | mips64vr5000-* | mips64vr5000el-* \ | mips64vr5900-* | mips64vr5900el-* \ | mipsisa32-* | mipsisa32el-* \ | mipsisa32r2-* | mipsisa32r2el-* \ | mipsisa32r6-* | mipsisa32r6el-* \ | mipsisa64-* | mipsisa64el-* \ | mipsisa64r2-* | mipsisa64r2el-* \ | mipsisa64r6-* | mipsisa64r6el-* \ | mipsisa64sb1-* | mipsisa64sb1el-* \ | mipsisa64sr71k-* | mipsisa64sr71kel-* \ | mipsr5900-* | mipsr5900el-* \ | mipstx39-* | mipstx39el-* \ | mmix-* \ | mt-* \ | msp430-* \ | nds32-* | nds32le-* | nds32be-* \ | nios-* | nios2-* | nios2eb-* | nios2el-* \ | none-* | np1-* | ns16k-* | ns32k-* \ | open8-* \ | or1k*-* \ | orion-* \ | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \ | pyramid-* \ | rl78-* | romp-* | rs6000-* | rx-* \ | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ | sparclite-* \ | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \ | tahoe-* \ | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ | tile*-* \ | tron-* \ | ubicom32-* \ | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \ | vax-* \ | we32k-* \ | x86-* | x86_64-* | xc16x-* | xps100-* \ | xstormy16-* | xtensa*-* \ | ymp-* \ | z8k-* | z80-*) ;; # Recognize the basic CPU types without company name, with glob match. xtensa*) basic_machine=$basic_machine-unknown ;; # Recognize the various machine names and aliases which stand # for a CPU type and a company and sometimes even an OS. 386bsd) basic_machine=i386-unknown os=-bsd ;; 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) basic_machine=m68000-att ;; 3b*) basic_machine=we32k-att ;; a29khif) basic_machine=a29k-amd os=-udi ;; abacus) basic_machine=abacus-unknown ;; adobe68k) basic_machine=m68010-adobe os=-scout ;; alliant | fx80) basic_machine=fx80-alliant ;; altos | altos3068) basic_machine=m68k-altos ;; am29k) basic_machine=a29k-none os=-bsd ;; amd64) basic_machine=x86_64-pc ;; amd64-*) basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` ;; amdahl) basic_machine=580-amdahl os=-sysv ;; amiga | amiga-*) basic_machine=m68k-unknown ;; amigaos | amigados) basic_machine=m68k-unknown os=-amigaos ;; amigaunix | amix) basic_machine=m68k-unknown os=-sysv4 ;; apollo68) basic_machine=m68k-apollo os=-sysv ;; apollo68bsd) basic_machine=m68k-apollo os=-bsd ;; aros) basic_machine=i386-pc os=-aros ;; aux) basic_machine=m68k-apple os=-aux ;; balance) basic_machine=ns32k-sequent os=-dynix ;; blackfin) basic_machine=bfin-unknown os=-linux ;; blackfin-*) basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'` os=-linux ;; bluegene*) basic_machine=powerpc-ibm os=-cnk ;; c54x-*) basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'` ;; c55x-*) basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'` ;; c6x-*) basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'` ;; c90) basic_machine=c90-cray os=-unicos ;; cegcc) basic_machine=arm-unknown os=-cegcc ;; convex-c1) basic_machine=c1-convex os=-bsd ;; convex-c2) basic_machine=c2-convex os=-bsd ;; convex-c32) basic_machine=c32-convex os=-bsd ;; convex-c34) basic_machine=c34-convex os=-bsd ;; convex-c38) basic_machine=c38-convex os=-bsd ;; cray | j90) basic_machine=j90-cray os=-unicos ;; craynv) basic_machine=craynv-cray os=-unicosmp ;; cr16 | cr16-*) basic_machine=cr16-unknown os=-elf ;; crds | unos) basic_machine=m68k-crds ;; crisv32 | crisv32-* | etraxfs*) basic_machine=crisv32-axis ;; cris | cris-* | etrax*) basic_machine=cris-axis ;; crx) basic_machine=crx-unknown os=-elf ;; da30 | da30-*) basic_machine=m68k-da30 ;; decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) basic_machine=mips-dec ;; decsystem10* | dec10*) basic_machine=pdp10-dec os=-tops10 ;; decsystem20* | dec20*) basic_machine=pdp10-dec os=-tops20 ;; delta | 3300 | motorola-3300 | motorola-delta \ | 3300-motorola | delta-motorola) basic_machine=m68k-motorola ;; delta88) basic_machine=m88k-motorola os=-sysv3 ;; dicos) basic_machine=i686-pc os=-dicos ;; djgpp) basic_machine=i586-pc os=-msdosdjgpp ;; dpx20 | dpx20-*) basic_machine=rs6000-bull os=-bosx ;; dpx2* | dpx2*-bull) basic_machine=m68k-bull os=-sysv3 ;; ebmon29k) basic_machine=a29k-amd os=-ebmon ;; elxsi) basic_machine=elxsi-elxsi os=-bsd ;; encore | umax | mmax) basic_machine=ns32k-encore ;; es1800 | OSE68k | ose68k | ose | OSE) basic_machine=m68k-ericsson os=-ose ;; fx2800) basic_machine=i860-alliant ;; genix) basic_machine=ns32k-ns ;; gmicro) basic_machine=tron-gmicro os=-sysv ;; go32) basic_machine=i386-pc os=-go32 ;; h3050r* | hiux*) basic_machine=hppa1.1-hitachi os=-hiuxwe2 ;; h8300hms) basic_machine=h8300-hitachi os=-hms ;; h8300xray) basic_machine=h8300-hitachi os=-xray ;; h8500hms) basic_machine=h8500-hitachi os=-hms ;; harris) basic_machine=m88k-harris os=-sysv3 ;; hp300-*) basic_machine=m68k-hp ;; hp300bsd) basic_machine=m68k-hp os=-bsd ;; hp300hpux) basic_machine=m68k-hp os=-hpux ;; hp3k9[0-9][0-9] | hp9[0-9][0-9]) basic_machine=hppa1.0-hp ;; hp9k2[0-9][0-9] | hp9k31[0-9]) basic_machine=m68000-hp ;; hp9k3[2-9][0-9]) basic_machine=m68k-hp ;; hp9k6[0-9][0-9] | hp6[0-9][0-9]) basic_machine=hppa1.0-hp ;; hp9k7[0-79][0-9] | hp7[0-79][0-9]) basic_machine=hppa1.1-hp ;; hp9k78[0-9] | hp78[0-9]) # FIXME: really hppa2.0-hp basic_machine=hppa1.1-hp ;; hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) # FIXME: really hppa2.0-hp basic_machine=hppa1.1-hp ;; hp9k8[0-9][13679] | hp8[0-9][13679]) basic_machine=hppa1.1-hp ;; hp9k8[0-9][0-9] | hp8[0-9][0-9]) basic_machine=hppa1.0-hp ;; hppa-next) os=-nextstep3 ;; hppaosf) basic_machine=hppa1.1-hp os=-osf ;; hppro) basic_machine=hppa1.1-hp os=-proelf ;; i370-ibm* | ibm*) basic_machine=i370-ibm ;; i*86v32) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv32 ;; i*86v4*) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv4 ;; i*86v) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv ;; i*86sol2) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-solaris2 ;; i386mach) basic_machine=i386-mach os=-mach ;; i386-vsta | vsta) basic_machine=i386-unknown os=-vsta ;; iris | iris4d) basic_machine=mips-sgi case $os in -irix*) ;; *) os=-irix4 ;; esac ;; isi68 | isi) basic_machine=m68k-isi os=-sysv ;; m68knommu) basic_machine=m68k-unknown os=-linux ;; m68knommu-*) basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'` os=-linux ;; m88k-omron*) basic_machine=m88k-omron ;; magnum | m3230) basic_machine=mips-mips os=-sysv ;; merlin) basic_machine=ns32k-utek os=-sysv ;; microblaze*) basic_machine=microblaze-xilinx ;; mingw64) basic_machine=x86_64-pc os=-mingw64 ;; mingw32) basic_machine=i686-pc os=-mingw32 ;; mingw32ce) basic_machine=arm-unknown os=-mingw32ce ;; miniframe) basic_machine=m68000-convergent ;; *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) basic_machine=m68k-atari os=-mint ;; mips3*-*) basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` ;; mips3*) basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown ;; monitor) basic_machine=m68k-rom68k os=-coff ;; morphos) basic_machine=powerpc-unknown os=-morphos ;; moxiebox) basic_machine=moxie-unknown os=-moxiebox ;; msdos) basic_machine=i386-pc os=-msdos ;; ms1-*) basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` ;; msys) basic_machine=i686-pc os=-msys ;; mvs) basic_machine=i370-ibm os=-mvs ;; nacl) basic_machine=le32-unknown os=-nacl ;; ncr3000) basic_machine=i486-ncr os=-sysv4 ;; netbsd386) basic_machine=i386-unknown os=-netbsd ;; netwinder) basic_machine=armv4l-rebel os=-linux ;; news | news700 | news800 | news900) basic_machine=m68k-sony os=-newsos ;; news1000) basic_machine=m68030-sony os=-newsos ;; news-3600 | risc-news) basic_machine=mips-sony os=-newsos ;; necv70) basic_machine=v70-nec os=-sysv ;; next | m*-next ) basic_machine=m68k-next case $os in -nextstep* ) ;; -ns2*) os=-nextstep2 ;; *) os=-nextstep3 ;; esac ;; nh3000) basic_machine=m68k-harris os=-cxux ;; nh[45]000) basic_machine=m88k-harris os=-cxux ;; nindy960) basic_machine=i960-intel os=-nindy ;; mon960) basic_machine=i960-intel os=-mon960 ;; nonstopux) basic_machine=mips-compaq os=-nonstopux ;; np1) basic_machine=np1-gould ;; neo-tandem) basic_machine=neo-tandem ;; nse-tandem) basic_machine=nse-tandem ;; nsr-tandem) basic_machine=nsr-tandem ;; op50n-* | op60c-*) basic_machine=hppa1.1-oki os=-proelf ;; openrisc | openrisc-*) basic_machine=or32-unknown ;; os400) basic_machine=powerpc-ibm os=-os400 ;; OSE68000 | ose68000) basic_machine=m68000-ericsson os=-ose ;; os68k) basic_machine=m68k-none os=-os68k ;; pa-hitachi) basic_machine=hppa1.1-hitachi os=-hiuxwe2 ;; paragon) basic_machine=i860-intel os=-osf ;; parisc) basic_machine=hppa-unknown os=-linux ;; parisc-*) basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'` os=-linux ;; pbd) basic_machine=sparc-tti ;; pbb) basic_machine=m68k-tti ;; pc532 | pc532-*) basic_machine=ns32k-pc532 ;; pc98) basic_machine=i386-pc ;; pc98-*) basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentium | p5 | k5 | k6 | nexgen | viac3) basic_machine=i586-pc ;; pentiumpro | p6 | 6x86 | athlon | athlon_*) basic_machine=i686-pc ;; pentiumii | pentium2 | pentiumiii | pentium3) basic_machine=i686-pc ;; pentium4) basic_machine=i786-pc ;; pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentiumpro-* | p6-* | 6x86-* | athlon-*) basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentium4-*) basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pn) basic_machine=pn-gould ;; power) basic_machine=power-ibm ;; ppc | ppcbe) basic_machine=powerpc-unknown ;; ppc-* | ppcbe-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppcle | powerpclittle | ppc-le | powerpc-little) basic_machine=powerpcle-unknown ;; ppcle-* | powerpclittle-*) basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppc64) basic_machine=powerpc64-unknown ;; ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppc64le | powerpc64little | ppc64-le | powerpc64-little) basic_machine=powerpc64le-unknown ;; ppc64le-* | powerpc64little-*) basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ps2) basic_machine=i386-ibm ;; pw32) basic_machine=i586-unknown os=-pw32 ;; rdos | rdos64) basic_machine=x86_64-pc os=-rdos ;; rdos32) basic_machine=i386-pc os=-rdos ;; rom68k) basic_machine=m68k-rom68k os=-coff ;; rm[46]00) basic_machine=mips-siemens ;; rtpc | rtpc-*) basic_machine=romp-ibm ;; s390 | s390-*) basic_machine=s390-ibm ;; s390x | s390x-*) basic_machine=s390x-ibm ;; sa29200) basic_machine=a29k-amd os=-udi ;; sb1) basic_machine=mipsisa64sb1-unknown ;; sb1el) basic_machine=mipsisa64sb1el-unknown ;; sde) basic_machine=mipsisa32-sde os=-elf ;; sei) basic_machine=mips-sei os=-seiux ;; sequent) basic_machine=i386-sequent ;; sh) basic_machine=sh-hitachi os=-hms ;; sh5el) basic_machine=sh5le-unknown ;; sh64) basic_machine=sh64-unknown ;; sparclite-wrs | simso-wrs) basic_machine=sparclite-wrs os=-vxworks ;; sps7) basic_machine=m68k-bull os=-sysv2 ;; spur) basic_machine=spur-unknown ;; st2000) basic_machine=m68k-tandem ;; stratus) basic_machine=i860-stratus os=-sysv4 ;; strongarm-* | thumb-*) basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'` ;; sun2) basic_machine=m68000-sun ;; sun2os3) basic_machine=m68000-sun os=-sunos3 ;; sun2os4) basic_machine=m68000-sun os=-sunos4 ;; sun3os3) basic_machine=m68k-sun os=-sunos3 ;; sun3os4) basic_machine=m68k-sun os=-sunos4 ;; sun4os3) basic_machine=sparc-sun os=-sunos3 ;; sun4os4) basic_machine=sparc-sun os=-sunos4 ;; sun4sol2) basic_machine=sparc-sun os=-solaris2 ;; sun3 | sun3-*) basic_machine=m68k-sun ;; sun4) basic_machine=sparc-sun ;; sun386 | sun386i | roadrunner) basic_machine=i386-sun ;; sv1) basic_machine=sv1-cray os=-unicos ;; symmetry) basic_machine=i386-sequent os=-dynix ;; t3e) basic_machine=alphaev5-cray os=-unicos ;; t90) basic_machine=t90-cray os=-unicos ;; tile*) basic_machine=$basic_machine-unknown os=-linux-gnu ;; tx39) basic_machine=mipstx39-unknown ;; tx39el) basic_machine=mipstx39el-unknown ;; toad1) basic_machine=pdp10-xkl os=-tops20 ;; tower | tower-32) basic_machine=m68k-ncr ;; tpf) basic_machine=s390x-ibm os=-tpf ;; udi29k) basic_machine=a29k-amd os=-udi ;; ultra3) basic_machine=a29k-nyu os=-sym1 ;; v810 | necv810) basic_machine=v810-nec os=-none ;; vaxv) basic_machine=vax-dec os=-sysv ;; vms) basic_machine=vax-dec os=-vms ;; vpp*|vx|vx-*) basic_machine=f301-fujitsu ;; vxworks960) basic_machine=i960-wrs os=-vxworks ;; vxworks68) basic_machine=m68k-wrs os=-vxworks ;; vxworks29k) basic_machine=a29k-wrs os=-vxworks ;; w65*) basic_machine=w65-wdc os=-none ;; w89k-*) basic_machine=hppa1.1-winbond os=-proelf ;; xbox) basic_machine=i686-pc os=-mingw32 ;; xps | xps100) basic_machine=xps100-honeywell ;; xscale-* | xscalee[bl]-*) basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'` ;; ymp) basic_machine=ymp-cray os=-unicos ;; z8k-*-coff) basic_machine=z8k-unknown os=-sim ;; z80-*-coff) basic_machine=z80-unknown os=-sim ;; none) basic_machine=none-none os=-none ;; # Here we handle the default manufacturer of certain CPU types. It is in # some cases the only manufacturer, in others, it is the most popular. w89k) basic_machine=hppa1.1-winbond ;; op50n) basic_machine=hppa1.1-oki ;; op60c) basic_machine=hppa1.1-oki ;; romp) basic_machine=romp-ibm ;; mmix) basic_machine=mmix-knuth ;; rs6000) basic_machine=rs6000-ibm ;; vax) basic_machine=vax-dec ;; pdp10) # there are many clones, so DEC is not a safe bet basic_machine=pdp10-unknown ;; pdp11) basic_machine=pdp11-dec ;; we32k) basic_machine=we32k-att ;; sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele) basic_machine=sh-unknown ;; sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v) basic_machine=sparc-sun ;; cydra) basic_machine=cydra-cydrome ;; orion) basic_machine=orion-highlevel ;; orion105) basic_machine=clipper-highlevel ;; mac | mpw | mac-mpw) basic_machine=m68k-apple ;; pmac | pmac-mpw) basic_machine=powerpc-apple ;; *-unknown) # Make sure to match an already-canonicalized machine name. ;; *) echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 exit 1 ;; esac # Here we canonicalize certain aliases for manufacturers. case $basic_machine in *-digital*) basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` ;; *-commodore*) basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` ;; *) ;; esac # Decode manufacturer-specific aliases for certain operating systems. if [ x"$os" != x"" ] then case $os in # First match some system type aliases # that might get confused with valid system types. # -solaris* is a basic system type, with this one exception. -auroraux) os=-auroraux ;; -solaris1 | -solaris1.*) os=`echo $os | sed -e 's|solaris1|sunos4|'` ;; -solaris) os=-solaris2 ;; -svr4*) os=-sysv4 ;; -unixware*) os=-sysv4.2uw ;; -gnu/linux*) os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` ;; # First accept the basic system types. # The portable systems comes first. # Each alternative MUST END IN A *, to match a version number. # -sysv* is not here because it comes later, after sysvr4. -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\ | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \ | -sym* | -kopensolaris* | -plan9* \ | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ | -aos* | -aros* \ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ | -bitrig* | -openbsd* | -solidbsd* \ | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ | -chorusos* | -chorusrdb* | -cegcc* \ | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \ | -linux-newlib* | -linux-musl* | -linux-uclibc* \ | -uxpv* | -beos* | -mpeix* | -udk* | -moxiebox* \ | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* | -tirtos*) # Remember, each alternative MUST END IN *, to match a version number. ;; -qnx*) case $basic_machine in x86-* | i*86-*) ;; *) os=-nto$os ;; esac ;; -nto-qnx*) ;; -nto*) os=`echo $os | sed -e 's|nto|nto-qnx|'` ;; -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \ | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) ;; -mac*) os=`echo $os | sed -e 's|mac|macos|'` ;; -linux-dietlibc) os=-linux-dietlibc ;; -linux*) os=`echo $os | sed -e 's|linux|linux-gnu|'` ;; -sunos5*) os=`echo $os | sed -e 's|sunos5|solaris2|'` ;; -sunos6*) os=`echo $os | sed -e 's|sunos6|solaris3|'` ;; -opened*) os=-openedition ;; -os400*) os=-os400 ;; -wince*) os=-wince ;; -osfrose*) os=-osfrose ;; -osf*) os=-osf ;; -utek*) os=-bsd ;; -dynix*) os=-bsd ;; -acis*) os=-aos ;; -atheos*) os=-atheos ;; -syllable*) os=-syllable ;; -386bsd) os=-bsd ;; -ctix* | -uts*) os=-sysv ;; -nova*) os=-rtmk-nova ;; -ns2 ) os=-nextstep2 ;; -nsk*) os=-nsk ;; # Preserve the version number of sinix5. -sinix5.*) os=`echo $os | sed -e 's|sinix|sysv|'` ;; -sinix*) os=-sysv4 ;; -tpf*) os=-tpf ;; -triton*) os=-sysv3 ;; -oss*) os=-sysv3 ;; -svr4) os=-sysv4 ;; -svr3) os=-sysv3 ;; -sysvr4) os=-sysv4 ;; # This must come after -sysvr4. -sysv*) ;; -ose*) os=-ose ;; -es1800*) os=-ose ;; -xenix) os=-xenix ;; -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) os=-mint ;; -aros*) os=-aros ;; -zvmoe) os=-zvmoe ;; -dicos*) os=-dicos ;; -nacl*) ;; -none) ;; *) # Get rid of the `-' at the beginning of $os. os=`echo $os | sed 's/[^-]*-//'` echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 exit 1 ;; esac else # Here we handle the default operating systems that come with various machines. # The value should be what the vendor currently ships out the door with their # machine or put another way, the most popular os provided with the machine. # Note that if you're going to try to match "-MANUFACTURER" here (say, # "-sun"), then you have to tell the case statement up towards the top # that MANUFACTURER isn't an operating system. Otherwise, code above # will signal an error saying that MANUFACTURER isn't an operating # system, and we'll never get to this point. case $basic_machine in score-*) os=-elf ;; spu-*) os=-elf ;; *-acorn) os=-riscix1.2 ;; arm*-rebel) os=-linux ;; arm*-semi) os=-aout ;; c4x-* | tic4x-*) os=-coff ;; c8051-*) os=-elf ;; hexagon-*) os=-elf ;; tic54x-*) os=-coff ;; tic55x-*) os=-coff ;; tic6x-*) os=-coff ;; # This must come before the *-dec entry. pdp10-*) os=-tops20 ;; pdp11-*) os=-none ;; *-dec | vax-*) os=-ultrix4.2 ;; m68*-apollo) os=-domain ;; i386-sun) os=-sunos4.0.2 ;; m68000-sun) os=-sunos3 ;; m68*-cisco) os=-aout ;; mep-*) os=-elf ;; mips*-cisco) os=-elf ;; mips*-*) os=-elf ;; or32-*) os=-coff ;; *-tti) # must be before sparc entry or we get the wrong os. os=-sysv3 ;; sparc-* | *-sun) os=-sunos4.1.1 ;; *-be) os=-beos ;; *-haiku) os=-haiku ;; *-ibm) os=-aix ;; *-knuth) os=-mmixware ;; *-wec) os=-proelf ;; *-winbond) os=-proelf ;; *-oki) os=-proelf ;; *-hp) os=-hpux ;; *-hitachi) os=-hiux ;; i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) os=-sysv ;; *-cbm) os=-amigaos ;; *-dg) os=-dgux ;; *-dolphin) os=-sysv3 ;; m68k-ccur) os=-rtu ;; m88k-omron*) os=-luna ;; *-next ) os=-nextstep ;; *-sequent) os=-ptx ;; *-crds) os=-unos ;; *-ns) os=-genix ;; i370-*) os=-mvs ;; *-next) os=-nextstep3 ;; *-gould) os=-sysv ;; *-highlevel) os=-bsd ;; *-encore) os=-bsd ;; *-sgi) os=-irix ;; *-siemens) os=-sysv4 ;; *-masscomp) os=-rtu ;; f30[01]-fujitsu | f700-fujitsu) os=-uxpv ;; *-rom68k) os=-coff ;; *-*bug) os=-coff ;; *-apple) os=-macos ;; *-atari*) os=-mint ;; *) os=-none ;; esac fi # Here we handle the case where we know the os, and the CPU type, but not the # manufacturer. We pick the logical manufacturer. vendor=unknown case $basic_machine in *-unknown) case $os in -riscix*) vendor=acorn ;; -sunos*) vendor=sun ;; -cnk*|-aix*) vendor=ibm ;; -beos*) vendor=be ;; -hpux*) vendor=hp ;; -mpeix*) vendor=hp ;; -hiux*) vendor=hitachi ;; -unos*) vendor=crds ;; -dgux*) vendor=dg ;; -luna*) vendor=omron ;; -genix*) vendor=ns ;; -mvs* | -opened*) vendor=ibm ;; -os400*) vendor=ibm ;; -ptx*) vendor=sequent ;; -tpf*) vendor=ibm ;; -vxsim* | -vxworks* | -windiss*) vendor=wrs ;; -aux*) vendor=apple ;; -hms*) vendor=hitachi ;; -mpw* | -macos*) vendor=apple ;; -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) vendor=atari ;; -vos*) vendor=stratus ;; esac basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` ;; esac echo $basic_machine$os exit # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" # End: ���libburn-1.4.2/ChangeLog�����������������������������������������������������������������������������0000644�0001757�0001751�00000054123�12652646133�011673� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ libburn-1.4.2.pl01.tar.gz Fri Jan 29 2016 =============================================================================== * Bug fix: cdrskin "failed to attach fifo" when burning from stdin. Regression of 1.4.2, rev 5522. libburn-1.4.2.tar.gz Sat Nov 28 2015 =============================================================================== * Bug fix: burn_disc_get_media_id() returned BD identifiers 2 chars too long * Bug fix: burn_disc_get_multi_caps() returned 2048 bytes too many in caps.start_range_high * Bug fix: Media summary session count of blank and closed media was short by 1 * Bug fix: Endless loop if transport error occurs while waiting for drive ready * New API calls burn_drive_get_serial_no() and burn_drive_get_media_sno() * Result of a Coverity audit: 40+ code changes, but no easy-to-trigger bugs libburn-1.4.0.tar.gz Sun May 17 2015 =============================================================================== * Bug fix: Double free with cdrskin -vvv. Introduced with rev 5065, version 1.3.1 * Bug fix: Wrong read access to memory. Reported by valgrind of lian jianfei. libburn-1.3.8.tar.gz Sat Jun 28 2014 =============================================================================== * Bug fix: Wrong stack usage caused SIGBUS on sparc when compiled by gcc -O2 * Bug fix: Minimum drive buffer fill was measured by cdrskin before the buffer could get full * Bug fix: A failed MMC BLANK command did not cause error indication by libburn * Bug fix: A final fsync(2) was performed with stdio drives, even if not desired libburn-1.3.6.pl01.tar.gz Tue Mar 18 2013 =============================================================================== * Bug fix: CD TAO with multiple tracks could cause a buffer overrun * Bug fix: Compilation warning for unsupported systems mutated into an error libburn-1.3.6.tar.gz Tue Mar 04 2013 =============================================================================== * New system adapter for NetBSD libburn-1.3.4.tar.gz Thu Dec 12 2013 =============================================================================== * Bug fix: Drive error reports were ignored during blanking and formatting * Bug fix: Drive LG BH16NS40 stalls on inspection of unformatted DVD+RW * New API call burn_disc_pretend_full_uncond() libburn-1.3.2.tar.gz Wed Aug 07 2013 =============================================================================== * Bug fix: cdrskin -msinfo on DVD and BD reported old session start = next writable address. Regression introduced by version 1.2.8 (rev 4956). * Bug fix: The signal handler aborted on SIGCONT, SIGTSTP, SIGTTIN, SIGTTOU * New API call burn_make_input_sheet_v07t() * API call burn_session_input_sheet_v07t(): read multiple blocks from same file * New API calls burn_drive_extract_audio(), burn_drive_extract_audio_track() * New cdrskin option textfile_to_v07t= * New cdrskin options cdtext_to_textfile= and cdtext_to_v07t= * New cdrskin options extract_audio_to= , extract_tracks= , extract_basename= , --extract_dap * New cdrskin option --pacifier_with_newline * Improved granularity of SCSI log time measurement, now with timestamp * Optional "make doc" now demands doxygen 1.8.4 libburn-1.3.0.pl01.tar.gz Fri May 31 2013 =============================================================================== * Bug fix: cdrskin -msinfo on DVD and BD reported old session start = next writable address. Regression introduced by version 1.2.8. libburn-1.3.0.tar.gz Fri May 17 2013 =============================================================================== * Bug fix: Full formatting of BD-RE used certification regardless of drive capabilities * Bug fix: DVD+R with damaged TOC were reported by -minfo with wrong end address libburn-1.2.8.tar.gz Mon Mar 18 2013 =============================================================================== * Bug fix: All CD tracks were reported with the sizes of the tracks in the first session. Regression introduced with version 1.2.0 (rev 4552). * Bug fix: On some drives the request for minimum speed yielded maximum speed * New cdrskin option --list_speeds * -toc and -minfo now report about tracks in the incomplete session * New API call burn_disc_get_incomplete_sessions() * New burn_toc_entry component .track_status_bits libburn-1.2.6.tar.gz Tue Jan 08 2013 =============================================================================== * Bug fix: Speed setting had no effect on BD media * New cdrskin option --no_load * New API call burn_read_audio() * New API call burn_list_sev_texts() libburn-1.2.4.tar.gz Fri Jul 20 2012 =============================================================================== * Bug fix: CD SAO sessions with data tracks started by an audio pause * Bug fix: CD tracks were perceived 2 sectors too short. Nice with TAO, bad with SAO. * Bug fix: cdrskin SIGSEGV if track source was added when no drive was available * New API call burn_write_opts_set_obs_pad(), ./configure --enable-dvd-obs-pad * New cdrskin option --obs_pad libburn-1.2.2.tar.gz Mon Apr 02 2012 =============================================================================== * Small internal refinements libburn-1.2.0.tar.gz Sat Jan 28 2012 =============================================================================== * Bug fix: cdrskin produced a memory fault if interupted before writing began * Bug fix: Solaris adapter mishandled write commands which failed on first try * Bug fix: Interrupting libburn while drive tray is loading led to endless loop * Bug fix: Progress report with blanking and formatting could be bogus * New API calls burn_disc_get_leadin_text(), burn_write_opts_set_leadin_text() * New API calls for composing CD-TEXT, see doc/cdtext.txt * New API call burn_session_by_cue_file() for reading CDRWIN .cue files * New API call burn_track_set_isrc_string() * New API calls burn_track_set_index(), burn_track_clear_indice() * New API calls burn_session_set_start_tno(), burn_session_get_start_tno() * New API calls burn_track_set_pregap_size(), burn_track_set_postgap_size() * Implemented cdrskin option textfile= * Implemented cdrskin option combination -vv -toc for cdtext.dat production * Implemented cdrskin options mcn= and isrc= * Implemented cdrskin options -scms -copy -nocopy -preemp -nopreemp * Implemented cdrskin option index= * Partly implemented cdrskin options cuefile= and -text * New cdrskin option input_sheet_v07t= for CD-TEXT definition * New cdrskin options --cdtext_dummy and --cdtext_verbose * New cdrskin options --four_channel --two_channel * New cdrskin option cd_start_tno= * New cdrskin options sao_pregap=, sao_postgap= libburn-1.1.8.tar.gz Mon Nov 21 2011 =============================================================================== * Bug fix: Misinterpreted mode page 2A if block descriptors are present * Enabled recognition of QEMU DVD-ROM 0.12 * Avoiding to intermediately close and open drive device file * New API call burn_drive_re_assess() libburn-1.1.6.tar.gz Tue Sep 27 2011 =============================================================================== * Bug fix: stdio sizes > 4 TB - 32 kB caused integer rollover * Worked around a collision with Linux udev which lets links vanish libburn-1.1.4.tar.gz Sun Aug 07 2011 =============================================================================== * Bug fix: Some drives return -150 as NWA of blank CD, rather than 0. libburn forwarded this misleading information to the application. * Bug fix: Some drives returned wrong CD sizes after having burned DVD-R * Bug fix: Empty ROM drive was mistaken to hold an unsuitable disc * Bug fix: Avoiding to load speed descriptor list twice * New API call burn_lookup_device_link() * New API call burn_disc_get_phys_format_info() * New cdrskin option --device_links Release 1.1.2 was skipped to get back in sync with libisoburn. libburn-1.1.0.pl01.tar.gz Mon Jun 20 2011 =============================================================================== * Bug fix: libburn-1.1.0 compiled only on Linux, FreeBSD, and Solaris libburn-1.1.0.tar.gz Sat Jun 18 2011 =============================================================================== * Bug fix: burn_disc_format() on DVD-RW issued wrong block size with type 00h * New API call burn_disc_next_track_is_damaged() * New API call burn_disc_close_damaged() * Dropped suffix .plXY from tarball name Release 1.0.8 was skipped to get back in sync with libisofs and libisoburn. libburn-1.0.6.pl00.tar.gz Sat Apr 9 2011 =============================================================================== * Burning DVD-R DAO with 2 kB size granularity rather than 32 kB * New API call burn_allow_drive_role_4() libburn-1.0.4.pl00.tar.gz Thu Mar 3 2011 =============================================================================== * Bug fix: Read-only file descriptors were classified as write-only pseudo drives libburn-1.0.2.pl00.tar.gz Wed Feb 23 2011 =============================================================================== * Removed compilation obstacles on Solaris 9. * Improved recognition of non-seekable stdio pseudo-drives. libburn-1.0.0.pl00.tar.gz Sun Jan 16 2011 =============================================================================== * Allowed umask to create stdio-drive files with rw-permissions for all * cdrskin now refuses to burn if the foreseeable size exceeds media capacity libburn-0.9.0.pl00.tar.gz Wed Dec 08 2010 =============================================================================== * Regression fix: SCSI reply data logging was disabled in release 0.8.6 libburn-0.8.8.pl00.tar.gz Wed Oct 20 2010 =============================================================================== * New API call burn_offst_source_new() * New API call burn_disc_get_bd_spare_info() libburn-0.8.6.pl00.tar.gz Fri Sep 17 2010 =============================================================================== * Lifted test reservation on DVD-R DL media. * Hiding all non-API symbols from the linker by use of --version-script * Now with history of release notes in ./ChangeLog file. libburn-0.8.4.pl00.tar.gz Wed Jun 30 2010 =============================================================================== * General POSIX system adapters ignore SIGWINCH and SIGURG if defined * Allowed 64 kB max output buffer size on all OSes libburn-0.8.2.pl00.tar.gz Fri Jun 11 2010 =============================================================================== * New system adapter for Solaris uscsi (tested on snv134, kernel 5.11) * Bug fix: CD TOC was not read if the first track did not start at LBA 0 * Bug fix: CD-ROM media got attributed random lead-in and lead-out adresses * Bug fix: SIGSEGV of experimental libcdio system adapter if drive list is empty libburn-0.8.0.pl00.tar.gz Fri Apr 09 2010 =============================================================================== * libburn now works with ahci driver on FreeBSD 8-STABLE. libburn-0.7.8.pl00.tar.gz Wed Mar 10 2010 =============================================================================== * Bug fix: On FreeBSD, piped input was falsely attributed a small fixed size. * Built-in abort handling is more suitable for FreeBSD now. cdrskin novelties: * Bug fix: Option fs=0 led to SIGSEGV. Regression introduced by version 0.7.4 in december 2009. * Abort handling is more suitable for FreeBSD now. libburn-0.7.6.pl00.tar.gz Sat Jan 23 2010 =============================================================================== * Bug fix: System adapter for generic X/Open was missing in libburn release tarball * Bug fix: with non-Linux adapters there were 0 readable bytes on block devices * Made FreeBSD system adapter safe from mutal burn spoiling and drive deadlock * Enabled FreeBSD system adapter for Debian kfreebsd * Experimental SCSI transport adapter via GNU libcdio 0.83git cdrskin novelties: * none libburn-0.7.4.pl01.tar.gz Sat Dec 26 2009 =============================================================================== * Bug fix: Added missing system adapter for generic X/Open to libburn release tarball Libburn 0.7.4.pl00 Mon Dec 07 2009 =============================================================================== * Bug fix: SIGSEGV from NULL pointer with media product id inquiry on LG GH22LS30 * Bug fix: DVD DAO track size was rounded up much too generously * Workaround for Pioneer DVR-216D which got stuck on DVD-R burns. (already fixed in 0.7.2.pl01) * Workaround for Pioneer DVR-216D refusal to eject. (already fixed in 0.7.2.pl01) * Configure options --enable-dvd-obs-64k, --enable-track-src-odirect * New API calls burn_write_opts_set_dvd_obs(), burn_write_opts_set_stdio_fsync() * New API call burn_set_scsi_logging() * New API calls burn_fifo_get_statistics(), burn_fifo_next_interval(), burn_fifo_fill() * Re-implemented ECMA-130 P-parity, Q-parity and scrambling for BURN_WRITE_RAW cdrskin novelties: * cdrskin option -V for logging of SCSI commands * New cdrskin options dvd_obs= and stdio_fsync= * New compile_cdrskin.sh option -dvd_obs_64k libburn-0.7.2.pl01.tar.gz Fri Nov 13 2009 =============================================================================== * Workaround for Pioneer DVR-216D which got stuck on DVD-R burns. * Workaround for Pioneer DVR-216D refusal to eject. Libburn 0.7.2.pl00 Mon Oct 12 2009 =============================================================================== * Bug fix: CD TAO sessions with multiple tracks did not work in -dummy mode * New API calls burn_get_media_product_id() , burn_guess_manufacturer() , burn_guess_cd_manufacturer() * New API call burn_disc_get_cd_info() * New API call burn_track_set_cdxa_conv() cdrskin novelties: * Better interpretation of options -mode2, -xa, -xa1, -xa2 * New option --xa1-ignore * New -atip report lines "Product Id:" and "Producer:" libburn-0.7.0.pl00.tar.gz Thu Aug 27 2009 =============================================================================== * New API calls burn_drive_get_all_profiles(), burn_obtain_profile_name() allow to inquire and process the list of supported media types. cdrskin lists all supported profiles with option -atip -v * New API call burn_drive_snooze() allows to calm down a drive when no i/o is expected for a while. * Bug fix: Some SCSI commands stalled on U3 memory sticks which appear as a hub with a memory stick and a CD-ROM drive containing a small CD. These commands make not much sense with a CD-ROM and are now avoided for this media situation. libburn-0.6.8.pl00.tar.gz Tue Jul 14 2009 =============================================================================== * Bug fix: Old MMC-1 drives were rejected because of mode page 2Ah length. * cdrskin -scanbus now works with high SCSI bus numbers. libburn-0.6.6.pl00.tar.gz Fri May 8 2009 =============================================================================== * Bug fix: Improper abort handling with broken pipe during outputto a stdio: pseudo-drive. * Bug fix: Device scan stalled on FreeBSD with non-burner USB device libburn-0.6.4.pl00.tar.gz Fri Mar 13 2009 =============================================================================== * New operating system adapter "dummy" for stdio on general X/Open systems * New API function burn_drive_set_stream_recording() allows to write the crucial start blocks of a filesystem with slow BD-RE Defect Management and to write the bulk of data with full nominal speed. libburn-0.6.2.pl00.tar.gz Fri Feb 20 2009 =============================================================================== * Improvements with build system for FreeBSD libburn-0.6.0.pl01.tar.gz Wed Jan 07 2009 =============================================================================== * Bug fix: BD-R were not correctly finalized libburn-0.6.0.pl00.tar.gz Sun Jan 04 2009 =============================================================================== * Formatting and writing of BD-R media * New API function burn_get_read_capacity() libburn-0.5.8.pl00.tar.gz Mon Dec 08 2008 =============================================================================== * Bug fix: A session without leadout entry on CD caused a SIGSEGV by NULL * Improvements about BD-RE formatting libburn-0.5.6.pl00.tar.gz Wed Nov 12 2008 =============================================================================== * Bug fix: libburn fifo thread was not aborted when burn run was aborted which could lead to use of freed memory. libburn-0.5.4.pl00.tar.gz Mon Oct 6 2008 =============================================================================== * Bug fix: On Linux 2.4 /dev/sr0 was accepted as enumerable address but then failed to work. libburn-0.5.2.pl00.tar.gz Wed Aug 20 2008 =============================================================================== * Larger set of possibly acceptable drive device file names libburn-0.5.0.pl00.tar.gz Thu Jul 17 2008 =============================================================================== * Bug fix: cdrskin option drive_scsi_dev_family=scd lead to buffer overflow * Ability to use /dev/scd as fallback if /dev/sr does not exist * New API call burn_fifo_peek_data() libburn-0.4.8.pl00.tar.gz Sat May 17 2008 =============================================================================== * Bug fix: Random access addressing for DVD-RAM and BD-RE did not work. * cdrskin: Affected were options write_start_address= and -- grow_overwriteable_iso on DVD-RAM or BD-RE. * xorriso: Affected were sessions on DVD-RAM or BD-RE after the first one. libburn-0.4.6.pl00.tar.gz Sun May 11 2008 =============================================================================== * Support for BD-RE media is now official * New burn_write_opts_set_stream_recording() can speed up DVD-RAM and BD-RE * New cdrskin option --list_formats * New cdrskin blank types for expert formatting of DVD-RAM and BD-RE * New cdrskin blank type blank=as_needed for automatic handling of media libburn-0.4.4.tar.gz Thu April 10 2008 =============================================================================== * Support for DVD+R/DL media is now official libburn-0.4.2.tar.gz Sun Feb 3 2008 =============================================================================== * Long term commitment to ABI libburn.so.4. * ABI compatibility is guaranteed for any older feature set released since libburn-0.3.2 about one year ago. * libburn provides means for compile time and runtime checking of its version. * Compile time check in cdrskin for proper version of libburn include file. Required is at least 0.4.2. * Runtime check in cdrskin prevents dynamic linking with outdated version of libburn.so.4. Required is at least the version seen in the include file at compile time. libburn-0.4.0.tar.gz Mon Oct 29 2007 =============================================================================== * New option direct_write_amount= * New option --grow_overwriteable_iso * New option --allow_emulated_drives dev=stdio:<path> * More cdrecord options supported: -format, -inq, -load, -lock, -immed, -waiti * New option fallback_program= * A lot of libburn API additions. libburn-0.3.8.tar.gz Tue Jul 31 2007 =============================================================================== * Now able to cope with the peculiarities of Linux 2.4 USB * Refusal to perform -dummy runs on media which cannot simulate burning * New option modesty_on_drive= may help with hda -> hdb burns * New option minbuf= , cdrecord compatible frontend of modesty_on_drive= * New option --adjust_speed_to_drive * Precautions against using the burner drive as track source * Note: ABI has not been broken. libburn-0.3.6.tar.gz Thu Apr 26 2007 =============================================================================== * On Linux kernel 2.6, /dev/sr* gets used rather than /dev/sg*. * DVD+R now get finalized (if not -multi is given) libburn-0.3.4.tar.gz Mon Mar 12 2007 =============================================================================== * Multi-session recording on DVD+R, including -toc, -msinfo * Options --tell_media_space , assert_write_lba= * Bug fix of rare multi track fifo stall libburn-0.3.2.tar.gz Feb 11 2007 =============================================================================== * Burnfree enabled by default * Multi-session recording on sequential DVD-R[W], including -toc, -msinfo * DVD-R[W] Disk-at-once recording libburn-0.3.0.1.tar.gz Tue Jan 30 2007 =============================================================================== * Improved recognition of unsuitable media types * Replaced ban of chmod u+s by loud warning * detailed man page for cdrskin * Burning of DVD+RW and DVD-RAM media as single-track TAO-like initial session * Formatting and then burning to DVD-RW like to DVD+RW * New option -msifile=path from cdrkit/wodim * 0.3.0.1 release notes * * Bug fix enabling tracks >= 1.3 GB from disk file libburn-0.2.6.3.tar.gz Fri Dec 29 2006 =============================================================================== * 0.2.6 release notes (Wed Nov 22 2006) * After a lot of time with dedication to this project, we proudly present you libburn 0.2.6. It is the first version of cdrskin and libburn after they have been split from genisofs and libisofs. Main new features are write mode TAO and support for multi session. * 0.2.6.1 release notes (Fri Nov 24 2006) * Point release to fix misleading version numbers in messages and documentation * 0.2.6.2 release notes (Sat Dec 16 2006) * cdrskin man page backported from development version 0.2.7. * 0.2.6.3 release notes (Fri Dec 29 2006) * Point release to fix build system problems people have experienced with the past release. libburn-0.2.3.snapshot02.tar.gz Thu Nov 02 2006 =============================================================================== * Stabilized snapshot including release 0.2.4.pl01 of cdrskin * cdrskin 0.2.4 release notes * Compatibility with cdrecord has been improved in respect to drive addresses, audio extraction from .wav, -scanbus, -toc, drive buffer fill indicator. * Note: The previous snapshot01 with the same source base is handicapped by a broken ./configure setup. It works well on Intel compatible CPUs but is supposed to be unusable on big-endian architectures. libburn-0.2.2.tar.gz Wed Sep 20 2006 =============================================================================== Initial release of libburnia's libburn combined with cdrskin. ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������libburn-1.4.2/COPYRIGHT�����������������������������������������������������������������������������0000644�0001757�0001751�00000001626�12652644224�011413� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������Derek Foreman <derek@signalmarketing.com> and Ben Jansens <xor@orodu.net> Copyright (C) 2002-2006 Derek Foreman and Ben Jansens Mario Danic <mario.danic@gmail.com>, Thomas Schmitt <scdbackup@gmx.net> Copyright (C) 2006-2014 Mario Danic, Thomas Schmitt This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 or later as published by the Free Software Foundation. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ����������������������������������������������������������������������������������������������������������libburn-1.4.2/configure.ac��������������������������������������������������������������������������0000644�0001757�0001751�00000027712�12652644224�012412� �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������AC_INIT([libburn], [1.4.2], [http://libburnia-project.org]) AC_PREREQ([2.50]) dnl AC_CONFIG_HEADER([config.h]) AC_CANONICAL_HOST AC_CANONICAL_TARGET LIBBURNIA_SET_FLAGS AM_INIT_AUTOMAKE([subdir-objects]) AC_CONFIG_MACRO_DIR([./]) dnl Notes about version numbers and .so numbers: dnl dnl Regrettably the meaning of the various version types was misunderstood dnl before version 0.4.1. dnl dnl In the past MAJOR.MINOR.MICRO versions led to the following SONAME numbers: dnl 0.2.2 = 2 , 0.2.3 = 3 , 0.2.6 = 6 dnl 0.3.0 = 0 , 0.3.2 = 2 , 0.3.4 = 4 . 0.3.6 = 6 , 0.3.8 = 4 dnl 0.4.0 = 0 (also released as SONAME 4) dnl dnl Meanwhile the following schemes are maintained in parallel: dnl dnl BURN_MAJOR_VERSION , BURN_MINOR_VERSION , BURN_MICRO_VERSION dnl are three small non-negative integers which describe the evolution dnl steps of the library. dnl Older applications are able to use younger libraries over dnl quite a long range of such steps. Some day, nevertheless, dnl compatibility might get terminated, after due notice. dnl dnl SONAME (libburn.so.4) dnl is a small positive integer which marks a family of compatible dnl evolution steps. Libraries with a particular SONAME allow a binary dnl with the same SONAME to start up. Any further compatibility check is to dnl be done by own runtime means. Especially *_version() calls in the API dnl which return BURN_MAJOR_VERSION, BURN_MINOR_VERSION, BURN_MICRO_VERSION. dnl See below. dnl dnl CURRENT, AGE, REVISION dnl are three integers used by libtool. CURRENT is positive, the others dnl non-negative. The use at runtime is not known yet. But libtool computes dnl at build time SONAME = CURRENT - AGE. dnl So this is a superspace of the SONAME version space. To avoid dnl ill SONAME, the value of CURRENT must be larger than AGE. dnl See also http://www.gnu.org/software/libtool/manual.html#Interfaces dnl dnl On Linux the name of the dynamic library will be dnl libburn.so.$SONAME.$AGE.$REV dnl In the terminology of this file: dnl CURRENT = LT_CURRENT dnl AGE = LT_AGE dnl REVISION= LT_REVISION dnl dnl Beginning with libburn-0.4.1 a rectified counting was introduced as dnl CURRENT=10, REVISION=1, AGE=6 dnl This rectification declared that version to be binary compatible up dnl from libburn-0.3.4. dnl Real compatibility was given since libburn-0.3.2. dnl Beware of libburn-0.2.6 which had SONAME=6 and is not binary compatible. dnl Applications for libburn-0.2 to libburn-0.3.1 need recompilation but no dnl source code changes. dnl dnl Neatly versioned stable releases meanwhile: dnl 0.4.2 = libburn.so.4.7.0 dnl 0.4.4 = libburn.so.4.9.0 dnl 0.4.6 = libburn.so.4.11.0 dnl 0.4.8 = libburn.so.4.13.0 dnl 0.5.0 = libburn.so.4.15.0 dnl 0.5.2 = libburn.so.4.17.0 dnl 0.5.4 = libburn.so.4.19.0 dnl 0.5.6 = libburn.so.4.21.0 dnl 0.5.8 = libburn.so.4.23.0 dnl 0.6.0 = libburn.so.4.25.0 dnl 0.6.2 = libburn.so.4.27.0 dnl 0.6.4 = libburn.so.4.29.0 dnl 0.6.6 = libburn.so.4.31.0 dnl 0.6.8 = libburn.so.4.33.0 dnl 0.7.0 = libburn.so.4.35.0 dnl 0.7.2 = libburn.so.4.37.0 dnl 0.7.4 = libburn.so.4.39.0 dnl 0.7.6 = libburn.so.4.41.0 dnl 0.7.8 = libburn.so.4.43.0 dnl 0.8.0 = libburn.so.4.45.0 dnl 0.8.2 = libburn.so.4.47.0 dnl 0.8.4 = libburn.so.4.49.0 dnl 0.8.6 = libburn.so.4.51.0 dnl 0.8.8 = libburn.so.4.53.0 dnl 0.9.0 = libburn.so.4.55.0 dnl 1.0.0 = libburn.so.4.57.0 dnl 1.0.2 = libburn.so.4.59.0 dnl 1.0.4 = libburn.so.4.61.0 dnl 1.0.6 = libburn.so.4.63.0 dnl 1.1.0 = libburn.so.4.65.0 dnl 1.1.4 = libburn.so.4.67.0 dnl 1.1.6 = libburn.so.4.69.0 dnl 1.1.8 = libburn.so.4.71.0 dnl 1.2.0 = libburn.so.4.73.0 dnl 1.2.2 = libburn.so.4.75.0 dnl 1.2.4 = libburn.so.4.77.0 dnl 1.2.6 = libburn.so.4.79.0 dnl 1.2.8 = libburn.so.4.81.0 dnl 1.3.0 = libburn.so.4.83.0 dnl 1.3.2 = libburn.so.4.85.0 dnl 1.3.4 = libburn.so.4.87.0 dnl 1.3.6 = libburn.so.4.89.0 dnl 1.3.8 = libburn.so.4.91.0 dnl 1.4.0 = libburn.so.4.93.0 dnl 1.4.2 = libburn.so.4.95.0 dnl dnl So LT_CURRENT, LT_REVISION and LT_AGE get set directly here. dnl SONAME of the emerging library is LT_CURRENT - LT_AGE. dnl The linker will do no finer checks. Especially no age range check for dnl the application binary. If SONAME matches, then the couple starts. dnl dnl Therefore at run time info is provided by libburn function burn_version(). dnl It returns the major, minor and micro revision of the library. dnl Before using any API feature, a program should check for age. dnl dnl The variables BURN_*_VERSION are mere copies for informing libtool. dnl The true values which get issued and should be compared are macros dnl defined in libburn/libburn.h . dnl dnl Normally one can allow a program to run with a library which passed the dnl linker SONAME test and which is not older than the library it was dnl developed for. Library2 is younger than library1 if: dnl major2>major1 || (major2==major1 && dnl (minor2>minor1 || (minor2==minor1 && micro2 > micro1))) dnl dnl If BURN_*_VERSION changes, be sure to change AC_INIT above to match. dnl dnl As said: Only copies. Original in libburn/libburn.h : burn_header_version_* BURN_MAJOR_VERSION=1 BURN_MINOR_VERSION=4 BURN_MICRO_VERSION=2 BURN_VERSION=$BURN_MAJOR_VERSION.$BURN_MINOR_VERSION.$BURN_MICRO_VERSION AC_SUBST(BURN_MAJOR_VERSION) AC_SUBST(BURN_MINOR_VERSION) AC_SUBST(BURN_MICRO_VERSION) AC_SUBST(BURN_VERSION) dnl Libtool versioning LT_RELEASE=$BURN_MAJOR_VERSION.$BURN_MINOR_VERSION.$BURN_MICRO_VERSION dnl dnl This is the release version libburn-1.4.2 dnl ### This is the development version after above release version dnl LT_CURRENT++, LT_AGE++ has not yet happened. dnl ### LT_CURRENT++, LT_AGE++ has happened meanwhile. dnl dnl SONAME = 99 - 95 = 4 . Linux library name = libburn.so.4.95.0 LT_CURRENT=99 LT_AGE=95 LT_REVISION=0 LT_CURRENT_MINUS_AGE=`expr $LT_CURRENT - $LT_AGE` AC_SUBST(LT_RELEASE) AC_SUBST(LT_CURRENT) AC_SUBST(LT_REVISION) AC_SUBST(LT_AGE) AC_SUBST(LT_CURRENT_MINUS_AGE) dnl ts A71207: This is done only not to break any old components BURN_INTERFACE_AGE=$LT_REVISION BURN_BINARY_AGE=`expr $LT_AGE + $BURN_INTERFACE_AGE` AC_SUBST(BURN_INTERFACE_AGE) AC_SUBST(BURN_BINARY_AGE) AC_PREFIX_DEFAULT([/usr/local]) test "$prefix" = "NONE" && prefix=$ac_default_prefix AM_MAINTAINER_MODE AM_PROG_CC_C_O AC_C_CONST AC_C_INLINE AC_C_BIGENDIAN dnl Large file support AC_SYS_LARGEFILE AC_FUNC_FSEEKO AC_CHECK_FUNC([fseeko]) if test ! $ac_cv_func_fseeko; then AC_ERROR([Libburn requires largefile support.]) fi AC_PROG_LIBTOOL AC_SUBST(LIBTOOL_DEPS) LIBTOOL="$LIBTOOL --silent" AC_PROG_INSTALL AC_CHECK_HEADERS() THREAD_LIBS=-lpthread AC_SUBST(THREAD_LIBS) TARGET_SHIZZLE AC_SUBST(ARCH) AC_SUBST(LIBBURNIA_PKGCONFDIR) AC_SUBST(LIBBURN_ARCH_LIBS) dnl ts A90303 dnl Check the preconditions for using statvfs() in sg-dummy dnl (sg-linux and sg-freebsd use statvfs() unconditionally) STATVFS_DEF=-DLibburn_os_has_statvfS AC_CHECK_HEADER(sys/statvfs.h, X=, STATVFS_DEF=) AC_CHECK_FUNC([statvfs], X=, STATVFS_DEF=) dnl If this would be done more specifically in Makefile.am dnl via libburn_libburn_la_CFLAGS then undesired .o file names would emerge CFLAGS="$STATVFS_DEF $CFLAGS" dnl ts A91122 AC_ARG_ENABLE(track-src-odirect, [ --enable-track-src-odirect Enable use of O_DIRECT with track input, default=no], , enable_track_src_odirect=no) if test x$enable_track_src_odirect = xyes; then LIBBURN_O_DIRECT_DEF="-DLibburn_read_o_direcT" echo "enabled use of O_DIRECT with track input" else LIBBURN_O_DIRECT_DEF= echo "disabled use of O_DIRECT with track input" fi dnl Avoid the need for libburn_libburn_la_CFLAGS in Makefile.am (ugly .o names) dnl ### AC_SUBST(LIBBURN_O_DIRECT_DEF) CFLAGS="$LIBBURN_O_DIRECT_DEF $CFLAGS" dnl ts A91116 AC_ARG_ENABLE(dvd-obs-64k, [ --enable-dvd-obs-64k 64 KB default size for DVD writing, default=no], , enable_dvd_obs_64k=no) if test x$enable_dvd_obs_64k = xyes; then LIBBURN_DVD_OBS_64K="-DLibburn_dvd_obs_default_64K" echo "enabled write size default 64 KB on DVD" else LIBBURN_DVD_OBS_64K= echo "disabled write size default 64 KB on DVD" fi CFLAGS="$LIBBURN_DVD_OBS_64K $CFLAGS" dnl ts B20413 AC_ARG_ENABLE(dvd-obs-pad, [ --enable-dvd-obs-pad pad DVD DAO sessions to 32 or 64 KB, default=no], , enable_dvd_obs_pad=no) if test x$enable_dvd_obs_pad = xyes; then LIBBURN_DVD_OBS_PAD="-DLibburn_dvd_always_obs_paD" echo "enabled padding of DVD DAO sessions to 32 or 64 KB" else LIBBURN_DVD_OBS_64K= echo "disabled padding of DVD DAO sessions to 32 or 64 KB" fi CFLAGS="$LIBBURN_DVD_OBS_PAD $CFLAGS" dnl ts A91218 - B21002 case $host_os in cygwin*|mingw*) default_libcdio=yes ;; *) default_libcdio=no ;; esac # Check for proper library versions if this is desired. # (It fails too often on too many systems.) AC_ARG_ENABLE(pkg-check-modules, [ --enable-pkg-check-modules Enable pkg-config check for libcdio , default=no], , enable_pkg_check_modules=no) AC_ARG_ENABLE(libcdio, [ --enable-libcdio Enable use of libcdio as system adapter, default=no (except on MSWindows)], , enable_libcdio=$default_libcdio) PKG_PROG_PKG_CONFIG if test x$enable_libcdio = xyes; then dnl Check whether there is libcdio-devel and libcdio-runtime. dnl If not, erase this macro LIBCDIO_DEF="-DLibburn_use_libcdiO" dnl The empty yes case obviously causes -lcdio to be linked AC_CHECK_HEADER(cdio/cdio.h, AC_CHECK_LIB(cdio, mmc_last_cmd_sense, , LIBCDIO_DEF= ), LIBCDIO_DEF= ) else LIBCDIO_DEF= fi if test x$LIBCDIO_DEF = x then if test x$enable_libcdio = xyes then echo "WARNING: could not enable use of libcdio as system adapter" fi else echo "enabled use of libcdio as system adapter" CFLAGS="$LIBCDIO_DEF $CFLAGS" if test x$enable_pkg_check_modules = xyes; then LIBCDIO_REQUIRED=0.83 PKG_CHECK_MODULES(LIBCDIO, libcdio >= $LIBCDIO_REQUIRED) else echo "checking for LIBCDIO... skipped, no --enable-pkg-check-modules" fi fi dnl ts B00704 # Library versioning normally serves a complex purpose. # Since libburn obeys strict ABI backward compatibility, it needs only the # simple feature to declare function names "global:" or "local:". Only the # global ones are visible to applications at library load time. AC_ARG_ENABLE(versioned-libs, [ --enable-versioned-libs Enable strict symbol encapsulation , default=yes], , enable_versioned_libs=yes) if test x$enable_versioned_libs = xyes; then vers_libs_test=no LIBBURN_ASSERT_VERS_LIBS if test x$vers_libs_test = xno then echo "disabled strict symbol encapsulation (test failed)" else echo "enabled strict symbol encapsulation" fi else echo "disabled strict symbol encapsulation" fi AC_ARG_ENABLE(ldconfig-at-install, [ --enable-ldconfig-at-install On GNU/Linux run ldconfig, default=yes], , ldconfig_at_install=yes) if test x$ldconfig_at_install = xyes; then dummy=dummy else LIBBURNIA_LDCONFIG_CMD="echo 'NOTE: ldconfig is disabled. If needed, configure manually for:'" echo "disabled run of ldconfig during installation on GNU/Linux" fi AC_SUBST(LIBBURNIA_LDCONFIG_CMD) dnl Add compiler-specific flags dnl See if the user wants aggressive optimizations of the code AC_ARG_ENABLE(debug, [ --enable-debug Disable aggressive optimizations [default=yes]], , enable_debug=yes) if test x$enable_debug != xyes; then if test x$GCC = xyes; then CFLAGS="-O3 $CFLAGS" CFLAGS="-fexpensive-optimizations $CFLAGS" fi CFLAGS="-DNDEBUG $CFLAGS" else if test x$GCC = xyes; then CFLAGS="-g -pedantic -Wall -Wextra -Wno-unused-parameter -Wno-char-subscripts $CFLAGS" fi CFLAGS="-DDEBUG $CFLAGS" fi dnl Determine target directory for libburn-*.pc dnl Important: Must be performed _after_ TARGET_SHIZZLE dnl LIBBURNIA_SET_PKGCONFIG AC_CONFIG_FILES([ Makefile doc/doxygen.conf version.h libburn-1.pc ]) AC_OUTPUT ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������