summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPali Rohár <pali.rohar@gmail.com>2018-12-28 13:02:37 +0100
committerAndrej Shadura <andrewsh@debian.org>2018-12-28 13:58:40 +0100
commit5c20c7932a35cb792aad928702cc34ebdfcb0f40 (patch)
tree4213bdcc4fbeff3aefa42cab1233370302c2095c
parent6779fa7c477d1639d3e76f206dbc434a7503e091 (diff)
parentf97eb8990990b7938aecad3f06883f682750a125 (diff)
udftools (2.1-1) unstable; urgency=medium * New upstream release (Closes: #916006) * Update Standards-Version to 4.3.0 * Update to debhelper 11 * Update copyright and signing-key.asc
-rw-r--r--AUTHORS8
-rw-r--r--ChangeLog479
-rw-r--r--Makefile.in6
-rw-r--r--NEWS23
-rw-r--r--aclocal.m4276
-rw-r--r--cdrwtool/Makefile.am2
-rw-r--r--cdrwtool/Makefile.in8
-rw-r--r--cdrwtool/cdrwtool.c2
-rw-r--r--cdrwtool/cdrwtool.h33
-rw-r--r--cdrwtool/main.c3
-rw-r--r--cdrwtool/options.c8
-rw-r--r--cdrwtool/options.h2
-rwxr-xr-xconfigure920
-rw-r--r--configure.ac23
-rw-r--r--debian/changelog10
-rw-r--r--debian/compat2
-rw-r--r--debian/control4
-rw-r--r--debian/copyright6
-rw-r--r--debian/upstream/signing-key.asc57
-rw-r--r--doc/Makefile.in6
-rw-r--r--doc/cdrwtool.16
-rw-r--r--doc/mkudffs.8292
-rw-r--r--doc/udfinfo.1104
-rw-r--r--doc/udflabel.8127
-rw-r--r--doc/wrudf.12
-rw-r--r--include/bswap.h28
-rw-r--r--include/config.in33
-rw-r--r--include/ecma_167.h7
-rw-r--r--include/libudffs.h12
-rw-r--r--include/osta_udf.h15
-rw-r--r--include/udf_endian.h104
-rw-r--r--libudffs/Makefile.am2
-rw-r--r--libudffs/Makefile.in8
-rw-r--r--libudffs/extent.c2
-rw-r--r--libudffs/misc.c76
-rw-r--r--libudffs/unicode.c2
-rw-r--r--mkudffs/Makefile.am2
-rw-r--r--mkudffs/Makefile.in8
-rw-r--r--mkudffs/defaults.c2
-rw-r--r--mkudffs/defaults.h2
-rw-r--r--mkudffs/file.c198
-rw-r--r--mkudffs/file.h7
-rw-r--r--mkudffs/main.c11
-rw-r--r--mkudffs/mkudffs.c212
-rw-r--r--mkudffs/mkudffs.h8
-rw-r--r--mkudffs/options.c184
-rw-r--r--mkudffs/options.h2
-rw-r--r--pktsetup/Makefile.am6
-rw-r--r--pktsetup/Makefile.in12
-rw-r--r--pktsetup/pktsetup.c1
-rw-r--r--udffsck/Makefile.in6
-rw-r--r--udffsck/main.c2
-rw-r--r--udfinfo/Makefile.am2
-rw-r--r--udfinfo/Makefile.in8
-rw-r--r--udfinfo/main.c11
-rw-r--r--udfinfo/options.c23
-rw-r--r--udfinfo/readdisc.c635
-rw-r--r--udflabel/Makefile.am2
-rw-r--r--udflabel/Makefile.in8
-rw-r--r--udflabel/main.c32
-rw-r--r--udflabel/options.c55
-rw-r--r--wrudf/Makefile.am9
-rw-r--r--wrudf/Makefile.in16
-rw-r--r--wrudf/wrudf-cmnd.c11
-rw-r--r--wrudf/wrudf.c21
-rw-r--r--wrudf/wrudf.h6
66 files changed, 3039 insertions, 1161 deletions
diff --git a/AUTHORS b/AUTHORS
index 75fcf9d..2b6c8d1 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -1,9 +1,9 @@
libudffs
- Ben Fennema <bfennema@falcon.csc.calpoly.edu>
+ Ben Fennema
Pali Rohár <pali.rohar@gmail.com>
mkudffs
- Ben Fennema <bfennema@falcon.csc.calpoly.edu>
+ Ben Fennema
Pali Rohár <pali.rohar@gmail.com>
Steve Kenton <skenton@ou.edu>
@@ -15,7 +15,7 @@ udflabel
cdrwtool
Jens Axboe <axboe@suse.de>
- Ben Fennema <bfennema@falcon.csc.calpoly.edu>
+ Ben Fennema
pktsetup
Jens Axboe <axboe@suse.de>
@@ -27,6 +27,6 @@ wrudf
doc
Paul Thompson <set@pobox.com>
- Ben Fennema <bfennema@falcon.csc.calpoly.edu>
+ Ben Fennema
Pali Rohár <pali.rohar@gmail.com>
Steve Kenton <skenton@ou.edu>
diff --git a/ChangeLog b/ChangeLog
index 415a8f9..87c87d8 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,482 @@
+2018-12-28 12:13:16 +0100 Pali Rohár <pali.rohar@gmail.com>
+
+ * Release version 2.1
+
+2018-12-28 11:54:03 +0100 Pali Rohár <pali.rohar@gmail.com>
+
+ * configure: Remove AC_HEADER_TIME and AC_STRUCT_TM macros
+
+ Nobody checks for TIME_WITH_SYS_TIME or TM_IN_SYS_TIME definitions,
+ therefore they are not needed.
+
+2018-12-28 11:45:43 +0100 Pali Rohár <pali.rohar@gmail.com>
+
+ * configure: Remove checking for POSIX headers
+
+ Nobody checks for HAVE_* definitions, therefore it is not needed to check
+ for them.
+
+2018-12-28 11:44:53 +0100 Pali Rohár <pali.rohar@gmail.com>
+
+ * configure: Remove AC_HEADER_STDC macro
+
+ Nobody checks return value of this macro, nor definition of STDC_HEADERS.
+ Therefore is not needed.
+
+2018-12-21 19:51:53 +0100 Pali Rohár <pali.rohar@gmail.com>
+
+ * configure: Remove check for include file string.h
+
+ It is not needed as there is already check for C99.
+
+2018-12-17 15:33:39 +0100 Pali Rohár <pali.rohar@gmail.com>
+
+ * all: Remove old non-working Ben's email address
+
+2018-12-17 15:33:33 +0100 Pali Rohár <pali.rohar@gmail.com>
+
+ * all: Update copyrights to reflect changes
+
+2018-12-16 10:15:24 +0100 Pali Rohár <pali.rohar@gmail.com>
+
+ * all: Remove unused include file udf_endian.h and fix other sources
+
+2018-12-16 09:49:20 +0100 Pali Rohár <pali.rohar@gmail.com>
+
+ * wrudf: Fix spelling
+
+2018-12-14 12:44:26 +0100 Pali Rohár <pali.rohar@gmail.com>
+
+ * travis: Add gcc-8, clang-6.0 and clang-7
+
+2018-12-14 11:26:49 +0100 Pali Rohár <pali.rohar@gmail.com>
+
+ * udfinfo: Fix checking if ICB for VAT is valid
+
+2018-12-10 19:34:08 +0100 Pali Rohár <pali.rohar@gmail.com>
+
+ * all: Add some workaround for Year 2038 Bug
+
+ Check return values of time(), localtime() and gettimeofday() functions
+ which may fail.
+
+ Fallback to date/time 1.1.1980 00:00:00 when those functions fail.
+
+2018-12-10 19:21:18 +0100 Pali Rohár <pali.rohar@gmail.com>
+
+ * all: Add randu32() function
+
+ It replaces semi-broken get_random_bytes() functions in mkudffs and
+ udflabel. Function rand() returns number from interval [0, RAND_MAX] where
+ RAND_MAX is in most case 2^31-1, so rand() returns only 31 random bits.
+
+2018-12-09 13:39:42 +0100 Pali Rohár <pali.rohar@gmail.com>
+
+ * all: Fix generating new random uuid
+
+2018-12-06 19:15:48 +0100 Pali Rohár <pali.rohar@gmail.com>
+
+ * doc/mkudffs.8: Fix constant width-font
+
+2018-11-16 18:40:53 +0100 Pali Rohár <pali.rohar@gmail.com>
+
+ * doc/mkudffs.8: Fix style
+
+2018-11-06 22:10:09 +0800 Roy Zhang <pudh4418@gmail.com>
+
+ * mkudffs: Fix minor typo
+
+2018-11-04 13:50:50 +0100 Pali Rohár <pali.rohar@gmail.com>
+
+ * doc: Update manpages
+
+2018-10-20 23:23:44 +0200 Pali Rohár <pali.rohar@gmail.com>
+
+ * udfinfo: Fix parsing LVIDIU on UDF 1.01 disks
+
+2018-10-20 23:22:32 +0200 Pali Rohár <pali.rohar@gmail.com>
+
+ * mkudffs: Add support for UDF revision 1.01
+
+ Finally I got official specification UDF_101.PDF and therefore I modified
+ mkudffs to support UDF 1.01.
+
+2018-10-16 22:19:11 +0200 Pali Rohár <pali.rohar@gmail.com>
+
+ * all: Fix strtou32
+
+ Instead of sscanf() for detecting whitespaces, use isspace().
+
+2018-10-15 23:38:31 +0200 Pali Rohár <pali.rohar@gmail.com>
+
+ * mkudffs: Fix prototype for udf_set_version() function
+
+ UDF revision is 16bit integer.
+
+2018-10-15 22:35:14 +0200 Pali Rohár <pali.rohar@gmail.com>
+
+ * all: Fix converting strings to integers
+
+ Stop using strtou* functions as they are broken by design. They do not
+ signal overflow so are fully unusable for untrusted input.
+
+ Instead use strtoll() which returns signed value, but signals correctly
+ underflow. This function ignores and skips leading whitespaces, so detect
+ them via sscanf() space and %n format.
+
+ Implement new strtou32() and strtou16() functions in libudffs and use them
+ in all tools.
+
+2018-10-15 22:01:41 +0200 Pali Rohár <pali.rohar@gmail.com>
+
+ * cdrwtool: Disallow specifying unsupported UDF revisions
+
+ First UDF revision which supports CD-RW discs is 1.50. And udftools does
+ not support 2.50 or 2.60 on CD-RW discs yet.
+
+2018-10-15 22:00:01 +0200 Pali Rohár <pali.rohar@gmail.com>
+
+ * cdrwtool: Include proper file for udf_set_version() function prototype
+
+2018-09-17 11:53:29 +0200 Pali Rohár <pali.rohar@gmail.com>
+
+ * udfinfo: Remove obsolete debug output
+
+2018-09-04 23:36:15 +0200 Pali Rohár <pali.rohar@gmail.com>
+
+ * udfinfo: Fix crashing when parsing incomplete disk image
+
+2018-08-12 14:53:18 +0200 Pali Rohár <pali.rohar@gmail.com>
+
+ * udfinfo: Fix compile warning comparison between signed and unsigned integer expressions
+
+2018-08-12 13:52:56 +0200 Pali Rohár <pali.rohar@gmail.com>
+
+ * udflabel: Fix offset overflow on 32bit systems
+
+ Use off_t type instead of size_t which is only 32bit on 32bit systems.
+
+2018-08-12 13:52:34 +0200 Pali Rohár <pali.rohar@gmail.com>
+
+ * udfinfo: Fix offset overflow on 32bit systems
+
+ Use off_t type instead of size_t which is only 32bit on 32bit systems.
+
+2018-08-12 13:51:42 +0200 Pali Rohár <pali.rohar@gmail.com>
+
+ * mkudffs: Fix overflow in multiplication
+
+ Because size_t is 32bit on 32bit systems.
+
+2018-08-12 13:49:52 +0200 Pali Rohár <pali.rohar@gmail.com>
+
+ * mkudffs: Make fallback function for random bytes more resource effective
+
+2018-08-12 13:49:30 +0200 Pali Rohár <pali.rohar@gmail.com>
+
+ * mkudffs: Fix fallback function for random bytes
+
+2018-07-21 23:04:48 +0200 Pali Rohár <pali.rohar@gmail.com>
+
+ * mkudffs: Fix alignment of VAT again
+
+2018-07-21 10:42:11 +0200 Pali Rohár <pali.rohar@gmail.com>
+
+ * mkudffs: Fix alignment of VAT, put it always to the last sector at the end of packet
+
+2018-07-21 10:41:08 +0200 Pali Rohár <pali.rohar@gmail.com>
+
+ * mkudffs: DVD and BD discs do not require minimal size of 300 sectors
+
+2018-07-21 10:38:34 +0200 Pali Rohár <pali.rohar@gmail.com>
+
+ * mkudffs: Allow to set alignment of UDF structures via --packetlen option for any media type
+
+2018-07-21 10:34:43 +0200 Pali Rohár <pali.rohar@gmail.com>
+
+ * doc: Fix formatting
+
+2018-06-30 12:16:41 +0200 Pali Rohár <pali.rohar@gmail.com>
+
+ * doc: Fix formatting
+
+2018-06-02 14:30:51 +0200 Pali Rohár <pali.rohar@gmail.com>
+
+ * doc: Use \(en for en-dash
+
+2018-06-02 14:30:44 +0200 Pali Rohár <pali.rohar@gmail.com>
+
+ * doc: Update documentation about VAT for udfinfo and udflabel
+
+2018-06-02 14:30:23 +0200 Pali Rohár <pali.rohar@gmail.com>
+
+ * udfinfo: Fix reading FSD on discs with VAT or Sparable partitions
+
+ Tag location must match original block number and not translated.
+
+2018-06-02 14:02:32 +0200 Pali Rohár <pali.rohar@gmail.com>
+
+ * udfinfo: Add another check for VAT length overflow
+
+2018-06-02 13:37:14 +0200 Pali Rohár <pali.rohar@gmail.com>
+
+ * udfinfo: Fix possible integer overflow
+
+2018-06-02 13:04:21 +0200 Pali Rohár <pali.rohar@gmail.com>
+
+ * udfinfo: Fix checks for VAT length
+
+2018-06-02 12:13:53 +0200 Pali Rohár <pali.rohar@gmail.com>
+
+ * udfinfo: Implement reading VAT outside of outside of ICB
+
+2018-05-27 12:47:36 +0200 Pali Rohár <pali.rohar@gmail.com>
+
+ * udfinfo: Fix locating blocks in spartable when packet length is not power of two
+
+2018-05-27 02:04:06 +0200 Pali Rohár <pali.rohar@gmail.com>
+
+ * udflabel: Remove misleading error check and message about writeonce partition << 2.00
+
+ Updating writeonce partition of UDF revision prior to 2.00 is possible via
+ Logical Volume Extended Information when Virtual Allocation Table is used.
+ But udflabel does not support updating VAT yet and this is covered by
+ another error check.
+
+2018-05-26 16:15:34 +0200 Pali Rohár <pali.rohar@gmail.com>
+
+ * mkudffs: Fix recalculation of lengthExtendedAttr
+
+2018-05-26 16:14:51 +0200 Pali Rohár <pali.rohar@gmail.com>
+
+ * mkudffs: Fix compile warning: 'location' may be used uninitialized in this function
+
+2018-05-26 15:47:45 +0200 Pali Rohár <pali.rohar@gmail.com>
+
+ * mkudffs: Implement generating UDF 1.50 Logical Volume Extended Information
+
+ It is Extended Attribute for UDF 1.50 disc with VAT and contains up-to-date
+ information about number of files, directories and last update of Logical
+ Volume Identifier.
+
+2018-05-26 15:47:27 +0200 Pali Rohár <pali.rohar@gmail.com>
+
+ * mkudffs: Implement function insert_ea() for inserting extended attributes into file entries
+
+2018-05-26 14:15:21 +0200 Pali Rohár <pali.rohar@gmail.com>
+
+ * mkudffs: Fix generating VAT on big endian systems
+
+2018-05-26 14:13:53 +0200 Pali Rohár <pali.rohar@gmail.com>
+
+ * udfinfo: Fix reading VAT on big endian systems
+
+2018-05-26 13:38:05 +0200 Pali Rohár <pali.rohar@gmail.com>
+
+ * udfinfo: Implement reading of UDF 1.50 Logical Volume Extended Information
+
+ For UDF 1.50 discs with VAT (defined in UDF 1.50 Errata, DCN 5003,
+ 3.3.4.5.1.3) it contains up-to-date information about number of files,
+ directories and last update of Logical Volume Identifier. Like in UDF 2.00.
+
+2018-05-25 08:29:10 +0200 Pali Rohár <pali.rohar@gmail.com>
+
+ * udfinfo: Fix reading and processing PD descriptors
+
+ UDF standard allows to have up to two PD descriptors. Process them both and
+ when other functions needs to access PD descriptor choose correct one based
+ on partition number.
+
+2018-05-25 08:28:12 +0200 Pali Rohár <pali.rohar@gmail.com>
+
+ * udfinfo: Fix reading VDP descriptor
+
+ VDP is also terminator of the current extent.
+
+2018-05-24 17:54:59 +0200 Pali Rohár <pali.rohar@gmail.com>
+
+ * udfinfo: Check for alloc errors
+
+2018-05-24 17:54:52 +0200 Pali Rohár <pali.rohar@gmail.com>
+
+ * udflabel: Check for alloc errors
+
+2018-05-24 17:54:43 +0200 Pali Rohár <pali.rohar@gmail.com>
+
+ * udflabel: Fix error message, there is only one FSD
+
+2018-05-18 17:02:44 +0200 Pali Rohár <pali.rohar@gmail.com>
+
+ * configure: Set minimal version of autoconf to 2.64
+
+ This version is required for PACKAGE_URL (5th param for AC_INIT) and for
+ blank arguments in AC_CHECK_LIB.
+
+ Fixes: https://github.com/pali/udftools/issues/19
+
+2018-04-23 16:03:19 +0200 Pierre-Yves <pyu@riseup.net>
+
+ * pktsetup: Ask udev for correct directory instead of trying to guess it
+
+ Signed-off-by: Pierre-Yves <pyu@riseup.net>
+
+2018-04-22 15:05:46 +0200 Thomas Petazzoni <thomas.petazzoni@bootlin.com>
+
+ * pktsetup/pktsetup.c: do not include <bits/types.h>
+
+ This header is not a standard header, and is for example not provided
+ by the musl C library.
+
+ This change has been tested by building udftools against glibc, uClibc
+ and musl.
+
+ Signed-off-by: Thomas Petazzoni <thomas.petazzoni@bootlin.com>
+
+2018-04-19 17:27:25 +0200 Pali Rohár <pali.rohar@gmail.com>
+
+ * doc: Fix hyphens, minuses, en dashes and spaces
+
+2018-02-26 12:47:36 +0100 Pali Rohár <pali.rohar@gmail.com>
+
+ * travis: Do not run Coverity Scan jobs on non-master branches and in pull requests
+
+2018-01-21 13:27:46 +0100 Pali Rohár <pali.rohar@gmail.com>
+
+ * udflabel: Do not try to update RVDS if points to same location as MVDS
+
+2018-01-21 13:27:23 +0100 Pali Rohár <pali.rohar@gmail.com>
+
+ * udfinfo: Correctly read filesytem which MVDS and RVDS points to same location
+
+2018-01-21 13:20:47 +0100 Pali Rohár <pali.rohar@gmail.com>
+
+ * mkudffs: For very small filesystems, reduct size of descriptors
+
+ UDF filesystems with less then 258 blocks are not strictly valid, therefore
+ there is no need for trying to achieve full compatibility with standards.
+
+ When less then 258 blocks is used, reduce overhead of UDF filesystem by not
+ storing RVDS and decrease size of MVDS and LVID bare minimum (6+1 blocks).
+
+2018-01-21 13:18:08 +0100 Pali Rohár <pali.rohar@gmail.com>
+
+ * mkudffs: Always setup Terminating Descriptor
+
+ Linux UDF kernel driver is not able to read UDF filesystem without
+ Terminating Descriptor. So rather disallow creating filesystem without it.
+
+2018-01-21 13:14:02 +0100 Pali Rohár <pali.rohar@gmail.com>
+
+ * mkudffs: Fix function udf_alloc_bitmap_blocks
+
+ Function rejected to allocate last bit in bitmap due to more restricted
+ check. Relax it.
+
+2018-01-21 13:11:48 +0100 Pali Rohár <pali.rohar@gmail.com>
+
+ * mkudffs: Fix function udf_find_next_one_bit
+
+ Make sure that function does not return bigger value then size argument.
+ Set remaining bit at size position to 1, so bigger value would not be
+ returned.
+
+2018-01-21 02:48:13 +0100 Pali Rohár <pali.rohar@gmail.com>
+
+ * mkudffs: Warn when creating UDF filesystem with less then 258 blocks
+
+ According to ECMA-167 3/8.1.2.1, number of last block shall be greater then
+256. Therefore UDF filesystem shall have at least 258 blocks. So show
+ warning that such filesystem can cause problems.
+
+2018-01-21 02:21:58 +0100 Pali Rohár <pali.rohar@gmail.com>
+
+ * udflabel: Fix changing label on big endian systems
+
+ Function compute_crc() must return crc value in system endianity.
+
+2018-01-14 15:35:03 +0100 Pali Rohár <pali.rohar@gmail.com>
+
+ * configure: Enforce ISO C99
+
+ Fix also CFLAGS for Travis.
+
+2018-01-13 14:51:18 +0100 Pali Rohár <pali.rohar@gmail.com>
+
+ * mkudffs: Fix reading lengthAllocDescs on big endian systems
+
+2018-01-13 14:48:16 +0100 Pali Rohár <pali.rohar@gmail.com>
+
+ * mkudffs: Fix infinite loop on big endian systems
+
+ Member numOfBits is stored in little endian.
+
+2018-01-12 22:57:08 +0100 Pali Rohár <pali.rohar@gmail.com>
+
+ * all: Simplify detection of big endian systems
+
+ Use autoconf AC_C_BIGENDIAN macro for it.
+
+2018-01-12 22:39:35 +0100 Pali Rohár <pali.rohar@gmail.com>
+
+ * travis: Add also system versions of clang into matrix
+
+2018-01-12 22:37:47 +0100 Pali Rohár <pali.rohar@gmail.com>
+
+ * travis: Set RUN variable with corresponding qemu binary
+
+2018-01-06 14:44:05 +0100 Pali Rohár <pali.rohar@gmail.com>
+
+ * wrudf: Check return value of fgets
+
+2018-01-06 13:43:53 +0100 Pali Rohár <pali.rohar@gmail.com>
+
+ * wrudf: Fix compilation without libreadline
+
+2018-01-06 13:23:51 +0100 Pali Rohár <pali.rohar@gmail.com>
+
+ * travis: Compile also for x32
+
+2018-01-06 13:20:51 +0100 Pali Rohár <pali.rohar@gmail.com>
+
+ * travis: Fix support for powerpc and arm
+
+2018-01-06 03:36:57 +0100 Pali Rohár <pali.rohar@gmail.com>
+
+ * travis: Do not use binfmt as it does not work and export configure flags
+
+2018-01-06 03:07:05 +0100 Pali Rohár <pali.rohar@gmail.com>
+
+ * travis: Compile also for powerpc and arm
+
+2018-01-06 02:54:47 +0100 Pali Rohár <pali.rohar@gmail.com>
+
+ * wrudf: Allow to compile without libreadline
+
+2018-01-05 23:05:05 +0100 Pali Rohár <pali.rohar@gmail.com>
+
+ * travis: Compile also without -O2
+
+2018-01-05 22:52:59 +0100 Pali Rohár <pali.rohar@gmail.com>
+
+ * travis: Enable -Wno-error=unused-function only for clang
+
+2018-01-02 15:10:34 +0100 Lars Wendler <polynomial-c@gentoo.org>
+
+ * Include <sys/sysmacros.h> to prevent build breakage with >=glibc-2.25
+
+ libtool: link: x86_64-pc-linux-gnu-gcc -march=native -mtune=native -O2
+ -pipe -Wl,-O1 -Wl,--hash-style=gnu -Wl,--sort-common -Wl,--as-needed -o
+ mkudffs main.o mkudffs.o defaults.o file.o options.o
+ ../libudffs/.libs/libudffs.a
+ main.o: In function `is_whole_disk':
+ main.c:(.text+0x2ce): undefined reference to `major'
+ main.c:(.text+0x2dd): undefined reference to `minor'
+ main.o: In function `main':
+ main.c:(.text.startup+0x72f): undefined reference to `minor'
+ main.c:(.text.startup+0x741): undefined reference to `major'
+ collect2: error: ld returned 1 exit status
+ make[1]: *** [Makefile:378: mkudffs] Error 1
+
2017-12-29 17:27:53 +0100 Pali Rohár <pali.rohar@gmail.com>
* Release version 2.0
diff --git a/Makefile.in b/Makefile.in
index b5e7d69..2aa041c 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -293,11 +293,17 @@ 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@
+UDEVDIR = @UDEVDIR@
+UDEV_CFLAGS = @UDEV_CFLAGS@
+UDEV_LIBS = @UDEV_LIBS@
VERSION = @VERSION@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
diff --git a/NEWS b/NEWS
index 8bbdcb2..857456f 100644
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,26 @@
+Changes in 2.1
+* Fixed compilation with glibc >= 2.25
+* Allow to compile without libreadline
+* Use pkgconfig for detection of udev rules directory
+* Set minimal version of autoconf to 2.64
+* Enforce ISO C99 compiler
+* Fixed support for big endian systems
+* Fixed converting strings to integers
+* Added support for UDF 1.50 Logical Volume Extended Information (contains volume label)
+* Added support for UDF 1.01 revision
+* Added workaround for Year 2038 Bug
+* udfinfo & udflabel:
+ * Fixed accessing disks when MVDS and RVDS descriptors points to same location
+ * Fixed support for disks >= 4GB on 32bit systems
+ * Implemented reading VAT outside of outside of ICB
+ * Various fixes for reading UDF descriptors
+* mkudffs:
+ * Space optimization for small disks
+ * Allow to set alignment of UDF structures via --packetlen option for any media type
+ * Fixed alignment of VAT and generation of DVD-R and BD-R discs
+* cdrwtool:
+ * Disallow specifying unsupported UDF revisions
+
Changes in 2.0
* For UDF uuid is used same algorithm as in util-linux v2.30
* Fixed Unicode encode/decode functions to correctly process OSTA Unicode d-string and d-characters
diff --git a/aclocal.m4 b/aclocal.m4
index c763971..77dcc64 100644
--- a/aclocal.m4
+++ b/aclocal.m4
@@ -9067,6 +9067,282 @@ 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])])
+dnl pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*-
+dnl serial 11 (pkg-config-0.29)
+dnl
+dnl Copyright © 2004 Scott James Remnant <scott@netsplit.com>.
+dnl Copyright © 2012-2015 Dan Nicholson <dbn.lists@gmail.com>
+dnl
+dnl This program is free software; you can redistribute it and/or modify
+dnl it under the terms of the GNU General Public License as published by
+dnl the Free Software Foundation; either version 2 of the License, or
+dnl (at your option) any later version.
+dnl
+dnl This program is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of
+dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+dnl General Public License for more details.
+dnl
+dnl You should have received a copy of the GNU General Public License
+dnl along with this program; if not, write to the Free Software
+dnl Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+dnl 02111-1307, USA.
+dnl
+dnl As a special exception to the GNU General Public License, if you
+dnl distribute this file as part of a program that contains a
+dnl configuration script generated by Autoconf, you may include it under
+dnl the same distribution terms that you use for the rest of that
+dnl program.
+
+dnl PKG_PREREQ(MIN-VERSION)
+dnl -----------------------
+dnl Since: 0.29
+dnl
+dnl Verify that the version of the pkg-config macros are at least
+dnl MIN-VERSION. Unlike PKG_PROG_PKG_CONFIG, which checks the user's
+dnl installed version of pkg-config, this checks the developer's version
+dnl of pkg.m4 when generating configure.
+dnl
+dnl To ensure that this macro is defined, also add:
+dnl m4_ifndef([PKG_PREREQ],
+dnl [m4_fatal([must install pkg-config 0.29 or later before running autoconf/autogen])])
+dnl
+dnl See the "Since" comment for each macro you use to see what version
+dnl of the macros you require.
+m4_defun([PKG_PREREQ],
+[m4_define([PKG_MACROS_VERSION], [0.29])
+m4_if(m4_version_compare(PKG_MACROS_VERSION, [$1]), -1,
+ [m4_fatal([pkg.m4 version $1 or higher is required but ]PKG_MACROS_VERSION[ found])])
+])dnl PKG_PREREQ
+
+dnl PKG_PROG_PKG_CONFIG([MIN-VERSION])
+dnl ----------------------------------
+dnl Since: 0.16
+dnl
+dnl Search for the pkg-config tool and set the PKG_CONFIG variable to
+dnl first found in the path. Checks that the version of pkg-config found
+dnl is at least MIN-VERSION. If MIN-VERSION is not specified, 0.9.0 is
+dnl used since that's the first version where most current features of
+dnl pkg-config existed.
+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
+])dnl PKG_PROG_PKG_CONFIG
+
+dnl PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
+dnl -------------------------------------------------------------------
+dnl Since: 0.18
+dnl
+dnl Check to see whether a particular set of modules exists. Similar to
+dnl PKG_CHECK_MODULES(), but does not set variables or print errors.
+dnl
+dnl Please remember that m4 expands AC_REQUIRE([PKG_PROG_PKG_CONFIG])
+dnl only at the first occurence in configure.ac, so if the first place
+dnl it's called might be skipped (such as if it is within an "if", you
+dnl 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])
+
+dnl _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES])
+dnl ---------------------------------------------
+dnl Internal wrapper calling pkg-config via PKG_CONFIG and setting
+dnl pkg_failed based on the result.
+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
+])dnl _PKG_CONFIG
+
+dnl _PKG_SHORT_ERRORS_SUPPORTED
+dnl ---------------------------
+dnl Internal check to see if pkg-config supports short errors.
+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
+])dnl _PKG_SHORT_ERRORS_SUPPORTED
+
+
+dnl PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND],
+dnl [ACTION-IF-NOT-FOUND])
+dnl --------------------------------------------------------------
+dnl Since: 0.4.0
+dnl
+dnl Note that if there is a possibility the first call to
+dnl PKG_CHECK_MODULES might not happen, you should be sure to include an
+dnl 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
+])dnl PKG_CHECK_MODULES
+
+
+dnl PKG_CHECK_MODULES_STATIC(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND],
+dnl [ACTION-IF-NOT-FOUND])
+dnl ---------------------------------------------------------------------
+dnl Since: 0.29
+dnl
+dnl Checks for existence of MODULES and gathers its build flags with
+dnl static libraries enabled. Sets VARIABLE-PREFIX_CFLAGS from --cflags
+dnl and VARIABLE-PREFIX_LIBS from --libs.
+dnl
+dnl Note that if there is a possibility the first call to
+dnl PKG_CHECK_MODULES_STATIC might not happen, you should be sure to
+dnl include an explicit call to PKG_PROG_PKG_CONFIG in your
+dnl configure.ac.
+AC_DEFUN([PKG_CHECK_MODULES_STATIC],
+[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
+_save_PKG_CONFIG=$PKG_CONFIG
+PKG_CONFIG="$PKG_CONFIG --static"
+PKG_CHECK_MODULES($@)
+PKG_CONFIG=$_save_PKG_CONFIG[]dnl
+])dnl PKG_CHECK_MODULES_STATIC
+
+
+dnl PKG_INSTALLDIR([DIRECTORY])
+dnl -------------------------
+dnl Since: 0.27
+dnl
+dnl Substitutes the variable pkgconfigdir as the location where a module
+dnl should install pkg-config .pc files. By default the directory is
+dnl $libdir/pkgconfig, but the default can be changed by passing
+dnl DIRECTORY. The user can override through the --with-pkgconfigdir
+dnl 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
+
+
+dnl PKG_NOARCH_INSTALLDIR([DIRECTORY])
+dnl --------------------------------
+dnl Since: 0.27
+dnl
+dnl Substitutes the variable noarch_pkgconfigdir as the location where a
+dnl module should install arch-independent pkg-config .pc files. By
+dnl default the directory is $datadir/pkgconfig, but the default can be
+dnl changed by passing DIRECTORY. The user can override through the
+dnl --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
+
+
+dnl PKG_CHECK_VAR(VARIABLE, MODULE, CONFIG-VARIABLE,
+dnl [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
+dnl -------------------------------------------
+dnl Since: 0.28
+dnl
+dnl 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
+])dnl PKG_CHECK_VAR
+
# Copyright (C) 2002-2014 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
diff --git a/cdrwtool/Makefile.am b/cdrwtool/Makefile.am
index 1d78c85..d647e55 100644
--- a/cdrwtool/Makefile.am
+++ b/cdrwtool/Makefile.am
@@ -1,5 +1,5 @@
bin_PROGRAMS = cdrwtool
cdrwtool_LDADD = $(top_builddir)/libudffs/libudffs.la
-cdrwtool_SOURCES = main.c options.c cdrwtool.c ../mkudffs/mkudffs.c ../mkudffs/defaults.c ../mkudffs/file.c options.h cdrwtool.h ../include/ecma_167.h ../include/osta_udf.h ../mkudffs/mkudffs.h ../mkudffs/defaults.h ../mkudffs/file.h ../include/libudffs.h ../include/udf_endian.h
+cdrwtool_SOURCES = main.c options.c cdrwtool.c ../mkudffs/mkudffs.c ../mkudffs/defaults.c ../mkudffs/file.c options.h cdrwtool.h ../include/ecma_167.h ../include/osta_udf.h ../mkudffs/mkudffs.h ../mkudffs/defaults.h ../mkudffs/file.h ../include/libudffs.h
AM_CPPFLAGS = -I$(top_srcdir)/include
diff --git a/cdrwtool/Makefile.in b/cdrwtool/Makefile.in
index 4797006..3341e0b 100644
--- a/cdrwtool/Makefile.in
+++ b/cdrwtool/Makefile.in
@@ -229,11 +229,17 @@ 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@
+UDEVDIR = @UDEVDIR@
+UDEV_CFLAGS = @UDEV_CFLAGS@
+UDEV_LIBS = @UDEV_LIBS@
VERSION = @VERSION@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
@@ -289,7 +295,7 @@ top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
cdrwtool_LDADD = $(top_builddir)/libudffs/libudffs.la
-cdrwtool_SOURCES = main.c options.c cdrwtool.c ../mkudffs/mkudffs.c ../mkudffs/defaults.c ../mkudffs/file.c options.h cdrwtool.h ../include/ecma_167.h ../include/osta_udf.h ../mkudffs/mkudffs.h ../mkudffs/defaults.h ../mkudffs/file.h ../include/libudffs.h ../include/udf_endian.h
+cdrwtool_SOURCES = main.c options.c cdrwtool.c ../mkudffs/mkudffs.c ../mkudffs/defaults.c ../mkudffs/file.c options.h cdrwtool.h ../include/ecma_167.h ../include/osta_udf.h ../mkudffs/mkudffs.h ../mkudffs/defaults.h ../mkudffs/file.h ../include/libudffs.h
AM_CPPFLAGS = -I$(top_srcdir)/include
all: all-am
diff --git a/cdrwtool/cdrwtool.c b/cdrwtool/cdrwtool.c
index 66f82a2..252de52 100644
--- a/cdrwtool/cdrwtool.c
+++ b/cdrwtool/cdrwtool.c
@@ -2,7 +2,7 @@
* cdrwtool - perform all sort of actions on a CD-R, CD-RW, and DVD-R drive.
*
* Copyright (c) 1999,2000 Jens Axboe <axboe@suse.de>
- * Copyright (c) 2002 Ben Fennema <bfennema@falcon.csc.calpoly.edu>
+ * Copyright (c) 2002 Ben Fennema
*
* 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
diff --git a/cdrwtool/cdrwtool.h b/cdrwtool/cdrwtool.h
index af6aa64..aed38fd 100644
--- a/cdrwtool/cdrwtool.h
+++ b/cdrwtool/cdrwtool.h
@@ -10,7 +10,7 @@
#ifndef _CDRWTOOL_H
#define _CDRWTOOL_H 1
-#include <inttypes.h>
+#include <stdint.h>
#include <linux/cdrom.h>
#include "../include/libudffs.h"
@@ -91,47 +91,29 @@ struct cdrw_disc
struct udf_disc udf_disc;
};
-#ifndef be16_to_cpu
-#define be16_to_cpu(x) \
- ((uint16_t)( \
- (((uint16_t)(x) & (uint16_t)0x00ffU) << 8) | \
- (((uint16_t)(x) & (uint16_t)0xff00U) >> 8) ))
-#endif
-
-#ifndef be32_to_cpu
-#define be32_to_cpu(x) \
- ((uint32_t)( \
- (((uint32_t)(x) & (uint32_t)0x000000ffUL) << 24) | \
- (((uint32_t)(x) & (uint32_t)0x0000ff00UL) << 8) | \
- (((uint32_t)(x) & (uint32_t)0x00ff0000UL) >> 8) | \
- (((uint32_t)(x) & (uint32_t)0xff000000UL) >> 24) ))
-#endif
-
typedef struct disc_info {
uint16_t length;
-#if __BYTE_ORDER == __BIG_ENDIAN
+#ifdef WORDS_BIGENDIAN
unsigned char reserved1 : 3;
unsigned char erasable : 1;
unsigned char border : 2;
unsigned char status : 2;
-#elif __BYTE_ORDER == __LITTLE_ENDIAN
+#else
unsigned char status : 2;
unsigned char border : 2;
unsigned char erasable : 1;
unsigned char reserved1 : 3;
-#else
-#error "<bits/endian.h> is wack"
#endif
uint8_t n_first_track;
uint8_t n_sessions_l;
uint8_t first_track_l;
uint8_t last_track_l;
-#if __BYTE_ORDER == __BIG_ENDIAN
+#ifdef WORDS_BIGENDIAN
unsigned char did_v : 1;
unsigned char dbc_v : 1;
unsigned char uru : 1;
unsigned char reserved2 : 5;
-#elif __BYTE_ORDER == __LITTLE_ENDIAN
+#else
unsigned char reserved2 : 5;
unsigned char uru : 1;
unsigned char dbc_v : 1;
@@ -160,7 +142,7 @@ typedef struct track_info {
uint8_t track_number_l;
uint8_t session_number_l;
uint8_t reserved1;
-#if __BYTE_ORDER == __BIG_ENDIAN
+#ifdef WORDS_BIGENDIAN
uint8_t reserved2 : 2;
uint8_t damage : 1;
uint8_t copy : 1;
@@ -173,7 +155,7 @@ typedef struct track_info {
uint8_t reserved3 : 6;
uint8_t lra_v : 1;
uint8_t nwa_v : 1;
-#elif __BYTE_ORDER == __LITTLE_ENDIAN
+#else
uint8_t track_mode : 4;
uint8_t copy : 1;
uint8_t damage : 1;
@@ -237,6 +219,5 @@ int print_disc_track_info(int);
void make_write_page(write_params_t *, struct cdrw_disc *);
void print_params(write_params_t *);
void cdrw_init_disc(struct cdrw_disc *);
-int udf_set_version(struct udf_disc *, int);
#endif /* _CDRWTOOL_H */
diff --git a/cdrwtool/main.c b/cdrwtool/main.c
index 6f0b547..7df67b1 100644
--- a/cdrwtool/main.c
+++ b/cdrwtool/main.c
@@ -1,7 +1,7 @@
/*
* main.c
*
- * Copyright (c) 2002 Ben Fennema <bfennema@falcon.csc.calpoly.edu>
+ * Copyright (c) 2002 Ben Fennema
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
@@ -24,6 +24,7 @@
#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
diff --git a/cdrwtool/options.c b/cdrwtool/options.c
index 91d222d..9f0d652 100644
--- a/cdrwtool/options.c
+++ b/cdrwtool/options.c
@@ -1,7 +1,7 @@
/*
* options.c
*
- * Copyright (c) 2002 Ben Fennema <bfennema@falcon.csc.calpoly.edu>
+ * Copyright (c) 2002 Ben Fennema
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
@@ -24,11 +24,14 @@
#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
#include "cdrwtool.h"
#include "libudffs.h"
#include "options.h"
+#include "../mkudffs/mkudffs.h"
+
struct option long_options[] = {
{ "help", no_argument, NULL, OPT_HELP },
{ "device", 1, NULL, 'd' },
@@ -105,7 +108,8 @@ void parse_args(int argc, char *argv[], struct cdrw_disc *disc, const char **dev
}
case 'v':
{
- if (udf_set_version(&disc->udf_disc, strtol(optarg, NULL, 16)))
+ int udf_rev = strtol(optarg, NULL, 16);
+ if (udf_rev < 0x0150 || udf_rev > 0x0201 || udf_set_version(&disc->udf_disc, udf_rev))
exit(1);
printf("udf version set to 0x%04x\n", disc->udf_disc.udf_rev);
break;
diff --git a/cdrwtool/options.h b/cdrwtool/options.h
index c67b43d..cbcd4dc 100644
--- a/cdrwtool/options.h
+++ b/cdrwtool/options.h
@@ -1,7 +1,7 @@
/*
* options.h
*
- * Copyright (c) 2002 Ben Fennema <bfennema@falcon.csc.calpoly.edu>
+ * Copyright (c) 2002 Ben Fennema
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
diff --git a/configure b/configure
index e253ea9..71aa827 100755
--- a/configure
+++ b/configure
@@ -1,6 +1,6 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for udftools 2.0.
+# Generated by GNU Autoconf 2.69 for udftools 2.1.
#
#
# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
@@ -587,8 +587,8 @@ MAKEFLAGS=
# Identity of this package.
PACKAGE_NAME='udftools'
PACKAGE_TARNAME='udftools'
-PACKAGE_VERSION='2.0'
-PACKAGE_STRING='udftools 2.0'
+PACKAGE_VERSION='2.1'
+PACKAGE_STRING='udftools 2.1'
PACKAGE_BUGREPORT=''
PACKAGE_URL='https://github.com/pali/udftools/'
@@ -631,7 +631,15 @@ ac_includes_default="\
ac_subst_vars='am__EXEEXT_FALSE
am__EXEEXT_TRUE
LIBOBJS
+USE_READLINE_FALSE
+USE_READLINE_TRUE
LTLIBOBJS
+UDEVDIR
+UDEV_LIBS
+UDEV_CFLAGS
+PKG_CONFIG_LIBDIR
+PKG_CONFIG_PATH
+PKG_CONFIG
CPP
LT_SYS_LIBRARY_PATH
OTOOL64
@@ -770,7 +778,12 @@ LDFLAGS
LIBS
CPPFLAGS
LT_SYS_LIBRARY_PATH
-CPP'
+CPP
+PKG_CONFIG
+PKG_CONFIG_PATH
+PKG_CONFIG_LIBDIR
+UDEV_CFLAGS
+UDEV_LIBS'
# Initialize some variables set by options.
@@ -1321,7 +1334,7 @@ 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 udftools 2.0 to adapt to many kinds of systems.
+\`configure' configures udftools 2.1 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1392,7 +1405,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
- short | recursive ) echo "Configuration of udftools 2.0:";;
+ short | recursive ) echo "Configuration of udftools 2.1:";;
esac
cat <<\_ACEOF
@@ -1436,6 +1449,13 @@ Some influential environment variables:
LT_SYS_LIBRARY_PATH
User-defined run-time library search path.
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
+ UDEV_CFLAGS C compiler flags for UDEV, overriding pkg-config
+ UDEV_LIBS linker flags for UDEV, 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.
@@ -1504,7 +1524,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
-udftools configure 2.0
+udftools configure 2.1
generated by GNU Autoconf 2.69
Copyright (C) 2012 Free Software Foundation, Inc.
@@ -1869,7 +1889,7 @@ 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 udftools $as_me 2.0, which was
+It was created by udftools $as_me 2.1, which was
generated by GNU Autoconf 2.69. Invocation command line was
$ $0 $@
@@ -2734,7 +2754,7 @@ fi
# Define the identity of the package.
PACKAGE='udftools'
- VERSION='2.0'
+ VERSION='2.1'
cat >>confdefs.h <<_ACEOF
@@ -2828,6 +2848,69 @@ END
fi
+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'
@@ -3675,69 +3758,6 @@ 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
-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
-
-
depcc="$CC" am_compiler_list=
@@ -3867,6 +3887,183 @@ else
fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C99" >&5
+$as_echo_n "checking for $CC option to accept ISO C99... " >&6; }
+if ${ac_cv_prog_cc_c99+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_cv_prog_cc_c99=no
+ac_save_CC=$CC
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdarg.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <wchar.h>
+#include <stdio.h>
+
+// Check varargs macros. These examples are taken from C99 6.10.3.5.
+#define debug(...) fprintf (stderr, __VA_ARGS__)
+#define showlist(...) puts (#__VA_ARGS__)
+#define report(test,...) ((test) ? puts (#test) : printf (__VA_ARGS__))
+static void
+test_varargs_macros (void)
+{
+ int x = 1234;
+ int y = 5678;
+ debug ("Flag");
+ debug ("X = %d\n", x);
+ showlist (The first, second, and third items.);
+ report (x>y, "x is %d but y is %d", x, y);
+}
+
+// Check long long types.
+#define BIG64 18446744073709551615ull
+#define BIG32 4294967295ul
+#define BIG_OK (BIG64 / BIG32 == 4294967297ull && BIG64 % BIG32 == 0)
+#if !BIG_OK
+ your preprocessor is broken;
+#endif
+#if BIG_OK
+#else
+ your preprocessor is broken;
+#endif
+static long long int bignum = -9223372036854775807LL;
+static unsigned long long int ubignum = BIG64;
+
+struct incomplete_array
+{
+ int datasize;
+ double data[];
+};
+
+struct named_init {
+ int number;
+ const wchar_t *name;
+ double average;
+};
+
+typedef const char *ccp;
+
+static inline int
+test_restrict (ccp restrict text)
+{
+ // See if C++-style comments work.
+ // Iterate through items via the restricted pointer.
+ // Also check for declarations in for loops.
+ for (unsigned int i = 0; *(text+i) != '\0'; ++i)
+ continue;
+ return 0;
+}
+
+// Check varargs and va_copy.
+static void
+test_varargs (const char *format, ...)
+{
+ va_list args;
+ va_start (args, format);
+ va_list args_copy;
+ va_copy (args_copy, args);
+
+ const char *str;
+ int number;
+ float fnumber;
+
+ while (*format)
+ {
+ switch (*format++)
+ {
+ case 's': // string
+ str = va_arg (args_copy, const char *);
+ break;
+ case 'd': // int
+ number = va_arg (args_copy, int);
+ break;
+ case 'f': // float
+ fnumber = va_arg (args_copy, double);
+ break;
+ default:
+ break;
+ }
+ }
+ va_end (args_copy);
+ va_end (args);
+}
+
+int
+main ()
+{
+
+ // Check bool.
+ _Bool success = false;
+
+ // Check restrict.
+ if (test_restrict ("String literal") == 0)
+ success = true;
+ char *restrict newvar = "Another string";
+
+ // Check varargs.
+ test_varargs ("s, d' f .", "string", 65, 34.234);
+ test_varargs_macros ();
+
+ // Check flexible array members.
+ struct incomplete_array *ia =
+ malloc (sizeof (struct incomplete_array) + (sizeof (double) * 10));
+ ia->datasize = 10;
+ for (int i = 0; i < ia->datasize; ++i)
+ ia->data[i] = i * 1.234;
+
+ // Check named initializers.
+ struct named_init ni = {
+ .number = 34,
+ .name = L"Test wide string",
+ .average = 543.34343,
+ };
+
+ ni.number = 58;
+
+ int dynamic_array[ni.number];
+ dynamic_array[ni.number - 1] = 543;
+
+ // work around unused variable warnings
+ return (!success || bignum == 0LL || ubignum == 0uLL || newvar[0] == 'x'
+ || dynamic_array[ni.number - 1] != 543);
+
+ ;
+ return 0;
+}
+_ACEOF
+for ac_arg in '' -std=gnu99 -std=c99 -c99 -AC99 -D_STDC_C99= -qlanglvl=extc99
+do
+ CC="$ac_save_CC $ac_arg"
+ if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_prog_cc_c99=$ac_arg
+fi
+rm -f core conftest.err conftest.$ac_objext
+ test "x$ac_cv_prog_cc_c99" != "xno" && break
+done
+rm -f conftest.$ac_ext
+CC=$ac_save_CC
+
+fi
+# AC_CACHE_VAL
+case "x$ac_cv_prog_cc_c99" 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_c99"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c99" >&5
+$as_echo "$ac_cv_prog_cc_c99" >&6; } ;;
+esac
+if test "x$ac_cv_prog_cc_c99" != xno; then :
+
+fi
+
+
# Check whether --enable-shared was given.
if test "${enable_shared+set}" = set; then :
enableval=$enable_shared; p=${PACKAGE-default}
@@ -11950,6 +12147,10 @@ CC=$lt_save_CC
+if test "$ac_cv_prog_cc_c99" = "no"; then
+ as_fn_error $? "Your C compiler does not support ISO C99." "$LINENO" 5
+fi
+
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for readline in -lreadline" >&5
$as_echo_n "checking for readline in -lreadline... " >&6; }
if ${ac_cv_lib_readline_readline+:} false; then :
@@ -11988,130 +12189,15 @@ fi
$as_echo "$ac_cv_lib_readline_readline" >&6; }
if test "x$ac_cv_lib_readline_readline" = xyes; then :
-else
- as_fn_error $? "cannot find -lreadline." "$LINENO" 5
-fi
-
-
-{ $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
-
-for ac_header in fcntl.h sys/time.h unistd.h getopt.h string.h
+for ac_header in readline/readline.h
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 :
+ ac_fn_c_check_header_mongrel "$LINENO" "readline/readline.h" "ac_cv_header_readline_readline_h" "$ac_includes_default"
+if test "x$ac_cv_header_readline_readline_h" = xyes; then :
cat >>confdefs.h <<_ACEOF
-#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+#define HAVE_READLINE_READLINE_H 1
_ACEOF
fi
@@ -12161,75 +12247,229 @@ _ACEOF
;;
esac
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether time.h and sys/time.h may both be included" >&5
-$as_echo_n "checking whether time.h and sys/time.h may both be included... " >&6; }
-if ${ac_cv_header_time+:} false; then :
+ { $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
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+ 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/time.h>
-#include <time.h>
+ #include <sys/param.h>
int
main ()
{
-if ((struct tm *) 0)
-return 0;
+#if BYTE_ORDER != BIG_ENDIAN
+ not big endian
+ #endif
+
;
return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
- ac_cv_header_time=yes
+ ac_cv_c_bigendian=yes
else
- ac_cv_header_time=no
+ ac_cv_c_bigendian=no
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_time" >&5
-$as_echo "$ac_cv_header_time" >&6; }
-if test $ac_cv_header_time = yes; then
-
-$as_echo "#define TIME_WITH_SYS_TIME 1" >>confdefs.h
+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>
-fi
+int
+main ()
+{
+#if ! (defined _LITTLE_ENDIAN || defined _BIG_ENDIAN)
+ bogus endian macros
+ #endif
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether struct tm is in sys/time.h or time.h" >&5
-$as_echo_n "checking whether struct tm is in sys/time.h or time.h... " >&6; }
-if ${ac_cv_struct_tm+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+ ;
+ 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 <time.h>
+#include <limits.h>
int
main ()
{
-struct tm tm;
- int *p = &tm.tm_sec;
- return !p;
+#ifndef _BIG_ENDIAN
+ not big endian
+ #endif
+
;
return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
- ac_cv_struct_tm=time.h
+ ac_cv_c_bigendian=yes
else
- ac_cv_struct_tm=sys/time.h
+ ac_cv_c_bigendian=no
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_struct_tm" >&5
-$as_echo "$ac_cv_struct_tm" >&6; }
-if test $ac_cv_struct_tm = sys/time.h; then
+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;
-$as_echo "#define TM_IN_SYS_TIME 1" >>confdefs.h
+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 :
@@ -12434,6 +12674,229 @@ 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
+
+pkg_failed=no
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for UDEV" >&5
+$as_echo_n "checking for UDEV... " >&6; }
+
+if test -n "$UDEV_CFLAGS"; then
+ pkg_cv_UDEV_CFLAGS="$UDEV_CFLAGS"
+ elif test -n "$PKG_CONFIG"; then
+ if test -n "$PKG_CONFIG" && \
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"udev\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "udev") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ pkg_cv_UDEV_CFLAGS=`$PKG_CONFIG --cflags "udev" 2>/dev/null`
+ test "x$?" != "x0" && pkg_failed=yes
+else
+ pkg_failed=yes
+fi
+ else
+ pkg_failed=untried
+fi
+if test -n "$UDEV_LIBS"; then
+ pkg_cv_UDEV_LIBS="$UDEV_LIBS"
+ elif test -n "$PKG_CONFIG"; then
+ if test -n "$PKG_CONFIG" && \
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"udev\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "udev") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ pkg_cv_UDEV_LIBS=`$PKG_CONFIG --libs "udev" 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
+ UDEV_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "udev" 2>&1`
+ else
+ UDEV_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "udev" 2>&1`
+ fi
+ # Put the nasty error message in config.log where it belongs
+ echo "$UDEV_PKG_ERRORS" >&5
+
+ as_fn_error $? "Package requirements (udev) were not met:
+
+$UDEV_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 UDEV_CFLAGS
+and UDEV_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 UDEV_CFLAGS
+and UDEV_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
+ UDEV_CFLAGS=$pkg_cv_UDEV_CFLAGS
+ UDEV_LIBS=$pkg_cv_UDEV_LIBS
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ ac_cv_udevdir=`$PKG_CONFIG --variable=udevdir udev`
+fi
+UDEVDIR=$ac_cv_udevdir
+
+
+
+
+ if test "$ac_cv_lib_readline_readline" = "yes" -a "$ac_cv_header_readline_readline_h" = "yes"; then
+ USE_READLINE_TRUE=
+ USE_READLINE_FALSE='#'
+else
+ USE_READLINE_TRUE='#'
+ USE_READLINE_FALSE=
+fi
+
+
ac_config_files="$ac_config_files Makefile libudffs/Makefile mkudffs/Makefile cdrwtool/Makefile pktsetup/Makefile udffsck/Makefile udfinfo/Makefile udflabel/Makefile wrudf/Makefile doc/Makefile"
@@ -12570,6 +13033,11 @@ if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then
Usually this means the macro was only invoked conditionally." "$LINENO" 5
fi
+if test -z "${USE_READLINE_TRUE}" && test -z "${USE_READLINE_FALSE}"; then
+ as_fn_error $? "conditional \"USE_READLINE\" 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
@@ -12966,7 +13434,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
-This file was extended by udftools $as_me 2.0, which was
+This file was extended by udftools $as_me 2.1, which was
generated by GNU Autoconf 2.69. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@@ -13033,7 +13501,7 @@ _ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\
-udftools config.status 2.0
+udftools config.status 2.1
configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\"
diff --git a/configure.ac b/configure.ac
index 95fbba3..2db31d0 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,30 +1,39 @@
dnl Process this file with autoconf to produce a configure script.
-AC_INIT(udftools, 2.0, , , [https://github.com/pali/udftools/])
+AC_PREREQ([2.64])
+AC_INIT(udftools, 2.1, , , [https://github.com/pali/udftools/])
AC_CONFIG_AUX_DIR(config)
AM_CONFIG_HEADER(include/config.h:include/config.in)
AM_INIT_AUTOMAKE
dnl Checks for programs.
-AC_PROG_CC
+AC_PROG_CC_C99
AC_DISABLE_SHARED
AM_PROG_LIBTOOL
+if test "$ac_cv_prog_cc_c99" = "no"; then
+ AC_MSG_ERROR([Your C compiler does not support ISO C99.])
+fi
+
dnl Checks for libraries.
-AC_CHECK_LIB(readline, readline, [ ], AC_MSG_ERROR([cannot find -lreadline.]))
+AC_CHECK_LIB(readline, readline, [ ])
dnl Checks for header files.
-AC_HEADER_STDC
-AC_CHECK_HEADERS(fcntl.h sys/time.h unistd.h getopt.h string.h)
+AC_CHECK_HEADERS(readline/readline.h)
dnl Checks for typedefs, structures, and compiler characteristics.
AC_C_INLINE
-AC_HEADER_TIME
-AC_STRUCT_TM
+AC_C_BIGENDIAN
AC_SYS_LARGEFILE
+PKG_PROG_PKG_CONFIG
+PKG_CHECK_MODULES(UDEV, [udev], [ac_cv_udevdir=`$PKG_CONFIG --variable=udevdir udev`])
+AC_SUBST(UDEVDIR, $ac_cv_udevdir)
+
dnl Checks for library functions.
AC_SUBST(LTLIBOBJS)
+AM_CONDITIONAL(USE_READLINE, test "$ac_cv_lib_readline_readline" = "yes" -a "$ac_cv_header_readline_readline_h" = "yes")
+
AC_CONFIG_FILES(Makefile libudffs/Makefile mkudffs/Makefile cdrwtool/Makefile pktsetup/Makefile udffsck/Makefile udfinfo/Makefile udflabel/Makefile wrudf/Makefile doc/Makefile)
AC_OUTPUT
diff --git a/debian/changelog b/debian/changelog
index 81c7acd..ddd0d37 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,12 @@
+udftools (2.1-1) unstable; urgency=medium
+
+ * New upstream release (Closes: #916006)
+ * Update Standards-Version to 4.3.0
+ * Update to debhelper 11
+ * Update copyright and signing-key.asc
+
+ -- Pali Rohár <pali.rohar@gmail.com> Fri, 28 Dec 2018 13:02:37 +0100
+
udftools (2.0-2) unstable; urgency=medium
* Fix installation in chroot (Closes: #890224)
@@ -349,4 +358,3 @@ udftools (0.9.3-1) unstable; urgency=low
* Initial Release. Finishes the ITP process, closes: #99767
-- Richard Atterer <atterer@debian.org> Mon, 4 Jun 2001 21:47:49 +0200
-
diff --git a/debian/compat b/debian/compat
index f599e28..b4de394 100644
--- a/debian/compat
+++ b/debian/compat
@@ -1 +1 @@
-10
+11
diff --git a/debian/control b/debian/control
index 6cb6a66..7935367 100644
--- a/debian/control
+++ b/debian/control
@@ -2,8 +2,8 @@ Source: udftools
Section: otherosfs
Priority: optional
Maintainer: Pali Rohár <pali.rohar@gmail.com>
-Build-Depends: debhelper (>= 10), libreadline-dev
-Standards-Version: 4.1.2
+Build-Depends: debhelper (>= 11~), pkg-config, udev, libreadline-dev
+Standards-Version: 4.3.0
Homepage: https://github.com/pali/udftools
Package: udftools
diff --git a/debian/copyright b/debian/copyright
index a1a03e0..f1b0ed3 100644
--- a/debian/copyright
+++ b/debian/copyright
@@ -1,4 +1,4 @@
-Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
+Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
Upstream-Name: udftools
Upstream-Contact: Pali Rohár <pali.rohar@gmail.com>
Source: https://github.com/pali/udftools
@@ -8,13 +8,13 @@ Copyright: 1999-2000 Jens Axboe <axboe@suse.de>
2001-2002 Ben Fennema <bfennema@falcon.csc.calpoly.edu>
2002 Paul Thompson <set@pobox.com>
2004 Peter Osterlund <petero2@telia.com>
- 2014-2017 Pali Rohár <pali.rohar@gmail.com>
+ 2014-2018 Pali Rohár <pali.rohar@gmail.com>
2016 Steve Kenton <skenton@ou.edu>
License: GPL-2+
Files: debian/*
Copyright: 2001-2008 Richard Atterer <atterer@debian.org>
- 2016-2017 Pali Rohár <pali.rohar@gmail.com>
+ 2016-2018 Pali Rohár <pali.rohar@gmail.com>
License: GPL-2+
License: GPL-2+
diff --git a/debian/upstream/signing-key.asc b/debian/upstream/signing-key.asc
index 6bd9d0f..8319090 100644
--- a/debian/upstream/signing-key.asc
+++ b/debian/upstream/signing-key.asc
@@ -1,5 +1,4 @@
-----BEGIN PGP PUBLIC KEY BLOCK-----
-Version: GnuPG v1.4.11 (GNU/Linux)
mQGiBEc+7j4RBADYPTqznflExRHwCUnn2TqwsiNvM/yRyS9ADKOsb2lFA7oVp9vJ
y+JWKsYRTH2Tk4n+42WCKbCXghgd4vDirAdOphWPs3X0iqxiXMdZS82cCZcFEHdc
@@ -10,32 +9,32 @@ OxWgCVXvM+7Re7HNlGsU9DXuvKq7eJvENNJxme4z49q0KKBpeAtyBOtrOq2libPO
8FgZA/0cC23Eustg4HwN89mSzjLIUHE0YaBij9JxSXST2C1j1N/lJ8lt0wIygvVZ
n21HjrIqsOYM4CKsdpRmQUECis6xr3nNfvhlhOcb6xN38PaATnYfIn4WSLi/qbiz
TPmO7JbtqHiy+uEoUj8WLSO42qVv/dxX6b5iB9olCYyaF0h3hLQiUGFsaSBSb2jD
-oXIgPHBhbGkucm9oYXJAZ21haWwuY29tPohmBBMRAgAmAhsjBgsJCAcDAgQVAggD
-BBYCAwECHgECF4AFAloQFMoFCRSyWgUACgkQi/DJPQPkQ1Ic4wCeMrL86tyPuaL1
-bMK//IgTqTyeigkAn3a76D7pQj8r+59Z7Z8fCsGJMJBRuQQNBEc+7owQEACtMxrp
-7tCouz5JXU0CY6Ao1vTSvmYps8IP5dYre4N6iQKDI2W9Kpmj4TA9sTmmBGEpPWMW
-b5Y5PWsiOi8Am6RQamhw6cLGiHfok4TPqGJvKcrBozoAvRrZb/w+HfTalAziivsl
-0kjfGt4+LuZdq1AfCQI4MFc1lyNa2bNMLlnw87FQ2Q/29lCpkSJnzaxoEEr+0aD9
-jn/tOCN+qg4SDzDFDwuR6CjrDrrBLJ2UuYHhB74Kqr4vuj9a3KU6Gvh+qdqVWyP9
-gmgNgQ1arXDT1UfuNVMyD2CFOmOlUvCzdJlmRMuh8I0PRTViaAA12t4Pcqftu+au
-ySTKhTztqzAcg0ymD7Nki5qutE4kWO0inde2+Ane7vZHVggwmlQ6oHdlFRal7N7/
-Z7Ws1NYwaPOaNC+3/EybAZvC6I6Mi3h3Su58w3LQouT4yxEIo//Xh2TR8EtfwXsV
-DQIR/mb+TQBv3eZJ2jzfSzhSIlNzolvaqdp0RIeaXZD/nx4g72pUvIPziuCZWwRV
-M3OKxtP6uS2kBzXx6PMXYwPhVnlxiNgwZt7b5fROGdKpgyTrUqbwE0ox4kJPVWgE
-LGbbNyCl/z9cdEVUgfMFX06i9Po9mIZRA15tJM5ti4R8mY/xWAYRVcnYRoakEmJm
-HBxM8Z0C0SmrURGbLhw/41pveWS5ytCAtBjKswADBQ//cFIM1EJsN3jncI4T+3t5
-y+YEdHaLvXsy0d7/maEtdSyxK4P5o6dzL/Dum7azk2Eq3KzHTQZaz7jUby6aqlEJ
-WLwFqZkRUPY96inhKWjAvn8HwRecFfCknAYGVSWy++e5QavNPwsKHHOKF158XIEj
-+sbsSXMOGAAe9MfqST1yUBkvdwKp1BC8f5i9uzp6sqb7/HojQhrU/+5ws1CBCH6u
-3QVyjuxiiKOYzphFQJYyEQXZwq7t/kywsdyyysHkd33b4ANQAcmJHdgBXFUh4RET
-li0fTmVfK6RII+ogM3OBqFw2UzKS2twnnJtvT//hiV4wA4aYY0jmAr79BQkSKDk2
-P7JlPSpy8otKULuuJggTWH99xvw5PFqbgatyUEsbg/qj1VuBXsUDbs04CXnI9PjY
-N+BtGaikY9d6/M0GLCwNwT0/GQ4pqevbwmHdJn888ENx40Ix1xpA+WRn9ShHcc3G
-1nNm0cXHz2Ti8pxN4yDGPnifUPpwTtcuKpCAIeUDE6ClMxDXggoUNIFJ/mtUwFTV
-+FnVPYxBM/IqU89tBfWP/ZeCvpcetK1ftiVMZtS1DmioL2qWVnIqVBnv2TZcAyoV
-/LMjnYXwlicsN7XBc/S5nDfLZobmN6oAF8FBF7H/2gFPOB2JeH0PqCr6JB6tF4LA
-hjB+ipPDTRRbNhozXZw3U4mITwQYEQIADwIbDAUCWhAU3QUJFLJZzAAKCRCL8Mk9
-A+RDUl0gAJ444h2K7Maa3EQf6sAQ/tYbbfFgbgCfUfDqmKRWYysMULP/R6xzU01p
-xUI=
-=mWCA
+oXIgPHBhbGkucm9oYXJAZ21haWwuY29tPoh9BBMRCAA9AhsjBgsJCAcDAgQVAggD
+BBYCAwECHgECF4AWIQS4VrIQdKium2krgIWL8Mk9A+RDUgUCW/FI+wUJFpOOPQAK
+CRCL8Mk9A+RDUkCtAKCsBZc7hCmYk1YOs6lCRgUCqO7Q5ACffhV3kCd6uHR3yrtd
+Yb9hLYTrcZG5BA0ERz7ujBAQAK0zGunu0Ki7PkldTQJjoCjW9NK+Zimzwg/l1it7
+g3qJAoMjZb0qmaPhMD2xOaYEYSk9YxZvljk9ayI6LwCbpFBqaHDpwsaId+iThM+o
+Ym8pysGjOgC9Gtlv/D4d9NqUDOKK+yXSSN8a3j4u5l2rUB8JAjgwVzWXI1rZs0wu
+WfDzsVDZD/b2UKmRImfNrGgQSv7RoP2Of+04I36qDhIPMMUPC5HoKOsOusEsnZS5
+geEHvgqqvi+6P1rcpToa+H6p2pVbI/2CaA2BDVqtcNPVR+41UzIPYIU6Y6VS8LN0
+mWZEy6HwjQ9FNWJoADXa3g9yp+275q7JJMqFPO2rMByDTKYPs2SLmq60TiRY7SKd
+17b4Cd7u9kdWCDCaVDqgd2UVFqXs3v9ntazU1jBo85o0L7f8TJsBm8LojoyLeHdK
+7nzDctCi5PjLEQij/9eHZNHwS1/BexUNAhH+Zv5NAG/d5knaPN9LOFIiU3OiW9qp
+2nREh5pdkP+fHiDvalS8g/OK4JlbBFUzc4rG0/q5LaQHNfHo8xdjA+FWeXGI2DBm
+3tvl9E4Z0qmDJOtSpvATSjHiQk9VaAQsZts3IKX/P1x0RVSB8wVfTqL0+j2YhlED
+Xm0kzm2LhHyZj/FYBhFVydhGhqQSYmYcHEzxnQLRKatREZsuHD/jWm95ZLnK0IC0
+GMqzAAMFD/9wUgzUQmw3eOdwjhP7e3nL5gR0dou9ezLR3v+ZoS11LLErg/mjp3Mv
+8O6btrOTYSrcrMdNBlrPuNRvLpqqUQlYvAWpmRFQ9j3qKeEpaMC+fwfBF5wV8KSc
+BgZVJbL757lBq80/Cwocc4oXXnxcgSP6xuxJcw4YAB70x+pJPXJQGS93AqnUELx/
+mL27Onqypvv8eiNCGtT/7nCzUIEIfq7dBXKO7GKIo5jOmEVAljIRBdnCru3+TLCx
+3LLKweR3fdvgA1AByYkd2AFcVSHhEROWLR9OZV8rpEgj6iAzc4GoXDZTMpLa3Cec
+m29P/+GJXjADhphjSOYCvv0FCRIoOTY/smU9KnLyi0pQu64mCBNYf33G/Dk8WpuB
+q3JQSxuD+qPVW4FexQNuzTgJecj0+Ng34G0ZqKRj13r8zQYsLA3BPT8ZDimp69vC
+Yd0mfzzwQ3HjQjHXGkD5ZGf1KEdxzcbWc2bRxcfPZOLynE3jIMY+eJ9Q+nBO1y4q
+kIAh5QMToKUzENeCChQ0gUn+a1TAVNX4WdU9jEEz8ipTz20F9Y/9l4K+lx60rV+2
+JUxm1LUOaKgvapZWcipUGe/ZNlwDKhX8syOdhfCWJyw3tcFz9LmcN8tmhuY3qgAX
+wUEXsf/aAU84HYl4fQ+oKvokHq0XgsCGMH6Kk8NNFFs2GjNdnDdTiYhmBBgRCAAm
+AhsMFiEEuFayEHSorptpK4CFi/DJPQPkQ1IFAlvxSRQFCRaTjggACgkQi/DJPQPk
+Q1I4/gCgzWponpAz5fmQJgC6kYK3FC5WJS0AmwaYGNlNbxo5yMKM1coVpPBgWNoV
+=6twr
-----END PGP PUBLIC KEY BLOCK-----
diff --git a/doc/Makefile.in b/doc/Makefile.in
index f00ffbb..94fcec8 100644
--- a/doc/Makefile.in
+++ b/doc/Makefile.in
@@ -212,11 +212,17 @@ 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@
+UDEVDIR = @UDEVDIR@
+UDEV_CFLAGS = @UDEV_CFLAGS@
+UDEV_LIBS = @UDEV_LIBS@
VERSION = @VERSION@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
diff --git a/doc/cdrwtool.1 b/doc/cdrwtool.1
index b93a8ee..1b951d1 100644
--- a/doc/cdrwtool.1
+++ b/doc/cdrwtool.1
@@ -110,8 +110,8 @@ Set write parameters determined by
options for the disc.
.IP "\fB\-v \fIversion\fP"
-Specify the udf revision to use. Valid revisions are 0x0201, 0x0200, 0x0150,
-and 0x0102. If omitted,
+Specify the udf revision to use. Valid revisions are 0x0201, 0x0200 and 0x0150.
+If omitted,
.B mkudffs
udf-version is 0x0150.
@@ -138,7 +138,7 @@ Set write offset.
.SH AUTHORS
.nf
Jens Axboe <axboe@suse.de>
-Ben Fennema <bfennema@falcon.csc.calpoly.edu>
+Ben Fennema
Some additions by Richard Atterer <atterer@debian.org>
.fi
diff --git a/doc/mkudffs.8 b/doc/mkudffs.8
index 0dd88bc..a97ddad 100644
--- a/doc/mkudffs.8
+++ b/doc/mkudffs.8
@@ -1,6 +1,6 @@
'\" t -*- coding: UTF-8 -*-
.\" Copyright 2002 Paul Thompson <set@pobox.com>
-.\" Copyright 2014-2017 Pali Rohár <pali.rohar@gmail.com>
+.\" Copyright 2014-2018 Pali Rohár <pali.rohar@gmail.com>
.\"
.\" This is free documentation; you can redistribute it and/or
.\" modify it under the terms of the GNU General Public License as
@@ -20,21 +20,21 @@
.\" 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.,
.\" 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-
+.\"
.TH MKUDFFS 8 "udftools" "System Management Commands"
.SH NAME
-mkudffs \- create an UDF filesystem
+mkudffs \(em create a UDF filesystem
.SH SYNOPSIS
.BI "mkudffs [ options ] " device " [ " blocks\-count " ] "
.SH DESCRIPTION
-\fBmkudffs\fP is used to create a UDF filesystem on a device (usually a disk).
-\fIdevice\fP is the special file corresponding to the device (e.g.
+\fBmkudffs\fP is used to create a UDF filesystem on a device (usually a disk). \
+\fIdevice\fP is the special file corresponding to the device (e.g. \
\fI/dev/hdX\fP) or file image. \fIblocks\-count\fP is the number of blocks on
-the device. If omitted, \fBmkudffs\fP automagically figures the filesystem size.
-The order of options matters. Encoding option must be first and options to
+the device. If omitted, \fBmkudffs\fP automagically figures the filesystem
+size. The order of options matters. Encoding option must be first and options to
override default settings implied by the media type or UDF revision should be
after the option they are overriding.
@@ -46,63 +46,63 @@ Display the usage and list of options.
.TP
.BI \-l,\-\-label= " label "
Specify the UDF label. UDF label is synonym for specifying both \fB\-\-lvid\fP
-and \fB\-\-vid\fP options. If omitted, \fBmkudffs\fP label is \fILinuxUDF\fP.
+and \fB\-\-vid\fP options. If omitted, \fBmkudffs\fP label is \fILinuxUDF\fP. \
(Option available since mkudffs 1.1)
.TP
.BI \-u,\-\-uuid= " uuid "
-Specify the UDF uuid. Must be exactly 16 hexadecimal lowercase digits and is
+Specify the UDF uuid. It must be exactly 16 hexadecimal lowercase digits and is
used for first 16 characters of \fB\-\-fullvsid\fP option. If omitted,
-\fBmkudffs\fP uuid is generated from local time and random number.
-(Option available since mkudffs 1.1)
+\fBmkudffs\fP uuid is generated from local time and a random number. (Option
+available since mkudffs 1.1)
.TP
.BI \-b,\-\-blocksize= " block\-size "
Specify the size of blocks in bytes. Valid block size for a UDF filesystem is
-power of two in range from 512 to 32768 and must match a device logical (sector)
-size. If omitted, \fBmkudffs\fP block\-size is set to device logical block
-(sector) size. If logical block (sector) size is unknown (e.g. when creating
-disk image) then for \fB\-\-media\-type\fP=\fIhd\fP is used block\-size 512 and
-for other media types 2048.
+power of two in range from \fI512\fP to \fI32768\fP and must match a device
+logical (sector) size. If omitted, \fBmkudffs\fP block size is set to device
+logical block (sector) size. If logical block (sector) size is unknown (e.g. \
+when creating disk image) then for \fB\-\-media\-type\fP=\fIhd\fP is used block
+size \fI512\fP and for other media types \fI2048\fP.
.TP
.BI \-m,\-\-media\-type= " media\-type "
-Specify the media type. Must be specified before \fB\-\-udfrev\fP.
-Valid media types are:
+Specify the media type. Must be specified before \fB\-\-udfrev\fP. Valid media
+types are:
.RS 1.2i
.TP 1.6i
-hd (default)
+.IR hd " (default)"
HD (Hard Disk)
.TP
-worm
+.I worm
WORM (Write Once Read Many)
.TP
-mo
+.I mo
MO (Magneto Optical)
.TP
-cd
-CD\-ROM (CD Read\-Only Memory)
+.I cd
+CD-ROM (CD Read-Only Memory)
.TP
-cdr
-CD\-R (CD Recordable)
+.I cdr
+CD-R (CD Recordable)
.TP
-cdrw
-CD\-RW (CD Read\-Write)
+.I cdrw
+CD-RW (CD Read-Write)
.TP
-dvd
-DVD\-ROM (DVD Read\-Only Memory)
+.I dvd
+DVD-ROM (DVD Read-Only Memory)
.TP
-dvdr
-DVD\-R (DVD Recordable)
+.I dvdr
+DVD-R (DVD Recordable)
.TP
-dvdrw
-DVD\-RW (DVD Read\-Write)
+.I dvdrw
+DVD-RW (DVD Read-Write)
.TP
-dvdram
-DVD\-RAM (DVD Random Access Memory)
+.I dvdram
+DVD-RAM (DVD Random Access Memory)
.TP
-bdr
-BD\-R (Blu\-ray Disc Recordable)
+.I bdr
+BD-R (Blu-ray Disc Recordable)
.RE
.RS
@@ -112,47 +112,47 @@ available since mkudffs 2.0)
.TP
.BI \-r,\-\-udfrev= " udf\-revision "
-Specify the UDF revision to use, either in hexadecimal (e.g. 0x0201) or decimal
-(e.g. 2.01) format. Valid revisions arei 1.02, 1.50, 2.00, 2.01, 2.50 and 2.60.
-If omitted, \fBmkudffs\fP udf\-revision is \fI2.01\fP, except for Blu-ray Discs
-which is \fI2.50\fP. UDF revisions higher then 2.01 are experimental. Option
-must be specified after \fB\-\-media\-type\fP. (Values in decimal format and
-revisions higher then 2.01 are supported since mkudffs 2.0)
+Specify the UDF revision to use, either in hexadecimal BCD (e.g. \fI0x0201\fP)
+or decimal (e.g. \fI2.01\fP) format. Valid revisions are \fI1.01\fP, \fI1.02\fP,
+\fI1.50\fP, \fI2.00\fP, \fI2.01\fP, \fI2.50\fP and \fI2.60\fP. If omitted,
+\fBmkudffs\fP UDF revision is \fI2.01\fP, except for Blu-ray Discs which is
+\fI2.50\fP. UDF revisions higher then \fI2.01\fP are experimental. Option must
+be specified after \fB\-\-media\-type\fP. (Values in decimal format and UDF
+revisions higher then \fI2.01\fP are supported since mkudffs 2.0, UDF revision
+1.01 is supported since mkudffs 2.1)
.TP
-.B \-n,\-\-no-write
+.B \-n,\-\-no\-write
Not really, do not write to \fIdevice\fP. Just simulate and display what would
-happen with \fIdevice\fP. Useful for determining calculated location of
-different UDF blocks.
-(Option available since mkudffs 2.0)
+happen with \fIdevice\fP. Useful for determining the calculated location of
+different UDF blocks. (Option available since mkudffs 2.0)
.TP
.B \-\-new\-file
Create a new image file specified by \fIdevice\fP with \fIblocks\-count\fP and
fail if file already exists. If omitted, \fBmkudffs\fP creates a new image file
-only in case it does not exist yet.
-(Option available since mkudffs 2.0)
+only in case it does not exist yet. (Option available since mkudffs 2.0)
.TP
.BI \-\-lvid= " logical\-volume\-identifier "
-Specify the \fILogical Volume Identifier\fP. If omitted, \fBmkudffs\fP
-logical\-volume\-identifier is \fILinuxUDF\fP. Most UDF implementations uses
-this identifier as a disk label.
+Specify the \fILogical Volume Identifier\fP. If omitted, \fBmkudffs\fP Logical
+Volume Identifier is \fILinuxUDF\fP. Most UDF implementations uses this
+identifier as a disk label.
.TP
.BI \-\-vid= " volume\-identifier "
-Specify the \fIVolume Identifier\fP. If omitted, \fBmkudffs\fP
-volume\-identifier is \fILinuxUDF\fP.
+Specify the \fIVolume Identifier\fP. If omitted, \fBmkudffs\fP Volume Identifier
+is \fILinuxUDF\fP.
.TP
.BI \-\-vsid= " volume\-set\-identifier "
-Specify the 17.-127. character of \fIVolume Set Identifier\fP. If omitted,
-\fBmkudffs\fP volume\-set\-identifier is \fILinuxUDF\fP.
+Specify the 17.\(en127. character of \fIVolume Set Identifier\fP. If omitted,
+\fBmkudffs\fP Volume Set Identifier is \fILinuxUDF\fP.
.TP
.BI \-\-fsid= " file\-set\-identifier "
-Specify the \fIFile Set Identifier\fP. If omitted, \fBmkudffs\fP
-file\-set\-identifier is \fILinuxUDF\fP.
+Specify the \fIFile Set Identifier\fP. If omitted, \fBmkudffs\fP File Set
+Identifier is \fILinuxUDF\fP.
.TP
.BI \-\-fullvsid= " full\-volume\-set\-identifier "
@@ -162,14 +162,14 @@ and \fB\-\-vsid\fP options. (Option available since mkudffs 1.1)
.TP
.BI \-\-uid= " uid "
Specify the uid of the root (/) directory. If omitted, \fBmkudffs\fP uid is
-\fI0\fP. Special value \fI-1\fP means invalid or not specified uid.
-(Option available since mkudffs 1.1)
+\fI0\fP. Special value \fI\-1\fP means invalid or not specified uid. (Option
+available since mkudffs 1.1)
.TP
.BI \-\-gid= " gid "
Specify the gid of the root (/) directory. If omitted, \fBmkudffs\fP gid is
-\fI0\fP. Special value \fI-1\fP means invalid or not specified gid.
-(Option available since mkudffs 1.1)
+\fI0\fP. Special value \fI\-1\fP means invalid or not specified gid. (Option
+available since mkudffs 1.1)
.TP
.BI \-\-mode= " mode "
@@ -178,24 +178,24 @@ Specify permissions in octal mode bits of the root (/) directory. If omitted,
.TP
.BI \-\-bootarea= " fill "
-Specify how to fill UDF boot area which is first 32kB of disk and is not used by
-UDF itself. Option \fImbr\fP make sense only when running mkudffs on whole disk,
-not on just one partition. Valid options are:
+Specify how to fill UDF boot area which is the first 32kB of the disk and is not
+used by UDF itself. Option \fImbr\fP make sense only when running \fBmkudffs\fP
+on whole disk, not on just one partition. Valid options are:
.RS 1.2i
-.TP 1.6i
-preserve
+.TP 1.4i
+.I preserve
preserve existing UDF boot area, do not touch it (default for media type
-different from hd)
+different from \fIhd\fP)
.TP
-erase
-erase existing UDF boot area, fill it by zeros (default for hd media type on
-partitions and on removable disks)
+.I erase
+erase existing UDF boot area, fill it by zeros (default for \fIhd\fP media type
+on partitions and on removable disks)
.TP
-mbr
+.I mbr
put MBR table with one partition which starts at sector 0 (includes MBR itself)
and spans whole disk device, needed only for non-removable hard disks used on
-Microsoft Windows systems (default for hd media type on non-removable hard disk
-without partitions), see section \fBWHOLE DISK VS PARTITION\fP
+Microsoft Windows systems (default for \fIhd\fP media type on non-removable hard
+disk without partitions), see section \fBWHOLE DISK VS PARTITION\fP
.RE
.RS
@@ -204,35 +204,42 @@ without partitions), see section \fBWHOLE DISK VS PARTITION\fP
.TP
.BI \-\-strategy= " strategy "
-Specify the allocation strategy to use. Valid strategies are 4 and 4096. If
-omitted, \fBmkudffs\fP strategy is based on the \fB\-\-media\-type\fP.
+Specify the allocation strategy to use. Valid strategies are \fI4\fP and
+\fI4096\fP. If omitted, \fBmkudffs\fP strategy is based on the
+\fB\-\-media\-type\fP.
.TP
.BI \-\-spartable,\ \-\-spartable= " spartable\-number "
Enable usage Sparing Table. Optionally specify also the number of sparing
-tables. Valid numbers are 1-4. When spartable\-number is omitted then two tables
-are written to disc. If option is omitted then usage of Sparing Table depends on
-media type. (Option prior to mkudffs 2.0 was available only for cdrw media type)
+tables. Valid numbers are \fI1\(en4\fP. When the spartable number is omitted
+then two tables are written to the disc. If the option is omitted then usage of
+Sparing Table depends on the media type. (Option prior to mkudffs 2.0 was
+available only for \fIcdrw\fP media type)
.TP
.BI \-\-sparspace= " num\-of\-entires "
-Specify the number of entries in Sparing Table. If omitted, default number of
-entries is 1024, but depends on media type. (Option available since mkudffs 2.0)
+Specify the number of entries in Sparing Table. If omitted, the default number
+of entries is \fI1024\fP, but depends on the media type. (Option available since
+mkudffs 2.0)
.TP
.BI \-\-packetlen= " length "
-Packet length in number of blocks for Sparing Table. It specify also size of the
-Sparing Space. If omitted, default value for DVD discs 16 blocks, otherwise 32.
+Packet length in a number of blocks used for alignment. All continuous UDF
+structures would be aligned to packets. It specifies also the size of the
+Sparing Space and packet length in Sparing Table. It should match the device
+ECC/packet length. If omitted, default value for DVD discs is \fI16\fP blocks,
+for CD/BD discs it is \fI32\fP blocks and otherwise \fI1\fP block. (Option prior
+to mkudffs 2.1 was available only for \fIcdrw\fP and \fIdvdrw\fP media types)
.TP
.B \-\-vat
Enable usage of Virtual Allocation Table (VAT). If omitted, usage depends on
-media type. (Option available since mkudffs 2.0)
+the media type. (Option available since mkudffs 2.0)
.TP
.B \-\-closed
Close disc with Virtual Allocation Table. AVDP is written also to the end of
-disc. By default disc with Virtual Allocation Table is not closed.
+the disc. By default, the disc with Virtual Allocation Table is not closed.
.TP
.BI \-\-space= " space "
@@ -243,16 +250,16 @@ which blocks needs to be specially prepared/erased before allocation. In Space
stored bitmap of unallocated blocks. Not used for VAT.
.RS 1.2i
.TP 1.6i
-freedbitmap
+.I freedbitmap
Freed Bitmap
.TP
-freedtable
+.I freedtable
Freed Table
.TP
-unallocbitmap
+.I unallocbitmap
Unallocated Bitmap (default)
.TP
-unalloctable
+.I unalloctable
Unallocated Table
.RE
@@ -261,26 +268,26 @@ Unallocated Table
Specify the Allocation Descriptors of the root (/) directory.
.RS 1.2i
.TP 1.6i
-inicb
+.I inicb
Allocation Descriptors in ICB (default)
.TP
-short
+.I short
Short Allocation Descriptors
.TP
-long
+.I long
Long Allocation Descriptors
.RE
.TP
.B \-\-noefe
-Don't Use Extended File Entries for the root (/) directory. Affects only
-UDF 2.00 or higher. Must be specified after \fB\-\-udfrev\fP.
+Don't Use Extended File Entries for the root (/) directory. Affects only UDF
+2.00 or higher. Must be specified after \fB\-\-udfrev\fP.
.TP
.B \-\-locale
-Treat identifier string options as strings encoded according to current locale
-settings (default). Must be specified as first argument.
-(Option available since mkudffs 2.0)
+Treat identifier string options as strings encoded according to the current
+locale settings (default). Must be specified as the first argument. (Option
+available since mkudffs 2.0)
.TP
.B \-\-u8
@@ -294,12 +301,12 @@ Treat identifier string options as strings encoded in 16-bit OSTA Compressed
Unicode format, equivalent to UCS-2BE. Note that it is not possible to include
zero byte in command line options, therefore any character which has at least
one zero byte cannot be supplied (this applies to all Latin1 characters). Must
-be specified as first argument.
+be specified as the first argument.
.TP
.B \-\-utf8
Treat identifier string options as strings encoded in UTF-8. Must be specified
-as first argument.
+as the first argument.
.SH COMPATIBILITY
@@ -316,8 +323,8 @@ Operating system Maximum UDF revision for
_
Name Version read write
=
-Linux 2.3.17 - 2.4.5 2.00 2.00
-\^ 2.4.6 - 2.6.25 2.01 2.01
+Linux 2.3.17 \(en 2.4.5 2.00 2.00
+\^ 2.4.6 \(en 2.6.25 2.01 2.01
\^ 2.6.26 (and new) 2.50 2.01
_
Windows 98/Me 1.02 none
@@ -325,10 +332,10 @@ Windows 98/Me 1.02 none
\^ XP 2.01 none
\^ Vista (and new) 2.60 2.50
_
-Mac OS 8.1 - 8.5 1.02 none
-\^ 8.6 - 9.2 1.50 1.50
+Mac OS 8.1 \(en 8.5 1.02 none
+\^ 8.6 \(en 9.2 1.50 1.50
_
-Mac OS X 10.0 - 10.3 1.50 1.50
+Mac OS X 10.0 \(en 10.3 1.50 1.50
\^ 10.4 2.01 2.01
\^ 10.5 (and new) 2.60 2.50
_
@@ -337,8 +344,8 @@ _
NetBSD 4.0 2.60 none
\^ 5.0 (and new) 2.60 2.60
_
-OpenBSD 3.8 - 3.9 1.02 none
-\^ 4.0 - 4.6 1.50 \^
+OpenBSD 3.8 \(en 3.9 1.02 none
+\^ 4.0 \(en 4.6 1.50 \^
\^ 4.7 (and new) 2.60 \^
_
Solaris 7 (and new) 1.50 1.50
@@ -346,56 +353,55 @@ _
AIX 5.2 (and new) 2.01 2.01
.TE
-
Note that Windows 98 and Windows Me can read UDF filesystem only from CD and DVD
optical discs, not from hard disks.
.SS "BLOCK SIZE"
-In most cases operating systems are unable to mount UDF filesystem if UDF block
-size differs from logical sector size of device. Typically hard disks have
+In most cases, operating systems are unable to mount UDF filesystem if UDF block
+size differs from logical sector size of the device. Typically hard disks have
sector size 512 bytes and optical media 2048 bytes. Therefore UDF block size
-must match logical sector size of device.
+must match the logical sector size of the device.
Linux kernel prior to version 2.6.30 used hardcoded UDF block size of 2048 bytes
independently of logical sector size, therefore it was not able to automatically
mount UDF filesystem if block size differed from 2048. Since 2.6.30 and prior to
-4.11 Linux kernel used logical sector size of device as UDF block size, plus it
-tried fallback to 2048. Since 4.11 it uses logical sector size and fallbacks to
-any valid block size between logical sector size and 4096. Therefore since
-version 2.6.30 Linux kernel can automatically mount UDF filesystems correctly if
-UDF block size matches device logical sector size and since version 4.11 can
-automatically also mount devices which sector size does not match UDF block
-size. In any case and also for Linux kernel prior to version 2.6.30, different
-UDF block size (which is not autodetected) can be manually specified via
-\fBbs\fP=\fIblocksize\fP mount parameter.
+4.11 Linux kernel used a logical sector size of the device as UDF block size,
+plus it tried fallback to 2048. Since 4.11 it uses logical sector size and
+fallbacks to any valid block size between logical sector size and 4096. \
+Therefore since version 2.6.30 Linux kernel can automatically mount UDF
+filesystems correctly if UDF block size matches device logical sector size and
+since version 4.11 can automatically also mount devices which sector size does
+not match UDF block size. In any case and also for Linux kernel prior to version
+2.6.30, different UDF block size (which is not autodetected) can be manually
+specified via \fBbs\fP=\fIblocksize\fP mount parameter.
.SS "WHOLE DISK VS PARTITION"
UDF filesystem is supposed to be formatted on the whole media and not to the
partitioned hard disk. Mac OS X systems enforce this rule and reject to
automatically mount UDF filesystem unless it is formatted on the whole
unpartitioned hard disk. Possible partition table (e.g. MBR or GPT) on disk with
-valid UDF filesystem is ignored. On the other hand Microsoft Windows systems are
-unable to detect non-removable hard disks without MBR or GPT partition table.
-Removable disks do not have this restriction. Consequence is that non-removable
-hard disks formatted to UDF by Windows Vista+ are not recognized by Mac OS X
-systems and vice-versa. Note that manual mount of UDF partition on partitioned
-hard disk on Mac OS X system is possible and working (e.g. by running commands
-mkdir /Volumes/DriveName && mount_udf /dev/disk1s1 /Volumes/DriveName). But
-there is no known way to mount unpartitioned non-removable disk on Windows
-system.
+valid UDF filesystem is ignored. On the other hand, Microsoft Windows systems
+are unable to detect non-removable hard disks without MBR or GPT partition
+table. Removable disks do not have this restriction. A consequence is that
+non-removable hard disks formatted to UDF by Windows Vista+ are not recognized
+by Mac OS X systems and vice-versa. Note that manual mount of UDF partition on
+partitioned hard disk on Mac OS X system is possible and working (e.g. by
+running commands: \f(CW\%mkdir \%/Volumes/DriveName \%&& \%mount_udf
+\%/dev/disk1s1 \%/Volumes/DriveName\fP). But there is no known way to mount an
+unpartitioned non-removable disk on Windows system.
Thanks to reserved and unused UDF boot area (first 32kB of UDF filesystem) it is
possible to deal with this problem, by putting MBR on such non-removable hard
disk just for compatibility reasons with Windows. Such MBR table would contain
-one partition which starts at sector 0 (includes MBR itself) and span whole disk
-device. So the whole disk device and also first partition on disk points to same
-sectors. Therefore UDF filesystem can be mounted either from whole disk device
-(needed for Mac OS X systems) or from first partition (needed for Microsoft
-Windows systems).
+one partition which starts at sector 0 (includes MBR itself) and spans whole
+disk device. So the whole disk device and also the first partition on disk
+points to same sectors. Therefore UDF filesystem can be mounted either from
+whole disk device (needed for Mac OS X systems) or from first partition (needed
+for Microsoft Windows systems).
-Linux kernel ignores MBR table if contains partition which starts at sector 0.
-Normally Linux kernel can detect and mount UDF filesystem either on partition or
-on whole disk device. It does not have any restrictions.
+Linux kernel ignores MBR table if contains partition which starts at sector 0. \
+Normally Linux kernel can detect and mount UDF filesystem either on a partition
+or on whole disk device. It does not have any restrictions.
\fBmkudffs\fP option \fB\-\-bootarea\fP=\fImbr\fP put such MBR table for
compatibility with Microsoft Windows systems into disk when formatting.
@@ -408,9 +414,9 @@ Volume Identifier\fP and \fIVolume Identifier\fP.
Linux libblkid prior to version 2.30 incorrectly processed non-ASCII identifier
strings encoded in 8-bit OSTA Compressed Unicode format. Therefore \fBmkudffs\fP
-since version 2.0 for compatibility reasons tries to encode non-ASCII identifier
-strings in 16-bit OSTA Compressed Unicode format and then fallbacks to 8-bit
-format.
+since version 2.0 for compatibility reasons tries to encode a non-ASCII
+identifier strings in 16-bit OSTA Compressed Unicode format and then fallbacks
+to 8-bit format.
For more information about UDF Label and UUID see \fBudflabel\fP(8) section
\fBUDF LABEL AND UUID\fP.
@@ -420,8 +426,8 @@ For more information about UDF Label and UUID see \fBudflabel\fP(8) section
.SH LIMITATIONS
\fBmkudffs\fP cannot create UDF 2.50 Metadata partition, therefore it does not
-support UDF revisions higher then 2.01 for non Write Once media yet. So there
-is no support for Blu\-ray discs which needs UDF 2.50 (except for Blu\-ray Disc
+support UDF revisions higher than 2.01 for non Write Once media yet. So there is
+no support for Blu-ray discs which needs UDF 2.50 (except for Blu-ray Disc
Recordable which does not require Metadata partition).
.SH BUGS
@@ -429,11 +435,11 @@ Recordable which does not require Metadata partition).
from identifier strings in \fB\-\-utf8\fP mode, \fB\-\-vsid\fP option was
completely broken and \fB\-\-blocksize\fP must have been manually specified for
hard disks as default value was hardcoded for optical disks. \fBmkudffs\fP prior
-to version 2.0 generated broken and unreadable cdr disc images.
+to version 2.0 generated broken and unreadable \fIcdr\fP disc images.
.SH AUTHOR
.nf
-Ben Fennema <bfennema@falcon.csc.calpoly.edu>
+Ben Fennema
Pali Rohár <pali.rohar@gmail.com>
.fi
diff --git a/doc/udfinfo.1 b/doc/udfinfo.1
index 83d7920..83a6967 100644
--- a/doc/udfinfo.1
+++ b/doc/udfinfo.1
@@ -1,5 +1,5 @@
'\" t -*- coding: UTF-8 -*-
-.\" Copyright (C) 2017 Pali Rohár <pali.rohar@gmail.com>
+.\" Copyright (C) 2017-2018 Pali Rohár <pali.rohar@gmail.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
@@ -14,11 +14,11 @@
.\" 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.,
.\" 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-
+.\"
.TH UDFINFO 1 "udftools" "Commands"
.SH NAME
-udfinfo \- show information about UDF filesystem
+udfinfo \(em show information about UDF filesystem
.SH SYNOPSIS
.BI "udfinfo [ options ] " device
@@ -36,9 +36,9 @@ Display the usage and the list of options.
.TP
.BI \-b,\-\-blocksize= " block\-size "
Specify the size of blocks in bytes. Valid block size for a UDF filesystem is
-power of two in range from 512 to 32768 and must match a device logical (sector)
-size. If omitted, \fBudfinfo\fP tries to autodetect block size. It tries logical
-(sector) size and then all valid block sizes.
+a power of two in the range from \fI512\fP to \fI32768\fP and must match a
+device logical (sector) size. If omitted, \fBudfinfo\fP tries to autodetect
+block size. First it tries logical (sector) size and then all valid block sizes.
.TP
.BI \-\-vatblock= " vat\-block "
@@ -48,14 +48,13 @@ last written/recorded disk block.
If omitted, \fBudfinfo\fP for optical disc tries to detect the last recorded
block with fallback to the last block of block device or disk file image. In
-most cases this fallback does not have to work and for disk file images with
-Virtual Allocation Table is necessary to specify correct location.
+most cases, this fallback does not have to work and for disk file images with
+Virtual Allocation Table is necessary to specify the correct location.
Virtual Allocation Table contains locations of UDF disk blocks needed to read
data storage, determinate used and free space blocks, read File Set Identifier
-and calculate Windows specific Volume Serial Number. Also on disks with UDF
-revisions higher then 1.50 it contains Logical Volume Identifier and overwrite
-one stored in Logical Volume Descriptor.
+and calculate Windows-specific Volume Serial Number. Also, it contains Logical
+Volume Identifier and overwrite previously stored in Logical Volume Descriptor.
.TP
.B \-\-locale
@@ -64,13 +63,13 @@ Encode UDF string identifiers on output according to current locale settings
.TP
.B \-\-u8
-Encode UDF string identifiers on output to 8 bit OSTA Compressed Unicode format,
+Encode UDF string identifiers on output to 8-bit OSTA Compressed Unicode format,
equivalent to Latin1 (ISO-8859-1). This will work only for strings which Unicode
code points are below U+100.
.TP
.B \-\-u16
-Encode UDF string identifiers on output to 16 bit OSTA Compressed Unicode
+Encode UDF string identifiers on output to 16-bit OSTA Compressed Unicode
format, equivalent to UCS-2BE.
.TP
@@ -78,8 +77,8 @@ format, equivalent to UCS-2BE.
Encode UDF string identifiers on output to UTF-8.
.SH "EXIT STATUS"
-\fBudfinfo\fP returns 0 if successful, non-zero if there are problems like block
-device does not contain UDF filesystem.
+\fBudfinfo\fP returns 0 if successful, non-zero if there are problems like a
+block device does not contain UDF filesystem.
.SH "OUTPUT FORMAT"
First part of the \fBudfinfo\fP standard output contains information in
@@ -88,76 +87,76 @@ following table:
.RS
.TP 1.6i
-filename
+.I filename
File name of the selected block device or disk file image
.TP
-label
-label is an alias for \fIlvid\fP, see \fBudflabel\fP(8) section \fBUDF LABEL AND
-UUID\fP
+.I label
+label is an alias for \fIlvid\fP, see \fBudflabel\fP(8) section
+\fBUDF LABEL AND UUID\fP
.TP
-uuid
+.I uuid
UUID are first 16 hexadecimal lowercase digits of \fIfullvsid\fP, but see
\fBudflabel\fP(8) section \fBUDF LABEL AND UUID\fP
.TP
-lvid
+.I lvid
UDF Logical Volume Identifier stored in UDF Logical Volume Descriptor
.TP
-vid
+.I vid
UDF Volume Identifier stored in UDF Primary Volume Descriptor
.TP
-vsid
-\fIfullvsid\fP after \fIuuid\fP part, typically 17.-127. character
+.I vsid
+\fIfullvsid\fP after \fIuuid\fP part, typically 17.\(en127. character
.TP
-fsid
+.I fsid
UDF File Set Identifier stored in UDF File Set Descriptor
.TP
-fullvsid
+.I fullvsid
UDF Volume Set Identifier stored in UDF Primary Volume Descriptor
.TP
-winserialnum
-Windows specific Volume Serial Number
+.I winserialnum
+Windows-specific Volume Serial Number
.TP
-blocksize
+.I blocksize
UDF block size
.TP
-blocks
+.I blocks
Number of all blocks on the selected block device or disk file image
.TP
-usedblocks
+.I usedblocks
Number of used space blocks on UDF disk for data storage
.TP
-freeblocks
+.I freeblocks
Number of free space blocks on UDF disk for data storage
.TP
-behindblocks
+.I behindblocks
Number of blocks which are behind the last block used by UDF disk
.TP
-numfiles
+.I numfiles
Number of stored files on UDF disk
.TP
-numdirs
+.I numdirs
Number of stored directories on UDF disk
.TP
-udfrev
+.I udfrev
UDF revision needed for reading UDF disk
.TP
-udfwriterev
+.I udfwriterev
UDF revision needed for writing or modifying UDF disk
.TP
-vatblock
+.I vatblock
UDF block location of the Virtual Allocation Table (visible only when available)
.TP
-integrity
+.I integrity
UDF integrity of Logical Volume, one of: \fIopened\fP, \fIclosed\fP,
\fIunknown\fP
.TP
-accesstype
+.I accesstype
UDF Access Type, one of: \fIoverwritable\fP, \fIrewritable\fP, \fIwriteonce\fP,
\fIreadonly\fP, \fIpseudo\-overwritable\fP, \fIunknown\fP
.RE
When UDF integrity is not \fIclosed\fP it means that the UDF disk was not
-properly unmounted, is in inconsistent state and needs repairing.
+properly unmounted, is in an inconsistent state and needs repairing.
All UDF string identifiers are stored on UDF disk in Unicode, therefore they are
locale or code page agnostic. Options \fB\-\-locale\fP, \fB\-\-u8\fP,
@@ -176,19 +175,22 @@ start=\fIblock\-num\fP, blocks=\fIblock\-count\fP, type=\fIblock\-type\fP
With meaning that \fIblock\-type\fP starts at UDF block \fIblock\-num\fP and
span \fIblock\-count\fP blocks on device.
-Windows specific \fIVolume Serial Number\fP is a non-standard 32 bit checksum,
-calculated as four separate 8 bit XOR checksums of 512 bytes long UDF File Set
-Descriptor. Therefore it cannot be set or changed as opposite to UUID which is
-moreover 64 bit long. This non-standard checksum is used only by Windows systems
+Windows-specific \fIVolume Serial Number\fP is a non-standard 32-bit checksum,
+calculated as four separate 8-bit XOR checksums of 512 bytes long UDF File Set
+Descriptor. Therefore, it cannot be set or changed as opposed to UUID which is
+64-bit long. This non-standard checksum is used only by Windows systems
(since Windows 98 era when it was introduced) and can be displayed on Windows
-systems by applications like \fBvol\fP, \fBdir\fP or \fBfsutil\fP.
+systems by applications like \fBvol\fP, \fBdir\fP or \fBfsutil.exe\fP.
.SH LIMITATIONS
-\fBudfinfo\fP is not able to read Metadata Partition and Virtual Allocation
-Table stored outside of Information Control Block yet. Therefore determining
-used and free space blocks, reading File Set Identifier and calculating Windows
-specific Volume Serial Number may not be available for some Write Once media
-and disks with UDF revisions higher then 2.01 which have Metadata Partition.
+\fBudfinfo\fP is not able to read Metadata Partition yet. Therefore, determining
+used and free space blocks, reading File Set Identifier and calculating
+Windows-specific Volume Serial Number may not be available for disks with UDF
+revisions higher than 2.01 which have Metadata Partition.
+
+\fBudfinfo\fP prior to version 2.1 was unable to read Virtual Allocation Table
+stored outside of Information Control Block. Therefore above limitation applied
+also for some Write Once media.
.SH AUTHOR
.nf
diff --git a/doc/udflabel.8 b/doc/udflabel.8
index 81ec038..69fffa9 100644
--- a/doc/udflabel.8
+++ b/doc/udflabel.8
@@ -1,5 +1,5 @@
'\" t -*- coding: UTF-8 -*-
-.\" Copyright (C) 2017 Pali Rohár <pali.rohar@gmail.com>
+.\" Copyright (C) 2017-2018 Pali Rohár <pali.rohar@gmail.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
@@ -14,22 +14,24 @@
.\" 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.,
.\" 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-
+.\"
.TH UDFLABEL 8 "udftools" "Commands"
.SH NAME
-udflabel \- show or change UDF filesystem label
+udflabel \(em show or change UDF filesystem label
.SH SYNOPSIS
-.BI "udflabel [encoding-options] [block-options] [identifier-options] " device " [" new-label "]"
+.BI "udflabel [encoding\-options] [block\-options] [identifier\-options] \
+" device " [" new\-label "]"
.SH DESCRIPTION
-When \fBudflabel\fP is invoked without \fBidentifier-options\fP and without
-specifying \fInew-label\fP then it show current label of UDF filesystem on
-\fIdevice\fP to standard output terminated by new line. Otherwise it update
+When \fBudflabel\fP is invoked without \fBidentifier\-options\fP and without
+specifying \fInew\-label\fP then it shows current label of UDF filesystem on
+\fIdevice\fP to standard output terminated by new line. Otherwise it updates
UDF filesystem (up to the revision 2.60) on \fIdevice\fP with new specified
-identifiers from \fBidentifier-options\fP. Specifying \fInew-label\fP is synonym
-for both \fI\-\-lvid\fP and \fI\-\-vid\fP, see section \fBUDF LABEL AND UUID\fP.
+identifiers from \fBidentifier\-options\fP. Specifying \fInew\-label\fP is
+synonym for both \fB\-\-lvid\fP and \fB\-\-vid\fP, see section
+\fBUDF LABEL AND UUID\fP.
.SH OPTIONS
@@ -42,9 +44,9 @@ Display the usage and the list of options.
.TP
.BI \-b,\-\-blocksize= " block\-size "
Specify the size of blocks in bytes. Valid block size for a UDF filesystem is
-power of two in range from 512 to 32768 and must match a device logical (sector)
-size. If omitted, \fBudflabel\fP tries to autodetect block size. It tries logical
-(sector) size and then all valid block sizes.
+a power of two in the range from \fI512\fP to \fI32768\fP and must match a
+device logical (sector) size. If omitted, \fBudflabel\fP tries to autodetect
+block size. First it tries logical (sector) size and then all valid block sizes.
.TP
.BI \-\-vatblock= " vat\-block "
@@ -54,26 +56,25 @@ last written/recorded disk block.
If omitted, \fBudflabel\fP for optical disc tries to detect the last recorded
block with fallback to the last block of block device or disk file image. In
-most cases this fallback does not have to work and for disk file images with
-Virtual Allocation Table is necessary to specify correct location.
+most cases, this fallback does not have to work and for disk file images with
+Virtual Allocation Table it is necessary to specify the correct location.
-Virtual Allocation Table on disks with UDF revisions higher then 1.50 contains
-Logical Volume Identifier (UDF Label).
+Virtual Allocation Table contains Logical Volume Identifier (UDF Label).
.TP
.B \-\-force
Force updating UDF disks without write support. Some media, like CD-ROM, DVD-ROM
-or BD-ROM are read-only. Other media, like CD-RW or DVD-RW are write-once. UDF
+or BD-ROM are read-only. Other media, like CD-RW or DVD-RW, are write-once. UDF
is designed also for such media where updating Label or Identifiers is not
-possible. But in some rare cases it could make sense to try overwrite existing
-Label or Identifiers also for UDF filesystem which has Access Type either
-Read-Only or Recordable (Write-Once). This is possible only if underlaying media
-supports overwriting. E.g. UDF image of CD-ROM stored on hard disk or Read-Only
-UDF image burned to DVD-RAM or BD-RE discs. Option \fI\-\-force\fP ignores UDF
-Access Type and treat it as Overwritable.
+possible. But in some rare cases, it could make sense to try and overwrite the
+existing Label or Identifiers also for UDF filesystem which has Access Type
+either Read-Only or Recordable (Write-Once). This is possible only if underlying
+media supports overwriting. E.g. UDF image of CD-ROM stored on hard disk or
+Read-Only UDF image burned to DVD-RAM or BD-RE discs. Option \fB\-\-force\fP
+ignores UDF Access Type and treats it as Overwritable.
.TP
-.B \-n,\-\-no-write
+.B \-n,\-\-no\-write
Not really, do not write to \fIdevice\fP. Just simulate and display what would
happen with \fIdevice\fP. Useful for determining which UDF blocks would be
overwritten.
@@ -83,7 +84,7 @@ overwritten.
.BI \-u,\-\-uuid= " uuid "
Specify the UDF uuid. Must be exactly 16 hexadecimal lowercase digits and is
used for first 16 characters of \fB\-\-fullvsid\fP option. Special value
-\fBrandom\fP generates new uuid from local time and random number. See section
+\fIrandom\fP generates new uuid from local time and a random number. See section
\fBUDF LABEL AND UUID\fP.
.TP
@@ -96,7 +97,7 @@ Specify the new Volume Identifier.
.TP
.BI \-\-vsid= " new\-volume\-set\-identifier "
-Specify the new 17.-127. character of Volume Set Identifier. See section
+Specify the new 17.\(en127. character of Volume Set Identifier. See section
\fBUDF LABEL AND UUID\fP.
.TP
@@ -112,7 +113,7 @@ Specify the new Volume Set identifier. Overwrite previous \fB\-\-uuid\fP and
.TP
.B \-\-locale
Treat identifier string options as strings encoded according to current locale
-settings (default). Must be specified as first argument.
+settings (default). Must be specified as the first argument.
.TP
.B \-\-u8
@@ -126,30 +127,31 @@ Treat identifier string options as strings encoded in 16-bit OSTA Compressed
Unicode format, equivalent to UCS-2BE. Note that it is not possible to include
zero byte in command line options, therefore any character which has at least
one zero byte cannot be supplied (this applies to all Latin1 characters). Must
-be specified as first argument.
+be specified as the first argument.
.TP
.B \-\-utf8
Treat identifier string options as strings encoded in UTF-8. Must be specified
-as first argument.
+as the first argument.
.SH "UDF LABEL AND UUID"
-UDF specification does not say anything about a disk label but describe that UDF
-Logical Volume Identifier is extremely important field for media identification
-in a jukebox as that field is displayed to the user. And based on this statement
-it is a common practice for majority of UDF implementations to use UDF Logical
-Volume Identifier as a UDF disk label.
-
-UDF specification does not have concept of disk UUID like other filesystems. But
-mandates that the first 16 characters of UDF Volume Set Identifier are unique,
-a non-fixed and a non-trivial value. Plus first eight characters are hexadecimal
-digits. Windows application format.exe and Mac OS X application newfs_udf are
-known to violates this requirement and set only the first 8 characters as unique
-(others are fixed). Because there are still lot of UDF implementations which use
-in the first 16 characters only hexadecimal digits and all compliant UDF
-implementations have hexadecimal digits in the first 8 characters, the following
-algorithm for generating stable UUID was informally chosen and now is used by
-udftools, util-linux, grub2 and other projects:
+UDF specification does not say anything about a disk label but it describes that
+UDF Logical Volume Identifier is an extremely important field for media
+identification in a jukebox as that field is displayed to the user. And based on
+this statement it is a common practice for the majority of UDF implementations
+to use UDF Logical Volume Identifier as a UDF disk label.
+
+UDF specification does not have a concept of disk UUID like other filesystems. \
+But mandates that the first 16 characters of UDF Volume Set Identifier are
+unique, a non-fixed and a non-trivial value. Plus first eight characters are
+hexadecimal digits. Windows application \fBformat.exe\fP and Mac OS X
+application \fBnewfs_udf\fP are known to violates this requirement and set only
+the first 8 characters as unique (others are fixed). Since, there are still a
+lot of UDF implementations which use in the first 16 characters only hexadecimal
+digits and all compliant UDF implementations have hexadecimal digits in the
+first 8 characters, the following algorithm for generating stable UUID was
+informally chosen and now is used by udftools, util-linux, grub2 and other
+projects:
.RS
0. If Volume Set Identifier has less then 8 characters then stop with empty UUID
@@ -163,30 +165,33 @@ their hexadecimal representation (resulting in 16 bytes) and use as UUID
.br
4. Otherwise, compose UUID from two 8 byte parts:
.RS
-1. part: Use lowercase form of the first 8 bytes (which are hexadecimal digits)
+1. part: Use the lowercase form of the first 8 bytes (which are hexadecimal
+digits)
.br
-2. part: Convert next 4 bytes (9.-12. pos.) to their hexadecimal representation
+2. part: Convert next 4 bytes (9.\(en12. pos.) to their hexadecimal
+representation
.RE
.RE
-Which means that this generated UUID has always 16 hexadecimal lowercase digits.
-In most cases this UUID matches case-insensitively the first 16 characters of
-UDF Volume Set Identifier and for all disks compliant to the UDF specification
-the first 8 bytes of UUID matches case-insensitively the first 8 characters of
-UDF Volume Set Identifier. In that algorithm was chosen UTF-8 encoding because
-it is the only commonly used Unicode transformation to bytes with fixed points
-in all hexadecimal digits.
+Which means that this generated UUID has always 16 hexadecimal lowercase
+digits. In most cases, this UUID matches case-insensitively the first 16
+characters of UDF Volume Set Identifier and for all disks compliant to the UDF
+specification the first 8 bytes of UUID matches case-insensitively the first 8
+characters of UDF Volume Set Identifier. In that algorithm was chosen UTF-8
+encoding because it is the only commonly used Unicode transformation to bytes
+with fixed points in all hexadecimal digits.
.SH "EXIT STATUS"
-\fBudflabel\fP returns 0 if successful, non-zero if there are problems like block
-device does not contain UDF filesystem or updating failed.
+\fBudflabel\fP returns 0 if successful, non-zero if there are problems like
+block device does not contain UDF filesystem or updating failed.
.SH LIMITATIONS
\fBudflabel\fP is not able to set new Label, Logical Volume Identifier and File
Set Identifier for disks with Metadata Partition (used by UDF revisions higher
-then 2.01) or Virtual Allocation Table (used by Write Once media). Also is not
-able to read Label correctly if disk has Virtual Allocation Table stored outside
-of Information Control Block.
+then 2.01) or Virtual Allocation Table (used by Write Once media).
+
+\fBudflabel\fP prior to version 2.1 was not able to read Label correctly if the
+disk has Virtual Allocation Table stored outside of Information Control Block.
.SH AUTHOR
.nf
@@ -194,8 +199,8 @@ Pali Rohár <pali.rohar@gmail.com>
.fi
.SH AVAILABILITY
-\fBudflabel\fP is part of the udftools package since version 2.0 and is available
-from https://github.com/pali/udftools/.
+\fBudflabel\fP is part of the udftools package since version 2.0 and is
+available from https://github.com/pali/udftools/.
.SH "SEE ALSO"
\fBmkudffs\fP(8), \fBpktsetup\fP(8), \fBcdrwtool\fP(1), \fBudfinfo\fP(1),
diff --git a/doc/wrudf.1 b/doc/wrudf.1
index 6de99ca..7373b09 100644
--- a/doc/wrudf.1
+++ b/doc/wrudf.1
@@ -1,7 +1,7 @@
.\" Text automatically generated by txt2man
.TH wrudf 1 "udftools" "Linux Reference Manual"
.SH NAME
-\fBwrudf \fP- Maintain an UDF filesystem.
+\fBwrudf \fP- Maintain a UDF filesystem.
.SH SYNOPSIS
.nf
.fam C
diff --git a/include/bswap.h b/include/bswap.h
index 00627fa..8cfc7ff 100644
--- a/include/bswap.h
+++ b/include/bswap.h
@@ -1,7 +1,7 @@
/*
* bswap.h
*
- * Copyright (c) 2001-2002 Ben Fennema <bfennema@falcon.csc.calpoly.edu>
+ * Copyright (c) 2001-2002 Ben Fennema
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
@@ -25,23 +25,9 @@
#include "config.h"
-#include <inttypes.h>
+#include <stdint.h>
#include <sys/types.h>
-#ifdef HAVE_SYS_ISA_DEFS_H
-#define __LITTLE_ENDIAN 1234
-#define __BIG_ENDIAN 4321
-#define __PDP_ENDIAN 3412
-
-#ifdef _LITTLE_ENDIAN
-#define __BYTE_ORDER __LITTLE_ENDIAN
-#endif
-
-#ifdef _BIG_ENDIAN
-#define __BYTE_ORDER __BIG_ENDIAN
-#endif
-#endif
-
#define constant_swab16(x) \
((uint16_t)((((uint16_t)(x) & 0x00FFU) << 8) | \
(((uint16_t)(x) & 0xFF00U) >> 8)))
@@ -135,11 +121,7 @@ static inline uint64_t swab64p(uint64_t *x)
((*(uint64_t *)(x) & 0xFF00000000000000ULL) >> 56)));
}
-#if __BYTE_ORDER == 0
-
-#error "__BYTE_ORDER must be defined"
-
-#elif __BYTE_ORDER == __BIG_ENDIAN
+#ifdef WORDS_BIGENDIAN
#define le16_to_cpu(x) (__builtin_constant_p(x) ? \
constant_swab16(x) : \
@@ -190,7 +172,7 @@ static inline uint64_t swab64p(uint64_t *x)
#define constant_be32_to_cpup(x) (*(uint32_t *)(x))
#define constant_be64_to_cpup(x) (*(uint64_t *)(x))
-#else /* __BYTE_ORDER == __LITTLE_ENDIAN */
+#else /* WORDS_BIGENDIAN */
#define le16_to_cpu(x) ((uint16_t)(x))
#define le32_to_cpu(x) ((uint32_t)(x))
@@ -241,7 +223,7 @@ static inline uint64_t swab64p(uint64_t *x)
#define constant_be32_to_cpup(x) constant_swab32p((x))
#define constant_be64_to_cpup(x) constant_swab64p((x))
-#endif /* __BYTE_ORDER == 0 */
+#endif /* WORDS_BIGENDIAN */
#define cpu_to_le16(x) le16_to_cpu((x))
#define cpu_to_le32(x) le32_to_cpu((x))
diff --git a/include/config.in b/include/config.in
index c92956c..f43bb67 100644
--- a/include/config.in
+++ b/include/config.in
@@ -1,20 +1,20 @@
/* include/config.in. Generated from configure.ac by autoheader. */
+/* Define if building universal (internal helper macro) */
+#undef AC_APPLE_UNIVERSAL_BUILD
+
/* Define to 1 if you have the <dlfcn.h> header file. */
#undef HAVE_DLFCN_H
-/* Define to 1 if you have the <fcntl.h> header file. */
-#undef HAVE_FCNTL_H
-
-/* Define to 1 if you have the <getopt.h> header file. */
-#undef HAVE_GETOPT_H
-
/* Define to 1 if you have the <inttypes.h> header file. */
#undef HAVE_INTTYPES_H
/* Define to 1 if you have the <memory.h> header file. */
#undef HAVE_MEMORY_H
+/* Define to 1 if you have the <readline/readline.h> header file. */
+#undef HAVE_READLINE_READLINE_H
+
/* Define to 1 if you have the <stdint.h> header file. */
#undef HAVE_STDINT_H
@@ -30,9 +30,6 @@
/* Define to 1 if you have the <sys/stat.h> header file. */
#undef HAVE_SYS_STAT_H
-/* Define to 1 if you have the <sys/time.h> header file. */
-#undef HAVE_SYS_TIME_H
-
/* Define to 1 if you have the <sys/types.h> header file. */
#undef HAVE_SYS_TYPES_H
@@ -66,15 +63,21 @@
/* Define to 1 if you have the ANSI C header files. */
#undef STDC_HEADERS
-/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
-#undef TIME_WITH_SYS_TIME
-
-/* Define to 1 if your <sys/time.h> declares `struct tm'. */
-#undef TM_IN_SYS_TIME
-
/* Version number of package */
#undef VERSION
+/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
+ significant byte first (like Motorola and SPARC, unlike Intel). */
+#if defined AC_APPLE_UNIVERSAL_BUILD
+# if defined __BIG_ENDIAN__
+# define WORDS_BIGENDIAN 1
+# endif
+#else
+# ifndef WORDS_BIGENDIAN
+# undef WORDS_BIGENDIAN
+# endif
+#endif
+
/* Enable large inode numbers on Mac OS X 10.5. */
#ifndef _DARWIN_USE_64_BIT_INODE
# define _DARWIN_USE_64_BIT_INODE 1
diff --git a/include/ecma_167.h b/include/ecma_167.h
index 9ef146c..8459aae 100644
--- a/include/ecma_167.h
+++ b/include/ecma_167.h
@@ -4,8 +4,8 @@
* This file is based on ECMA-167 3rd edition (June 1997)
* http://www.ecma.ch
*
- * Copyright (c) 2001-2002 Ben Fennema <bfennema@falcon.csc.calpoly.edu>
- * Copyright (c) 2017 Pali Rohár <pali.rohar@gmail.com>
+ * Copyright (c) 2001-2002 Ben Fennema
+ * Copyright (c) 2017-2018 Pali Rohár <pali.rohar@gmail.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -38,7 +38,7 @@
* ECMA-167r3 defines and structure definitions
*/
-#include <inttypes.h>
+#include <stdint.h>
#ifndef _ECMA_167_H
#define _ECMA_167_H 1
@@ -746,6 +746,7 @@ struct appUseExtAttr
#define EXTATTR_DEV_SPEC 12
#define EXTATTR_IMP_USE 2048
#define EXTATTR_APP_USE 65536
+#define EXTATTR_SUBTYPE 1
/* Unallocated Space Entry (ECMA 167r3 4/14.11) */
diff --git a/include/libudffs.h b/include/libudffs.h
index 3f1abe3..fe88ca9 100644
--- a/include/libudffs.h
+++ b/include/libudffs.h
@@ -1,8 +1,8 @@
/*
* libudffs.h
*
- * Copyright (c) 2001-2002 Ben Fennema <bfennema@falcon.csc.calpoly.edu>
- * Copyright (c) 2014-2017 Pali Rohár <pali.rohar@gmail.com>
+ * Copyright (c) 2001-2002 Ben Fennema
+ * Copyright (c) 2014-2018 Pali Rohár <pali.rohar@gmail.com>
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
@@ -29,9 +29,11 @@
#ifndef __LIBUDFFS_H
#define __LIBUDFFS_H
+#include <stddef.h>
+
#include "ecma_167.h"
#include "osta_udf.h"
-#include "udf_endian.h"
+#include "bswap.h"
#define FLAG_FREED_BITMAP 0x00000001
#define FLAG_FREED_TABLE 0x00000002
@@ -130,6 +132,7 @@ struct udf_disc
struct primaryVolDesc *udf_pvd[2];
struct logicalVolDesc *udf_lvd[2];
struct partitionDesc *udf_pd[2];
+ struct partitionDesc *udf_pd2[2];
struct unallocSpaceDesc *udf_usd[2];
struct impUseVolDesc *udf_iuvd[2];
struct terminatingDesc *udf_td[2];
@@ -231,5 +234,8 @@ extern size_t encode_string(struct udf_disc *, dstring *, const char *, size_t);
/* misc.c */
extern const char *appname;
size_t gen_uuid_from_vol_set_ident(char[17], const dstring *, size_t);
+uint32_t strtou32(const char *, int, int *);
+uint16_t strtou16(const char *, int, int *);
+uint32_t randu32(void);
#endif /* __LIBUDFFS_H */
diff --git a/include/osta_udf.h b/include/osta_udf.h
index 413c816..39d46fe 100644
--- a/include/osta_udf.h
+++ b/include/osta_udf.h
@@ -4,8 +4,8 @@
* This file is based on OSTA UDF(tm) 2.01 (March 15, 2000)
* http://www.osta.org
*
- * Copyright (c) 2001-2002 Ben Fennema <bfennema@falcon.csc.calpoly.edu>
- * Copyright (c) 2017 Pali Rohár <pali.rohar@gmail.com>
+ * Copyright (c) 2001-2002 Ben Fennema
+ * Copyright (c) 2017-2018 Pali Rohár <pali.rohar@gmail.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -55,6 +55,7 @@
#define UDF_ID_FREE_EA "*UDF FreeEASpace"
#define UDF_ID_FREE_APP_EA "*UDF FreeAppEASpace"
#define UDF_ID_DVD_CGMS "*UDF DVD CGMS Info"
+#define UDF_ID_VAT_LVEXTENSION "*UDF VAT LVExtension"
#define UDF_ID_OS2_EA "*UDF OS/2 EA"
#define UDF_ID_OS2_EA_LENGTH "*UDF OS/2 EALength"
#define UDF_ID_MAC_VOLUME "*UDF Mac VolumeInfo"
@@ -231,6 +232,16 @@ struct DVDCopyrightImpUse
uint8_t protectionSystemInfo[4];
} __attribute__ ((packed));
+/* Logical Volume Extended Information (UDF 1.50 Errata, DCN 5003, 3.3.4.5.1.3) */
+struct LVExtensionEA
+{
+ uint16_t headerChecksum;
+ uint64_t verificationID;
+ uint32_t numFiles;
+ uint32_t numDirs;
+ dstring logicalVolIdent[128];
+} __attribute__ ((packed));
+
/* Application Use Extended Attribute (UDF 2.01 3.3.4.6) */
/* FreeAppEASpace (UDF 2.01 3.3.4.6.1) */
struct freeAppEASpace
diff --git a/include/udf_endian.h b/include/udf_endian.h
deleted file mode 100644
index daa0e3d..0000000
--- a/include/udf_endian.h
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * udf_endian.h
- *
- * Copyright (c) 2001-2002 Ben Fennema <bfennema@falcon.csc.calpoly.edu>
- * All rights reserved.
- *
- * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-#ifndef __UDF_ENDIAN_H
-#define __UDF_ENDIAN_H
-
-#include <string.h>
-
-#include "bswap.h"
-
-static inline lb_addr lelb_to_cpu(lb_addr in)
-{
- lb_addr out;
- out.logicalBlockNum = le32_to_cpu(in.logicalBlockNum);
- out.partitionReferenceNum = le16_to_cpu(in.partitionReferenceNum);
- return out;
-}
-
-static inline lb_addr cpu_to_lelb(lb_addr in)
-{
- lb_addr out;
- out.logicalBlockNum = cpu_to_le32(in.logicalBlockNum);
- out.partitionReferenceNum = cpu_to_le16(in.partitionReferenceNum);
- return out;
-}
-
-static inline timestamp lets_to_cpu(timestamp in)
-{
- timestamp out;
- memcpy(&out, &in, sizeof(timestamp));
- out.typeAndTimezone = le16_to_cpu(in.typeAndTimezone);
- out.year = le16_to_cpu(in.year);
- return out;
-}
-
-static inline short_ad lesa_to_cpu(short_ad in)
-{
- short_ad out;
- out.extLength = le32_to_cpu(in.extLength);
- out.extPosition = le32_to_cpu(in.extPosition);
- return out;
-}
-
-static inline short_ad cpu_to_lesa(short_ad in)
-{
- short_ad out;
- out.extLength = cpu_to_le32(in.extLength);
- out.extPosition = cpu_to_le32(in.extPosition);
- return out;
-}
-
-static inline long_ad lela_to_cpu(long_ad in)
-{
- long_ad out;
- out.extLength = le32_to_cpu(in.extLength);
- out.extLocation = lelb_to_cpu(in.extLocation);
- return out;
-}
-
-static inline long_ad cpu_to_lela(long_ad in)
-{
- long_ad out;
- out.extLength = cpu_to_le32(in.extLength);
- out.extLocation = cpu_to_lelb(in.extLocation);
- return out;
-}
-
-static inline extent_ad leea_to_cpu(extent_ad in)
-{
- extent_ad out;
- out.extLength = le32_to_cpu(in.extLength);
- out.extLocation = le32_to_cpu(in.extLocation);
- return out;
-}
-
-static inline timestamp cpu_to_lets(timestamp in)
-{
- timestamp out;
- memcpy(&out, &in, sizeof(timestamp));
- out.typeAndTimezone = cpu_to_le16(in.typeAndTimezone);
- out.year = cpu_to_le16(in.year);
- return out;
-}
-
-#endif /* __UDF_ENDIAN_H */
diff --git a/libudffs/Makefile.am b/libudffs/Makefile.am
index 2e829be..59f56cb 100644
--- a/libudffs/Makefile.am
+++ b/libudffs/Makefile.am
@@ -1,5 +1,5 @@
noinst_LTLIBRARIES = libudffs.la
-libudffs_la_SOURCES = crc.c extent.c misc.c unicode.c ../include/libudffs.h ../include/ecma_167.h ../include/osta_udf.h ../include/udf_endian.h ../include/bswap.h
+libudffs_la_SOURCES = crc.c extent.c misc.c unicode.c ../include/libudffs.h ../include/ecma_167.h ../include/osta_udf.h ../include/bswap.h
libudffs_la_LIBADD = @LTLIBOBJS@
AM_CPPFLAGS = -I$(top_srcdir)/include
diff --git a/libudffs/Makefile.in b/libudffs/Makefile.in
index e2a0c34..348b9d3 100644
--- a/libudffs/Makefile.in
+++ b/libudffs/Makefile.in
@@ -225,11 +225,17 @@ 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@
+UDEVDIR = @UDEVDIR@
+UDEV_CFLAGS = @UDEV_CFLAGS@
+UDEV_LIBS = @UDEV_LIBS@
VERSION = @VERSION@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
@@ -285,7 +291,7 @@ top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
noinst_LTLIBRARIES = libudffs.la
-libudffs_la_SOURCES = crc.c extent.c misc.c unicode.c ../include/libudffs.h ../include/ecma_167.h ../include/osta_udf.h ../include/udf_endian.h ../include/bswap.h
+libudffs_la_SOURCES = crc.c extent.c misc.c unicode.c ../include/libudffs.h ../include/ecma_167.h ../include/osta_udf.h ../include/bswap.h
libudffs_la_LIBADD = @LTLIBOBJS@
AM_CPPFLAGS = -I$(top_srcdir)/include
all: all-am
diff --git a/libudffs/extent.c b/libudffs/extent.c
index 8e5f1fb..5856ed8 100644
--- a/libudffs/extent.c
+++ b/libudffs/extent.c
@@ -1,7 +1,7 @@
/*
* extent.c
*
- * Copyright (c) 2001-2002 Ben Fennema <bfennema@falcon.csc.calpoly.edu>
+ * Copyright (c) 2001-2002 Ben Fennema
* Copyright (c) 2014-2017 Pali Rohár <pali.rohar@gmail.com>
* All rights reserved.
*
diff --git a/libudffs/misc.c b/libudffs/misc.c
index 6369078..a0e496a 100644
--- a/libudffs/misc.c
+++ b/libudffs/misc.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2017 Pali Rohár <pali.rohar@gmail.com>
+ * Copyright (C) 2017-2018 Pali Rohár <pali.rohar@gmail.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
@@ -19,9 +19,15 @@
#include "config.h"
#include <ctype.h>
+#include <errno.h>
+#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <time.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/types.h>
#include "libudffs.h"
@@ -82,3 +88,71 @@ size_t gen_uuid_from_vol_set_ident(char uuid[17], const dstring *vol_set_ident,
return 16;
}
+
+uint32_t strtou32(const char *str, int base, int *failed)
+{
+ char *endptr = NULL;
+ long long int ret;
+
+ /* strtou* does not signal underflow, so use signed variant */
+ errno = 0;
+ ret = strtoll(str, &endptr, base);
+ /* strto* skips leading whitespaces, so detect them via isspace */
+ *failed = (!*str || isspace(*str) || *endptr || errno || ret < 0 || ret > UINT32_MAX) ? 1 : 0;
+ return ret;
+}
+
+uint16_t strtou16(const char *str, int base, int *failed)
+{
+ uint32_t ret;
+
+ ret = strtou32(str, base, failed);
+ *failed = (*failed || ret > UINT16_MAX) ? 1 : 0;
+ return ret;
+}
+
+static inline unsigned int intlog2(unsigned int word)
+{
+ unsigned int result = 0;
+
+ while (word >>= 1)
+ result++;
+ return result;
+}
+
+uint32_t randu32(void)
+{
+ int fd;
+ uint32_t value;
+ unsigned int bits;
+ unsigned int rand_bits;
+
+ static int srand_done = 0;
+
+ fd = open("/dev/urandom", O_RDONLY);
+ if (fd >= 0)
+ {
+ if (read(fd, &value, sizeof(value)) == sizeof(value))
+ {
+ close(fd);
+ return value;
+ }
+ close(fd);
+ }
+
+ if (!srand_done)
+ {
+ srand(time(NULL) * getpid());
+ srand_done = 1;
+ }
+
+ value = 0;
+ rand_bits = intlog2((unsigned int)RAND_MAX+1);
+ for (bits = 0; bits < 32; bits += rand_bits)
+ {
+ value <<= rand_bits;
+ value |= rand();
+ }
+
+ return value;
+}
diff --git a/libudffs/unicode.c b/libudffs/unicode.c
index e31d4de..d8bbf73 100644
--- a/libudffs/unicode.c
+++ b/libudffs/unicode.c
@@ -1,7 +1,7 @@
/*
* unicode.c
*
- * Copyright (c) 2001-2002 Ben Fennema <bfennema@falcon.csc.calpoly.edu>
+ * Copyright (c) 2001-2002 Ben Fennema
* Copyright (c) 2014-2017 Pali Rohár <pali.rohar@gmail.com>
* All rights reserved.
*
diff --git a/mkudffs/Makefile.am b/mkudffs/Makefile.am
index 8c8ba8d..fc9e54f 100644
--- a/mkudffs/Makefile.am
+++ b/mkudffs/Makefile.am
@@ -1,6 +1,6 @@
sbin_PROGRAMS = mkudffs
mkudffs_LDADD = $(top_builddir)/libudffs/libudffs.la
-mkudffs_SOURCES = main.c mkudffs.c defaults.c file.c options.c mkudffs.h defaults.h file.h options.h ../include/ecma_167.h ../include/osta_udf.h ../include/libudffs.h ../include/udf_endian.h ../include/bswap.h
+mkudffs_SOURCES = main.c mkudffs.c defaults.c file.c options.c mkudffs.h defaults.h file.h options.h ../include/ecma_167.h ../include/osta_udf.h ../include/libudffs.h ../include/bswap.h
AM_CPPFLAGS = -I$(top_srcdir)/include
diff --git a/mkudffs/Makefile.in b/mkudffs/Makefile.in
index 6c24c6b..e8d1ba3 100644
--- a/mkudffs/Makefile.in
+++ b/mkudffs/Makefile.in
@@ -228,11 +228,17 @@ 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@
+UDEVDIR = @UDEVDIR@
+UDEV_CFLAGS = @UDEV_CFLAGS@
+UDEV_LIBS = @UDEV_LIBS@
VERSION = @VERSION@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
@@ -288,7 +294,7 @@ top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
mkudffs_LDADD = $(top_builddir)/libudffs/libudffs.la
-mkudffs_SOURCES = main.c mkudffs.c defaults.c file.c options.c mkudffs.h defaults.h file.h options.h ../include/ecma_167.h ../include/osta_udf.h ../include/libudffs.h ../include/udf_endian.h ../include/bswap.h
+mkudffs_SOURCES = main.c mkudffs.c defaults.c file.c options.c mkudffs.h defaults.h file.h options.h ../include/ecma_167.h ../include/osta_udf.h ../include/libudffs.h ../include/bswap.h
AM_CPPFLAGS = -I$(top_srcdir)/include
all: all-am
diff --git a/mkudffs/defaults.c b/mkudffs/defaults.c
index ed0a4d3..b438deb 100644
--- a/mkudffs/defaults.c
+++ b/mkudffs/defaults.c
@@ -1,7 +1,7 @@
/*
* defaults.c
*
- * Copyright (c) 2001-2002 Ben Fennema <bfennema@falcon.csc.calpoly.edu>
+ * Copyright (c) 2001-2002 Ben Fennema
* Copyright (c) 2014-2017 Pali Rohár <pali.rohar@gmail.com>
* All rights reserved.
*
diff --git a/mkudffs/defaults.h b/mkudffs/defaults.h
index 9a6ed99..69ca181 100644
--- a/mkudffs/defaults.h
+++ b/mkudffs/defaults.h
@@ -1,7 +1,7 @@
/*
* defaults.h
*
- * Copyright (c) 2001-2002 Ben Fennema <bfennema@falcon.csc.calpoly.edu>
+ * Copyright (c) 2001-2002 Ben Fennema
* Copyright (c) 2016-2017 Pali Rohár <pali.rohar@gmail.com>
* All rights reserved.
*
diff --git a/mkudffs/file.c b/mkudffs/file.c
index a931b69..555bec3 100644
--- a/mkudffs/file.c
+++ b/mkudffs/file.c
@@ -1,8 +1,8 @@
/*
* file.c
*
- * Copyright (c) 2001-2002 Ben Fennema <bfennema@falcon.csc.calpoly.edu>
- * Copyright (c) 2016-2017 Pali Rohár <pali.rohar@gmail.com>
+ * Copyright (c) 2001-2002 Ben Fennema
+ * Copyright (c) 2016-2018 Pali Rohár <pali.rohar@gmail.com>
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
@@ -30,6 +30,7 @@
#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
#include <sys/stat.h>
#include "libudffs.h"
@@ -126,16 +127,17 @@ tag query_tag(struct udf_disc *disc, struct udf_extent *ext, struct udf_desc *de
* @param SerialNum the serial number to assign
* @param Location the block number of the on-disc tag:Ident udf_descriptor
* @param data the udf_data list head
+ * @param skip the skip data length
* @param length the summed data length
* @return the tag
*/
-tag udf_query_tag(struct udf_disc *disc, uint16_t Ident, uint16_t SerialNum, uint32_t Location, struct udf_data *data, uint16_t length)
+tag udf_query_tag(struct udf_disc *disc, uint16_t Ident, uint16_t SerialNum, uint32_t Location, struct udf_data *data, uint32_t skip, uint32_t length)
{
tag ret;
int i;
uint16_t crc = 0;
- int offset = sizeof(tag);
- int clength;
+ uint32_t clength;
+ uint32_t offset = sizeof(tag);
ret.tagIdent = cpu_to_le16(Ident);
if (disc->udf_rev >= 0x0200)
@@ -150,9 +152,10 @@ tag udf_query_tag(struct udf_disc *disc, uint16_t Ident, uint16_t SerialNum, uin
{
if ((clength = data->length) > length)
clength = length;
- crc = udf_crc(data->buffer + offset, clength - offset, crc);
+ crc = udf_crc(data->buffer + skip + offset, clength - offset, crc);
length -= clength;
offset = 0;
+ skip = 0;
data = data->next;
}
ret.descCRC = cpu_to_le16(crc);
@@ -439,7 +442,7 @@ void insert_fid(struct udf_disc *disc, struct udf_extent *pspace, struct udf_des
fid->lengthFileIdent = length;
fid->lengthOfImpUse = cpu_to_le16(0);
memcpy(fid->fileIdent, name, length);
- fid->descTag = udf_query_tag(disc, TAG_IDENT_FID, 1, le32_to_cpu(fid->descTag.tagLocation), data, ilength);
+ fid->descTag = udf_query_tag(disc, TAG_IDENT_FID, 1, le32_to_cpu(fid->descTag.tagLocation), data, 0, ilength);
efe->informationLength = cpu_to_le64(le64_to_cpu(efe->informationLength) + ilength);
efe->objectSize = cpu_to_le64(le64_to_cpu(efe->objectSize) + ilength);
@@ -472,13 +475,177 @@ void insert_fid(struct udf_disc *disc, struct udf_extent *pspace, struct udf_des
fid->lengthFileIdent = length;
fid->lengthOfImpUse = cpu_to_le16(0);
memcpy(fid->fileIdent, name, length);
- fid->descTag = udf_query_tag(disc, TAG_IDENT_FID, 1, le32_to_cpu(fid->descTag.tagLocation), data, ilength);
+ fid->descTag = udf_query_tag(disc, TAG_IDENT_FID, 1, le32_to_cpu(fid->descTag.tagLocation), data, 0, ilength);
fe->informationLength = cpu_to_le64(le64_to_cpu(fe->informationLength) + ilength);
}
*(tag *)desc->data->buffer = query_tag(disc, pspace, desc, 1);
*(tag *)parent->data->buffer = query_tag(disc, pspace, parent, 1);
}
+void insert_ea(struct udf_disc *disc, struct udf_desc *desc, struct genericFormat *ea, uint32_t length)
+{
+ struct extendedAttrHeaderDesc *ea_hdr;
+ struct extendedFileEntry *efe = NULL;
+ struct fileEntry *fe = NULL;
+ uint8_t *extendedAttr;
+ uint32_t lengthExtendedAttr;
+ uint32_t location = 0;
+
+#define UPDATE_PTR \
+ do { \
+ if (disc->flags & FLAG_EFE) \
+ { \
+ efe = (struct extendedFileEntry *)desc->data->buffer; \
+ lengthExtendedAttr = efe->lengthExtendedAttr; \
+ extendedAttr = efe->extendedAttr; \
+ } \
+ else \
+ { \
+ fe = (struct fileEntry *)desc->data->buffer; \
+ lengthExtendedAttr = fe->lengthExtendedAttr; \
+ extendedAttr = fe->extendedAttr; \
+ } \
+ ea_hdr = (struct extendedAttrHeaderDesc *)extendedAttr; \
+ } while ( 0 )
+
+ UPDATE_PTR;
+
+ if (le32_to_cpu(lengthExtendedAttr) && le32_to_cpu(ea_hdr->impAttrLocation) > le32_to_cpu(lengthExtendedAttr))
+ ea_hdr->impAttrLocation = cpu_to_le32(0xFFFFFFFF);
+ if (le32_to_cpu(lengthExtendedAttr) && le32_to_cpu(ea_hdr->appAttrLocation) > le32_to_cpu(lengthExtendedAttr))
+ ea_hdr->appAttrLocation = cpu_to_le32(0xFFFFFFFF);
+
+ if (!le32_to_cpu(lengthExtendedAttr))
+ {
+ desc->length += sizeof(*ea_hdr);
+ desc->data->length += sizeof(*ea_hdr);
+ desc->data->buffer = realloc(desc->data->buffer, desc->data->length);
+
+ UPDATE_PTR;
+
+ if (disc->flags & FLAG_EFE)
+ {
+ lengthExtendedAttr = efe->lengthExtendedAttr = cpu_to_le32(sizeof(*ea_hdr));
+ if (le32_to_cpu(efe->lengthAllocDescs))
+ memmove(&efe->allocDescs[sizeof(*ea_hdr)], efe->allocDescs, le32_to_cpu(efe->lengthAllocDescs));
+ }
+ else
+ {
+ lengthExtendedAttr = fe->lengthExtendedAttr = cpu_to_le32(sizeof(*ea_hdr));
+ if (le32_to_cpu(fe->lengthAllocDescs))
+ memmove(&fe->allocDescs[sizeof(*ea_hdr)], fe->allocDescs, le32_to_cpu(fe->lengthAllocDescs));
+ }
+
+ ea_hdr->impAttrLocation = cpu_to_le32(0xFFFFFFFF);
+ ea_hdr->appAttrLocation = cpu_to_le32(0xFFFFFFFF);
+ }
+
+ if (le32_to_cpu(ea->attrType) < 2048)
+ {
+ desc->length += length;
+ desc->data->length += length;
+ desc->data->buffer = realloc(desc->data->buffer, desc->data->length);
+
+ UPDATE_PTR;
+
+ if (le32_to_cpu(ea_hdr->appAttrLocation) != 0xFFFFFFFF)
+ {
+ location = le32_to_cpu(ea_hdr->appAttrLocation);
+ memmove(&extendedAttr[location+length], &extendedAttr[location], le32_to_cpu(lengthExtendedAttr) - location);
+ ea_hdr->appAttrLocation = cpu_to_le32(location+length);
+ }
+
+ if (le32_to_cpu(ea_hdr->impAttrLocation) != 0xFFFFFFFF)
+ {
+ location = le32_to_cpu(ea_hdr->impAttrLocation);
+ if (le32_to_cpu(ea_hdr->appAttrLocation) == 0xFFFFFFFF)
+ memmove(&extendedAttr[location+length], &extendedAttr[location], le32_to_cpu(lengthExtendedAttr) - location);
+ else
+ memmove(&extendedAttr[location+length], &extendedAttr[location], le32_to_cpu(ea_hdr->appAttrLocation) - location);
+ ea_hdr->impAttrLocation = cpu_to_le32(location+length);
+ }
+ else if (le32_to_cpu(ea_hdr->appAttrLocation) == 0xFFFFFFFF)
+ {
+ location = le32_to_cpu(lengthExtendedAttr);
+ }
+
+ memcpy(&extendedAttr[location], ea, length);
+ lengthExtendedAttr = cpu_to_le32(le32_to_cpu(lengthExtendedAttr) + length);
+ if (disc->flags & FLAG_EFE)
+ efe->lengthExtendedAttr = lengthExtendedAttr;
+ else
+ fe->lengthExtendedAttr = lengthExtendedAttr;
+ }
+ else if (le32_to_cpu(ea->attrType) < 65536)
+ {
+ desc->length += length;
+ desc->data->length += length;
+ desc->data->buffer = realloc(desc->data->buffer, desc->data->length);
+
+ UPDATE_PTR;
+
+ if (le32_to_cpu(ea_hdr->appAttrLocation) != 0xFFFFFFFF)
+ {
+ location = le32_to_cpu(ea_hdr->appAttrLocation);
+ memmove(&extendedAttr[location+length], &extendedAttr[location], le32_to_cpu(lengthExtendedAttr) - location);
+ ea_hdr->appAttrLocation = cpu_to_le32(location+length);
+ }
+ else
+ {
+ location = le32_to_cpu(lengthExtendedAttr);
+ }
+
+ if (le32_to_cpu(ea_hdr->impAttrLocation) == 0xFFFFFFFF)
+ {
+ if (le32_to_cpu(ea_hdr->appAttrLocation) == 0xFFFFFFFF)
+ ea_hdr->impAttrLocation = lengthExtendedAttr;
+ else
+ ea_hdr->impAttrLocation = ea_hdr->appAttrLocation;
+ }
+
+ memcpy(&extendedAttr[location], ea, length);
+ lengthExtendedAttr = cpu_to_le32(le32_to_cpu(lengthExtendedAttr) + length);
+ if (disc->flags & FLAG_EFE)
+ efe->lengthExtendedAttr = lengthExtendedAttr;
+ else
+ fe->lengthExtendedAttr = lengthExtendedAttr;
+ }
+ else
+ {
+ desc->length += length;
+ desc->data->length += length;
+ desc->data->buffer = realloc(desc->data->buffer, desc->data->length);
+
+ UPDATE_PTR;
+
+ if (le32_to_cpu(ea_hdr->appAttrLocation) == 0xFFFFFFFF)
+ ea_hdr->appAttrLocation = lengthExtendedAttr;
+
+ memcpy(&extendedAttr[le32_to_cpu(lengthExtendedAttr)], ea, length);
+ lengthExtendedAttr = cpu_to_le32(le32_to_cpu(lengthExtendedAttr) + length);
+ if (disc->flags & FLAG_EFE)
+ efe->lengthExtendedAttr = lengthExtendedAttr;
+ else
+ fe->lengthExtendedAttr = lengthExtendedAttr;
+ }
+
+ /* UDF-1.50: 3.3.4.1 Extended Attribute Header Descriptor
+ * If the attributes associated with the location fields highlighted above do not exist,
+ * then the value of the location field shall point to the byte after the extended
+ * attribute space. */
+ if (disc->udf_rev < 0x0200)
+ {
+ if (le32_to_cpu(lengthExtendedAttr) && le32_to_cpu(ea_hdr->impAttrLocation) == 0xFFFFFFFF)
+ ea_hdr->impAttrLocation = lengthExtendedAttr;
+ if (le32_to_cpu(lengthExtendedAttr) && le32_to_cpu(ea_hdr->appAttrLocation) == 0xFFFFFFFF)
+ ea_hdr->appAttrLocation = lengthExtendedAttr;
+ }
+
+ ea_hdr->descTag = udf_query_tag(disc, TAG_IDENT_EAHD, 1, desc->offset, desc->data, (disc->flags & FLAG_EFE) ? sizeof(*efe) : sizeof(*fe), sizeof(*ea_hdr));
+
+#undef UPDATE_PTR
+}
+
/**
* @brief create a file tag:FE/EFE udf_descriptor and add the file to a directory
* @param disc the udf_disc
@@ -722,6 +889,7 @@ static inline unsigned long udf_find_next_one_bit (void * addr, unsigned long si
tmp = leBPL_to_cpup(&tmp);
found_first:
tmp &= ~0UL >> (BITS_PER_LONG-size);
+ tmp |= (1UL << size);
found_middle:
return result + ffz(~tmp);
}
@@ -791,18 +959,18 @@ int udf_alloc_bitmap_blocks(struct udf_disc *disc, struct udf_desc *bitmap, uint
do
{
start = ((start + alignment - 1) / alignment) * alignment;
- if (start + blocks >= sbd->numOfBits)
+ if (start + blocks > le32_to_cpu(sbd->numOfBits))
{
fprintf(stderr, "%s: Error: Not enough blocks on device\n", appname);
exit(1);
}
if (sbd->bitmap[start/8] & (1 << (start%8)))
{
- end = udf_find_next_zero_bit(sbd->bitmap, sbd->numOfBits, start);
+ end = udf_find_next_zero_bit(sbd->bitmap, le32_to_cpu(sbd->numOfBits), start);
}
else
- start = end = udf_find_next_one_bit(sbd->bitmap, sbd->numOfBits, start);
- } while ((end - start) <= blocks);
+ start = end = udf_find_next_one_bit(sbd->bitmap, le32_to_cpu(sbd->numOfBits), start);
+ } while ((end - start) < blocks);
clear_bits(sbd->bitmap, start, blocks);
return start;
@@ -825,7 +993,7 @@ int udf_alloc_table_blocks(struct udf_disc *disc, struct udf_desc *table, uint32
do
{
- if (offset >= use->lengthAllocDescs)
+ if (offset >= le32_to_cpu(use->lengthAllocDescs))
{
fprintf(stderr, "%s: Error: Not enough blocks on device\n", appname);
exit(1);
@@ -869,7 +1037,7 @@ int udf_alloc_table_blocks(struct udf_disc *disc, struct udf_desc *table, uint32
sad->extLength = cpu_to_le32(EXT_NOT_RECORDED_ALLOCATED | (end - start - blocks) * disc->blocksize);
use->lengthAllocDescs = cpu_to_le32(le32_to_cpu(use->lengthAllocDescs) + sizeof(short_ad));
}
- use->descTag = udf_query_tag(disc, TAG_IDENT_USE, 1, table->offset, table->data, sizeof(struct unallocSpaceEntry) + le32_to_cpu(use->lengthAllocDescs));
+ use->descTag = udf_query_tag(disc, TAG_IDENT_USE, 1, table->offset, table->data, 0, sizeof(struct unallocSpaceEntry) + le32_to_cpu(use->lengthAllocDescs));
return start;
}
@@ -923,7 +1091,7 @@ int udf_alloc_blocks(struct udf_disc *disc, struct udf_extent *pspace, uint32_t
exit(1);
}
for (i = 0; i < blocks; ++i)
- disc->vat[disc->vat_entries++] = start+i;
+ disc->vat[disc->vat_entries++] = cpu_to_le32(start+i);
return start;
}
else
diff --git a/mkudffs/file.h b/mkudffs/file.h
index d9b4efe..bae6f7b 100644
--- a/mkudffs/file.h
+++ b/mkudffs/file.h
@@ -1,8 +1,8 @@
/*
* libudffs.h
*
- * Copyright (c) 2001-2002 Ben Fennema <bfennema@falcon.csc.calpoly.edu>
- * Copyright (c) 2016-2017 Pali Rohár <pali.rohar@gmail.com>
+ * Copyright (c) 2001-2002 Ben Fennema
+ * Copyright (c) 2016-2018 Pali Rohár <pali.rohar@gmail.com>
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
@@ -27,11 +27,12 @@
#include "libudffs.h"
tag query_tag(struct udf_disc *, struct udf_extent *, struct udf_desc *, uint16_t);
-extern tag udf_query_tag(struct udf_disc *, uint16_t, uint16_t, uint32_t, struct udf_data *, uint16_t);
+extern tag udf_query_tag(struct udf_disc *, uint16_t, uint16_t, uint32_t, struct udf_data *, uint32_t, uint32_t);
extern struct udf_desc *udf_create(struct udf_disc *, struct udf_extent *, const dchars *, uint8_t, uint32_t, struct udf_desc *, uint8_t, uint8_t, uint16_t);
extern struct udf_desc *udf_mkdir(struct udf_disc *, struct udf_extent *, const dchars *, uint8_t, uint32_t, struct udf_desc *);
extern void insert_data(struct udf_disc *disc, struct udf_extent *pspace, struct udf_desc *desc, struct udf_data *data);
extern void insert_fid(struct udf_disc *, struct udf_extent *, struct udf_desc *, struct udf_desc *, const dchars *, uint8_t, uint8_t);
+extern void insert_ea(struct udf_disc *disc, struct udf_desc *desc, struct genericFormat *ea, uint32_t length);
extern int udf_alloc_blocks(struct udf_disc *, struct udf_extent *, uint32_t, uint32_t);
static inline void clear_bits(uint8_t *bitmap, uint32_t offset, uint64_t length)
diff --git a/mkudffs/main.c b/mkudffs/main.c
index 066afac..0932013 100644
--- a/mkudffs/main.c
+++ b/mkudffs/main.c
@@ -1,8 +1,8 @@
/*
* main.c
*
- * Copyright (c) 2001-2002 Ben Fennema <bfennema@falcon.csc.calpoly.edu>
- * Copyright (c) 2014-2017 Pali Rohár <pali.rohar@gmail.com>
+ * Copyright (c) 2001-2002 Ben Fennema
+ * Copyright (c) 2014-2018 Pali Rohár <pali.rohar@gmail.com>
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
@@ -30,19 +30,19 @@
#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
#include <locale.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
-#include <time.h>
-#include <sys/time.h>
#include <errno.h>
#include <limits.h>
#include <dirent.h>
#include <sys/ioctl.h>
#include <linux/fs.h>
#include <linux/fd.h>
+#include <sys/sysmacros.h>
#include "mkudffs.h"
#include "defaults.h"
@@ -474,6 +474,9 @@ int main(int argc, char *argv[])
dump_space(&disc);
+ if (disc.blocks <= 257)
+ fprintf(stderr, "%s: Warning: UDF filesystem has less than 258 blocks, it can cause problems\n", appname);
+
if (len == (size_t)-1)
fprintf(stderr, "%s: Warning: Volume Set Identifier must be at least 8 characters long\n", appname);
else if (len < 16)
diff --git a/mkudffs/mkudffs.c b/mkudffs/mkudffs.c
index 9ad3500..59b529c 100644
--- a/mkudffs/mkudffs.c
+++ b/mkudffs/mkudffs.c
@@ -1,8 +1,8 @@
/*
* mkudffs.c
*
- * Copyright (c) 2001-2002 Ben Fennema <bfennema@falcon.csc.calpoly.edu>
- * Copyright (c) 2014-2017 Pali Rohár <pali.rohar@gmail.com>
+ * Copyright (c) 2001-2002 Ben Fennema
+ * Copyright (c) 2014-2018 Pali Rohár <pali.rohar@gmail.com>
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
@@ -30,6 +30,7 @@
#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
@@ -50,9 +51,8 @@ void udf_init_disc(struct udf_disc *disc)
struct timeval tv;
struct tm *tm;
int altzone;
- unsigned long int rnd;
-
- srand(time(NULL));
+ uint32_t uuid_time;
+ char uuid[17];
memset(disc, 0x00, sizeof(*disc));
@@ -62,31 +62,50 @@ void udf_init_disc(struct udf_disc *disc)
disc->blkssz = 512;
disc->mode = 0755;
- gettimeofday(&tv, NULL);
- tm = localtime(&tv.tv_sec);
- altzone = timezone - 3600;
- if (daylight)
- ts.typeAndTimezone = cpu_to_le16(((-altzone/60) & 0x0FFF) | 0x1000);
+ if (gettimeofday(&tv, NULL) != 0 || tv.tv_sec == (time_t)-1 || (tm = localtime(&tv.tv_sec)) == NULL || tm->tm_year < 1-1900 || tm->tm_year > 9999-1900)
+ {
+ /* fallback to 1.1.1980 00:00:00 */
+ ts.typeAndTimezone = cpu_to_le16(0x1000);
+ ts.year = cpu_to_le16(1980);
+ ts.month = 1;
+ ts.day = 1;
+ ts.hour = 0;
+ ts.minute = 0;
+ ts.second = 0;
+ ts.centiseconds = 0;
+ ts.hundredsOfMicroseconds = 0;
+ ts.microseconds = 0;
+ /* and for uuid use random bytes */
+ uuid_time = randu32();
+ }
else
- ts.typeAndTimezone = cpu_to_le16(((-timezone/60) & 0x0FFF) | 0x1000);
- ts.year = cpu_to_le16(1900 + tm->tm_year);
- ts.month = 1 + tm->tm_mon;
- ts.day = tm->tm_mday;
- ts.hour = tm->tm_hour;
- ts.minute = tm->tm_min;
- ts.second = tm->tm_sec;
- ts.centiseconds = tv.tv_usec / 10000;
- ts.hundredsOfMicroseconds = (tv.tv_usec - ts.centiseconds * 10000) / 100;
- ts.microseconds = tv.tv_usec - ts.centiseconds * 10000 - ts.hundredsOfMicroseconds * 100;
-
- get_random_bytes(&rnd, sizeof(rnd));
+ {
+ altzone = timezone - 3600;
+ if (daylight)
+ ts.typeAndTimezone = cpu_to_le16(((-altzone/60) & 0x0FFF) | 0x1000);
+ else
+ ts.typeAndTimezone = cpu_to_le16(((-timezone/60) & 0x0FFF) | 0x1000);
+ ts.year = cpu_to_le16(1900 + tm->tm_year);
+ ts.month = 1 + tm->tm_mon;
+ ts.day = tm->tm_mday;
+ ts.hour = tm->tm_hour;
+ ts.minute = tm->tm_min;
+ ts.second = tm->tm_sec;
+ ts.centiseconds = tv.tv_usec / 10000;
+ ts.hundredsOfMicroseconds = (tv.tv_usec - ts.centiseconds * 10000) / 100;
+ ts.microseconds = tv.tv_usec - ts.centiseconds * 10000 - ts.hundredsOfMicroseconds * 100;
+ if (tv.tv_sec < 0)
+ uuid_time = randu32();
+ else
+ uuid_time = tv.tv_sec & 0xFFFFFFFF;
+ }
/* Allocate/Initialize Descriptors */
disc->udf_pvd[0] = malloc(sizeof(struct primaryVolDesc));
memcpy(disc->udf_pvd[0], &default_pvd, sizeof(struct primaryVolDesc));
memcpy(&disc->udf_pvd[0]->recordingDateAndTime, &ts, sizeof(timestamp));
- sprintf((char *)&disc->udf_pvd[0]->volSetIdent[1], "%08lx%08lx%s",
- ((unsigned long int)mktime(tm))%0xFFFFFFFF, rnd%0xFFFFFFFF, &disc->udf_pvd[0]->volSetIdent[17]);
+ snprintf(uuid, sizeof(uuid), "%08lx%08lx", (unsigned long int)uuid_time, (unsigned long int)randu32());
+ memcpy(&disc->udf_pvd[0]->volSetIdent[1], uuid, 16);
disc->udf_pvd[0]->volIdent[31] = strlen((char *)disc->udf_pvd[0]->volIdent);
disc->udf_pvd[0]->volSetIdent[127] = strlen((char *)disc->udf_pvd[0]->volSetIdent);
@@ -142,14 +161,16 @@ void udf_init_disc(struct udf_disc *disc)
disc->head->tail = NULL;
}
-int udf_set_version(struct udf_disc *disc, int udf_rev)
+int udf_set_version(struct udf_disc *disc, uint16_t udf_rev)
{
struct logicalVolIntegrityDescImpUse *lvidiu;
uint16_t udf_rev_le16;
if (disc->udf_rev == udf_rev)
return 0;
- else if (udf_rev != 0x0102 &&
+ else if (
+ udf_rev != 0x0101 &&
+ udf_rev != 0x0102 &&
udf_rev != 0x0150 &&
udf_rev != 0x0200 &&
udf_rev != 0x0201 &&
@@ -172,7 +193,7 @@ int udf_set_version(struct udf_disc *disc, int udf_rev)
disc->flags &= ~FLAG_EFE;
strcpy((char *)disc->udf_pd[0]->partitionContents.ident, PD_PARTITION_CONTENTS_NSR02);
}
- else // 0x0102
+ else // 0x0102 and older
{
disc->flags &= ~FLAG_VAT;
disc->flags &= ~FLAG_EFE;
@@ -185,33 +206,24 @@ int udf_set_version(struct udf_disc *disc, int udf_rev)
memcpy(disc->udf_iuvd[0]->impIdent.identSuffix, &udf_rev_le16, sizeof(udf_rev_le16));
memcpy(disc->udf_stable[0]->sparingIdent.identSuffix, &udf_rev_le16, sizeof(udf_rev_le16));
lvidiu = query_lvidiu(disc);
- if (udf_rev == 0x0260)
- lvidiu->minUDFReadRev = cpu_to_le16(0x0250);
+ if (udf_rev < 0x0102)
+ {
+ /* The ImplementationUse area for the Logical Volume Integrity Descriptor
+ * prior to UDF 1.02 does not define UDF revisions, so clear these fields */
+ lvidiu->minUDFReadRev = cpu_to_le16(0);
+ lvidiu->minUDFWriteRev = cpu_to_le16(0);
+ lvidiu->maxUDFWriteRev = cpu_to_le16(0);
+ }
else
- lvidiu->minUDFReadRev = cpu_to_le16(udf_rev);
- lvidiu->minUDFWriteRev = cpu_to_le16(udf_rev);
- lvidiu->maxUDFWriteRev = cpu_to_le16(udf_rev);
- return 0;
-}
-
-void get_random_bytes(void *buffer, size_t count)
-{
- int fd;
- size_t i;
-
- fd = open("/dev/urandom", O_RDONLY);
- if (fd >= 0)
{
- if (read(fd, buffer, count) == (ssize_t)count)
- {
- close(fd);
- return;
- }
- close(fd);
+ if (udf_rev == 0x0260)
+ lvidiu->minUDFReadRev = cpu_to_le16(0x0250);
+ else
+ lvidiu->minUDFReadRev = cpu_to_le16(udf_rev);
+ lvidiu->minUDFWriteRev = cpu_to_le16(udf_rev);
+ lvidiu->maxUDFWriteRev = cpu_to_le16(udf_rev);
}
-
- for (i = 0; i < count; ++i)
- ((uint8_t *)buffer)[i] = rand() % 0xFF;
+ return 0;
}
void split_space(struct udf_disc *disc)
@@ -276,9 +288,12 @@ void split_space(struct udf_disc *disc)
}
accessType = le32_to_cpu(disc->udf_pd[0]->accessType);
- if ((accessType == PD_ACCESS_TYPE_OVERWRITABLE || accessType == PD_ACCESS_TYPE_REWRITABLE) && sizes[LVID_SIZE] * (size_t)disc->blocksize < 8192)
+ if ((accessType == PD_ACCESS_TYPE_OVERWRITABLE || accessType == PD_ACCESS_TYPE_REWRITABLE) && (uint64_t)sizes[LVID_SIZE] * disc->blocksize < 8192 && blocks > 257)
sizes[LVID_SIZE] = (8192 + disc->blocksize-1) / disc->blocksize;
+ if (sizes[VDS_SIZE] > 6 && blocks <= 257)
+ sizes[VDS_SIZE] = 6;
+
if (!(disc->flags & FLAG_VAT) && blocks < 770)
start = 0;
else
@@ -301,7 +316,7 @@ void split_space(struct udf_disc *disc)
}
set_extent(disc, RVDS, start, sizes[VDS_SIZE]);
}
- else
+ else if (blocks > 257)
{
if (blocks >= 3072)
start = find_next_extent_size(disc, (blocks-257+97)/32*32, USPACE, sizes[VDS_SIZE], offsets[VDS_SIZE]);
@@ -502,7 +517,7 @@ static void fill_mbr(struct udf_disc *disc, struct mbr *mbr, uint32_t start)
}
if (!mbr->disk_signature)
- get_random_bytes(&mbr->disk_signature, sizeof(mbr->disk_signature));
+ mbr->disk_signature = le32_to_cpu(randu32());
lba_blocks = ((uint64_t)disc->blocks * disc->blocksize + disc->blkssz - 1) / disc->blkssz;
@@ -608,13 +623,21 @@ void setup_anchor(struct udf_disc *disc)
mlen = ext->blocks * disc->blocksize;
ext = next_extent(disc->head, RVDS);
- if (!ext)
+ if (!ext && disc->blocks > 257)
{
fprintf(stderr, "%s: Error: Not enough blocks on device\n", appname);
exit(1);
}
- rloc = ext->start;
- rlen = ext->blocks * disc->blocksize;
+ if (disc->blocks > 257)
+ {
+ rloc = ext->start;
+ rlen = ext->blocks * disc->blocksize;
+ }
+ else
+ {
+ rloc = mloc;
+ rlen = mlen;
+ }
ext = next_extent(disc->head, ANCHOR);
if (!ext)
@@ -720,7 +743,7 @@ int setup_space(struct udf_disc *disc, struct udf_extent *pspace, uint32_t offse
if (pspace->blocks%8)
sbd->bitmap[nBytes-1] = 0xFF >> (8-(pspace->blocks%8));
clear_bits(sbd->bitmap, offset, (length + disc->blocksize - 1) / disc->blocksize);
- sbd->descTag = udf_query_tag(disc, TAG_IDENT_SBD, 1, desc->offset, desc->data, sizeof(struct spaceBitmapDesc));
+ sbd->descTag = udf_query_tag(disc, TAG_IDENT_SBD, 1, desc->offset, desc->data, 0, sizeof(struct spaceBitmapDesc));
}
else if (disc->flags & FLAG_SPACE_TABLE)
{
@@ -776,7 +799,7 @@ int setup_space(struct udf_disc *disc, struct udf_extent *pspace, uint32_t offse
use->icbTag.parentICBLocation.partitionReferenceNum = cpu_to_le16(0);
use->icbTag.fileType = ICBTAG_FILE_TYPE_USE;
use->icbTag.flags = cpu_to_le16(ICBTAG_FLAG_AD_SHORT);
- use->descTag = udf_query_tag(disc, TAG_IDENT_USE, 1, desc->offset, desc->data, sizeof(struct unallocSpaceEntry) + le32_to_cpu(use->lengthAllocDescs));
+ use->descTag = udf_query_tag(disc, TAG_IDENT_USE, 1, desc->offset, desc->data, 0, sizeof(struct unallocSpaceEntry) + le32_to_cpu(use->lengthAllocDescs));
if (disc->flags & FLAG_STRATEGY4096)
{
@@ -971,7 +994,7 @@ void setup_vds(struct udf_disc *disc)
stable[0] = next_extent(disc->head, STABLE);
sspace = next_extent(disc->head, SSPACE);
- if (!mvds || !rvds || !lvid)
+ if (!mvds || (!rvds && disc->blocks > 257) || !lvid)
{
fprintf(stderr, "%s: Error: Not enough blocks on device\n", appname);
exit(1);
@@ -993,8 +1016,7 @@ void setup_vds(struct udf_disc *disc)
setup_pd(disc, mvds, rvds, 2);
setup_usd(disc, mvds, rvds, 3);
setup_iuvd(disc, mvds, rvds, 4);
- if (mvds->blocks > 5)
- setup_td(disc, mvds, rvds, 5);
+ setup_td(disc, mvds, rvds, 5);
}
void setup_pvd(struct udf_disc *disc, struct udf_extent *mvds, struct udf_extent *rvds, uint32_t offset)
@@ -1007,6 +1029,8 @@ void setup_pvd(struct udf_disc *disc, struct udf_extent *mvds, struct udf_extent
desc->data->buffer = disc->udf_pvd[0];
disc->udf_pvd[0]->descTag = query_tag(disc, mvds, desc, 1);
+ if (!rvds)
+ return;
desc = set_desc(rvds, TAG_IDENT_PVD, offset, length, NULL);
memcpy(disc->udf_pvd[1] = desc->data->buffer, disc->udf_pvd[0], length);
disc->udf_pvd[1]->descTag = query_tag(disc, rvds, desc, 1);
@@ -1026,6 +1050,8 @@ void setup_lvd(struct udf_disc *disc, struct udf_extent *mvds, struct udf_extent
desc->data->buffer = disc->udf_lvd[0];
disc->udf_lvd[0]->descTag = query_tag(disc, mvds, desc, 1);
+ if (!rvds)
+ return;
desc = set_desc(rvds, TAG_IDENT_LVD, offset, length, NULL);
memcpy(disc->udf_lvd[1] = desc->data->buffer, disc->udf_lvd[0], length);
disc->udf_lvd[1]->descTag = query_tag(disc, rvds, desc, 1);
@@ -1057,6 +1083,8 @@ void setup_pd(struct udf_disc *disc, struct udf_extent *mvds, struct udf_extent
desc->data->buffer = disc->udf_pd[0];
disc->udf_pd[0]->descTag = query_tag(disc, mvds, desc, 1);
+ if (!rvds)
+ return;
desc = set_desc(rvds, TAG_IDENT_PD, offset, length, NULL);
memcpy(disc->udf_pd[1] = desc->data->buffer, disc->udf_pd[0], length);
disc->udf_pd[1]->descTag = query_tag(disc, rvds, desc, 1);
@@ -1086,6 +1114,8 @@ void setup_usd(struct udf_disc *disc, struct udf_extent *mvds, struct udf_extent
desc->data->buffer = disc->udf_usd[0];
disc->udf_usd[0]->descTag = query_tag(disc, mvds, desc, 1);
+ if (!rvds)
+ return;
desc = set_desc(rvds, TAG_IDENT_USD, offset, length, NULL);
memcpy(disc->udf_usd[1] = desc->data->buffer, disc->udf_usd[0], length);
disc->udf_usd[1]->descTag = query_tag(disc, rvds, desc, 1);
@@ -1103,6 +1133,8 @@ void setup_iuvd(struct udf_disc *disc, struct udf_extent *mvds, struct udf_exten
desc->data->buffer = disc->udf_iuvd[0];
disc->udf_iuvd[0]->descTag = query_tag(disc, mvds, desc, 1);
+ if (!rvds)
+ return;
desc = set_desc(rvds, TAG_IDENT_IUVD, offset, length, NULL);
memcpy(disc->udf_iuvd[1] = desc->data->buffer, disc->udf_iuvd[0], length);
disc->udf_iuvd[1]->descTag = query_tag(disc, rvds, desc, 1);
@@ -1118,6 +1150,8 @@ void setup_td(struct udf_disc *disc, struct udf_extent *mvds, struct udf_extent
desc->data->buffer = disc->udf_td[0];
disc->udf_td[0]->descTag = query_tag(disc, mvds, desc, 1);
+ if (!rvds)
+ return;
desc = set_desc(rvds, TAG_IDENT_TD, offset, length, NULL);
memcpy(disc->udf_td[1] = desc->data->buffer, disc->udf_td[0], length);
disc->udf_td[1]->descTag = query_tag(disc, rvds, desc, 1);
@@ -1211,21 +1245,32 @@ void setup_stable(struct udf_disc *disc, struct udf_extent *stable[4], struct ud
void setup_vat(struct udf_disc *disc, struct udf_extent *pspace)
{
- uint32_t offset = 0;
+ uint32_t offset;
struct udf_extent *anchor;
struct udf_desc *vtable;
struct udf_data *data;
- uint32_t len;
+ uint32_t len, i;
struct virtualAllocationTable15 *vat15;
struct virtualAllocationTable20 *vat20;
+ struct impUseExtAttr *ea_attr;
+ struct LVExtensionEA *ea_lv;
+ uint8_t buffer[(sizeof(*ea_attr)+sizeof(*ea_lv)+3)/4*4];
+ uint16_t checksum;
uint16_t udf_rev_le16;
+ uint32_t min_blocks;
+ uint32_t align;
+
+ /* Put VAT to the last sector correctly aligned */
+ align = disc->sizing[PSPACE_SIZE].align;
+ offset = pspace->tail->offset + (pspace->tail->length + disc->blocksize-1) / disc->blocksize;
+ offset = (offset + align) / align * align - 1;
if (disc->flags & FLAG_MIN_300_BLOCKS)
{
- // On optical discs one track has minimal size of 300 sectors, so put VAT to the last sector
- offset = pspace->tail->offset + (pspace->tail->length + disc->blocksize-1) / disc->blocksize;
- if (pspace->start + offset < 299)
- offset = 299 - pspace->start;
+ // On optical TAO discs one track has minimal size of 300 sectors
+ min_blocks = (300 + align) / align * align - 1;
+ if (pspace->start + offset < min_blocks)
+ offset = min_blocks - pspace->start;
}
if (disc->flags & FLAG_CLOSED)
@@ -1260,12 +1305,41 @@ void setup_vat(struct udf_disc *disc, struct udf_extent *pspace)
{
vtable = udf_create(disc, pspace, (const dchars *)"\x08" UDF_ID_ALLOC, strlen(UDF_ID_ALLOC)+1, offset, NULL, FID_FILE_CHAR_HIDDEN, ICBTAG_FILE_TYPE_UNDEF, 0);
disc->vat_entries--; // Remove VAT file itself from VAT table
+ udf_rev_le16 = cpu_to_le16(disc->udf_rev);
+ memset(&buffer, 0, sizeof(buffer));
+ ea_attr = (struct impUseExtAttr *)buffer;
+ ea_attr->attrType = cpu_to_le32(EXTATTR_IMP_USE);
+ ea_attr->attrSubtype = EXTATTR_SUBTYPE;
+ ea_attr->attrLength = cpu_to_le32(sizeof(buffer));
+ ea_attr->impUseLength = cpu_to_le32(sizeof(*ea_lv));
+ ea_attr->impIdent.identSuffix[2] = UDF_OS_CLASS_UNIX;
+ ea_attr->impIdent.identSuffix[3] = UDF_OS_ID_LINUX;
+ memcpy(ea_attr->impIdent.identSuffix, &udf_rev_le16, sizeof(udf_rev_le16));
+ strcpy((char *)ea_attr->impIdent.ident, UDF_ID_VAT_LVEXTENSION);
+ ea_lv = (struct LVExtensionEA *)&ea_attr->impUse[0];
+ checksum = 0;
+ for (i = 0; i < sizeof(*ea_attr); ++i)
+ checksum += ((uint8_t *)ea_attr)[i];
+ ea_lv->headerChecksum = cpu_to_le16(checksum);
+ if (disc->flags & FLAG_EFE)
+ {
+ struct extendedFileEntry *efe = (struct extendedFileEntry *)vtable->data->buffer;
+ ea_lv->verificationID = efe->uniqueID;
+ }
+ else
+ {
+ struct fileEntry *fe = (struct fileEntry *)vtable->data->buffer;
+ ea_lv->verificationID = fe->uniqueID;
+ }
+ ea_lv->numFiles = query_lvidiu(disc)->numFiles;
+ ea_lv->numDirs = query_lvidiu(disc)->numDirs;
+ memcpy(ea_lv->logicalVolIdent, disc->udf_lvd[0]->logicalVolIdent, 128);
+ insert_ea(disc, vtable, (struct genericFormat *)buffer, sizeof(buffer));
len = sizeof(struct virtualAllocationTable15);
data = alloc_data(disc->vat, disc->vat_entries * sizeof(uint32_t));
insert_data(disc, pspace, vtable, data);
data = alloc_data(&default_vat15, len);
vat15 = data->buffer;
- udf_rev_le16 = cpu_to_le16(disc->udf_rev);
memcpy(vat15->vatIdent.identSuffix, &udf_rev_le16, sizeof(udf_rev_le16));
insert_data(disc, pspace, vtable, data);
}
diff --git a/mkudffs/mkudffs.h b/mkudffs/mkudffs.h
index 510c8e0..b9adad3 100644
--- a/mkudffs/mkudffs.h
+++ b/mkudffs/mkudffs.h
@@ -1,8 +1,8 @@
/*
* mkudffs.h
*
- * Copyright (c) 2001-2002 Ben Fennema <bfennema@falcon.csc.calpoly.edu>
- * Copyright (c) 2016-2017 Pali Rohár <pali.rohar@gmail.com>
+ * Copyright (c) 2001-2002 Ben Fennema
+ * Copyright (c) 2016-2018 Pali Rohár <pali.rohar@gmail.com>
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
@@ -26,7 +26,6 @@
#include "ecma_167.h"
#include "osta_udf.h"
-#include "udf_endian.h"
#include "libudffs.h"
#define CS0 0x00000001
@@ -62,8 +61,7 @@ enum media_type {
extern char *udf_space_type_str[UDF_SPACE_TYPE_SIZE];
void udf_init_disc(struct udf_disc *);
-int udf_set_version(struct udf_disc *, int);
-void get_random_bytes(void *, size_t);
+int udf_set_version(struct udf_disc *, uint16_t);
void split_space(struct udf_disc *);
void dump_space(struct udf_disc *);
int write_disc(struct udf_disc *);
diff --git a/mkudffs/options.c b/mkudffs/options.c
index 67a71db..75be672 100644
--- a/mkudffs/options.c
+++ b/mkudffs/options.c
@@ -1,8 +1,8 @@
/*
* options.c
*
- * Copyright (c) 2001-2002 Ben Fennema <bfennema@falcon.csc.calpoly.edu>
- * Copyright (c) 2014-2017 Pali Rohár <pali.rohar@gmail.com>
+ * Copyright (c) 2001-2002 Ben Fennema
+ * Copyright (c) 2014-2018 Pali Rohár <pali.rohar@gmail.com>
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
@@ -30,6 +30,7 @@
#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
#include <getopt.h>
#include <ctype.h>
#include <errno.h>
@@ -85,7 +86,7 @@ void usage(void)
"\t--uuid=, -u UDF uuid, first 16 characters of Volume set identifier (default: random)\n"
"\t--blocksize=, -b Size of blocks in bytes (512, 1024, 2048, 4096, 8192, 16384, 32768; default: detect)\n"
"\t--media-type=, -m Media type (hd, dvd, dvdram, dvdrw, dvdr, worm, mo, cdrw, cdr, cd, bdr; default: hd)\n"
- "\t--udfrev=, -r UDF revision (1.02, 1.50, 2.00, 2.01, 2.50, 2.60; default: 2.01)\n"
+ "\t--udfrev=, -r UDF revision (1.01, 1.02, 1.50, 2.00, 2.01, 2.50, 2.60; default: 2.01)\n"
"\t--no-write, -n Not really, do not write to device, just simulate\n"
"\t--new-file Create new image file, fail if already exists\n"
"\t--lvid= Logical Volume Identifier (default: LinuxUDF)\n"
@@ -100,7 +101,7 @@ void usage(void)
"\t--strategy= Allocation strategy to use (4, 4096; default: based on media type)\n"
"\t--spartable Use Sparing Table (default: based on media type) and set its count (1 - 4; default: 2)\n"
"\t--sparspace= Number of entries in Sparing Table (default: 1024, but based on media type)\n"
- "\t--packetlen= Packet length in number of blocks for Sparing Table (default: based on media type)\n"
+ "\t--packetlen= Packet length in number of blocks used for alignment (default: based on media type)\n"
"\t--vat Use Virtual Allocation Table (default: based on media type)\n"
"\t--closed Close disc with Virtual Allocation Table (default: do not close)\n"
"\t--space= Space (freedbitmap, freedtable, unallocbitmap, unalloctable; default: unallocbitmap)\n"
@@ -114,26 +115,16 @@ void usage(void)
exit(1);
}
-static unsigned long int strtoul_safe(const char *str, int base, int *failed)
-{
- char *endptr = NULL;
- unsigned long int ret;
- errno = 0;
- ret = strtoul(str, &endptr, base);
- *failed = (!*str || *endptr || errno) ? 1 : 0;
- return ret;
-}
-
void parse_args(int argc, char *argv[], struct udf_disc *disc, char **device, int *create_new_file, int *blocksize, int *media_ptr)
{
int retval;
int i;
int media = MEDIA_TYPE_NONE;
- uint16_t packetlen = 0;
- unsigned long int blocks = 0;
- int rev = 0;
int use_sparable = 0;
- unsigned long int sparspace = 0;
+ uint16_t rev = 0;
+ uint32_t spartable = 2;
+ uint32_t sparspace = 0;
+ uint16_t packetlen = 0;
int failed;
while ((retval = getopt_long(argc, argv, "l:u:b:m:r:nh", long_options, NULL)) != EOF)
@@ -146,7 +137,7 @@ void parse_args(int argc, char *argv[], struct udf_disc *disc, char **device, in
break;
case OPT_BLK_SIZE:
case 'b':
- disc->blocksize = strtoul_safe(optarg, 0, &failed);
+ disc->blocksize = strtou32(optarg, 0, &failed);
if (failed || disc->blocksize < 512 || disc->blocksize > 32768 || (disc->blocksize & (disc->blocksize - 1)))
{
fprintf(stderr, "%s: Error: Invalid value for option --blocksize\n", appname);
@@ -161,16 +152,14 @@ void parse_args(int argc, char *argv[], struct udf_disc *disc, char **device, in
unsigned char maj = 0;
unsigned char min = 0;
int len = 0;
- if (sscanf(optarg, "%hhx.%hhx%n", &maj, &min, &len) >= 2 && !optarg[len])
+ if (sscanf(optarg, "%*[0-9].%*[0-9]%n", &len) >= 0 && !optarg[len] && sscanf(optarg, "%hhx.%hhx%n", &maj, &min, &len) >= 2 && !optarg[len])
{
rev = (maj << 8) | min;
}
else
{
- unsigned long int rev_opt = strtoul_safe(optarg, 16, &failed);
- if (!failed && rev_opt < INT_MAX)
- rev = rev_opt;
- else
+ rev = strtou16(optarg, 16, &failed);
+ if (failed)
rev = 0;
}
if (!rev || udf_set_version(disc, rev))
@@ -418,40 +407,42 @@ void parse_args(int argc, char *argv[], struct udf_disc *disc, char **device, in
}
case OPT_UID:
{
- unsigned long int uid = strtoul_safe(optarg, 0, &failed);
if (strcmp(optarg, "-1") == 0)
{
- uid = UINT32_MAX;
- failed = 0;
+ disc->uid = UINT32_MAX;
}
- if (failed || uid > UINT32_MAX)
+ else
{
- fprintf(stderr, "%s: Error: Invalid value for option --uid\n", appname);
- exit(1);
+ disc->uid = strtou32(optarg, 0, &failed);
+ if (failed)
+ {
+ fprintf(stderr, "%s: Error: Invalid value for option --uid\n", appname);
+ exit(1);
+ }
}
- disc->uid = uid;
break;
}
case OPT_GID:
{
- unsigned long int gid = strtoul_safe(optarg, 0, &failed);
if (strcmp(optarg, "-1") == 0)
{
- gid = UINT32_MAX;
- failed = 0;
+ disc->gid = UINT32_MAX;
}
- if (failed || gid > UINT32_MAX)
+ else
{
- fprintf(stderr, "%s: Error: Invalid value for option --gid\n", appname);
- exit(1);
+ disc->gid = strtou32(optarg, 0, &failed);
+ if (failed)
+ {
+ fprintf(stderr, "%s: Error: Invalid value for option --gid\n", appname);
+ exit(1);
+ }
}
- disc->gid = gid;
break;
}
case OPT_MODE:
{
- unsigned long int mode = strtoul_safe(optarg, 8, &failed);
- if (failed || mode > UINT16_MAX || (mode & ~(S_IRWXU|S_IRWXG|S_IRWXO)))
+ uint16_t mode = strtou16(optarg, 8, &failed);
+ if (failed || (mode & ~(S_IRWXU|S_IRWXG|S_IRWXO)))
{
fprintf(stderr, "%s: Error: Invalid value for option --mode\n", appname);
exit(1);
@@ -477,25 +468,23 @@ void parse_args(int argc, char *argv[], struct udf_disc *disc, char **device, in
}
case OPT_STRATEGY:
{
- unsigned long int strategy = strtoul_safe(optarg, 0, &failed);
- if (failed || (strategy != 4 && strategy != 4096))
+ if (strcmp(optarg, "4096") == 0)
+ disc->flags |= FLAG_STRATEGY4096;
+ else if (strcmp(optarg, "4") == 0)
+ disc->flags &= ~FLAG_STRATEGY4096;
+ else
{
fprintf(stderr, "%s: Error: Invalid value for option --strategy\n", appname);
exit(1);
}
- if (strategy == 4096)
- disc->flags |= FLAG_STRATEGY4096;
- else
- disc->flags &= ~FLAG_STRATEGY4096;
break;
}
case OPT_SPARTABLE:
{
- unsigned long int spartable = 2;
if (optarg)
{
- spartable = strtoul_safe(optarg, 0, &failed);
- if (failed || spartable > 4)
+ spartable = strtou32(optarg, 0, &failed);
+ if (failed || spartable == 0 || spartable > 4)
{
fprintf(stderr, "%s: Error: Invalid value for option --spartable\n", appname);
exit(1);
@@ -506,7 +495,6 @@ void parse_args(int argc, char *argv[], struct udf_disc *disc, char **device, in
fprintf(stderr, "%s: Error: Cannot use Sparing Table when VAT is enabled\n", appname);
exit(1);
}
- add_type2_sparable_partition(disc, 0, spartable, packetlen);
use_sparable = 1;
break;
}
@@ -517,8 +505,8 @@ void parse_args(int argc, char *argv[], struct udf_disc *disc, char **device, in
fprintf(stderr, "%s: Error: Option --spartable must be specified before option --sparspace\n", appname);
exit(1);
}
- sparspace = strtoul_safe(optarg, 0, &failed);
- if (failed || sparspace > UINT32_MAX)
+ sparspace = strtou32(optarg, 0, &failed);
+ if (failed)
{
fprintf(stderr, "%s: Error: Invalid value for option --sparspace\n", appname);
exit(1);
@@ -527,21 +515,22 @@ void parse_args(int argc, char *argv[], struct udf_disc *disc, char **device, in
}
case OPT_PACKETLEN:
{
- struct sparablePartitionMap *spm;
- unsigned long int packetlen_opt = strtoul_safe(optarg, 0, &failed);
- if (failed || packetlen_opt > UINT16_MAX)
+ packetlen = strtou16(optarg, 0, &failed);
+ if (failed || packetlen == 0)
{
fprintf(stderr, "%s: Error: Invalid value for option --packetlen\n", appname);
exit(1);
}
- packetlen = packetlen_opt;
- if ((spm = find_type2_sparable_partition(disc, 0)))
- spm->packetLength = cpu_to_le16(packetlen);
break;
}
case OPT_MEDIA_TYPE:
case 'm':
{
+ if (media != MEDIA_TYPE_NONE)
+ {
+ fprintf(stderr, "%s: Error: Option --media-type was specified more times\n", appname);
+ exit(1);
+ }
if (rev)
{
fprintf(stderr, "%s: Error: Option --media-type must be specified before option --udfrev\n", appname);
@@ -552,60 +541,59 @@ void parse_args(int argc, char *argv[], struct udf_disc *disc, char **device, in
fprintf(stderr, "%s: Error: Option --media-type must be specified before option --packetlen\n", appname);
exit(1);
}
- if (media != MEDIA_TYPE_NONE)
- {
- fprintf(stderr, "%s: Error: Option --media-type was specified more times\n", appname);
- exit(1);
- }
if (!strcmp(optarg, "hd"))
{
disc->udf_pd[0]->accessType = cpu_to_le32(PD_ACCESS_TYPE_OVERWRITABLE);
media = MEDIA_TYPE_HD;
+ packetlen = 1;
}
else if (!strcmp(optarg, "dvd"))
{
disc->udf_pd[0]->accessType = cpu_to_le32(PD_ACCESS_TYPE_READ_ONLY);
media = MEDIA_TYPE_DVD;
+ packetlen = 16;
}
else if (!strcmp(optarg, "dvdram"))
{
disc->udf_pd[0]->accessType = cpu_to_le32(PD_ACCESS_TYPE_OVERWRITABLE);
media = MEDIA_TYPE_DVDRAM;
+ packetlen = 16;
}
else if (!strcmp(optarg, "dvdrw"))
{
- struct sparablePartitionMap *spm;
disc->udf_pd[0]->accessType = cpu_to_le32(PD_ACCESS_TYPE_OVERWRITABLE);
media = MEDIA_TYPE_DVDRW;
use_sparable = 1;
packetlen = 16;
- if ((spm = find_type2_sparable_partition(disc, 0)))
- spm->packetLength = cpu_to_le16(packetlen);
}
else if (!strcmp(optarg, "dvdr"))
{
disc->udf_pd[0]->accessType = cpu_to_le32(PD_ACCESS_TYPE_WRITE_ONCE);
media = MEDIA_TYPE_DVDR;
- disc->flags |= FLAG_VAT | FLAG_MIN_300_BLOCKS;
+ disc->flags |= FLAG_VAT;
disc->flags &= ~FLAG_CLOSED;
+ packetlen = 16;
}
else if (!strcmp(optarg, "worm"))
{
disc->udf_pd[0]->accessType = cpu_to_le32(PD_ACCESS_TYPE_WRITE_ONCE);
media = MEDIA_TYPE_WORM;
disc->flags |= (FLAG_STRATEGY4096 | FLAG_BLANK_TERMINAL);
+ packetlen = 1;
}
else if (!strcmp(optarg, "mo"))
{
disc->udf_pd[0]->accessType = cpu_to_le32(PD_ACCESS_TYPE_REWRITABLE);
media = MEDIA_TYPE_MO;
disc->flags |= (FLAG_STRATEGY4096 | FLAG_BLANK_TERMINAL);
+ packetlen = 1;
}
else if (!strcmp(optarg, "cdrw"))
{
disc->udf_pd[0]->accessType = cpu_to_le32(PD_ACCESS_TYPE_REWRITABLE);
media = MEDIA_TYPE_CDRW;
use_sparable = 1;
+ packetlen = 32;
}
else if (!strcmp(optarg, "cdr"))
{
@@ -613,19 +601,22 @@ void parse_args(int argc, char *argv[], struct udf_disc *disc, char **device, in
media = MEDIA_TYPE_CDR;
disc->flags |= FLAG_VAT | FLAG_MIN_300_BLOCKS;
disc->flags &= ~FLAG_CLOSED;
+ packetlen = 32;
}
else if (!strcmp(optarg, "cd"))
{
disc->udf_pd[0]->accessType = cpu_to_le32(PD_ACCESS_TYPE_READ_ONLY);
media = MEDIA_TYPE_CD;
+ packetlen = 32;
}
else if (!strcmp(optarg, "bdr"))
{
disc->udf_pd[0]->accessType = cpu_to_le32(PD_ACCESS_TYPE_WRITE_ONCE);
media = MEDIA_TYPE_BDR;
- disc->flags |= FLAG_VAT | FLAG_MIN_300_BLOCKS;
+ disc->flags |= FLAG_VAT;
disc->flags &= ~FLAG_CLOSED;
udf_set_version(disc, 0x0250);
+ packetlen = 32;
}
else
{
@@ -685,46 +676,45 @@ void parse_args(int argc, char *argv[], struct udf_disc *disc, char **device, in
optind ++;
if (optind < argc)
{
- blocks = strtoul_safe(argv[optind++], 0, &failed);
- if (failed || blocks > UINT32_MAX)
+ disc->blocks = strtou32(argv[optind++], 0, &failed);
+ if (failed)
{
fprintf(stderr, "%s: Error: Invalid value for block-count\n", appname);
exit(1);
}
- disc->blocks = blocks;
}
if (optind < argc)
usage();
- if (packetlen && !use_sparable)
+ /* TODO: autodetection */
+ if (media == MEDIA_TYPE_NONE)
{
- fprintf(stderr, "%s: Error: Option --packetlen cannot be used without Sparing Table\n", appname);
- exit(1);
+ media = MEDIA_TYPE_HD;
+ packetlen = 1;
}
- if (le32_to_cpu(disc->udf_lvd[0]->numPartitionMaps) == 0)
+ if (disc->flags & FLAG_VAT)
{
- if (disc->flags & FLAG_VAT)
+ if (disc->udf_rev < 0x0150)
{
- if (disc->udf_rev < 0x0150)
- {
- fprintf(stderr, "%s: Error: At least UDF revision 1.50 is needed for VAT\n", appname);
- exit(1);
- }
- add_type1_partition(disc, 0);
- add_type2_virtual_partition(disc, 0);
+ fprintf(stderr, "%s: Error: At least UDF revision 1.50 is needed for VAT\n", appname);
+ exit(1);
}
- else if (use_sparable)
+ add_type1_partition(disc, 0);
+ add_type2_virtual_partition(disc, 0);
+ }
+ else if (use_sparable)
+ {
+ if (disc->udf_rev < 0x0150)
{
- if (disc->udf_rev < 0x0150)
- {
- fprintf(stderr, "%s: Error: At least UDF revision 1.50 is needed for Sparing Table\n", appname);
- exit(1);
- }
- add_type2_sparable_partition(disc, 0, 2, packetlen);
+ fprintf(stderr, "%s: Error: At least UDF revision 1.50 is needed for Sparing Table\n", appname);
+ exit(1);
}
- else
- add_type1_partition(disc, 0);
+ add_type2_sparable_partition(disc, 0, spartable, packetlen);
+ }
+ else
+ {
+ add_type1_partition(disc, 0);
}
/* TODO: UDF 2.50+ require for non-VAT disks Metadata partition which mkudffs cannot create yet */
@@ -749,12 +739,9 @@ void parse_args(int argc, char *argv[], struct udf_disc *disc, char **device, in
exit(1);
}
- /* TODO: autodetection */
- if (media == MEDIA_TYPE_NONE)
- media = MEDIA_TYPE_HD;
-
for (i=0; i<UDF_ALLOC_TYPE_SIZE; i++)
{
+ disc->sizing[i].align = packetlen;
if (disc->sizing[i].denomSize == 0)
disc->sizing[i] = default_sizing[default_media[media]][i];
}
@@ -766,11 +753,6 @@ void parse_args(int argc, char *argv[], struct udf_disc *disc, char **device, in
disc->sizing[SSPACE_SIZE].minSize = sparspace;
disc->sizing[STABLE_SIZE].minSize = 0; // recalculation is implemented in split_space()
}
- if (!packetlen)
- packetlen = le16_to_cpu(default_sparmap.packetLength);
- disc->sizing[PSPACE_SIZE].align = packetlen;
- disc->sizing[SSPACE_SIZE].align = packetlen;
- disc->sizing[STABLE_SIZE].align = packetlen;
if (disc->sizing[SSPACE_SIZE].minSize == 0)
disc->sizing[SSPACE_SIZE].minSize = 1024;
}
diff --git a/mkudffs/options.h b/mkudffs/options.h
index 883f5be..a40f1e6 100644
--- a/mkudffs/options.h
+++ b/mkudffs/options.h
@@ -1,7 +1,7 @@
/*
* options.h
*
- * Copyright (c) 2001-2002 Ben Fennema <bfennema@falcon.csc.calpoly.edu>
+ * Copyright (c) 2001-2002 Ben Fennema
* Copyright (c) 2014-2017 Pali Rohár <pali.rohar@gmail.com>
* All rights reserved.
*
diff --git a/pktsetup/Makefile.am b/pktsetup/Makefile.am
index 344dbfe..0c5fd1c 100644
--- a/pktsetup/Makefile.am
+++ b/pktsetup/Makefile.am
@@ -3,8 +3,8 @@ pktsetup_SOURCES = pktsetup.c
EXTRA_DIST = pktsetup.rules
install-data-local:
- mkdir -p "$(DESTDIR)/lib/udev/rules.d"
- $(INSTALL_DATA) "$(srcdir)/pktsetup.rules" "$(DESTDIR)/lib/udev/rules.d/80-pktsetup.rules"
+ mkdir -p "$(DESTDIR)$(UDEVDIR)/rules.d"
+ $(INSTALL_DATA) "$(srcdir)/pktsetup.rules" "$(DESTDIR)$(UDEVDIR)/rules.d/80-pktsetup.rules"
uninstall-local:
- rm -f "$(DESTDIR)/lib/udev/rules.d/80-pktsetup.rules"
+ rm -f "$(DESTDIR)$(UDEVDIR)/rules.d/80-pktsetup.rules"
diff --git a/pktsetup/Makefile.in b/pktsetup/Makefile.in
index a2fbf6d..cc0fdb7 100644
--- a/pktsetup/Makefile.in
+++ b/pktsetup/Makefile.in
@@ -227,11 +227,17 @@ 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@
+UDEVDIR = @UDEVDIR@
+UDEV_CFLAGS = @UDEV_CFLAGS@
+UDEV_LIBS = @UDEV_LIBS@
VERSION = @VERSION@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
@@ -621,11 +627,11 @@ uninstall-am: uninstall-local uninstall-sbinPROGRAMS
install-data-local:
- mkdir -p "$(DESTDIR)/lib/udev/rules.d"
- $(INSTALL_DATA) "$(srcdir)/pktsetup.rules" "$(DESTDIR)/lib/udev/rules.d/80-pktsetup.rules"
+ mkdir -p "$(DESTDIR)$(UDEVDIR)/rules.d"
+ $(INSTALL_DATA) "$(srcdir)/pktsetup.rules" "$(DESTDIR)$(UDEVDIR)/rules.d/80-pktsetup.rules"
uninstall-local:
- rm -f "$(DESTDIR)/lib/udev/rules.d/80-pktsetup.rules"
+ rm -f "$(DESTDIR)$(UDEVDIR)/rules.d/80-pktsetup.rules"
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
diff --git a/pktsetup/pktsetup.c b/pktsetup/pktsetup.c
index 8b3df51..81ed142 100644
--- a/pktsetup/pktsetup.c
+++ b/pktsetup/pktsetup.c
@@ -27,7 +27,6 @@
#include <sys/stat.h>
#include <unistd.h>
#include <getopt.h>
-#include <bits/types.h>
#include <sys/types.h>
#include <string.h>
#include <limits.h>
diff --git a/udffsck/Makefile.in b/udffsck/Makefile.in
index 60d4c26..df902f4 100644
--- a/udffsck/Makefile.in
+++ b/udffsck/Makefile.in
@@ -226,11 +226,17 @@ 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@
+UDEVDIR = @UDEVDIR@
+UDEV_CFLAGS = @UDEV_CFLAGS@
+UDEV_LIBS = @UDEV_LIBS@
VERSION = @VERSION@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
diff --git a/udffsck/main.c b/udffsck/main.c
index 28d7ca3..154d0a6 100644
--- a/udffsck/main.c
+++ b/udffsck/main.c
@@ -1,7 +1,7 @@
/*
* main.c
*
- * Copyright (c) 2001-2002 Ben Fennema <bfennema@falcon.csc.calpoly.edu>
+ * Copyright (c) 2001-2002 Ben Fennema
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
diff --git a/udfinfo/Makefile.am b/udfinfo/Makefile.am
index fd3f5bb..9d36d8c 100644
--- a/udfinfo/Makefile.am
+++ b/udfinfo/Makefile.am
@@ -1,4 +1,4 @@
bin_PROGRAMS = udfinfo
udfinfo_LDADD = $(top_builddir)/libudffs/libudffs.la
-udfinfo_SOURCES = main.c readdisc.c options.c readdisc.h options.h ../include/ecma_167.h ../include/osta_udf.h ../include/libudffs.h ../include/udf_endian.h ../include/bswap.h
+udfinfo_SOURCES = main.c readdisc.c options.c readdisc.h options.h ../include/ecma_167.h ../include/osta_udf.h ../include/libudffs.h ../include/bswap.h
AM_CPPFLAGS = -I$(top_srcdir)/include
diff --git a/udfinfo/Makefile.in b/udfinfo/Makefile.in
index dddf1a7..4b22d7d 100644
--- a/udfinfo/Makefile.in
+++ b/udfinfo/Makefile.in
@@ -228,11 +228,17 @@ 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@
+UDEVDIR = @UDEVDIR@
+UDEV_CFLAGS = @UDEV_CFLAGS@
+UDEV_LIBS = @UDEV_LIBS@
VERSION = @VERSION@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
@@ -288,7 +294,7 @@ top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
udfinfo_LDADD = $(top_builddir)/libudffs/libudffs.la
-udfinfo_SOURCES = main.c readdisc.c options.c readdisc.h options.h ../include/ecma_167.h ../include/osta_udf.h ../include/libudffs.h ../include/udf_endian.h ../include/bswap.h
+udfinfo_SOURCES = main.c readdisc.c options.c readdisc.h options.h ../include/ecma_167.h ../include/osta_udf.h ../include/libudffs.h ../include/bswap.h
AM_CPPFLAGS = -I$(top_srcdir)/include
all: all-am
diff --git a/udfinfo/main.c b/udfinfo/main.c
index da7dd1d..0c17679 100644
--- a/udfinfo/main.c
+++ b/udfinfo/main.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2017 Pali Rohár <pali.rohar@gmail.com>
+ * Copyright (C) 2017-2018 Pali Rohár <pali.rohar@gmail.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
@@ -179,8 +179,15 @@ int main(int argc, char *argv[])
appname = "udfinfo";
memset(&disc, 0, sizeof(disc));
- disc.flags = FLAG_LOCALE;
+
disc.head = calloc(1, sizeof(struct udf_extent));
+ if (!disc.head)
+ {
+ fprintf(stderr, "%s: Error: calloc failed: %s\n", appname, strerror(errno));
+ exit(1);
+ }
+
+ disc.flags = FLAG_LOCALE;
disc.tail = disc.head;
disc.head->space_type = USPACE;
diff --git a/udfinfo/options.c b/udfinfo/options.c
index fbc6a95..de93e38 100644
--- a/udfinfo/options.c
+++ b/udfinfo/options.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2017 Pali Rohár <pali.rohar@gmail.com>
+ * Copyright (C) 2017-2018 Pali Rohár <pali.rohar@gmail.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
@@ -48,19 +48,8 @@ static void usage(void)
exit(1);
}
-static unsigned long int strtoul_safe(const char *str, int base, int *failed)
-{
- char *endptr = NULL;
- unsigned long int ret;
- errno = 0;
- ret = strtoul(str, &endptr, base);
- *failed = (!*str || *endptr || errno) ? 1 : 0;
- return ret;
-}
-
void parse_args(int argc, char *argv[], struct udf_disc *disc, char **filename)
{
- unsigned long int value;
int failed;
int ret;
@@ -74,22 +63,20 @@ void parse_args(int argc, char *argv[], struct udf_disc *disc, char **filename)
break;
case OPT_BLK_SIZE:
case 'b':
- value = strtoul_safe(optarg, 0, &failed);
- if (failed || value < 512 || value > 32768 || (value & (value - 1)))
+ disc->blocksize = strtou32(optarg, 0, &failed);
+ if (failed || disc->blocksize < 512 || disc->blocksize > 32768 || (disc->blocksize & (disc->blocksize - 1)))
{
fprintf(stderr, "%s: Error: Invalid value for option --blocksize\n", appname);
exit(1);
}
- disc->blocksize = value;
break;
case OPT_VAT_BLOCK:
- value = strtoul_safe(optarg, 0, &failed);
- if (failed || value > UINT32_MAX)
+ disc->vat_block = strtou32(optarg, 0, &failed);
+ if (failed)
{
fprintf(stderr, "%s: Error: Invalid value for option --vatblock\n", appname);
exit(1);
}
- disc->vat_block = value;
break;
case OPT_UNICODE8:
disc->flags &= ~FLAG_CHARSET;
diff --git a/udfinfo/readdisc.c b/udfinfo/readdisc.c
index 076723d..a82f383 100644
--- a/udfinfo/readdisc.c
+++ b/udfinfo/readdisc.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2017 Pali Rohár <pali.rohar@gmail.com>
+ * Copyright (C) 2017-2018 Pali Rohár <pali.rohar@gmail.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
@@ -34,12 +34,12 @@
#include "libudffs.h"
#include "readdisc.h"
-static int read_offset(int fd, struct udf_disc *disc, void *buf, size_t offset, size_t count, int warn_beyond)
+static int read_offset(int fd, struct udf_disc *disc, void *buf, off_t offset, size_t count, int warn_beyond)
{
off_t off;
ssize_t ret;
- if (offset + count > (size_t)disc->blocks * disc->blocksize)
+ if (offset + (off_t)count > (off_t)disc->blocks * disc->blocksize)
{
if (warn_beyond)
fprintf(stderr, "%s: Warning: Trying to read beyond end of disk\n", appname);
@@ -47,7 +47,7 @@ static int read_offset(int fd, struct udf_disc *disc, void *buf, size_t offset,
}
off = lseek(fd, offset, SEEK_SET);
- if (off != (off_t)-1 && (size_t)off != offset)
+ if (off != (off_t)-1 && off != offset)
{
errno = EIO;
off = (off_t)-1;
@@ -201,7 +201,7 @@ static int read_anchor_i(int fd, struct udf_disc *disc, int i, uint32_t location
struct anchorVolDescPtr avdp;
struct udf_extent *ext;
- if (read_offset(fd, disc, &avdp, (size_t)location * disc->blocksize, sizeof(avdp), 1) < 0)
+ if (read_offset(fd, disc, &avdp, (off_t)location * disc->blocksize, sizeof(avdp), 1) < 0)
return -2;
if (le32_to_cpu(avdp.descTag.tagLocation) != location)
@@ -233,14 +233,14 @@ static int read_anchor_second(int fd, struct udf_disc *disc)
{
int ret1, ret2;
- if (disc->blocks > 257 && (size_t)(disc->blocks - 257) * disc->blocksize > (size_t)32768 + disc->blocksize && disc->blocks - 257 != 256)
+ if (disc->blocks > 257 && (off_t)(disc->blocks - 257) * disc->blocksize > (off_t)32768 + disc->blocksize && disc->blocks - 257 != 256)
ret1 = read_anchor_i(fd, disc, 1, disc->blocks - 257);
else
ret1 = -2;
if (ret1 == -1)
return -1;
- if ((size_t)(disc->blocks - 1) * disc->blocksize > (size_t)32768 + disc->blocksize && disc->blocks - 1 != 256)
+ if ((off_t)(disc->blocks - 1) * disc->blocksize > (off_t)32768 + disc->blocksize && disc->blocks - 1 != 256)
ret2 = read_anchor_i(fd, disc, 2, disc->blocks - 1);
else
ret2 = -2;
@@ -505,10 +505,11 @@ static int choose_anchor(struct udf_disc *disc)
static int scan_vds(int fd, struct udf_disc *disc, enum udf_space_type vds_type)
{
uint32_t location, length, count, i;
- uint32_t next_vdp_num, next_location, next_length, next_count;
+ uint32_t next_location, next_length, next_count;
uint16_t type, udf_rev_le16;
size_t gd_length;
struct genericDesc *gd_ptr;
+ struct partitionDesc *pd_ptr;
struct udf_extent *ext;
struct volDescPtr *vdp;
struct logicalVolDesc *lvd;
@@ -516,6 +517,7 @@ static int scan_vds(int fd, struct udf_disc *disc, enum udf_space_type vds_type)
unsigned char buffer[512];
int id, anchor;
int nested;
+ int done;
anchor = choose_anchor(disc);
if (anchor == -1)
@@ -532,6 +534,18 @@ static int scan_vds(int fd, struct udf_disc *disc, enum udf_space_type vds_type)
next_location = le32_to_cpu(disc->udf_anchor[anchor]->reserveVolDescSeqExt.extLocation);
next_length = le32_to_cpu(disc->udf_anchor[anchor]->reserveVolDescSeqExt.extLength) & EXT_LENGTH_MASK;
id = 1;
+ if (next_location == le32_to_cpu(disc->udf_anchor[anchor]->mainVolDescSeqExt.extLocation))
+ {
+ fprintf(stderr, "%s: Warning: Reserve Volume Descriptor Sequence is on same location as Main\n", appname);
+ disc->udf_pvd[1] = disc->udf_pvd[0];
+ disc->udf_lvd[1] = disc->udf_lvd[0];
+ disc->udf_pd[1] = disc->udf_pd[0];
+ disc->udf_pd2[1] = disc->udf_pd2[0];
+ disc->udf_usd[1] = disc->udf_usd[0];
+ disc->udf_iuvd[1] = disc->udf_iuvd[0];
+ disc->udf_td[1] = disc->udf_td[0];
+ return 0;
+ }
}
else
{
@@ -545,7 +559,6 @@ static int scan_vds(int fd, struct udf_disc *disc, enum udf_space_type vds_type)
return -2;
nested = 0;
- next_vdp_num = 0;
while (next_location && next_count)
{
@@ -567,6 +580,8 @@ static int scan_vds(int fd, struct udf_disc *disc, enum udf_space_type vds_type)
if (count > 256)
length = 256 * disc->blocksize;
+ done = 0;
+
for (i = 0; i < count; ++i)
{
if (count >= 256)
@@ -575,7 +590,7 @@ static int scan_vds(int fd, struct udf_disc *disc, enum udf_space_type vds_type)
break;
}
- if (read_offset(fd, disc, &buffer, ((size_t)location+i) * disc->blocksize, sizeof(buffer), 1) < 0)
+ if (read_offset(fd, disc, &buffer, ((off_t)location+i) * disc->blocksize, sizeof(buffer), 1) < 0)
return -3;
gd_ptr = (struct genericDesc *)&buffer;
@@ -606,19 +621,44 @@ static int scan_vds(int fd, struct udf_disc *disc, enum udf_space_type vds_type)
memcpy(gd_ptr, &buffer, sizeof(buffer));
set_desc(ext, type, i, sizeof(buffer), alloc_data(gd_ptr, sizeof(buffer)));
- if (type == TAG_IDENT_PVD && (!disc->udf_pvd[id] || le32_to_cpu(disc->udf_pvd[id]->volDescSeqNum) < le32_to_cpu(gd_ptr->volDescSeqNum)))
- disc->udf_pvd[id] = (struct primaryVolDesc *)gd_ptr;
- else if (type == TAG_IDENT_PD && (!disc->udf_pd[id] || le32_to_cpu(disc->udf_pd[id]->volDescSeqNum) < le32_to_cpu(gd_ptr->volDescSeqNum)))
- disc->udf_pd[id] = (struct partitionDesc *)gd_ptr;
- else if (type == TAG_IDENT_IUVD && (!disc->udf_iuvd[id] || le32_to_cpu(disc->udf_iuvd[id]->volDescSeqNum) < le32_to_cpu(gd_ptr->volDescSeqNum)))
- disc->udf_iuvd[id] = (struct impUseVolDesc *)gd_ptr;
- else if (type == TAG_IDENT_TD && !disc->udf_td[id])
- disc->udf_td[id] = (struct terminatingDesc *)gd_ptr;
- else if (type == TAG_IDENT_VDP)
+ switch (type)
{
- vdp = (struct volDescPtr *)gd_ptr;
- if (next_vdp_num < le32_to_cpu(vdp->volDescSeqNum))
- {
+ case TAG_IDENT_PVD:
+ if (!disc->udf_pvd[id] || le32_to_cpu(disc->udf_pvd[id]->volDescSeqNum) < le32_to_cpu(gd_ptr->volDescSeqNum))
+ disc->udf_pvd[id] = (struct primaryVolDesc *)gd_ptr;
+ break;
+
+ case TAG_IDENT_PD:
+ pd_ptr = (struct partitionDesc *)gd_ptr;
+ if (!disc->udf_pd[id] || le16_to_cpu(disc->udf_pd[id]->partitionNumber) == le16_to_cpu(pd_ptr->partitionNumber))
+ {
+ if (!disc->udf_pd[id] || le32_to_cpu(disc->udf_pd[id]->volDescSeqNum) < le32_to_cpu(pd_ptr->volDescSeqNum))
+ disc->udf_pd[id] = pd_ptr;
+ }
+ else if (!disc->udf_pd2[id] || le16_to_cpu(disc->udf_pd2[id]->partitionNumber) == le16_to_cpu(pd_ptr->partitionNumber))
+ {
+ if (!disc->udf_pd2[id] || le32_to_cpu(disc->udf_pd2[id]->volDescSeqNum) < le32_to_cpu(pd_ptr->volDescSeqNum))
+ disc->udf_pd2[id] = pd_ptr;
+ }
+ else
+ {
+ fprintf(stderr, "%s: Warning: More then two Partition Descriptors are present, ignoring others\n", appname);
+ }
+ break;
+
+ case TAG_IDENT_IUVD:
+ if (!disc->udf_iuvd[id] || le32_to_cpu(disc->udf_iuvd[id]->volDescSeqNum) < le32_to_cpu(gd_ptr->volDescSeqNum))
+ disc->udf_iuvd[id] = (struct impUseVolDesc *)gd_ptr;
+ break;
+
+ case TAG_IDENT_TD:
+ if (!disc->udf_td[id])
+ disc->udf_td[id] = (struct terminatingDesc *)gd_ptr;
+ done = 1;
+ break;
+
+ case TAG_IDENT_VDP:
+ vdp = (struct volDescPtr *)gd_ptr;
next_location = le32_to_cpu(vdp->nextVolDescSeqExt.extLocation);
if (next_location <= location)
{
@@ -627,14 +667,16 @@ static int scan_vds(int fd, struct udf_disc *disc, enum udf_space_type vds_type)
}
else
{
- next_vdp_num = le32_to_cpu(vdp->volDescSeqNum);
next_length = le32_to_cpu(vdp->nextVolDescSeqExt.extLength) & EXT_LENGTH_MASK;
next_count = next_length / disc->blocksize;
}
- }
+ done = 1;
+ break;
+
+ default:
+ fprintf(stderr, "%s: Warning: Unknown descriptor in Volume Descriptor Sequence\n", appname);
+ break;
}
- else
- fprintf(stderr, "%s: Warning: Unknown descriptor in Volume Descriptor Sequence\n", appname);
break;
case TAG_IDENT_LVD:
@@ -733,7 +775,7 @@ static int scan_vds(int fd, struct udf_disc *disc, enum udf_space_type vds_type)
break;
}
- if (type == TAG_IDENT_TD)
+ if (done)
break;
}
}
@@ -796,7 +838,7 @@ static void scan_lvis(int fd, struct udf_disc *disc)
break;
}
- if (read_offset(fd, disc, &buffer, (size_t)location * disc->blocksize, sizeof(buffer), 1) < 0)
+ if (read_offset(fd, disc, &buffer, (off_t)location * disc->blocksize, sizeof(buffer), 1) < 0)
return;
descTag = (tag *)&buffer;
@@ -907,10 +949,15 @@ static void parse_lvidiu(struct udf_disc *disc)
}
lvidiu = (struct logicalVolIntegrityDescImpUse *)&(disc->udf_lvid->impUse[le32_to_cpu(disc->udf_lvid->numOfPartitions) * 2 * sizeof(uint32_t)]);
- disc->udf_rev = le16_to_cpu(lvidiu->minUDFReadRev);
- disc->udf_write_rev = le16_to_cpu(lvidiu->minUDFWriteRev);
disc->num_files = le32_to_cpu(lvidiu->numFiles);
disc->num_dirs = le32_to_cpu(lvidiu->numDirs);
+
+ /* Fields minUDFReadRev and minUDFWriteRev are defined since UDF 1.02 */
+ if (disc->udf_rev >= 0x0102)
+ {
+ disc->udf_rev = le16_to_cpu(lvidiu->minUDFReadRev);
+ disc->udf_write_rev = le16_to_cpu(lvidiu->minUDFWriteRev);
+ }
}
static struct genericPartitionMap *find_partition(struct udf_disc *disc, uint8_t type, const char *ident)
@@ -971,25 +1018,61 @@ static struct genericPartitionMap *get_partition(struct udf_disc *disc, int id,
return pmap;
}
-static uint32_t find_block_position(struct udf_disc *disc, struct genericPartitionMap *pmap, uint32_t block)
+static struct partitionDesc *find_partition_descriptor(struct udf_disc *disc, uint16_t partition)
+{
+ int id;
+
+ if (disc->udf_pd[0])
+ id = 0;
+ else if (disc->udf_pd[1])
+ id = 1;
+ else
+ return NULL;
+
+ if (le16_to_cpu(disc->udf_pd[id]->partitionNumber) == partition)
+ return disc->udf_pd[id];
+
+ if (disc->udf_pd2[0])
+ id = 0;
+ else if (disc->udf_pd2[1])
+ id = 1;
+ else
+ return NULL;
+
+ if (le16_to_cpu(disc->udf_pd2[id]->partitionNumber) == partition)
+ return disc->udf_pd2[id];
+
+ return NULL;
+}
+
+static uint32_t find_block_position(struct udf_disc *disc, struct genericPartitionMap *pmap, uint32_t block, uint16_t *partition)
{
+ struct genericPartitionMap1 *pm1;
struct udfPartitionMap2 *upm2;
+ struct virtualPartitionMap *vpm;
struct sparablePartitionMap *spm;
uint8_t count, i;
uint16_t packet_len, num, j;
uint32_t location, packet, offset;
if (pmap->partitionMapType == GP_PARTITION_MAP_TYPE_1)
+ {
+ pm1 = (struct genericPartitionMap1 *)pmap;
+ *partition = le16_to_cpu(pm1->partitionNum);
return block;
+ }
else if (pmap->partitionMapType == GP_PARTITION_MAP_TYPE_2)
{
upm2 = (struct udfPartitionMap2 *)pmap;
if (strncmp((char *)upm2->partIdent.ident, UDF_ID_VIRTUAL, sizeof(upm2->partIdent.ident)) == 0)
{
+ vpm = (struct virtualPartitionMap *)upm2;
+ *partition = le16_to_cpu(vpm->partitionNum);
+
if (!disc->vat)
return UINT32_MAX;
else if (block < disc->vat_entries)
- return disc->vat[block];
+ return le32_to_cpu(disc->vat[block]);
else
return block;
}
@@ -998,9 +1081,10 @@ static uint32_t find_block_position(struct udf_disc *disc, struct genericPartiti
spm = (struct sparablePartitionMap *)upm2;
count = spm->numSparingTables;
packet_len = le16_to_cpu(spm->packetLength);
+ *partition = le16_to_cpu(spm->partitionNum);
- packet = block & ~(packet_len-1);
- offset = block & (packet_len-1);
+ offset = block % packet_len;
+ packet = block - offset;
for (i = 0; i < count; ++i)
{
@@ -1070,7 +1154,7 @@ static void read_stable(int fd, struct udf_disc *disc)
{
location = le32_to_cpu(spm->locSparingTable[i]);
- if (read_offset(fd, disc, &buffer, (size_t)location * disc->blocksize, sizeof(buffer), 1) < 0)
+ if (read_offset(fd, disc, &buffer, (off_t)location * disc->blocksize, sizeof(buffer), 1) < 0)
return;
st = (struct sparingTable *)&buffer;
@@ -1135,28 +1219,47 @@ static void read_stable(int fd, struct udf_disc *disc)
static void read_vat(int fd, struct udf_disc *disc)
{
long last;
+ struct partitionDesc *pd;
+ struct virtualPartitionMap *vpm;
+ long_ad *lad;
+ short_ad *sad;
+ uint32_t j, count;
+ uint32_t ext_length, ext_position, ext_location;
+ uint16_t ext_partition;
+ uint64_t vat_length, vat_offset;
uint32_t i, vat_block;
uint32_t length, offset, location;
+ uint32_t ea_length, ea_offset;
+ uint32_t ea_attr_length, ea_attr_offset;
+ uint64_t unique_id;
struct stat st;
struct fileEntry *fe;
struct extendedFileEntry *efe;
struct virtualAllocationTable15 *vat15;
struct virtualAllocationTable20 *vat20;
+ struct extendedAttrHeaderDesc ea_hdr;
+ struct impUseExtAttr ea_attr;
+ struct LVExtensionEA ea_lv;
unsigned char *vat;
+ unsigned char *descs;
unsigned char buffer[512];
- int id;
- if (disc->udf_pd[0])
- id = 0;
- else if (disc->udf_pd[1])
- id = 1;
- else
+ vpm = (struct virtualPartitionMap *)find_partition(disc, GP_PARTITION_MAP_TYPE_2, UDF_ID_VIRTUAL);
+ if (!vpm)
+ {
+ if (disc->vat_block)
+ fprintf(stderr, "%s: Error: Virtual Partition Map not found, but --vatblock specified\n", appname);
return;
+ }
- location = le32_to_cpu(disc->udf_pd[id]->partitionStartingLocation);
-
- if (!find_partition(disc, GP_PARTITION_MAP_TYPE_2, UDF_ID_VIRTUAL))
+ pd = find_partition_descriptor(disc, le16_to_cpu(vpm->partitionNum));
+ if (!pd)
+ {
+ fprintf(stderr, "%s: Error: Virtual Partition Map found, but corresponding Partition Descriptor not found\n", appname);
return;
+ }
+
+ location = le32_to_cpu(pd->partitionStartingLocation);
if (disc->vat_block)
vat_block = disc->vat_block;
@@ -1167,7 +1270,7 @@ static void read_vat(int fd, struct udf_disc *disc)
for (i = vat_block + 3; i > 0 && i > vat_block - 32; --i)
{
- if (read_offset(fd, disc, &buffer, (size_t)i * disc->blocksize, sizeof(buffer), 0) < 0)
+ if (read_offset(fd, disc, &buffer, (off_t)i * disc->blocksize, sizeof(buffer), 0) < 0)
continue;
fe = (struct fileEntry *)&buffer;
@@ -1184,62 +1287,203 @@ static void read_vat(int fd, struct udf_disc *disc)
continue;
}
- if ((le16_to_cpu(fe->icbTag.flags) & ICBTAG_FLAG_AD_MASK) != ICBTAG_FLAG_AD_IN_ICB)
- {
- fprintf(stderr, "%s: Warning: Reading Virtual Allocation Table outside of Information Control Block is not supported yet\n", appname);
- break;
- }
-
if (le16_to_cpu(fe->descTag.tagIdent) == TAG_IDENT_FE)
{
- offset = sizeof(*fe) + le32_to_cpu(fe->lengthExtendedAttr);
+ ea_offset = sizeof(*fe);
+ ea_length = le32_to_cpu(fe->lengthExtendedAttr);
+ offset = ea_offset + ea_length;
length = le32_to_cpu(fe->lengthAllocDescs);
+ unique_id = le64_to_cpu(fe->uniqueID);
}
else if (le16_to_cpu(fe->descTag.tagIdent) == TAG_IDENT_EFE)
{
efe = (struct extendedFileEntry *)&buffer;
- offset = sizeof(*efe) + le32_to_cpu(efe->lengthExtendedAttr);
+ ea_offset = sizeof(*efe);
+ ea_length = le32_to_cpu(efe->lengthExtendedAttr);
+ offset = ea_offset + ea_length;
length = le32_to_cpu(efe->lengthAllocDescs);
+ unique_id = le64_to_cpu(efe->uniqueID);
}
else
continue;
- if (le64_to_cpu(fe->informationLength) > length)
+ if (length == 0)
{
- fprintf(stderr, "%s: Warning: Virtual Allocation Table inside of Information Control Block is larger then allocated block\n", appname);
+ fprintf(stderr, "%s: Warning: Information Control Block for Virtual Allocation Table is empty\n", appname);
break;
}
- length = le64_to_cpu(fe->informationLength);
-
- if (length < 36)
+ if (ea_length > disc->blocksize || offset > disc->blocksize || length > disc->blocksize || offset + length > disc->blocksize)
{
- fprintf(stderr, "%s: Warning: Virtual Allocation Table is too small\n", appname);
+ fprintf(stderr, "%s: Warning: Information Control Block for Virtual Allocation Table is larger then block size\n", appname);
break;
}
- if (offset+length > disc->blocksize)
+ descs = malloc(length);
+ if (!descs)
{
- fprintf(stderr, "%s: Warning: Virtual Allocation Table inside of Information Control Block is larger then block size\n", appname);
+ fprintf(stderr, "%s: Error: malloc failed: %s\n", appname, strerror(errno));
break;
}
- vat = malloc(length);
- if (!vat)
+ if (read_offset(fd, disc, descs, (off_t)i * disc->blocksize + offset, length, 1) < 0)
{
- fprintf(stderr, "%s: Error: malloc failed: %s\n", appname, strerror(errno));
+ free(descs);
break;
}
- if (read_offset(fd, disc, vat, (size_t)i * disc->blocksize + offset, length, 1) < 0)
+ if ((le16_to_cpu(fe->icbTag.flags) & ICBTAG_FLAG_AD_MASK) == ICBTAG_FLAG_AD_IN_ICB)
{
- free(vat);
- break;
+ if (le64_to_cpu(fe->informationLength) > length)
+ {
+ fprintf(stderr, "%s: Warning: Virtual Allocation Table inside of Information Control Block is larger then allocated block\n", appname);
+ free(descs);
+ break;
+ }
+ vat = descs;
+ vat_length = le64_to_cpu(fe->informationLength);
+ }
+ else
+ {
+ sad = NULL;
+ lad = NULL;
+ if ((le16_to_cpu(fe->icbTag.flags) & ICBTAG_FLAG_AD_MASK) == ICBTAG_FLAG_AD_SHORT)
+ {
+ sad = (short_ad *)descs;
+ count = length / sizeof(short_ad);
+ vat_length = 0;
+ for (j = 0; j < count; ++j)
+ {
+ if ((le32_to_cpu(sad[j].extLength) & EXT_LENGTH_MASK) >= UINT64_MAX - vat_length)
+ {
+ vat_length = UINT64_MAX;
+ break;
+ }
+ vat_length += le32_to_cpu(sad[j].extLength) & EXT_LENGTH_MASK;
+ }
+ }
+ else if ((le16_to_cpu(fe->icbTag.flags) & ICBTAG_FLAG_AD_MASK) == ICBTAG_FLAG_AD_LONG)
+ {
+ lad = (long_ad *)descs;
+ count = length / sizeof(long_ad);
+ vat_length = 0;
+ for (j = 0; j < count; ++j)
+ {
+ if ((le32_to_cpu(lad[j].extLength) & EXT_LENGTH_MASK) >= UINT64_MAX - vat_length)
+ {
+ vat_length = UINT64_MAX;
+ break;
+ }
+ vat_length += le32_to_cpu(lad[j].extLength) & EXT_LENGTH_MASK;
+ }
+ }
+ else
+ {
+ fprintf(stderr, "%s: Error: Information Control Block for Virtual Allocation Table has unknown Allocation Descriptors type\n", appname);
+ free(descs);
+ break;
+ }
+
+ if (vat_length == 0)
+ {
+ fprintf(stderr, "%s: Warning: Virtual Allocation Table is empty\n", appname);
+ free(descs);
+ break;
+ }
+ else if (vat_length > (uint64_t)256 * disc->blocksize)
+ {
+ fprintf(stderr, "%s: Warning: Virtual Allocation Table is too big\n", appname);
+ free(descs);
+ break;
+ }
+
+ /* Prefer non-virtual partition if exists */
+ if (disc->udf_pd[0] && le16_to_cpu(disc->udf_pd[0]->partitionNumber) != le16_to_cpu(vpm->partitionNum))
+ {
+ ext_location = le32_to_cpu(disc->udf_pd[0]->partitionStartingLocation);
+ ext_partition = le16_to_cpu(disc->udf_pd[0]->partitionNumber);
+ }
+ else if (disc->udf_pd[1] && le16_to_cpu(disc->udf_pd[1]->partitionNumber) != le16_to_cpu(vpm->partitionNum))
+ {
+ ext_location = le32_to_cpu(disc->udf_pd[1]->partitionStartingLocation);
+ ext_partition = le16_to_cpu(disc->udf_pd[1]->partitionNumber);
+ }
+ else if (disc->udf_pd2[0] && le16_to_cpu(disc->udf_pd2[0]->partitionNumber) != le16_to_cpu(vpm->partitionNum))
+ {
+ ext_location = le32_to_cpu(disc->udf_pd2[0]->partitionStartingLocation);
+ ext_partition = le16_to_cpu(disc->udf_pd2[0]->partitionNumber);
+ }
+ else if (disc->udf_pd2[1] && le16_to_cpu(disc->udf_pd2[1]->partitionNumber) != le16_to_cpu(vpm->partitionNum))
+ {
+ ext_location = le32_to_cpu(disc->udf_pd2[1]->partitionStartingLocation);
+ ext_partition = le16_to_cpu(disc->udf_pd2[1]->partitionNumber);
+ }
+ else
+ {
+ ext_location = location;
+ ext_partition = le16_to_cpu(vpm->partitionNum);
+ }
+
+ vat = malloc(vat_length);
+ if (!vat)
+ {
+ fprintf(stderr, "%s: Error: malloc failed: %s\n", appname, strerror(errno));
+ free(descs);
+ break;
+ }
+
+ vat_offset = 0;
+ for (j = 0; j < count; ++j)
+ {
+ if ((le16_to_cpu(fe->icbTag.flags) & ICBTAG_FLAG_AD_MASK) == ICBTAG_FLAG_AD_SHORT)
+ {
+ ext_length = le32_to_cpu(sad[j].extLength) & EXT_LENGTH_MASK;
+ ext_position = le32_to_cpu(sad[j].extPosition);
+ if (ext_length == 0)
+ continue;
+ }
+ else
+ {
+ ext_length = le32_to_cpu(lad[j].extLength) & EXT_LENGTH_MASK;
+ ext_position = le32_to_cpu(lad[j].extLocation.logicalBlockNum);
+ if (ext_length == 0)
+ continue;
+ if (le32_to_cpu(lad[j].extLocation.partitionReferenceNum) != ext_partition)
+ {
+ fprintf(stderr, "%s: Error: Virtual Allocation Table is stored on different partition\n", appname);
+ count = 0;
+ break;
+ }
+ }
+
+ if (read_offset(fd, disc, vat + vat_offset, (off_t)(ext_location + ext_position) * disc->blocksize, ext_length, 1) != 0)
+ {
+ fprintf(stderr, "%s: Error: Virtual Allocation Table is damaged\n", appname);
+ count = 0;
+ break;
+ }
+
+ vat_offset += ext_length;
+ }
+
+ free(descs);
+
+ if (count == 0)
+ {
+ free(vat);
+ break;
+ }
}
if (fe->icbTag.fileType == ICBTAG_FILE_TYPE_UNDEF)
{
- vat15 = (struct virtualAllocationTable15 *)(vat + ((length - 36) / 4) * 4);
+ if (vat_length < 36)
+ {
+ fprintf(stderr, "%s: Warning: Virtual Allocation Table is too small\n", appname);
+ free(vat);
+ break;
+ }
+ vat15 = (struct virtualAllocationTable15 *)(vat + ((vat_length - 36) / 4) * 4);
if (strncmp((const char *)vat15->vatIdent.ident, UDF_ID_ALLOC, sizeof(vat15->vatIdent.ident)) != 0)
{
fprintf(stderr, "%s: Warning: Virtual Allocation Table is damaged\n", appname);
@@ -1247,12 +1491,71 @@ static void read_vat(int fd, struct udf_disc *disc)
break;
}
disc->vat = (uint32_t *)vat;
- disc->vat_entries = (length - 36) / 4;
+ disc->vat_entries = (vat_length - 36) / 4;
+ if (ea_length)
+ {
+ if (sizeof(ea_hdr) > ea_length)
+ fprintf(stderr, "%s: Warning: Extended Attributes for Virtual Allocation Table are damaged\n", appname);
+ else if (read_offset(fd, disc, &ea_hdr, (off_t)i * disc->blocksize + ea_offset, sizeof(ea_hdr), 1) != 0)
+ fprintf(stderr, "%s: Warning: Extended Attributes for Virtual Allocation Table are damaged\n", appname);
+ else
+ {
+ /* UDF 1.50 3.3.4.1: if attribute does not exist then location point to byte after the EA space */
+ ea_attr_offset = le32_to_cpu(ea_hdr.impAttrLocation);
+ while (ea_attr_offset < ea_length)
+ {
+ if (read_offset(fd, disc, &ea_attr, (off_t)i * disc->blocksize + ea_offset + ea_attr_offset, sizeof(ea_attr), 1) != 0)
+ {
+ fprintf(stderr, "%s: Warning: Extended Attributes for Virtual Allocation Table are damaged\n", appname);
+ break;
+ }
+ ea_attr_length = le32_to_cpu(ea_attr.attrLength);
+ if (ea_attr_length == 0)
+ break;
+ if (ea_attr_offset + ea_attr_length > ea_length || sizeof(ea_attr) + le32_to_cpu(ea_attr.impUseLength) > ea_attr_length)
+ {
+ fprintf(stderr, "%s: Warning: Extended Attributes for Virtual Allocation Table are damaged\n", appname);
+ break;
+ }
+ if (le32_to_cpu(ea_attr.attrType) == EXTATTR_IMP_USE && strncmp((const char *)ea_attr.impIdent.ident, UDF_ID_VAT_LVEXTENSION, sizeof(ea_attr.impIdent.ident)) == 0)
+ {
+ if (ea_attr_length < sizeof(ea_attr) + sizeof(ea_lv) || le32_to_cpu(ea_attr.impUseLength) < sizeof(ea_lv))
+ {
+ fprintf(stderr, "%s: Warning: Logical Volume Extended Information for Virtual Allocation Table is damaged\n", appname);
+ break;
+ }
+ if (read_offset(fd, disc, &ea_lv, (off_t)i * disc->blocksize + ea_offset + ea_attr_offset + sizeof(ea_attr), sizeof(ea_lv), 1) != 0)
+ {
+ fprintf(stderr, "%s: Warning: Logical Volume Extended Information for Virtual Allocation Table is damaged\n", appname);
+ break;
+ }
+ if (le64_to_cpu(ea_lv.verificationID) != unique_id)
+ {
+ fprintf(stderr, "%s: Warning: Logical Volume Extended Information for Virtual Allocation Table is damaged\n", appname);
+ }
+ else
+ {
+ if (disc->udf_lvd[0])
+ memcpy(disc->udf_lvd[0]->logicalVolIdent, ea_lv.logicalVolIdent, sizeof(ea_lv.logicalVolIdent));
+ if (disc->udf_lvd[1])
+ memcpy(disc->udf_lvd[1]->logicalVolIdent, ea_lv.logicalVolIdent, sizeof(ea_lv.logicalVolIdent));
+ if (disc->udf_lvid)
+ {
+ disc->num_files = le32_to_cpu(ea_lv.numFiles);
+ disc->num_dirs = le32_to_cpu(ea_lv.numDirs);
+ }
+ break;
+ }
+ }
+ ea_attr_offset += ea_attr_length;
+ }
+ }
+ }
}
else if (fe->icbTag.fileType == ICBTAG_FILE_TYPE_VAT20)
{
vat20 = (struct virtualAllocationTable20 *)vat;
- if (vat20->lengthHeader < sizeof(*vat20) || vat20->lengthHeader != sizeof(*vat20) + vat20->lengthImpUse || vat20->lengthHeader > length)
+ if (le16_to_cpu(vat20->lengthHeader) < sizeof(*vat20) || le16_to_cpu(vat20->lengthHeader) != sizeof(*vat20) + le16_to_cpu(vat20->lengthImpUse) || le16_to_cpu(vat20->lengthHeader) > vat_length)
{
fprintf(stderr, "%s: Warning: Virtual Allocation Table is damaged\n", appname);
free(vat);
@@ -1269,13 +1572,13 @@ static void read_vat(int fd, struct udf_disc *disc)
disc->num_files = le32_to_cpu(vat20->numFiles);
disc->num_dirs = le32_to_cpu(vat20->numDirs);
}
- disc->vat = (uint32_t *)(vat + vat20->lengthHeader);
- disc->vat_entries = (length - vat20->lengthHeader) / 4;
+ disc->vat = (uint32_t *)(vat + le16_to_cpu(vat20->lengthHeader));
+ disc->vat_entries = (vat_length - le16_to_cpu(vat20->lengthHeader)) / 4;
}
else
{
- free(vat);
- continue;
+ fprintf(stderr, "%s: Error: Wrong file type\n", appname);
+ exit(1);
}
disc->vat_block = i;
@@ -1292,40 +1595,53 @@ static void read_vat(int fd, struct udf_disc *disc)
fprintf(stderr, "%s: Error: Virtual Allocation Table not found, maybe wrong --vatblock?\n", appname);
}
-static void setup_pspace(struct udf_disc *disc)
+static void setup_pspace(struct udf_disc *disc, int second)
{
+ struct partitionDesc *pd;
struct udf_extent *ext, *new_ext;
uint32_t location, blocks;
- int id;
- if (disc->udf_pd[0])
- id = 0;
- else if (disc->udf_pd[1])
- id = 1;
+ if (!second)
+ {
+ if (disc->udf_pd[0])
+ pd = disc->udf_pd[0];
+ else if (disc->udf_pd[1])
+ pd = disc->udf_pd[1];
+ else
+ {
+ fprintf(stderr, "%s: Warning: Partition Space not found\n", appname);
+ return;
+ }
+ }
else
{
- fprintf(stderr, "%s: Warning: Partition Space not found\n", appname);
- return;
+ if (disc->udf_pd2[0])
+ pd = disc->udf_pd2[0];
+ else if (disc->udf_pd2[1])
+ pd = disc->udf_pd2[1];
+ else
+ return;
}
- location = le32_to_cpu(disc->udf_pd[id]->partitionStartingLocation);
- blocks = le32_to_cpu(disc->udf_pd[id]->partitionLength);
- if (!location || !blocks)
+ location = le32_to_cpu(pd->partitionStartingLocation);
+
+ blocks = le32_to_cpu(pd->partitionLength);
+ if (!blocks)
{
- fprintf(stderr, "%s: Warning: Partition Space not found\n", appname);
+ fprintf(stderr, "%s: Warning: %sPartition Space not found\n", appname, second ? "Second " : "");
return;
}
if (location + blocks > disc->blocks && !find_partition(disc, GP_PARTITION_MAP_TYPE_2, UDF_ID_VIRTUAL))
- fprintf(stderr, "%s: Warning: Partition Space is beyond end of disk\n", appname);
+ fprintf(stderr, "%s: Warning: %sPartition Space is beyond end of disk\n", appname, second ? "Second " : "");
ext = find_extent(disc, location);
if (ext->space_type != USPACE)
{
- fprintf(stderr, "%s: Warning: Partition Space overlaps with other blocks\n", appname);
- ext = ext->next;
- if (ext->space_type == USPACE)
+ fprintf(stderr, "%s: Warning: %sPartition Space overlaps with other blocks\n", appname, second ? "Second " : "");
+ if (ext->next && ext->next->space_type == USPACE)
{
+ ext = ext->next;
if (blocks > ext->start - location && blocks - (ext->start - location) < ext->blocks)
ext = set_extent(disc, PSPACE, ext->start, blocks - (ext->start - location));
else
@@ -1336,14 +1652,20 @@ static void setup_pspace(struct udf_disc *disc)
else
{
new_ext = malloc(sizeof(struct udf_extent));
+ if (!new_ext)
+ {
+ fprintf(stderr, "%s: Error: malloc failed: %s\n", appname, strerror(errno));
+ return;
+ }
new_ext->space_type = PSPACE;
new_ext->start = location;
new_ext->blocks = blocks;
new_ext->head = new_ext->tail = NULL;
- new_ext->prev = ext->prev;
- new_ext->next = ext;
+ new_ext->prev = ext;
+ new_ext->next = ext->next;
new_ext->prev->next = new_ext;
- new_ext->next->prev = new_ext;
+ if (new_ext->next)
+ new_ext->next->prev = new_ext;
}
}
else
@@ -1351,7 +1673,7 @@ static void setup_pspace(struct udf_disc *disc)
if ((location == ext->start || (location > ext->start && location + blocks > ext->start + ext->blocks)) && blocks > ext->blocks)
{
if (ext != disc->tail)
- fprintf(stderr, "%s: Warning: Partition Space overlaps with other blocks\n", appname);
+ fprintf(stderr, "%s: Warning: %sPartition Space overlaps with other blocks\n", appname, second ? "Second " : "");
ext = set_extent(disc, PSPACE, location, ext->blocks);
ext->blocks = blocks;
}
@@ -1364,24 +1686,21 @@ static void read_fsd(int fd, struct udf_disc *disc)
{
long_ad *ad;
uint16_t partition;
- uint32_t block_num, location, position, length;
+ uint32_t block, location, position, length;
struct genericPartitionMap *pmap;
struct udf_extent *ext;
+ struct partitionDesc *pd;
int id;
- if (disc->udf_lvd[0] && disc->udf_pd[0])
- id = 0;
- else if (disc->udf_lvd[1] && disc->udf_pd[1])
- id = 1;
- else if (disc->udf_lvd[0] && disc->udf_pd[1])
+ if (disc->udf_lvd[0])
id = 0;
- else if (disc->udf_lvd[1] && disc->udf_pd[0])
+ else if (disc->udf_lvd[1])
id = 1;
else
return;
ad = (long_ad *)disc->udf_lvd[id]->logicalVolContentsUse;
- block_num = le32_to_cpu(ad->extLocation.logicalBlockNum);
+ block = le32_to_cpu(ad->extLocation.logicalBlockNum);
partition = le16_to_cpu(ad->extLocation.partitionReferenceNum);
length = le32_to_cpu(ad->extLength) & EXT_LENGTH_MASK;
@@ -1392,19 +1711,21 @@ static void read_fsd(int fd, struct udf_disc *disc)
return;
}
- position = find_block_position(disc, pmap, block_num);
+ position = find_block_position(disc, pmap, block, &partition);
if (position == UINT32_MAX)
{
fprintf(stderr, "%s: Warning: File Set Descriptor cannot be read\n", appname);
return;
}
- if (id == 0 && !disc->udf_pd[0])
- id = 1;
- else if (id == 1 && !disc->udf_pd[1])
- id = 0;
+ pd = find_partition_descriptor(disc, partition);
+ if (!pd)
+ {
+ fprintf(stderr, "%s: Warning: File Set Descriptor cannot be read\n", appname);
+ return;
+ }
- location = le32_to_cpu(disc->udf_pd[id]->partitionStartingLocation) + position;
+ location = le32_to_cpu(pd->partitionStartingLocation) + position;
if (sizeof(*disc->udf_fsd) > length)
{
@@ -1419,14 +1740,14 @@ static void read_fsd(int fd, struct udf_disc *disc)
return;
}
- if (read_offset(fd, disc, disc->udf_fsd, (size_t)location * disc->blocksize, length, 1) < 0)
+ if (read_offset(fd, disc, disc->udf_fsd, (off_t)location * disc->blocksize, length, 1) < 0)
{
free(disc->udf_fsd);
disc->udf_fsd = NULL;
return;
}
- if (le32_to_cpu(disc->udf_fsd->descTag.tagLocation) != position)
+ if (le32_to_cpu(disc->udf_fsd->descTag.tagLocation) != block)
{
fprintf(stderr, "%s: Warning: Incorrect Logical Volume Integrity Descriptor\n", appname);
free(disc->udf_fsd);
@@ -1450,6 +1771,7 @@ static void read_fsd(int fd, struct udf_disc *disc)
static void setup_total_space_blocks(struct udf_disc *disc)
{
int id;
+ int warn_beyond;
if (disc->udf_pd[0])
id = 0;
@@ -1463,14 +1785,35 @@ static void setup_total_space_blocks(struct udf_disc *disc)
disc->total_space_blocks = le32_to_cpu(disc->udf_pd[id]->partitionLength);
- if (disc->total_space_blocks + le32_to_cpu(disc->udf_pd[id]->partitionStartingLocation) > disc->blocks && !find_partition(disc, GP_PARTITION_MAP_TYPE_2, UDF_ID_VIRTUAL))
+ warn_beyond = !find_partition(disc, GP_PARTITION_MAP_TYPE_2, UDF_ID_VIRTUAL);
+
+ if (warn_beyond && disc->total_space_blocks + le32_to_cpu(disc->udf_pd[id]->partitionStartingLocation) > disc->blocks)
+ {
fprintf(stderr, "%s: Warning: Some space blocks are beyond end of disk\n", appname);
+ warn_beyond = 0;
+ }
+
+ if (disc->udf_pd2[0])
+ id = 0;
+ else if (disc->udf_pd2[1])
+ id = 1;
+ else
+ return;
+
+ if (warn_beyond && le32_to_cpu(disc->udf_pd2[id]->partitionLength) + le32_to_cpu(disc->udf_pd2[id]->partitionStartingLocation) > disc->blocks)
+ fprintf(stderr, "%s: Warning: Some space blocks are beyond end of disk\n", appname);
+
+ disc->total_space_blocks += le32_to_cpu(disc->udf_pd2[id]->partitionLength);
}
-static uint32_t count_bitmap_blocks(int fd, struct udf_disc *disc, uint32_t location, uint32_t length)
+static uint32_t count_bitmap_blocks(int fd, struct udf_disc *disc, struct genericPartitionMap *pmap, uint32_t block, uint32_t length)
{
unsigned long int buffer[512/sizeof(unsigned long int)];
unsigned long int val;
+ uint32_t location;
+ uint32_t position;
+ uint16_t partition;
+ struct partitionDesc *pd;
struct spaceBitmapDesc sbd;
uint32_t bits;
uint32_t bytes;
@@ -1483,7 +1826,17 @@ static uint32_t count_bitmap_blocks(int fd, struct udf_disc *disc, uint32_t loca
return 0;
}
- if (read_offset(fd, disc, &sbd, (size_t)location * disc->blocksize, sizeof(sbd), 1) < 0)
+ position = find_block_position(disc, pmap, block, &partition);
+ if (position == UINT32_MAX)
+ return 0;
+
+ pd = find_partition_descriptor(disc, partition);
+ if (!pd)
+ return 0;
+
+ location = le32_to_cpu(pd->partitionStartingLocation) + position;
+
+ if (read_offset(fd, disc, &sbd, (off_t)location * disc->blocksize, sizeof(sbd), 1) < 0)
return 0;
bits = le32_to_cpu(sbd.numOfBits);
@@ -1543,9 +1896,13 @@ static uint32_t count_bitmap_blocks(int fd, struct udf_disc *disc, uint32_t loca
return blocks;
}
-static uint32_t count_table_blocks(int fd, struct udf_disc *disc, uint32_t location, uint32_t length)
+static uint32_t count_table_blocks(int fd, struct udf_disc *disc, struct genericPartitionMap *pmap, uint32_t block, uint32_t length)
{
unsigned char buffer[512];
+ uint32_t location;
+ uint32_t position;
+ uint16_t partition;
+ struct partitionDesc *pd;
struct unallocSpaceEntry *use;
size_t use_len;
uint64_t space, blocks;
@@ -1559,7 +1916,17 @@ static uint32_t count_table_blocks(int fd, struct udf_disc *disc, uint32_t locat
return 0;
}
- if (read_offset(fd, disc, &buffer, (size_t)location * disc->blocksize, sizeof(buffer), 1) < 0)
+ position = find_block_position(disc, pmap, block, &partition);
+ if (position == UINT32_MAX)
+ return 0;
+
+ pd = find_partition_descriptor(disc, partition);
+ if (!pd)
+ return 0;
+
+ location = le32_to_cpu(pd->partitionStartingLocation) + position;
+
+ if (read_offset(fd, disc, &buffer, (off_t)location * disc->blocksize, sizeof(buffer), 1) < 0)
return 0;
use = (struct unallocSpaceEntry *)&buffer;
@@ -1642,9 +2009,10 @@ static void scan_free_space_blocks(int fd, struct udf_disc *disc)
{
long_ad *ad;
uint16_t partition;
- uint32_t blocks, position, location, length;
+ uint32_t blocks, location, length;
struct genericPartitionMap *pmap;
struct partitionHeaderDesc *phd;
+ struct partitionDesc *pd;
char *ident;
int id;
@@ -1675,29 +2043,29 @@ static void scan_free_space_blocks(int fd, struct udf_disc *disc)
if (!pmap)
return;
- if (find_block_position(disc, pmap, 0) == UINT32_MAX)
+ if (find_block_position(disc, pmap, 0, &partition) == UINT32_MAX)
{
fprintf(stderr, "%s: Warning: Determining free space blocks is not possible\n", appname);
return;
}
- if (disc->udf_pd[0])
- id = 0;
- else if (disc->udf_pd[1])
- id = 1;
- else
+ pd = find_partition_descriptor(disc, partition);
+ if (!pd)
+ {
+ fprintf(stderr, "%s: Warning: Determining free space blocks is not possible\n", appname);
return;
+ }
- ident = (char *)disc->udf_pd[id]->partitionContents.ident;
- length = sizeof(disc->udf_pd[id]->partitionContents.ident);
+ ident = (char *)pd->partitionContents.ident;
+ length = sizeof(pd->partitionContents.ident);
if (strncmp(ident, PD_PARTITION_CONTENTS_NSR02, length) != 0 && strncmp(ident, PD_PARTITION_CONTENTS_NSR03, length) != 0)
{
fprintf(stderr, "%s: Warning: Unknown Partition Descriptor Content, determining free space blocks is not possible\n", appname);
return;
}
- location = le32_to_cpu(disc->udf_pd[id]->partitionStartingLocation);
- phd = (struct partitionHeaderDesc *)disc->udf_pd[id]->partitionContentsUse;
+ location = le32_to_cpu(pd->partitionStartingLocation);
+ phd = (struct partitionHeaderDesc *)pd->partitionContentsUse;
if (disc->vat)
{
@@ -1708,8 +2076,7 @@ static void scan_free_space_blocks(int fd, struct udf_disc *disc)
length = le32_to_cpu(phd->unallocSpaceBitmap.extLength) & EXT_LENGTH_MASK;
if (length)
{
- position = find_block_position(disc, pmap, le32_to_cpu(phd->unallocSpaceBitmap.extPosition));
- blocks = count_bitmap_blocks(fd, disc, location + position, length);
+ blocks = count_bitmap_blocks(fd, disc, pmap, le32_to_cpu(phd->unallocSpaceBitmap.extPosition), length);
if (blocks)
{
disc->free_space_blocks = blocks;
@@ -1720,8 +2087,7 @@ static void scan_free_space_blocks(int fd, struct udf_disc *disc)
length = le32_to_cpu(phd->freedSpaceBitmap.extLength) & EXT_LENGTH_MASK;
if (length)
{
- position = find_block_position(disc, pmap, le32_to_cpu(phd->freedSpaceBitmap.extPosition));
- blocks = count_bitmap_blocks(fd, disc, location + position, length);
+ blocks = count_bitmap_blocks(fd, disc, pmap, le32_to_cpu(phd->freedSpaceBitmap.extPosition), length);
if (blocks)
{
disc->free_space_blocks = blocks;
@@ -1732,8 +2098,7 @@ static void scan_free_space_blocks(int fd, struct udf_disc *disc)
length = le32_to_cpu(phd->unallocSpaceTable.extLength) & EXT_LENGTH_MASK;
if (length)
{
- position = find_block_position(disc, pmap, le32_to_cpu(phd->unallocSpaceTable.extPosition));
- blocks = count_table_blocks(fd, disc, location + position, length);
+ blocks = count_table_blocks(fd, disc, pmap, le32_to_cpu(phd->unallocSpaceTable.extPosition), length);
if (blocks)
{
disc->free_space_blocks = blocks;
@@ -1744,8 +2109,7 @@ static void scan_free_space_blocks(int fd, struct udf_disc *disc)
length = le32_to_cpu(phd->freedSpaceTable.extLength) & EXT_LENGTH_MASK;
if (length)
{
- position = find_block_position(disc, pmap, le32_to_cpu(phd->freedSpaceTable.extPosition));
- blocks = count_table_blocks(fd, disc, location + position, length);
+ blocks = count_table_blocks(fd, disc, pmap, le32_to_cpu(phd->freedSpaceTable.extPosition), length);
if (blocks)
{
disc->free_space_blocks = blocks;
@@ -1791,7 +2155,8 @@ int read_disc(int fd, struct udf_disc *disc)
parse_lvidiu(disc);
read_stable(fd, disc);
read_vat(fd, disc);
- setup_pspace(disc);
+ setup_pspace(disc, 0);
+ setup_pspace(disc, 1);
/* TODO: setup USPACE extents */
diff --git a/udflabel/Makefile.am b/udflabel/Makefile.am
index 4f5a488..99de9d7 100644
--- a/udflabel/Makefile.am
+++ b/udflabel/Makefile.am
@@ -1,4 +1,4 @@
sbin_PROGRAMS = udflabel
udflabel_LDADD = $(top_builddir)/libudffs/libudffs.la
-udflabel_SOURCES = main.c options.c ../udfinfo/readdisc.c options.h ../udfinfo/readdisc.h ../include/ecma_167.h ../include/osta_udf.h ../include/libudffs.h ../include/udf_endian.h ../include/bswap.h
+udflabel_SOURCES = main.c options.c ../udfinfo/readdisc.c options.h ../udfinfo/readdisc.h ../include/ecma_167.h ../include/osta_udf.h ../include/libudffs.h ../include/bswap.h
AM_CPPFLAGS = -I$(top_srcdir)/include
diff --git a/udflabel/Makefile.in b/udflabel/Makefile.in
index 0dba0ab..14abcb8 100644
--- a/udflabel/Makefile.in
+++ b/udflabel/Makefile.in
@@ -228,11 +228,17 @@ 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@
+UDEVDIR = @UDEVDIR@
+UDEV_CFLAGS = @UDEV_CFLAGS@
+UDEV_LIBS = @UDEV_LIBS@
VERSION = @VERSION@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
@@ -288,7 +294,7 @@ top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
udflabel_LDADD = $(top_builddir)/libudffs/libudffs.la
-udflabel_SOURCES = main.c options.c ../udfinfo/readdisc.c options.h ../udfinfo/readdisc.h ../include/ecma_167.h ../include/osta_udf.h ../include/libudffs.h ../include/udf_endian.h ../include/bswap.h
+udflabel_SOURCES = main.c options.c ../udfinfo/readdisc.c options.h ../udfinfo/readdisc.h ../include/ecma_167.h ../include/osta_udf.h ../include/libudffs.h ../include/bswap.h
AM_CPPFLAGS = -I$(top_srcdir)/include
all: all-am
diff --git a/udflabel/main.c b/udflabel/main.c
index 5c8c48d..28ff242 100644
--- a/udflabel/main.c
+++ b/udflabel/main.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2017 Pali Rohár <pali.rohar@gmail.com>
+ * Copyright (C) 2017-2018 Pali Rohár <pali.rohar@gmail.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
@@ -85,7 +85,7 @@ static int get_sector_size(int fd)
static uint16_t compute_crc(void *desc, size_t length)
{
- return cpu_to_le16(udf_crc((uint8_t *)desc + sizeof(tag), length - sizeof(tag), 0));
+ return udf_crc((uint8_t *)desc + sizeof(tag), length - sizeof(tag), 0);
}
static uint8_t compute_checksum(tag *tag)
@@ -127,7 +127,7 @@ static void write_desc(int fd, struct udf_disc *disc, enum udf_space_type type,
struct udf_extent *ext;
struct udf_desc *desc;
off_t off;
- size_t offset;
+ off_t offset;
ssize_t ret;
ext = disc->head;
@@ -141,9 +141,9 @@ static void write_desc(int fd, struct udf_disc *disc, enum udf_space_type type,
printf(" ... at block %lu\n", (unsigned long int)(ext->start + desc->offset));
- offset = (size_t)disc->blocksize * (ext->start + desc->offset);
+ offset = (off_t)disc->blocksize * (ext->start + desc->offset);
off = lseek(fd, offset, SEEK_SET);
- if (off != (off_t)-1 && (size_t)off != offset)
+ if (off != (off_t)-1 && off != offset)
{
errno = EIO;
off = (off_t)-1;
@@ -213,8 +213,15 @@ int main(int argc, char *argv[])
appname = "udflabel";
memset(&disc, 0, sizeof(disc));
- disc.flags = FLAG_LOCALE;
+
disc.head = calloc(1, sizeof(struct udf_extent));
+ if (!disc.head)
+ {
+ fprintf(stderr, "%s: Error: calloc failed: %s\n", appname, strerror(errno));
+ exit(1);
+ }
+
+ disc.flags = FLAG_LOCALE;
disc.tail = disc.head;
disc.head->space_type = USPACE;
@@ -381,11 +388,6 @@ int main(int argc, char *argv[])
break;
case PD_ACCESS_TYPE_WRITE_ONCE:
- if (!force && disc.udf_rev < 0x0200)
- {
- fprintf(stderr, "%s: Error: Cannot update writeonce partition of UDF revision prior to 2.00\n", appname);
- exit(1);
- }
if (!force && (new_fullvsid[0] != 0xFF || new_vid[0] != 0xFF))
{
fprintf(stderr, "%s: Error: Cannot update --vid, --vsid, --uuid or --fullvid on writeonce partition\n", appname);
@@ -535,7 +537,7 @@ int main(int argc, char *argv[])
{
if (!disc.udf_fsd || !check_desc(disc.udf_fsd, sizeof(*disc.udf_fsd)))
{
- fprintf(stderr, "%s: Error: Main File Set Descriptor is damaged\n", appname);
+ fprintf(stderr, "%s: Error: File Set Descriptor is damaged\n", appname);
exit(1);
}
}
@@ -647,21 +649,21 @@ int main(int argc, char *argv[])
write_desc(fd, &disc, PSPACE, TAG_IDENT_FSD, disc.udf_fsd);
}
- if (update_pvd)
+ if (update_pvd && disc.udf_pvd[1] != disc.udf_pvd[0])
{
printf("Updating Reserve Primary Volume Descriptor...\n");
update_desc(disc.udf_pvd[1], sizeof(*disc.udf_pvd[1]));
write_desc(fd, &disc, RVDS, TAG_IDENT_PVD, disc.udf_pvd[1]);
}
- if (update_lvd)
+ if (update_lvd && disc.udf_lvd[1] != disc.udf_lvd[0])
{
printf("Updating Reserve Logical Volume Descriptor...\n");
update_desc(disc.udf_lvd[1], sizeof(*disc.udf_lvd[1]) + le32_to_cpu(disc.udf_lvd[1]->mapTableLength));
write_desc(fd, &disc, RVDS, TAG_IDENT_LVD, disc.udf_lvd[1]);
}
- if (update_iuvd)
+ if (update_iuvd && disc.udf_iuvd[1] != disc.udf_iuvd[0])
{
printf("Updating Reserve Implementation Use Volume Descriptor...\n");
update_desc(disc.udf_iuvd[1], sizeof(*disc.udf_iuvd[1]));
diff --git a/udflabel/options.c b/udflabel/options.c
index 347461f..8220785 100644
--- a/udflabel/options.c
+++ b/udflabel/options.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2017 Pali Rohár <pali.rohar@gmail.com>
+ * Copyright (C) 2017-2018 Pali Rohár <pali.rohar@gmail.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
@@ -23,6 +23,7 @@
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
#include <time.h>
#include <fcntl.h>
@@ -89,45 +90,20 @@ static void usage(void)
exit(1);
}
-static unsigned long int strtoul_safe(const char *str, int base, int *failed)
-{
- char *endptr = NULL;
- unsigned long int ret;
- errno = 0;
- ret = strtoul(str, &endptr, base);
- *failed = (!*str || *endptr || errno) ? 1 : 0;
- return ret;
-}
-
-static void get_random_bytes(void *buffer, size_t count)
-{
- int fd;
- size_t i;
-
- fd = open("/dev/urandom", O_RDONLY);
- if (fd >= 0)
- {
- if (read(fd, buffer, count) == (ssize_t)count)
- {
- close(fd);
- return;
- }
- close(fd);
- }
-
- for (i = 0; i < count; ++i)
- ((uint8_t *)buffer)[i] = rand() % 0xFF;
-}
-
static void process_uuid_arg(const char *arg, char *new_uuid)
{
- unsigned long int rnd;
int i;
+ time_t cur_time;
+ uint32_t uuid_time;
if (strcmp(arg, "random") == 0)
{
- get_random_bytes(&rnd, sizeof(rnd));
- snprintf(new_uuid, 17, "%08lx%08lx", ((unsigned long int)time(NULL)) % 0xFFFFFFFF, rnd % 0xFFFFFFFF);
+ cur_time = time(NULL);
+ if (cur_time != (time_t)-1 && cur_time >= 0)
+ uuid_time = cur_time & 0xFFFFFFFF;
+ else
+ uuid_time = randu32();
+ snprintf(new_uuid, 17, "%08lx%08lx", (unsigned long int)uuid_time, (unsigned long int)randu32());
return;
}
@@ -181,7 +157,6 @@ static void process_vid_lvid_arg(struct udf_disc *disc, int option, const char *
void parse_args(int argc, char *argv[], struct udf_disc *disc, char **filename, int *force, dstring *new_lvid, dstring *new_vid, dstring *new_fsid, dstring *new_fullvsid, char *new_uuid, dstring *new_vsid)
{
- unsigned long int value;
int failed;
int ret;
size_t len;
@@ -196,22 +171,20 @@ void parse_args(int argc, char *argv[], struct udf_disc *disc, char **filename,
break;
case OPT_BLK_SIZE:
case 'b':
- value = strtoul_safe(optarg, 0, &failed);
- if (failed || value < 512 || value > 32768 || (value & (value - 1)))
+ disc->blocksize = strtou32(optarg, 0, &failed);
+ if (failed || disc->blocksize < 512 || disc->blocksize > 32768 || (disc->blocksize & (disc->blocksize - 1)))
{
fprintf(stderr, "%s: Error: Invalid value for option --blocksize\n", appname);
exit(1);
}
- disc->blocksize = value;
break;
case OPT_VAT_BLOCK:
- value = strtoul_safe(optarg, 0, &failed);
- if (failed || value > UINT32_MAX)
+ disc->vat_block = strtou32(optarg, 0, &failed);
+ if (failed)
{
fprintf(stderr, "%s: Error: Invalid value for option --vatblock\n", appname);
exit(1);
}
- disc->vat_block = value;
break;
case OPT_FORCE:
*force = 1;
diff --git a/wrudf/Makefile.am b/wrudf/Makefile.am
index fe1c269..4224b13 100644
--- a/wrudf/Makefile.am
+++ b/wrudf/Makefile.am
@@ -1,5 +1,10 @@
bin_PROGRAMS = wrudf
-wrudf_LDADD = $(top_builddir)/libudffs/libudffs.la -lreadline
+wrudf_LDADD = $(top_builddir)/libudffs/libudffs.la
wrudf_SOURCES = wrudf.c wrudf-cmnd.c wrudf-desc.c wrudf-cdrw.c wrudf-cdr.c ide-pc.c wrudf.h ide-pc.h ../include/ecma_167.h ../include/osta_udf.h ../include/bswap.h
-AM_CPPFLAGS = -I$(top_srcdir)/include -D_GNU_SOURCE -DDEBUG
+AM_CPPFLAGS = -I$(top_srcdir)/include
+
+if USE_READLINE
+wrudf_LDADD += -lreadline
+AM_CPPFLAGS += -DUSE_READLINE
+endif
diff --git a/wrudf/Makefile.in b/wrudf/Makefile.in
index bb55fa1..b27abea 100644
--- a/wrudf/Makefile.in
+++ b/wrudf/Makefile.in
@@ -89,6 +89,8 @@ POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
bin_PROGRAMS = wrudf$(EXEEXT)
+@USE_READLINE_TRUE@am__append_1 = -lreadline
+@USE_READLINE_TRUE@am__append_2 = -DUSE_READLINE
subdir = wrudf
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/configure.ac
@@ -105,7 +107,9 @@ am_wrudf_OBJECTS = wrudf.$(OBJEXT) wrudf-cmnd.$(OBJEXT) \
wrudf-desc.$(OBJEXT) wrudf-cdrw.$(OBJEXT) wrudf-cdr.$(OBJEXT) \
ide-pc.$(OBJEXT)
wrudf_OBJECTS = $(am_wrudf_OBJECTS)
-wrudf_DEPENDENCIES = $(top_builddir)/libudffs/libudffs.la
+am__DEPENDENCIES_1 =
+wrudf_DEPENDENCIES = $(top_builddir)/libudffs/libudffs.la \
+ $(am__DEPENDENCIES_1)
AM_V_lt = $(am__v_lt_@AM_V@)
am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
am__v_lt_0 = --silent
@@ -229,11 +233,17 @@ 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@
+UDEVDIR = @UDEVDIR@
+UDEV_CFLAGS = @UDEV_CFLAGS@
+UDEV_LIBS = @UDEV_LIBS@
VERSION = @VERSION@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
@@ -288,9 +298,9 @@ target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
-wrudf_LDADD = $(top_builddir)/libudffs/libudffs.la -lreadline
+wrudf_LDADD = $(top_builddir)/libudffs/libudffs.la $(am__append_1)
wrudf_SOURCES = wrudf.c wrudf-cmnd.c wrudf-desc.c wrudf-cdrw.c wrudf-cdr.c ide-pc.c wrudf.h ide-pc.h ../include/ecma_167.h ../include/osta_udf.h ../include/bswap.h
-AM_CPPFLAGS = -I$(top_srcdir)/include -D_GNU_SOURCE -DDEBUG
+AM_CPPFLAGS = -I$(top_srcdir)/include $(am__append_2)
all: all-am
.SUFFIXES:
diff --git a/wrudf/wrudf-cmnd.c b/wrudf/wrudf-cmnd.c
index bfa8136..e861d82 100644
--- a/wrudf/wrudf-cmnd.c
+++ b/wrudf/wrudf-cmnd.c
@@ -1097,12 +1097,17 @@ int
questionOverwrite(Directory *dir, struct fileIdentDesc *fid, char* name)
{
printf("File %s already exists. Overwrite ? (y/N) : ", name);
-#ifdef _GNU_SOURCE
+#ifdef USE_READLINE
readLine(NULL);
#else
- fgets(line, 256, stdin);
+ if (!fgets(line, 256, stdin))
+ line[0] = 0;
#endif
- if( !line || line[0] != 'y' )
+#ifdef USE_READLINE
+ if( !line )
+ return 1;
+#endif
+ if( line[0] != 'y' )
return 1;
deleteFID(dir, fid);
return 0;
diff --git a/wrudf/wrudf.c b/wrudf/wrudf.c
index 74dcdaf..27ba7a9 100644
--- a/wrudf/wrudf.c
+++ b/wrudf/wrudf.c
@@ -13,6 +13,10 @@
#include <locale.h>
#include <sys/resource.h>
+#ifdef USE_READLINE
+#include <readline/readline.h>
+#endif
+
#include "wrudf.h"
char *devicename; /* "/dev/cdrom" or disk image filename */
@@ -21,12 +25,12 @@ int devicetype;
enum MEDIUM medium;
int ignoreReadError; /* used while reading VRS which may be absent on open CDR */
-#ifdef _GNU_SOURCE
+#ifdef USE_READLINE
char *line;
#define GETLINE(prompt) readLine(prompt);
#else
char line[256];
-#define GETLINE(prompt) printf(prompt); fgets(line, 256, stdin); *strchr(line, '\n') = 0;
+#define GETLINE(prompt) do { printf("%s", prompt); if (fgets(line, 256, stdin)) *strchr(line, '\n') = 0; else line[0] = 0; } while (0)
#endif
@@ -74,12 +78,14 @@ struct sparingTable *st;
int spaceMapDirty, usdDirty, sparingTableDirty;
+#ifdef USE_READLINE
char* readLine(char* prompt) {
if( line ) {
free(line);
}
return line = readline(prompt);
}
+#endif
void
@@ -310,9 +316,14 @@ initialise(char *devicename)
fsdOut[0] = 0;
printf("You are going to update fileset '%s'\nProceed (y/N) : ", fsdOut);
- readLine(NULL);
+ GETLINE("");
+
+#ifdef USE_READLINE
+ if( !line )
+ fail("wrudf terminated\n");
+#endif
- if( !line || line[0] != 'y' )
+ if( line[0] != 'y' )
fail("wrudf terminated\n");
/* Read Logical Volume Integrity sequence */
@@ -632,7 +643,7 @@ parseCmnd(char* line)
int show_help()
{
char *msg =
- "Interactive tool to maintain an UDF filesystem.\n"
+ "Interactive tool to maintain a UDF filesystem.\n"
"Usage:\n"
"\twrudf [device]\n"
"Available commands:\n"
diff --git a/wrudf/wrudf.h b/wrudf/wrudf.h
index d9edba6..5d6a7f9 100644
--- a/wrudf/wrudf.h
+++ b/wrudf/wrudf.h
@@ -46,9 +46,7 @@ extern enum MEDIUM medium;
extern uint32_t trackSize;
-#ifdef _GNU_SOURCE
-/* I appear not to have readline.h */
-char* readline(char* prompt);
+#ifdef USE_READLINE
extern char *line;
#else
extern char line[256];
@@ -99,7 +97,9 @@ extern Directory *rootDir, *curDir;
/*wrudf.c */
+#ifdef USE_READLINE
char* readLine(char *prompt);
+#endif
/* wrudf-cmnd.c */
int updateDirectory(Directory* dir);